From ccd69d3f8817a14fdb80306a754009e4ac7b9693 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Tue, 24 Aug 2010 19:41:23 +0000 Subject: [PATCH] Dropped old SOPE patches Monotone-Parent: a87b5d8eea8be842c1ab7dc48667af2debe9bb21 Monotone-Revision: 398d5b0c3ce7ef971f2aa9111d0c4c5da3cba021 Monotone-Author: ludovic@Sophos.ca Monotone-Date: 2010-08-24T19:41:23 Monotone-Branch: ca.inverse.sogo --- SOPE/sope-debian.diff | 11495 -------------------------------- SOPE/sope-debugleaks.diff | 29 - SOPE/sope-gsmake2.diff | 3144 --------- SOPE/sope-ngobjweb-fix.diff | 12 - SOPE/sope-patchset-r1664.diff | 9408 -------------------------- 5 files changed, 24088 deletions(-) delete mode 100644 SOPE/sope-debian.diff delete mode 100644 SOPE/sope-debugleaks.diff delete mode 100644 SOPE/sope-gsmake2.diff delete mode 100644 SOPE/sope-ngobjweb-fix.diff delete mode 100644 SOPE/sope-patchset-r1664.diff diff --git a/SOPE/sope-debian.diff b/SOPE/sope-debian.diff deleted file mode 100644 index 14355227c..000000000 --- a/SOPE/sope-debian.diff +++ /dev/null @@ -1,11495 +0,0 @@ ---- sope-4.9.r1664.orig/debian/sope_SOPEVER_-gdl1-postgresql.install -+++ sope-4.9.r1664/debian/sope_SOPEVER_-gdl1-postgresql.install -@@ -1 +1 @@ --usr/lib/sope-*/dbadaptors/PostgreSQL.gdladaptor -+usr/lib/GNUstep/GDLAdaptors-*/PostgreSQL.gdladaptor ---- sope-4.9.r1664.orig/debian/libsope-ical_SOPEVER_-dev.install -+++ sope-4.9.r1664/debian/libsope-ical_SOPEVER_-dev.install -@@ -1,2 +1,2 @@ --usr/include/NGiCal -+usr/include/GNUstep/NGiCal - usr/lib/libNGiCal.so ---- sope-4.9.r1664.orig/debian/changelog -+++ sope-4.9.r1664/debian/changelog -@@ -1,3 +1,28 @@ -+sope (4.9.r1664-1) unstable; urgency=low -+ -+ * updated SOPE patchset for SOGo 1.2.0. -+ * updated upstream SOPE revision to 1664. -+ -+ -- Inverse Support Wed, 06 Jan 2010 14:49:27 -0500 -+ -+sope (4.9.r1660-2) unstable; urgency=low -+ -+ * debian/control: -+ - we now build the sopeXX-gdl1-mysql package. -+ * updated SOPE patchset from SOGo 1.1.0. -+ -+ -- Inverse Support Mon, 19 Oct 2009 16:36:29 -0400 -+ -+sope (4.9.r1660-1) unstable; urgency=low -+ -+ * debian/control: -+ - updated dependencies -+ - changed {Source-Version} with {binary:Version} -+ - bumbed standard to 3.8.2 -+ - updated debian/copyright with recent LGPL-2 -+ -+ -- Inverse Support Wed, 12 Aug 2009 10:34:00 -0400 -+ - sope (4.7.0-0) UNRELEASED; urgency=low - - * New upstream release. ---- sope-4.9.r1664.orig/debian/rules -+++ sope-4.9.r1664/debian/rules -@@ -7,13 +7,16 @@ - #export DH_VERBOSE=1 - - # Include dpatch stuff. --include /usr/share/dpatch/dpatch.make -+# include /usr/share/dpatch/dpatch.make -+ -+PATCHES = sope-gsmake2.diff sope-patchset-r1664.diff debian-build-mysql.diff -+RPATCHES = debian-build-mysql.diff sope-patchset-r1664.diff sope-gsmake2.diff - - CFLAGS = -Wall -g - #WARN: doesn't compile/package if HAS_LIBRARY_* options not present (since we use configure now) - MAKE_FLAGS = messages=yes OPTFLAG=-O0 HAS_LIBRARY_ldap=yes HAS_LIBRARY_pq=yes HAS_LIBRARY_xml2=yes - --GNUSTEP_SETUP=/usr/lib/opengroupware.org/System/Library/Makefiles/GNUstep.sh -+GNUSTEP_SETUP=/usr/share/GNUstep/Makefiles/GNUstep.sh - - include Version - SOPEVER=$(MAJOR_VERSION).$(MINOR_VERSION) -@@ -50,17 +53,17 @@ - done; \ - rm controlfiles.tmp; \ - fi -- -+ - debian/control: debian/control.in debian/rules - sed -e s/_SOPEVER_/$(SOPEVER)/g < debian/control.in > debian/control - --config.status: configure -+config.make: patch-stamp - dh_testdir - CFLAGS="$(CFLAGS)" . $(GNUSTEP_SETUP); \ -- ./configure -- --build: build-stamp controlfiles --build-stamp: patch-stamp -+ ./configure --with-gnustep --enable-debug --disable-strip -+ -+build: config.make build-stamp controlfiles -+build-stamp: - dh_testdir - - -mv sope-core/NGStreams/config.guess sope-core/NGStreams/config.guess.upstream -@@ -71,14 +74,14 @@ - CFLAGS="$(CFLAGS)" . $(GNUSTEP_SETUP); \ - $(MAKE) $(MAKE_FLAGS) all - -- cp -R sope-appserver/mod_ngobjweb sope-appserver/mod_ngobjweb-apache2 -+# cp -R sope-appserver/mod_ngobjweb sope-appserver/mod_ngobjweb-apache2 - -- CFLAGS="$(CFLAGS)" . $(GNUSTEP_SETUP); \ -- $(MAKE) $(MAKE_FLAGS) APXS=/usr/bin/apxs -C sope-appserver/mod_ngobjweb all -- -- CFLAGS="$(CFLAGS)" . $(GNUSTEP_SETUP); \ -- $(MAKE) $(MAKE_FLAGS) APXS="/usr/bin/apxs2" APXS_INCLUDE_DIRS="$(shell apxs2 -q EXTRA_INCLUDES)"\ -- -C sope-appserver/mod_ngobjweb-apache2 all -+# CFLAGS="$(CFLAGS)" . $(GNUSTEP_SETUP); \ -+# $(MAKE) $(MAKE_FLAGS) APXS=/usr/bin/apxs -C sope-appserver/mod_ngobjweb all -+ -+# CFLAGS="$(CFLAGS)" . $(GNUSTEP_SETUP); \ -+# $(MAKE) $(MAKE_FLAGS) APXS="/usr/bin/apxs2" APXS_INCLUDE_DIRS="$(shell apxs2 -q EXTRA_INCLUDES)"\ -+# -C sope-appserver/mod_ngobjweb-apache2 all - - touch build-stamp - -@@ -87,12 +90,14 @@ - dh_testroot - rm -f configure-stamp - rm -f build-stamp -+ rm -f config-NSStreams.log - rm -rf sope-appserver/mod_ngobjweb-apache2 -+ rm -rf sope-core/NGStreams/x86_64 - -- if [ -l sope-core/NGStreams/config.guess ]; then \ -+ if [ -L sope-core/NGStreams/config.guess ]; then \ - rm sope-core/NGStreams/config.guess; \ - fi -- if [ -l sope-core/NGStreams/config.sub ]; then \ -+ if [ -L sope-core/NGStreams/config.sub ]; then \ - rm sope-core/NGStreams/config.sub; \ - fi - if [ -f sope-core/NGStreams/config.guess.upstream ]; then \ -@@ -102,8 +107,8 @@ - mv sope-core/NGStreams/config.sub.upstream sope-core/NGStreams/config.sub; \ - fi - -- -. $(GNUSTEP_SETUP); $(MAKE) -C sope-appserver/mod_ngobjweb clean -- -. $(GNUSTEP_SETUP); $(MAKE) -C sope-appserver/mod_ngobjweb distclean -+# -. $(GNUSTEP_SETUP); $(MAKE) -C sope-appserver/mod_ngobjweb clean -+# -. $(GNUSTEP_SETUP); $(MAKE) -C sope-appserver/mod_ngobjweb distclean - - -. $(GNUSTEP_SETUP); $(MAKE) clean - -. $(GNUSTEP_SETUP); $(MAKE) distclean -@@ -116,24 +121,24 @@ - dh_clean -k - dh_installdirs - -- # Add here commands to install the package into debian/tmp -+# Add here commands to install the package into debian/tmp - CFLAGS="$(CFLAGS)" . $(GNUSTEP_SETUP); \ - $(MAKE) $(MAKE_FLAGS) install \ -- GNUSTEP_INSTALLATION_DIR=$(CURDIR)/debian/tmp/$$GNUSTEP_SYSTEM_ROOT\ -- INSTALL_ROOT_DIR=$(CURDIR)/debian/tmp\ -+ DESTDIR=$(CURDIR)/debian/tmp GNUSTEP_INSTALLATION_DOMAIN=SYSTEM -+# INSTALL_ROOT_DIR=$(CURDIR)/debian/tmp\ - FHS_INSTALL_ROOT=$(CURDIR)/debian/tmp/usr \ - FHS_LIB_DIR=$(CURDIR)/debian/tmp/usr/lib/ #WARN: <- trailing slash unbroke build/packages?! - -- CFLAGS="$(CFLGAS)" . $(GNUSTEP_SETUP); \ -+# CFLAGS="$(CFLGAS)" . $(GNUSTEP_SETUP); \ - $(MAKE) $(MAKE_FLAGS) -C sope-appserver/mod_ngobjweb install \ -- GNUSTEP_INSTALLATION_DIR=$(CURDIR)/debian/tmp/usr/lib/apache/1.3 -+ GNUSTEP_INSTALLATION_DOMAIN=$(CURDIR)/debian/tmp/usr/lib/apache/1.3 - -- CFLAGS="$(CFLGAS)" . $(GNUSTEP_SETUP); \ -+# CFLAGS="$(CFLGAS)" . $(GNUSTEP_SETUP); \ - $(MAKE) $(MAKE_FLAGS) -C sope-appserver/mod_ngobjweb-apache2 install \ -- GNUSTEP_INSTALLATION_DIR=$(CURDIR)/debian/tmp/usr/lib/apache2/modules -+ GNUSTEP_INSTALLATION_DOMAIN=$(CURDIR)/debian/tmp/usr/lib/apache2/modules - -- install -m 644 debian/500mod_ngobjweb.info $(CURDIR)/debian/libapache-mod-ngobjweb/usr/lib/apache/1.3 -- install -m 644 debian/ngobjweb.load $(CURDIR)/debian/libapache2-mod-ngobjweb/etc/apache2/mods-available -+# install -m 644 debian/500mod_ngobjweb.info $(CURDIR)/debian/libapache-mod-ngobjweb/usr/lib/apache/1.3 -+# install -m 644 debian/ngobjweb.load $(CURDIR)/debian/libapache2-mod-ngobjweb/etc/apache2/mods-available - - # Build architecture-independent files here. - binary-indep: build install -@@ -172,5 +177,28 @@ - dh_md5sums - dh_builddeb - -+patch-stamp: patch -+patch: -+ for patch in $(PATCHES); \ -+ do \ -+ if ! test -f debian/patches/$$patch.stamp; \ -+ then \ -+ patch -p0 < debian/patches/$$patch; \ -+ touch debian/patches/$$patch.stamp; \ -+ fi; \ -+ done -+ touch patch-stamp -+ -+unpatch: -+ if test -f patch-stamp; \ -+ then \ -+ for patch in $(RPATCHES); \ -+ do \ -+ patch -p0 -R < debian/patches/$$patch; \ -+ rm -f debian/patches/$$patch.stamp; \ -+ done; \ -+ rm -f patch-stamp; \ -+ fi -+ - binary: binary-indep binary-arch - .PHONY: build clean binary-indep binary-arch binary install configure ---- sope-4.9.r1664.orig/debian/sope_SOPEVER_-libxmlsaxdriver.install -+++ sope-4.9.r1664/debian/sope_SOPEVER_-libxmlsaxdriver.install -@@ -1 +1 @@ --usr/lib/sope-*/saxdrivers/libxmlSAXDriver.sax -+usr/lib/GNUstep/SaxDrivers-*/libxmlSAXDriver.sax ---- sope-4.9.r1664.orig/debian/sope_SOPEVER_-gdl1-mysql.install -+++ sope-4.9.r1664/debian/sope_SOPEVER_-gdl1-mysql.install -@@ -0,0 +1 @@ -+usr/lib/GNUstep/GDLAdaptors-*/MySQL.gdladaptor ---- sope-4.9.r1664.orig/debian/control.in -+++ sope-4.9.r1664/debian/control.in -@@ -1,8 +1,9 @@ - Source: sope -+Section: web - Priority: extra --Maintainer: Sebastian Ley --Build-Depends: debhelper (>= 4.0.0), dpatch, gnustep-make-ogo, gobjc | objc-compiler, libfoundation1.1-dev, libobjc1, libxml2-dev, libldap2-dev | libldap-dev, libssl-dev, zlib1g-dev, libpq-dev | postgresql-dev, libecpg-dev, apache-dev, apache2-threaded-dev | apache2-prefork-dev | apache2-dev, autotools-dev --Standards-Version: 3.6.1 -+Maintainer: Inverse Support -+Build-Depends: debhelper (>= 4.0.0), gnustep-make, libgnustep-base-dev, gobjc | objc-compiler, libxml2-dev, libldap2-dev | libldap-dev, libssl-dev, zlib1g-dev, libpq-dev | postgresql-dev, libmysqlclient-dev (>= 5.0) | libmysqlclient15-dev (>= 5.0), autotools-dev -+Standards-Version: 3.8.2 - - Package: libsope_SOPEVER_-dev - Section: libdevel -@@ -22,7 +23,7 @@ - Architecture: any - Provides: libsope-appserver-dev - Conflicts: libsope-appserver-dev --Depends: libsope-appserver_SOPEVER_ (= ${Source-Version}) -+Depends: libsope-appserver_SOPEVER_ (= ${binary:Version}) - Description: Development files for the SOPE libraries - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -@@ -75,7 +76,7 @@ - Architecture: any - Provides: libsope-core-dev - Conflicts: libsope-core-dev --Depends: libsope-core_SOPEVER_ (= ${Source-Version}) -+Depends: libsope-core_SOPEVER_ (= ${binary:Version}) - Description: Development files for the SOPE core libraries - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -@@ -98,7 +99,7 @@ - Architecture: any - Provides: libsope-xml-dev - Conflicts: libsope-xml-dev --Depends: libsope-xml_SOPEVER_ (= ${Source-Version}) -+Depends: libsope-xml_SOPEVER_ (= ${binary:Version}) - Description: Development files for the SOPE XML libraries - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -@@ -125,7 +126,7 @@ - Architecture: any - Provides: libsope-ldap-dev - Conflicts: libsope-ldap-dev --Depends: libsope-ldap_SOPEVER_ (= ${Source-Version}) -+Depends: libsope-ldap_SOPEVER_ (= ${binary:Version}) - Description: Development files for the SOPE LDAP libraries - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -@@ -149,7 +150,7 @@ - Architecture: any - Provides: libsope-mime-dev - Conflicts: libsope-mime-dev --Depends: libsope-mime_SOPEVER_ (= ${Source-Version}) -+Depends: libsope-mime_SOPEVER_ (= ${binary:Version}) - Description: Development files for the SOPE MIME libraries - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -@@ -176,7 +177,7 @@ - Architecture: any - Provides: libsope-ical-dev - Conflicts: libsope-ical-dev --Depends: libsope-ical_SOPEVER_ (= ${Source-Version}) -+Depends: libsope-ical_SOPEVER_ (= ${binary:Version}) - Description: Development files for the SOPE iCal libraries - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -@@ -200,7 +201,7 @@ - Architecture: any - Provides: libsope-gdl1-dev - Conflicts: libsope-gdl1-dev --Depends: libsope-gdl1-_SOPEVER_ (= ${Source-Version}) -+Depends: libsope-gdl1-_SOPEVER_ (= ${binary:Version}) - Description: Development files for the GNUstep database libraries - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -@@ -223,15 +224,28 @@ - Section: web - Architecture: any - Depends: ${shlibs:Depends}, ${misc:Depends} --Provides: sope-db-connector --Recommends: postgresql (>= 7.2.0) -+Provides: sope_SOPEVER_-db-connector -+Suggests: postgresql (>= 8.2) - Description: PostgreSQL connector for SOPE's fork of the GNUstep database environment - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. - . - This package contains the postgresql connector for SOPE's fork of the - GNUstep database libraries. -- -+ -+Package: sope_SOPEVER_-gdl1-mysql -+Section: web -+Architecture: any -+Depends: ${shlibs:Depends}, ${misc:Depends} -+Provides: sope_SOPEVER_-db-connector -+Recommends: mysql-server (>= 5.0) -+Description: MySQL connector for SOPE's fork of the GNUstep database environment -+ SOPE is a framework for developing web applications and services. The -+ name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -+ . -+ This package contains the mysql connector for SOPE's fork of the -+ GNUstep database libraries. -+ - Package: sope_SOPEVER_-stxsaxdriver - Section: web - Architecture: any -@@ -264,19 +278,3 @@ - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. - . - This parser enables SOPE's SAX engine to parse iCal and vCard files. -- --Package: libapache-mod-ngobjweb --Section: web --Architecture: any --Depends: ${shlibs:Depends}, ${misc:Depends}, ucf (>= 0.8), apache-common (>= 1.3.29) --Description: Apache module for the SOPE application server -- This package contains an apache module which enables the apache -- webserver to deliver pages generated by the SOPE application server. -- --Package: libapache2-mod-ngobjweb --Section: web --Architecture: any --Depends: ${shlibs:Depends}, ${misc:Depends}, apache2-common | apache2.2-common --Description: Apache2 module for the SOPE application server -- This package contains an apache module which enables the apache2 -- webserver to deliver pages generated by the SOPE application server. ---- sope-4.9.r1664.orig/debian/libsope-ical_SOPEVER_.install -+++ sope-4.9.r1664/debian/libsope-ical_SOPEVER_.install -@@ -1,2 +1,2 @@ - usr/lib/libNGiCal.so.* --usr/share/sope-*/saxmappings -+usr/lib/GNUstep/SaxMappings/* ---- sope-4.9.r1664.orig/debian/libsope-core_SOPEVER_-dev.install -+++ sope-4.9.r1664/debian/libsope-core_SOPEVER_-dev.install -@@ -1,6 +1,6 @@ --usr/include/NGExtensions --usr/include/EOControl --usr/include/NGStreams -+usr/include/GNUstep/NGExtensions -+usr/include/GNUstep/EOControl -+usr/include/GNUstep/NGStreams - usr/lib/libNGExtensions.so - usr/lib/libEOControl.so - usr/lib/libNGStreams.so ---- sope-4.9.r1664.orig/debian/sope_SOPEVER_-stxsaxdriver.install -+++ sope-4.9.r1664/debian/sope_SOPEVER_-stxsaxdriver.install -@@ -1 +1 @@ --usr/lib/sope-*/saxdrivers/STXSaxDriver.sax -+usr/lib/GNUstep/SaxDrivers-*/STXSaxDriver.sax ---- sope-4.9.r1664.orig/debian/compat -+++ sope-4.9.r1664/debian/compat -@@ -1 +1 @@ --4 -+5 ---- sope-4.9.r1664.orig/debian/libsope-mime_SOPEVER_-dev.install -+++ sope-4.9.r1664/debian/libsope-mime_SOPEVER_-dev.install -@@ -1,4 +1,4 @@ --usr/include/NGMime --usr/include/NGImap4 --usr/include/NGMail -+usr/include/GNUstep/NGMime -+usr/include/GNUstep/NGImap4 -+usr/include/GNUstep/NGMail - usr/lib/libNGMime.so ---- sope-4.9.r1664.orig/debian/copyright -+++ sope-4.9.r1664/debian/copyright -@@ -8,19 +8,19 @@ - - License: - -- This package is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -+ This library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - -- This package is distributed in the hope that it will be useful, -+ This library 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 -- Lesser General Public License for more details. -+ Library General Public License for more details. - -- You should have received a copy of the GNU Lesser General Public -- License along with this package; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ You should have received a copy of the GNU Library General Public -+ License along with this library; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA - - On Debian systems, the complete text of the GNU Lesser General - Public License can be found in `/usr/share/common-licenses/LGPL'. ---- sope-4.9.r1664.orig/debian/libsope-appserver_SOPEVER_-dev.install -+++ sope-4.9.r1664/debian/libsope-appserver_SOPEVER_-dev.install -@@ -1,11 +1,10 @@ --usr/include/NGHttp --usr/include/NGObjWeb --usr/include/WOXML --usr/include/WOExtensions --usr/include/WEExtensions --usr/include/NGXmlRpc --usr/include/SoOFS --usr/lib/opengroupware.org/System/Library/Makefiles -+usr/include/GNUstep/NGHttp -+usr/include/GNUstep/NGObjWeb -+usr/include/GNUstep/WOXML -+usr/include/GNUstep/WOExtensions -+usr/include/GNUstep/WEExtensions -+usr/include/GNUstep/NGXmlRpc -+usr/include/GNUstep/SoOFS - usr/lib/libNGObjWeb.so - usr/lib/libWOXML.so - usr/lib/libWOExtensions.so -@@ -13,3 +12,4 @@ - usr/lib/libNGXmlRpc.so - usr/lib/libSoOFS.so - usr/lib/libWEPrototype.so -+usr/share/GNUstep/Makefiles/* ---- sope-4.9.r1664.orig/debian/control -+++ sope-4.9.r1664/debian/control -@@ -1,8 +1,9 @@ - Source: sope -+Section: web - Priority: extra --Maintainer: Sebastian Ley --Build-Depends: debhelper (>= 4.0.0), dpatch, gnustep-make-ogo, gobjc | objc-compiler, libfoundation1.1-dev, libobjc1, libxml2-dev, libldap2-dev | libldap-dev, libssl-dev, zlib1g-dev, libpq-dev | postgresql-dev, libecpg-dev, apache-dev, apache2-threaded-dev | apache2-prefork-dev | apache2-dev, autotools-dev --Standards-Version: 3.6.1 -+Maintainer: Inverse Support -+Build-Depends: debhelper (>= 4.0.0), gnustep-make, libgnustep-base-dev, gobjc | objc-compiler, libxml2-dev, libldap2-dev | libldap-dev, libssl-dev, zlib1g-dev, libpq-dev | postgresql-dev, libmysqlclient-dev (>= 5.0) | libmysqlclient15-dev (>= 5.0), autotools-dev -+Standards-Version: 3.8.2 - - Package: libsope4.9-dev - Section: libdevel -@@ -22,7 +23,7 @@ - Architecture: any - Provides: libsope-appserver-dev - Conflicts: libsope-appserver-dev --Depends: libsope-appserver4.9 (= ${Source-Version}) -+Depends: libsope-appserver4.9 (= ${binary:Version}) - Description: Development files for the SOPE libraries - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -@@ -75,7 +76,7 @@ - Architecture: any - Provides: libsope-core-dev - Conflicts: libsope-core-dev --Depends: libsope-core4.9 (= ${Source-Version}) -+Depends: libsope-core4.9 (= ${binary:Version}) - Description: Development files for the SOPE core libraries - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -@@ -98,7 +99,7 @@ - Architecture: any - Provides: libsope-xml-dev - Conflicts: libsope-xml-dev --Depends: libsope-xml4.9 (= ${Source-Version}) -+Depends: libsope-xml4.9 (= ${binary:Version}) - Description: Development files for the SOPE XML libraries - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -@@ -125,7 +126,7 @@ - Architecture: any - Provides: libsope-ldap-dev - Conflicts: libsope-ldap-dev --Depends: libsope-ldap4.9 (= ${Source-Version}) -+Depends: libsope-ldap4.9 (= ${binary:Version}) - Description: Development files for the SOPE LDAP libraries - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -@@ -149,7 +150,7 @@ - Architecture: any - Provides: libsope-mime-dev - Conflicts: libsope-mime-dev --Depends: libsope-mime4.9 (= ${Source-Version}) -+Depends: libsope-mime4.9 (= ${binary:Version}) - Description: Development files for the SOPE MIME libraries - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -@@ -176,7 +177,7 @@ - Architecture: any - Provides: libsope-ical-dev - Conflicts: libsope-ical-dev --Depends: libsope-ical4.9 (= ${Source-Version}) -+Depends: libsope-ical4.9 (= ${binary:Version}) - Description: Development files for the SOPE iCal libraries - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -@@ -200,7 +201,7 @@ - Architecture: any - Provides: libsope-gdl1-dev - Conflicts: libsope-gdl1-dev --Depends: libsope-gdl1-4.9 (= ${Source-Version}) -+Depends: libsope-gdl1-4.9 (= ${binary:Version}) - Description: Development files for the GNUstep database libraries - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -@@ -223,15 +224,28 @@ - Section: web - Architecture: any - Depends: ${shlibs:Depends}, ${misc:Depends} --Provides: sope-db-connector --Recommends: postgresql (>= 7.2.0) -+Provides: sope4.9-db-connector -+Suggests: postgresql (>= 8.2) - Description: PostgreSQL connector for SOPE's fork of the GNUstep database environment - SOPE is a framework for developing web applications and services. The - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. - . - This package contains the postgresql connector for SOPE's fork of the - GNUstep database libraries. -- -+ -+Package: sope4.9-gdl1-mysql -+Section: web -+Architecture: any -+Depends: ${shlibs:Depends}, ${misc:Depends} -+Provides: sope4.9-db-connector -+Recommends: mysql-server (>= 5.0) -+Description: MySQL connector for SOPE's fork of the GNUstep database environment -+ SOPE is a framework for developing web applications and services. The -+ name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. -+ . -+ This package contains the mysql connector for SOPE's fork of the -+ GNUstep database libraries. -+ - Package: sope4.9-stxsaxdriver - Section: web - Architecture: any -@@ -264,19 +278,3 @@ - name "SOPE" (SKYRiX Object Publishing Environment) is inspired by ZOPE. - . - This parser enables SOPE's SAX engine to parse iCal and vCard files. -- --Package: libapache-mod-ngobjweb --Section: web --Architecture: any --Depends: ${shlibs:Depends}, ${misc:Depends}, ucf (>= 0.8), apache-common (>= 1.3.29) --Description: Apache module for the SOPE application server -- This package contains an apache module which enables the apache -- webserver to deliver pages generated by the SOPE application server. -- --Package: libapache2-mod-ngobjweb --Section: web --Architecture: any --Depends: ${shlibs:Depends}, ${misc:Depends}, apache2-common | apache2.2-common --Description: Apache2 module for the SOPE application server -- This package contains an apache module which enables the apache2 -- webserver to deliver pages generated by the SOPE application server. ---- sope-4.9.r1664.orig/debian/libsope-xml_SOPEVER_-dev.install -+++ sope-4.9.r1664/debian/libsope-xml_SOPEVER_-dev.install -@@ -1,6 +1,6 @@ --usr/include/DOM --usr/include/SaxObjC --usr/include/XmlRpc -+usr/include/GNUstep/DOM -+usr/include/GNUstep/SaxObjC -+usr/include/GNUstep/XmlRpc - usr/lib/libDOM.so - usr/lib/libSaxObjC.so - usr/lib/libXmlRpc.so ---- sope-4.9.r1664.orig/debian/sope_SOPEVER_-versitsaxdriver.install -+++ sope-4.9.r1664/debian/sope_SOPEVER_-versitsaxdriver.install -@@ -1 +1 @@ --usr/lib/sope-*/saxdrivers/versitSaxDriver.sax -+usr/lib/GNUstep/SaxDrivers-*/versitSaxDriver.sax ---- sope-4.9.r1664.orig/debian/libsope-gdl1-_SOPEVER_-dev.install -+++ sope-4.9.r1664/debian/libsope-gdl1-_SOPEVER_-dev.install -@@ -1,2 +1,2 @@ --usr/include/GDLAccess -+usr/include/GNUstep/GDLAccess - usr/lib/libGDLAccess.so ---- sope-4.9.r1664.orig/debian/libsope-ldap_SOPEVER_-dev.install -+++ sope-4.9.r1664/debian/libsope-ldap_SOPEVER_-dev.install -@@ -1,2 +1,2 @@ --usr/include/NGLdap -+usr/include/GNUstep/NGLdap - usr/lib/libNGLdap.so ---- sope-4.9.r1664.orig/debian/libsope-appserver_SOPEVER_.install -+++ sope-4.9.r1664/debian/libsope-appserver_SOPEVER_.install -@@ -5,6 +5,6 @@ - usr/lib/libNGXmlRpc.so.* - usr/lib/libSoOFS.so.* - usr/lib/libWEPrototype.so.* --usr/share/sope-*/ngobjweb --usr/lib/sope-*/products --usr/lib/sope-*/wox-builders -+usr/lib/GNUstep/Libraries/Resources/NGObjWeb/* -+usr/lib/GNUstep/SoProducts-*/* -+usr/lib/GNUstep/WOxElemBuilders-*/* ---- sope-4.9.r1664.orig/debian/patches/sope-patchset-r1664.diff -+++ sope-4.9.r1664/debian/patches/sope-patchset-r1664.diff -@@ -0,0 +1,7726 @@ -+Index: sope-ldap/NGLdap/NGLdapEntry.m -+=================================================================== -+--- sope-ldap/NGLdap/NGLdapEntry.m (revision 1664) -++++ sope-ldap/NGLdap/NGLdapEntry.m (working copy) -+@@ -105,14 +105,16 @@ -+ - (NGLdapAttribute *)attributeWithName:(NSString *)_name { -+ NSEnumerator *e; -+ NGLdapAttribute *a; -+- -++ NSString *upperName; -++ -+ if (_name == nil) -+ return nil; -+ -++ upperName = [_name uppercaseString]; -+ e = [self->attributes objectEnumerator]; -+ -+ while ((a = [e nextObject])) { -+- if ([[a attributeName] isEqualToString:_name]) -++ if ([[[a attributeName] uppercaseString] isEqualToString:upperName]) -+ return a; -+ } -+ return nil; -+Index: sope-ldap/NGLdap/ChangeLog -+=================================================================== -+--- sope-ldap/NGLdap/ChangeLog (revision 1664) -++++ sope-ldap/NGLdap/ChangeLog (working copy) -+@@ -1,3 +1,8 @@ -++2009-08-13 Wolfgang Sourdeau -++ -++ * NGLdapEntry.m (-attributeWithName:): attribute names are now -++ accessed in a case-insensitive way. -++ -+ 2009-04-02 Wolfgang Sourdeau -+ -+ * NGLdapConnection.m (useSSL,startTLS): new method enabling -+Index: sope-gdl1/PostgreSQL/PostgreSQL72Channel.m -+=================================================================== -+--- sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (revision 1664) -++++ sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (working copy) -+@@ -713,6 +713,39 @@ -+ return ms; -+ } -+ -++/* GCSEOAdaptorChannel protocol */ -++static NSString *sqlFolderFormat = (@"CREATE TABLE %@ (\n" \ -++ @" c_name VARCHAR (256) NOT NULL PRIMARY KEY,\n" -++ @" c_content VARCHAR (100000) NOT NULL,\n" -++ @" c_creationdate INT4 NOT NULL,\n" -++ @" c_lastmodified INT4 NOT NULL,\n" -++ @" c_version INT4 NOT NULL,\n" -++ @" c_deleted INT4 NULL\n" -++ @")"); -++static NSString *sqlFolderACLFormat = (@"CREATE TABLE %@ (\n" \ -++ @" c_uid VARCHAR (256) NOT NULL,\n" -++ @" c_object VARCHAR (256) NOT NULL,\n" -++ @" c_role VARCHAR (80) NOT NULL\n" -++ @")"); -++ -++- (NSException *) createGCSFolderTableWithName: (NSString *) tableName -++{ -++ NSString *sql; -++ -++ sql = [NSString stringWithFormat: sqlFolderFormat, tableName]; -++ -++ return [self evaluateExpressionX: sql]; -++} -++ -++- (NSException *) createGCSFolderACLTableWithName: (NSString *) tableName -++{ -++ NSString *sql; -++ -++ sql = [NSString stringWithFormat: sqlFolderACLFormat, tableName]; -++ -++ return [self evaluateExpressionX: sql]; -++} -++ -+ @end /* PostgreSQL72Channel */ -+ -+ @implementation PostgreSQL72Channel(PrimaryKeyGeneration) -+Index: sope-gdl1/MySQL/MySQL4Channel.m -+=================================================================== -+--- sope-gdl1/MySQL/MySQL4Channel.m (revision 1664) -++++ sope-gdl1/MySQL/MySQL4Channel.m (working copy) -+@@ -755,6 +755,39 @@ -+ return pkey; -+ } -+ -++/* GCSEOAdaptorChannel protocol */ -++static NSString *sqlFolderFormat = (@"CREATE TABLE %@ (\n" \ -++ @" c_name VARCHAR (256) NOT NULL PRIMARY KEY,\n" -++ @" c_content VARCHAR (100000) NOT NULL,\n" -++ @" c_creationdate INT NOT NULL,\n" -++ @" c_lastmodified INT NOT NULL,\n" -++ @" c_version INT NOT NULL,\n" -++ @" c_deleted INT NULL\n" -++ @")"); -++static NSString *sqlFolderACLFormat = (@"CREATE TABLE %@ (\n" \ -++ @" c_uid VARCHAR (256) NOT NULL,\n" -++ @" c_object VARCHAR (256) NOT NULL,\n" -++ @" c_role VARCHAR (80) NOT NULL\n" -++ @")"); -++ -++- (NSException *) createGCSFolderTableWithName: (NSString *) tableName -++{ -++ NSString *sql; -++ -++ sql = [NSString stringWithFormat: sqlFolderFormat, tableName]; -++ -++ return [self evaluateExpressionX: sql]; -++} -++ -++- (NSException *) createGCSFolderACLTableWithName: (NSString *) tableName -++{ -++ NSString *sql; -++ -++ sql = [NSString stringWithFormat: sqlFolderACLFormat, tableName]; -++ -++ return [self evaluateExpressionX: sql]; -++} -++ -+ @end /* MySQL4Channel */ -+ -+ void __link_MySQL4Channel() { -+Index: sope-gdl1/Oracle8/OracleAdaptorChannel.m -+=================================================================== -+--- sope-gdl1/Oracle8/OracleAdaptorChannel.m (revision 1664) -++++ sope-gdl1/Oracle8/OracleAdaptorChannel.m (working copy) -+@@ -1,7 +1,7 @@ -+ /* -+ ** OracleAdaptorChannel.m -+ ** -+-** Copyright (c) 2007 Inverse groupe conseil inc. and Ludovic Marcotte -++** Copyright (c) 2007-2009 Inverse inc. and Ludovic Marcotte -+ ** -+ ** Author: Ludovic Marcotte -+ ** -+@@ -30,6 +30,11 @@ -+ -+ #import -+ -++#include -++ -++static BOOL debugOn = NO; -++static int maxTry = 3; -++static int maxSleep = 500; -+ // -+ // -+ // -+@@ -41,10 +46,11 @@ -+ -+ @implementation OracleAdaptorChannel (Private) -+ -+-- (void) _cleanup -++- (void) _cleanup -+ { -+ column_info *info; -+ int c; -++ sword result; -+ -+ [_resultSetProperties removeAllObjects]; -+ -+@@ -58,11 +64,29 @@ -+ // so we just free the value instead. -+ if (info->value) -+ { -+- if (OCIDescriptorFree((dvoid *)info->value, (ub4)OCI_DTYPE_LOB) != OCI_SUCCESS) -++ if (info->type == SQLT_CLOB -++ || info->type == SQLT_BLOB -++ || info->type == SQLT_BFILEE -++ || info->type == SQLT_CFILEE) -++ { -++ result = OCIDescriptorFree((dvoid *)info->value, (ub4) OCI_DTYPE_LOB); -++ if (result != OCI_SUCCESS) -++ { -++ NSLog (@"value was not a LOB descriptor"); -++ abort(); -++ } -++ } -++ else -+ free(info->value); -+ info->value = NULL; -+ } -+- free(info); -++ else -++ { -++ NSLog (@"trying to free an already freed value!"); -++ abort(); -++ } -++ free(info); -++ -+ [_row_buffer removeObjectAtIndex: c]; -+ } -+ -+@@ -78,8 +102,7 @@ -+ // -+ @implementation OracleAdaptorChannel -+ -+-static void -+-DBTerminate() -++static void DBTerminate() -+ { -+ if (OCITerminate(OCI_DEFAULT)) -+ NSLog(@"FAILED: OCITerminate()"); -+@@ -89,6 +112,11 @@ -+ -+ + (void) initialize -+ { -++ NSUserDefaults *ud; -++ -++ ud = [NSUserDefaults standardUserDefaults]; -++ debugOn = [ud boolForKey: @"OracleAdaptorDebug"]; -++ -+ // We Initialize the OCI process environment. -+ if (OCIInitialize((ub4)OCI_DEFAULT, (dvoid *)0, -+ (dvoid * (*)(dvoid *, size_t)) 0, -+@@ -156,14 +184,17 @@ -+ [super closeChannel]; -+ -+ // We logoff from the database. -+- if (OCILogoff(_oci_ctx, _oci_err)) -++ if (!_oci_ctx || !_oci_err || OCILogoff(_oci_ctx, _oci_err)) -+ { -+ NSLog(@"FAILED: OCILogoff()"); -+ } -+ -++ if (_oci_ctx) -++ OCIHandleFree(_oci_ctx, OCI_HTYPE_SVCCTX); -+ -+- OCIHandleFree(_oci_ctx, OCI_HTYPE_SVCCTX); -+- OCIHandleFree(_oci_err, OCI_HTYPE_ERROR); -++ if (_oci_err) -++ OCIHandleFree(_oci_err, OCI_HTYPE_ERROR); -++ -+ // OCIHandleFree(_oci_env, OCI_HTYPE_ENV); -+ -+ _oci_ctx = (OCISvcCtx *)0; -+@@ -177,7 +208,8 @@ -+ // -+ - (void) dealloc -+ { -+- //NSLog(@"OracleAdaptorChannel: -dealloc"); -++ if (debugOn) -++ NSLog(@"OracleAdaptorChannel: -dealloc"); -+ -+ [self _cleanup]; -+ -+@@ -222,7 +254,7 @@ -+ { -+ EOAttribute *attribute; -+ OCIParam *param; -+- -++ int rCount; -+ column_info *info; -+ ub4 i, clen, count; -+ text *sql, *cname; -+@@ -231,6 +263,9 @@ -+ -+ [self _cleanup]; -+ -++ if (debugOn) -++ [self logWithFormat: @"expression: %@", theExpression]; -++ -+ if (!theExpression || ![theExpression length]) -+ { -+ [NSException raise: @"OracleInvalidExpressionException" -+@@ -244,7 +279,9 @@ -+ } -+ -+ sql = (text *)[theExpression UTF8String]; -+- -++ -++ rCount = 0; -++ retry: -+ // We alloc our statement handle -+ if ((status = OCIHandleAlloc((dvoid *)_oci_env, (dvoid **)&_current_stm, (ub4)OCI_HTYPE_STMT, (CONST size_t) 0, (dvoid **) 0))) -+ { -+@@ -264,13 +301,39 @@ -+ // We check if we're doing a SELECT and if so, we're fetching data! -+ OCIAttrGet(_current_stm, OCI_HTYPE_STMT, &type, 0, OCI_ATTR_STMT_TYPE, _oci_err); -+ self->isFetchInProgress = (type == OCI_STMT_SELECT ? YES : NO); -+- -++ -+ // We execute our statement. Not that we _MUST_ set iter to 0 for non-SELECT statements. -+ if ((status = OCIStmtExecute(_oci_ctx, _current_stm, _oci_err, (self->isFetchInProgress ? (ub4)0 : (ub4)1), (ub4)0, (CONST OCISnapshot *)NULL, (OCISnapshot *)NULL, -+ ([(OracleAdaptorContext *)[self adaptorContext] autoCommit] ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT)))) -+ { -++ ub4 serverStatus; -++ -+ checkerr(_oci_err, status); -+ NSLog(@"Statement execute failed (OCI_ERROR): %@", theExpression); -++ -++ // We check to see if we lost connection and need to reconnect. -++ serverStatus = 0; -++ OCIAttrGet((dvoid *)_oci_env, OCI_HTYPE_SERVER, (dvoid *)&serverStatus, (ub4 *)0, OCI_ATTR_SERVER_STATUS, _oci_err); -++ -++ if (serverStatus == OCI_SERVER_NOT_CONNECTED) -++ { -++ // We cleanup our previous handles -++ [self cancelFetch]; -++ [self closeChannel]; -++ -++ // We try to reconnect a couple of times before giving up... -++ while (rCount < maxTry) -++ { -++ usleep(maxSleep); -++ rCount++; -++ -++ if ([self openChannel]) -++ { -++ NSLog(@"Connection re-established to Oracle - retrying to process the statement."); -++ goto retry; -++ } -++ } -++ } -+ return NO; -+ } -+ -+@@ -302,7 +365,9 @@ -+ // We read the maximum width of a column -+ info->max_width = 0; -+ status = OCIAttrGet((dvoid*)param, (ub4)OCI_DTYPE_PARAM, (dvoid*)&(info->max_width), (ub4 *)0, (ub4)OCI_ATTR_DATA_SIZE, (OCIError *)_oci_err); -+- -++ -++ if (debugOn) -++ NSLog(@"name: %s, type: %d", cname, info->type); -+ attribute = [EOAttribute attributeWithOracleType: info->type name: cname length: clen width: info->max_width]; -+ [_resultSetProperties addObject: attribute]; -+ -+@@ -394,16 +459,17 @@ -+ return NO; -+ } -+ -+- -+ if (OCIEnvInit((OCIEnv **)&_oci_env, (ub4)OCI_DEFAULT, (size_t)0, (dvoid **)0)) -+ { -+ NSLog(@"FAILED: OCIEnvInit()"); -++ [self closeChannel]; -+ return NO; -+ } -+ -+ if (OCIHandleAlloc((dvoid *)_oci_env, (dvoid *)&_oci_err, (ub4)OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0)) -+ { -+ NSLog(@"FAILED: OCIHandleAlloc() on errhp"); -++ [self closeChannel]; -+ return NO; -+ } -+ -+@@ -414,7 +480,10 @@ -+ // Under Oracle 10g, the third parameter of OCILogon() has the form: [//]host[:port][/service_name] -+ // See http://download-west.oracle.com/docs/cd/B12037_01/network.101/b10775/naming.htm#i498306 for -+ // all juicy details. -+- database = [[NSString stringWithFormat:@"%@:%@", [o serverName], [o port]] UTF8String]; -++ if ([o serverName] && [o port]) -++ database = [[NSString stringWithFormat:@"%@:%@/%@", [o serverName], [o port], [o databaseName]] UTF8String]; -++ else -++ database = [[o databaseName] UTF8String]; -+ -+ // We logon to the database. -+ if (OCILogon(_oci_env, _oci_err, &_oci_ctx, (const OraText*)username, strlen(username), -+@@ -422,6 +491,7 @@ -+ { -+ NSLog(@"FAILED: OCILogon(). username = %s password = %s" -+ @" database = %s", username, password, database); -++ [self closeChannel]; -+ return NO; -+ } -+ -+@@ -438,6 +508,11 @@ -+ { -+ sword status; -+ -++ // We check if our connection is open prior to trying to fetch any data. OCIStmtFetch2() returns -++ // NO error code if the OCI environment is set up but the OCILogon() has failed. -++ if (![self isOpen]) -++ return nil; -++ -+ status = OCIStmtFetch2(_current_stm, _oci_err, (ub4)1, (ub4)OCI_FETCH_NEXT, (sb4)0, (ub4)OCI_DEFAULT); -+ -+ if (status == OCI_NO_DATA) -+@@ -609,7 +684,7 @@ -+ -+ /* GCSEOAdaptorChannel protocol */ -+ static NSString *sqlFolderFormat = (@"CREATE TABLE %@ (\n" \ -+- @" c_name VARCHAR2 (256) NOT NULL,\n" -++ @" c_name VARCHAR2 (256) NOT NULL PRIMARY KEY,\n" -+ @" c_content CLOB NOT NULL,\n" -+ @" c_creationdate INTEGER NOT NULL,\n" -+ @" c_lastmodified INTEGER NOT NULL,\n" -+Index: sope-gdl1/Oracle8/OracleAdaptorChannelController.m -+=================================================================== -+--- sope-gdl1/Oracle8/OracleAdaptorChannelController.m (revision 1664) -++++ sope-gdl1/Oracle8/OracleAdaptorChannelController.m (working copy) -+@@ -31,6 +31,8 @@ -+ #import -+ #import -+ -++static BOOL debugOn = NO; -++ -+ // -+ // -+ // -+@@ -48,6 +50,14 @@ -+ // -+ @implementation OracleAdaptorChannelController -+ -+++ (void) initialize -++{ -++ NSUserDefaults *ud; -++ -++ ud = [NSUserDefaults standardUserDefaults]; -++ debugOn = [ud boolForKey: @"OracleAdaptorDebug"]; -++} -++ -+ - (EODelegateResponse) adaptorChannel: (id) theChannel -+ willInsertRow: (NSMutableDictionary *) theRow -+ forEntity: (EOEntity *) theEntity -+@@ -56,7 +66,8 @@ -+ NSArray *keys; -+ int i, c; -+ -+- NSLog(@"willInsertRow: %@ %@", [theRow description], [theEntity description]); -++ if (debugOn) -++ NSLog(@"willInsertRow: %@ %@", [theRow description], [theEntity description]); -+ -+ s = AUTORELEASE([[NSMutableString alloc] init]); -+ -+@@ -101,7 +112,8 @@ -+ NSArray *keys; -+ int i, c; -+ -+- NSLog(@"willUpdatetRow: %@ %@", [theRow description], [theQualifier description]); -++ if (debugOn) -++ NSLog(@"willUpdateRow: %@ %@", [theRow description], [theQualifier description]); -+ -+ s = AUTORELEASE([[NSMutableString alloc] init]); -+ -+Index: sope-mime/NGImap4/NGImap4Functions.m -+=================================================================== -+--- sope-mime/NGImap4/NGImap4Functions.m (revision 1664) -++++ sope-mime/NGImap4/NGImap4Functions.m (working copy) -+@@ -367,3 +367,16 @@ -+ } -+ -+ @end /* NGImap4FolderHandler */ -++ -++NSString * -++SaneFolderName(NSString *folderName) -++{ -++ NSString *saneFName; -++ -++ saneFName = [[folderName stringByReplacingString: @"\\" -++ withString: @"\\\\"] -++ stringByReplacingString: @"\"" -++ withString: @"\\\""]; -++ -++ return saneFName; -++} -+Index: sope-mime/NGImap4/NGImap4Client.h -+=================================================================== -+--- sope-mime/NGImap4/NGImap4Client.h (revision 1664) -++++ sope-mime/NGImap4/NGImap4Client.h (working copy) -+@@ -62,6 +62,8 @@ -+ NGImap4ResponseNormalizer *normer; -+ NSMutableArray *responseReceiver; -+ -++ BOOL loggedIn; -++ -+ BOOL isLogin; -+ unsigned tagId; -+ -+@@ -117,9 +119,11 @@ -+ - (NSDictionary *)noop; -+ -+ - (NSDictionary *)capability; -++- (NSDictionary *)namespace; -+ - (NSDictionary *)list:(NSString *)_folder pattern:(NSString *)_pattern; -+ - (NSDictionary *)lsub:(NSString *)_folder pattern:(NSString *)_pattern; -+ - (NSDictionary *)select:(NSString *)_folder; -++- (NSDictionary *)unselect; -+ - (NSDictionary *)status:(NSString *)_folder flags:(NSArray *)_flags; -+ - (NSDictionary *)rename:(NSString *)_folder to:(NSString *)_newName; -+ - (NSDictionary *)delete:(NSString *)_folder; -+@@ -138,7 +142,7 @@ -+ flags:(NSArray *)_flags; -+ - (NSDictionary *)storeFrom:(unsigned)_from to:(unsigned)_to -+ add:(NSNumber *)_add flags:(NSArray *)_flags; -+-- (NSDictionary *)storeFlags:(NSArray *)_flags forMSNs:(id)_msns -++- (NSDictionary *)storeFlags:(NSArray *)_flags forUIDs:(id)_uids -+ addOrRemove:(BOOL)_flag; -+ -+ - (NSDictionary *)copyUid:(unsigned)_uid toFolder:(NSString *)_folder; -+Index: sope-mime/NGImap4/NGImap4Client.m -+=================================================================== -+--- sope-mime/NGImap4/NGImap4Client.m (revision 1664) -++++ sope-mime/NGImap4/NGImap4Client.m (working copy) -+@@ -24,6 +24,8 @@ -+ #include "NGImap4Client.h" -+ #include "NGImap4Context.h" -+ #include "NGImap4Support.h" -++#include "NGImap4Envelope.h" -++#include "NGImap4EnvelopeAddress.h" -+ #include "NGImap4Functions.h" -+ #include "NGImap4ResponseParser.h" -+ #include "NGImap4ResponseNormalizer.h" -+@@ -53,17 +55,17 @@ -+ -+ @end /* NGImap4Client(ConnectionRegistration); */ -+ -+-#if GNUSTEP_BASE_LIBRARY -+-/* FIXME: TODO: move someplace better (hh: NGExtensions...) */ -+-@implementation NSException(setUserInfo) -++// #if GNUSTEP_BASE_LIBRARY -++// /* FIXME: TODO: move someplace better (hh: NGExtensions...) */ -++// @implementation NSException(setUserInfo) -+ -+-- (id)setUserInfo:(NSDictionary *)_userInfo { -+- ASSIGN(self->_e_info, _userInfo); -+- return self; -+-} -++// - (id)setUserInfo:(NSDictionary *)_userInfo { -++// ASSIGN(self->_e_info, _userInfo); -++// return self; -++// } -+ -+-@end /* NSException(setUserInfo) */ -+-#endif -++// @end /* NSException(setUserInfo) */ -++// #endif -+ -+ @interface NGImap4Client(Private) -+ -+@@ -84,6 +86,8 @@ -+ -+ - (NSDictionary *)login; -+ -++- (NSDictionary *) _sopeSORT: (id)_sortSpec qualifier:(EOQualifier *)_qual encoding:(NSString *)_encoding; -++ -+ @end -+ -+ /* -+@@ -110,6 +114,9 @@ -+ static BOOL ImapDebugEnabled = NO; -+ static NSArray *Imap4SystemFlags = nil; -+ -++static NSMutableDictionary *capabilities; -++static NSMutableDictionary *namespaces; -++ -+ - (BOOL)useSSL { -+ return self->useSSL; -+ } -+@@ -140,6 +147,9 @@ -+ -+ Imap4SystemFlags = [[NSArray alloc] initWithObjects: @"seen", @"answered", -+ @"deleted", @"draft", nil]; -++ -++ capabilities = [[NSMutableDictionary alloc] init]; -++ namespaces = [[NSMutableDictionary alloc] init]; -+ } -+ -+ /* constructors */ -+@@ -195,11 +205,14 @@ -+ self->debug = ImapDebugEnabled; -+ self->responseReceiver = [[NSMutableArray alloc] initWithCapacity:128]; -+ self->normer = [[NGImap4ResponseNormalizer alloc] initWithClient:self]; -++ self->loggedIn = NO; -++ self->context = nil; -+ } -+ return self; -+ } -+ -+ - (void)dealloc { -++ if (self->loggedIn) [self logout]; -+ [self removeFromConnectionRegister]; -+ [self->normer release]; -+ [self->text release]; -+@@ -457,8 +470,8 @@ -+ - (void)reconnect { -+ if ([self->context lastException] != nil) -+ return; -+- -+- [self closeConnection]; -++ -++ [self closeConnection]; -+ self->tagId = 0; -+ [self openConnection]; -+ -+@@ -481,6 +494,7 @@ -+ */ -+ NGHashMap *map; -+ NSString *s, *log; -++ NSDictionary *response; -+ -+ if (self->isLogin ) -+ return nil; -+@@ -499,7 +513,11 @@ -+ -+ self->isLogin = NO; -+ -+- return [self->normer normalizeResponse:map]; -++ response = [self->normer normalizeResponse:map]; -++ -++ self->loggedIn = [[response valueForKey:@"result"] boolValue]; -++ -++ return response; -+ } -+ -+ - (NSDictionary *)logout { -+@@ -508,6 +526,8 @@ -+ -+ map = [self processCommand:@"logout"]; -+ [self closeConnection]; -++ [self->selectedFolder release]; self->selectedFolder = nil; -++ self->loggedIn = NO; -+ -+ return [self->normer normalizeResponse:map]; -+ } -+@@ -530,7 +550,7 @@ -+ NSAutoreleasePool *pool; -+ NGHashMap *map; -+ NSDictionary *result; -+- NSString *s; -++ NSString *s, *prefix; -+ -+ pool = [[NSAutoreleasePool alloc] init]; -+ -+@@ -547,7 +567,11 @@ -+ if (!(_pattern = [self _folder2ImapFolder:_pattern])) -+ return nil; -+ -+- s = [NSString stringWithFormat:@"list \"%@\" \"%@\"", _folder, _pattern]; -++ if ([_folder length] > 0) -++ prefix = [NSString stringWithFormat: @"%@%@", SaneFolderName(_folder), self->delimiter]; -++ else -++ prefix = @""; -++ s = [NSString stringWithFormat:@"list \"%@\" \"%@\"", prefix, _pattern]; -+ map = [self processCommand:s]; -+ -+ if (self->delimiter == nil) { -+@@ -563,18 +587,49 @@ -+ } -+ -+ - (NSDictionary *)capability { -++ NSDictionary *result; -+ id capres; -+- capres = [self processCommand:@"capability"]; -+- return [self->normer normalizeCapabilityRespone:capres]; -++ -++ result = [capabilities objectForKey: [self->address description]]; -++ -++ if (!result) -++ { -++ capres = [self processCommand:@"capability"]; -++ result = [self->normer normalizeCapabilityResponse:capres]; -++ -++ if (result) -++ [capabilities setObject: result forKey: [self->address description]]; -++ } -++ return result; -+ } -+ -++- (NSDictionary *)namespace { -++ NSArray *capabilities; -++ NGHashMap *namesres; -++ id namespace; -++ -++ namespace = [namespaces objectForKey: [self->address description]]; -++ if (!namespace) { -++ capabilities = [[self capability] objectForKey: @"capability"]; -++ if ([capabilities containsObject: @"namespace"]) { -++ namesres = [self processCommand: @"namespace"]; -++ namespace = [self->normer normalizeNamespaceResponse:namesres]; -++ } -++ else -++ namespace = [NSNull null]; -++ [namespaces setObject: namespace forKey: [self->address description]]; -++ } -++ -++ return ([namespace isKindOfClass: [NSNull class]] ? nil : namespace); -++} -++ -+ - (NSDictionary *)lsub:(NSString *)_folder pattern:(NSString *)_pattern { -+ /* -+ The method build statements like 'LSUB "_folder" "_pattern"'. -+ The returnvalue is the same like the list:pattern: method -+ */ -+ NGHashMap *map; -+- NSString *s; -++ NSString *s, *prefix; -+ -+ if (_folder == nil) -+ _folder = @""; -+@@ -591,7 +646,11 @@ -+ return nil; -+ } -+ -+- s = [NSString stringWithFormat:@"lsub \"%@\" \"%@\"", _folder, _pattern]; -++ if ([_folder length] > 0) -++ prefix = [NSString stringWithFormat: @"%@%@", SaneFolderName(_folder), self->delimiter]; -++ else -++ prefix = @""; -++ s = [NSString stringWithFormat:@"lsub \"%@\" \"%@\"", prefix, _pattern]; -+ map = [self processCommand:s]; -+ -+ if (self->delimiter == nil) { -+@@ -617,24 +676,25 @@ -+ 'flags' - array of strings (eg (answered,flagged,draft,seen); -+ 'RawResponse' - the raw IMAP4 response -+ */ -+- NSString *s; -+- id tmp; -+- -+- tmp = self->selectedFolder; // remember ptr to old folder name -+- -++ NSString *s, *newFolder; -++ -+ if (![_folder isNotEmpty]) -+ return nil; -+ if ((_folder = [self _folder2ImapFolder:_folder]) == nil) -+ return nil; -+ -+- self->selectedFolder = [_folder copy]; -+- -+- [tmp release]; tmp = nil; // release old folder name -++ newFolder = [NSString stringWithString: _folder]; -++ ASSIGN (self->selectedFolder, newFolder); -+ -+- s = [NSString stringWithFormat:@"select \"%@\"", self->selectedFolder]; -++ s = [NSString stringWithFormat:@"select \"%@\"", SaneFolderName(self->selectedFolder)]; -+ return [self->normer normalizeSelectResponse:[self processCommand:s]]; -+ } -+ -++- (NSDictionary *)unselect { -++ [self->selectedFolder release]; self->selectedFolder = nil; -++ return [self->normer normalizeResponse:[self processCommand:@"unselect"]]; -++} -++ -+ - (NSDictionary *)status:(NSString *)_folder flags:(NSArray *)_flags { -+ NSString *cmd; -+ -+@@ -646,7 +706,7 @@ -+ return nil; -+ -+ cmd = [NSString stringWithFormat:@"status \"%@\" (%@)", -+- _folder, [_flags componentsJoinedByString:@" "]]; -++ SaneFolderName(_folder), [_flags componentsJoinedByString:@" "]]; -+ return [self->normer normalizeStatusResponse:[self processCommand:cmd]]; -+ } -+ -+@@ -663,24 +723,28 @@ -+ if ((_newName = [self _folder2ImapFolder:_newName]) == nil) -+ return nil; -+ -+- cmd = [NSString stringWithFormat:@"rename \"%@\" \"%@\"", _folder, _newName]; -++ cmd = [NSString stringWithFormat:@"rename \"%@\" \"%@\"", -++ SaneFolderName(_folder), SaneFolderName(_newName)]; -+ -+ return [self->normer normalizeResponse:[self processCommand:cmd]]; -+ } -+ -+ - (NSDictionary *)_performCommand:(NSString *)_op onFolder:(NSString *)_fname { -+ NSString *command; -+- -++ -+ if ((_fname = [self _folder2ImapFolder:_fname]) == nil) -+ return nil; -+- -++ -+ // eg: 'delete "blah"' -+- command = [NSString stringWithFormat:@"%@ \"%@\"", _op, _fname]; -+- -++ command = [NSString stringWithFormat:@"%@ \"%@\"", _op, SaneFolderName(_fname)]; -++ -+ return [self->normer normalizeResponse:[self processCommand:command]]; -+ } -+ -+ - (NSDictionary *)delete:(NSString *)_name { -++ if ([self->selectedFolder isEqualToString:_name]) { -++ [self unselect]; -++ } -+ return [self _performCommand:@"delete" onFolder:_name]; -+ } -+ - (NSDictionary *)create:(NSString *)_name { -+@@ -820,23 +884,23 @@ -+ return [self->normer normalizeResponse:[self processCommand:cmd]]; -+ } -+ -+-- (NSDictionary *)storeFlags:(NSArray *)_flags forMSNs:(id)_msns -++- (NSDictionary *)storeFlags:(NSArray *)_flags forUIDs:(id)_uids -+ addOrRemove:(BOOL)_flag -+ { -+ NSString *cmd; -+ NSString *flagstr; -+ NSString *seqstr; -+ -+- if ([_msns isKindOfClass:[NSArray class]]) { -++ if ([_uids isKindOfClass:[NSArray class]]) { -+ // TODO: improve by using ranges, eg 1:5 instead of 1,2,3,4,5 -+- _msns = [_msns valueForKey:@"stringValue"]; -+- seqstr = [_msns componentsJoinedByString:@","]; -++ _uids = [_uids valueForKey:@"stringValue"]; -++ seqstr = [_uids componentsJoinedByString:@","]; -+ } -+ else -+- seqstr = [_msns stringValue]; -++ seqstr = [_uids stringValue]; -+ -+ flagstr = [_flags2ImapFlags(self, _flags) componentsJoinedByString:@" "]; -+- cmd = [NSString stringWithFormat:@"store %@ %cFLAGS (%@)", -++ cmd = [NSString stringWithFormat:@"UID STORE %@ %cFLAGS (%@)", -+ seqstr, _flag ? '+' : '-', flagstr]; -+ -+ return [self->normer normalizeResponse:[self processCommand:cmd]]; -+@@ -967,11 +1031,12 @@ -+ descr = @"Could not process qualifier for imap search "; -+ descr = [descr stringByAppendingString:reason]; -+ -+- exception = [[NGImap4SearchException alloc] initWithFormat:@"%@", descr]; -+ ui = [NSDictionary dictionaryWithObject:_q forKey:@"qualifier"]; -+- [exception setUserInfo:ui]; -++ exception -++ = [NGImap4SearchException exceptionWithName: @"NGImap4SearchException" -++ reason: descr -++ userInfo: ui]; -+ [self->context setLastException:exception]; -+- [exception release]; -+ } -+ -+ - (NSString *)_searchExprForQual:(EOQualifier *)_qualifier { -+@@ -1093,7 +1158,18 @@ -+ Eg: UID SORT ( DATE REVERSE SUBJECT ) UTF-8 TODO -+ */ -+ NSString *tmp; -++ NSArray *capa; -+ -++ // We first check to see if our server supports IMAP SORT. If not -++ // we'll sort ourself the results. -++ capa = [[self capability] objectForKey: @"capability"]; -++ -++ if ([capa indexOfObject: @"sort"] == NSNotFound) -++ { -++ return [self _sopeSORT: _sortSpec qualifier: _qual encoding: _encoding]; -++ } -++ -++ -+ if ([_sortSpec isKindOfClass:[NSArray class]]) -+ tmp = [self _generateIMAP4SortOrderings:_sortSpec]; -+ else if ([_sortSpec isKindOfClass:[EOSortOrdering class]]) -+@@ -1107,9 +1183,10 @@ -+ tmp = @"DATE"; -+ } -+ -++ -+ return [self primarySort:tmp -+- qualifierString:[self _searchExprForQual:_qual] -+- encoding:_encoding]; -++ qualifierString:[self _searchExprForQual:_qual] -++ encoding:_encoding]; -+ } -+ - (NSDictionary *)sort:(NSArray *)_sortOrderings -+ qualifier:(EOQualifier *)_qual -+@@ -1130,7 +1207,7 @@ -+ return nil; -+ } -+ -+- s = [@"search" stringByAppendingString:s]; -++ s = [@"UID SEARCH" stringByAppendingString:s]; -+ return [self->normer normalizeSearchResponse:[self processCommand:s]]; -+ } -+ -+@@ -1142,7 +1219,7 @@ -+ if ((_folder = [self _folder2ImapFolder:_folder]) == nil) -+ return nil; -+ -+- cmd = [NSString stringWithFormat:@"getacl \"%@\"", _folder]; -++ cmd = [NSString stringWithFormat:@"getacl \"%@\"", SaneFolderName(_folder)]; -+ return [self->normer normalizeGetACLResponse:[self processCommand:cmd]]; -+ } -+ -+@@ -1155,7 +1232,7 @@ -+ return nil; -+ -+ cmd = [NSString stringWithFormat:@"setacl \"%@\" \"%@\" \"%@\"", -+- _folder, _uid, _r]; -++ SaneFolderName(_folder), _uid, _r]; -+ return [self->normer normalizeResponse:[self processCommand:cmd]]; -+ } -+ -+@@ -1166,7 +1243,7 @@ -+ return nil; -+ -+ cmd = [NSString stringWithFormat:@"deleteacl \"%@\" \"%@\"", -+- _folder, _uid]; -++ SaneFolderName(_folder), _uid]; -+ return [self->normer normalizeResponse:[self processCommand:cmd]]; -+ } -+ -+@@ -1177,7 +1254,7 @@ -+ return nil; -+ -+ cmd = [NSString stringWithFormat:@"listrights \"%@\" \"%@\"", -+- _folder, _uid]; -++ SaneFolderName(_folder), _uid]; -+ return [self->normer normalizeListRightsResponse:[self processCommand:cmd]]; -+ } -+ -+@@ -1187,12 +1264,94 @@ -+ if ((_folder = [self _folder2ImapFolder:_folder]) == nil) -+ return nil; -+ -+- cmd = [NSString stringWithFormat:@"myrights \"%@\"", _folder]; -++ cmd = [NSString stringWithFormat:@"myrights \"%@\"", SaneFolderName(_folder)]; -+ return [self->normer normalizeMyRightsResponse:[self processCommand:cmd]]; -+ } -+ -+ /* Private Methods */ -+ -++- (NSDictionary *) _sopeSORT: (id)_sortSpec qualifier:(EOQualifier *)_qual encoding:(NSString *)_encoding { -++ NSMutableDictionary *result; -++ NSDictionary *d; -++ NSCalendarDate *envDate; -++ -++ result = [NSMutableDictionary dictionary]; -++ [result setObject: [NSNumber numberWithBool: NO] forKey: @"result"]; -++ -++ // _sortSpec: [REVERSE] {DATE,FROM,SUBJECT} -++ d = [self searchWithQualifier: _qual]; -++ -++ if ((d = [d objectForKey: @"RawResponse"])) { -++ NSMutableDictionary *dict; -++ NSArray *a, *s_a; -++ BOOL b; -++ int i; -++ -++ a = [d objectForKey: @"search"]; -++ if ([a isNotEmpty]) { -++ d = [self fetchUids: a -++ parts: [NSArray arrayWithObjects: @"ENVELOPE", -++ @"RFC822.SIZE", nil]]; -++ a = [d objectForKey: @"fetch"]; -++ -++ dict = [NSMutableDictionary dictionary]; -++ b = YES; -++ -++ for (i = 0; i < [a count]; i++) { -++ NGImap4Envelope *env; -++ id o, uid, s; -++ -++ o = [a objectAtIndex: i]; -++ env = [o objectForKey: @"envelope"]; -++ uid = [o objectForKey: @"uid"]; -++ -++ if ([_sortSpec rangeOfString: @"SUBJECT"].length) { -++ s = [env subject]; -++ if ([s isKindOfClass: [NSData class]]) -++ s = [[[NSString alloc] initWithData: s encoding: NSUTF8StringEncoding] autorelease]; -++ -++ [dict setObject: (s != nil ? s : (id)@"") forKey: uid]; -++ } -++ else if ([_sortSpec rangeOfString: @"FROM"].length) { -++ s = [[[env from] lastObject] email]; -++ [dict setObject: (s != nil ? s : (id)@"") forKey: uid]; -++ } -++ else if ([_sortSpec rangeOfString: @"SIZE"].length) { -++ s = [o objectForKey: @"size"]; -++ [dict setObject: (s != nil ? s : [NSNumber numberWithInt: 0]) -++ forKey: uid]; -++ b = NO; -++ } -++ else { -++ envDate = [env date]; -++ if (!envDate) -++ envDate = [NSCalendarDate date]; -++ [dict setObject: envDate forKey: uid]; -++ b = NO; -++ } -++ } -++ -++ if (b) -++ s_a = [dict keysSortedByValueUsingSelector: @selector(caseInsensitiveCompare:)]; -++ else -++ s_a = [dict keysSortedByValueUsingSelector: @selector(compare:)]; -++ -++ if ([_sortSpec rangeOfString: @"REVERSE"].length) { -++ s_a = [[s_a reverseObjectEnumerator] allObjects]; -++ } -++ -++ } -++ else { -++ s_a = [NSArray array]; -++ } -++ [result setObject: [NSNumber numberWithBool: YES] forKey: @"result"]; -++ [result setObject: s_a forKey: @"sort"]; -++ } -++ -++ return result; -++} -++ -++ -+ - (NSException *)_processCommandParserException:(NSException *)_exception { -+ [self logWithFormat:@"ERROR(%s): catched IMAP4 parser exception %@: %@", -+ __PRETTY_FUNCTION__, [_exception name], [_exception reason]]; -+@@ -1412,21 +1571,24 @@ -+ return nil; -+ } -+ -+- array = [_folder pathComponents]; -++// array = [_folder pathComponents]; -++ array = [_folder componentsSeparatedByString:@"/"]; -+ -+- if ([array isNotEmpty]) { -++ if ([array count]) { -+ NSString *o; -+ -+ o = [array objectAtIndex:0]; -+- if (([o isEqualToString:@"/"]) || ([o length] == 0)) -++ if ([o length] == 0) -+ array = [array subarrayWithRange:NSMakeRange(1, [array count] - 1)]; -+- -+- o = [array lastObject]; -+- if (([o length] == 0) || ([o isEqualToString:@"/"])) -+- array = [array subarrayWithRange:NSMakeRange(0, [array count] - 1)]; -++ -++ if ([array count]) { -++ o = [array lastObject]; -++ if ([o length] == 0) -++ array = [array subarrayWithRange:NSMakeRange(0, [array count] - 1)]; -++ } -+ } -+ return [[array componentsJoinedByString:self->delimiter] -+- stringByEncodingImap4FolderName]; -++ stringByEncodingImap4FolderName]; -+ } -+ -+ - (NSString *)_imapFolder2Folder:(NSString *)_folder { -+@@ -1442,10 +1604,16 @@ -+ return nil; -+ } -+ -++ if ([_folder hasPrefix: self->delimiter]) -++ _folder = [_folder substringFromIndex: 1]; -++ if ([_folder hasSuffix: self->delimiter]) -++ _folder = [_folder substringToIndex: [_folder length] - 1]; -++ -+ array = [array arrayByAddingObjectsFromArray: -+ [_folder componentsSeparatedByString:[self delimiter]]]; -+- -+- return [[NSString pathWithComponents:array] stringByDecodingImap4FolderName]; -++ -++ return [[array componentsJoinedByString: @"/"] -++ stringByDecodingImap4FolderName]; -+ } -+ -+ - (void)setContext:(NGImap4Context *)_ctx { -+Index: sope-mime/NGImap4/NGSieveClient.m -+=================================================================== -+--- sope-mime/NGImap4/NGSieveClient.m (revision 1664) -++++ sope-mime/NGImap4/NGSieveClient.m (working copy) -+@@ -294,8 +294,8 @@ -+ return con; -+ } -+ -+- logLen = [self->login cStringLength]; -+- bufLen = (logLen * 2) + [self->password cStringLength] +2; -++ logLen = [self->login lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; -++ bufLen = (logLen * 2) + [self->password lengthOfBytesUsingEncoding: NSUTF8StringEncoding] +2; -+ -+ buf = calloc(bufLen + 2, sizeof(char)); -+ -+@@ -306,8 +306,9 @@ -+ password -+ */ -+ sprintf(buf, "%s %s %s", -+- [self->login cString], [self->login cString], -+- [self->password cString]); -++ [self->login cStringUsingEncoding:NSUTF8StringEncoding], -++ [self->login cStringUsingEncoding:NSUTF8StringEncoding], -++ [self->password cStringUsingEncoding:NSUTF8StringEncoding]); -+ -+ buf[logLen] = '\0'; -+ buf[logLen * 2 + 1] = '\0'; -+@@ -656,7 +657,7 @@ -+ fputc('\n', stderr); -+ } -+ else -+- fprintf(stderr, "C: %s\n", [_txt cString]); -++ fprintf(stderr, "C: %s\n", [_txt cStringUsingEncoding:NSUTF8StringEncoding]); -+ } -+ -+ /* write */ -+Index: sope-mime/NGImap4/NGImap4Connection.h -+=================================================================== -+--- sope-mime/NGImap4/NGImap4Connection.h (revision 1664) -++++ sope-mime/NGImap4/NGImap4Connection.h (working copy) -+@@ -52,7 +52,7 @@ -+ NSString *separator; -+ -+ /* hierarchy cache */ -+- NSDictionary *subfolders; -++ NSMutableDictionary *subfolders; -+ -+ /* permission cache */ -+ NSMutableDictionary *urlToRights; -+@@ -72,8 +72,9 @@ -+ -+ - (NSDate *)creationTime; -+ -+-- (void)cacheHierarchyResults:(NSDictionary *)_hierarchy; -+-- (NSDictionary *)cachedHierarchyResults; -++- (void)cacheHierarchyResults:(NSDictionary *)_hierarchy -++ forURL:(NSURL *)_url; -++- (NSDictionary *)cachedHierarchyResultsForURL:(NSURL *)_url; -+ - (void)flushFolderHierarchyCache; -+ -+ - (id)cachedUIDsForURL:(NSURL *)_url qualifier:(id)_q sortOrdering:(id)_so; -+@@ -88,7 +89,12 @@ -+ /* folder operations */ -+ -+ - (NSArray *)subfoldersForURL:(NSURL *)_url; -++- (NSArray *)subfoldersForURL:(NSURL *)_url -++ onlySubscribedFolders: (BOOL) subscribedFoldersOnly; -+ - (NSArray *)allFoldersForURL:(NSURL *)_url; -++- (NSArray *)allFoldersForURL:(NSURL *)_url -++ onlySubscribedFolders: (BOOL) subscribedFoldersOnly; -++- (BOOL)selectFolder:(id)_url; -+ -+ /* message operations */ -+ -+Index: sope-mime/NGImap4/NGImap4ResponseNormalizer.h -+=================================================================== -+--- sope-mime/NGImap4/NGImap4ResponseNormalizer.h (revision 1664) -++++ sope-mime/NGImap4/NGImap4ResponseNormalizer.h (working copy) -+@@ -49,7 +49,8 @@ -+ - (NSDictionary *)normalizeSearchResponse:(NGHashMap *)_map; -+ - (NSDictionary *)normalizeSortResponse:(NGHashMap *)_map; -+ - (NSDictionary *)normalizeThreadResponse:(NGHashMap *)_map; -+-- (NSDictionary *)normalizeCapabilityRespone:(NGHashMap *)_map; -++- (NSDictionary *)normalizeCapabilityResponse:(NGHashMap *)_map; -++- (NSDictionary *)normalizeNamespaceResponse:(NGHashMap *)_map; -+ - (NSDictionary *)normalizeQuotaResponse:(NGHashMap *)_map; -+ -+ /* ACL */ -+Index: sope-mime/NGImap4/NGImap4Connection.m -+=================================================================== -+--- sope-mime/NGImap4/NGImap4Connection.m (revision 1664) -++++ sope-mime/NGImap4/NGImap4Connection.m (working copy) -+@@ -22,6 +22,7 @@ -+ #include "NGImap4Connection.h" -+ #include "NGImap4MailboxInfo.h" -+ #include "NGImap4Client.h" -++#include "NGImap4Functions.h" -+ #include "imCommon.h" -+ -+ @implementation NGImap4Connection -+@@ -66,7 +67,8 @@ -+ self->creationTime = [[NSDate alloc] init]; -+ -+ // TODO: retrieve from IMAP4 instead of using a default -+- self->separator = imap4Separator; -++ self->separator = [imap4Separator copy]; -++ self->subfolders = [NSMutableDictionary new]; -+ } -+ return self; -+ } -+@@ -100,11 +102,13 @@ -+ return self->creationTime; -+ } -+ -+-- (void)cacheHierarchyResults:(NSDictionary *)_hierarchy { -+- ASSIGNCOPY(self->subfolders, _hierarchy); -++- (void)cacheHierarchyResults:(NSDictionary *)_hierarchy -++ forURL:(NSURL *)_url -++{ -++ [self->subfolders setObject:_hierarchy forKey:[_url absoluteString]]; -+ } -+-- (NSDictionary *)cachedHierarchyResults { -+- return self->subfolders; -++- (NSDictionary *)cachedHierarchyResultsForURL:(NSURL *)_url { -++ return [self->subfolders objectForKey:[_url absoluteString]]; -+ } -+ - (void)flushFolderHierarchyCache { -+ [self->subfolders release]; self->subfolders = nil; -+@@ -152,7 +156,6 @@ -+ ASSIGN(self->cachedUIDs, nil); -+ } -+ -+- -+ /* errors */ -+ -+ - (NSException *)errorCouldNotSelectURL:(NSURL *)_url { -+@@ -215,18 +218,13 @@ -+ NSMutableArray *ma; -+ unsigned i, count, prefixlen; -+ -+- if ((count = [_array count]) < 2) { -+- /* one entry is the folder itself, so we need at least two */ -+- return [NSArray array]; -+- } -++ count = [_array count]; -+ -+ // TODO: somehow results are different on OSX -+ // we should investigate and test all Foundation libraries and document the -+ // differences -+ #if __APPLE__ -+ prefixlen = [_fn isEqualToString:@""] ? 0 : [_fn length] + 1; -+-#elif GNUSTEP_BASE_LIBRARY -+- prefixlen = [_fn isEqualToString:@"/"] ? 1 : [_fn length]; -+ #else -+ prefixlen = [_fn isEqualToString:@"/"] ? 1 : [_fn length] + 1; -+ #endif -+@@ -321,13 +319,15 @@ -+ return nil; -+ if ([folderName characterAtIndex:0] == '/') -+ folderName = [folderName substringFromIndex:1]; -++ if ([folderName hasSuffix: @"/"]) -++ folderName = [folderName substringToIndex:[folderName length] - 1]; -+ -+ if (_delfn) folderName = [folderName stringByDeletingLastPathComponent]; -+ -+ if ([[self imap4Separator] isEqualToString:@"/"]) -+ return folderName; -+ -+- names = [folderName pathComponents]; -++ names = [folderName componentsSeparatedByString: @"/"]; -+ return [names componentsJoinedByString:[self imap4Separator]]; -+ } -+ - (NSString *)imap4FolderNameForURL:(NSURL *)_url { -+@@ -373,16 +373,26 @@ -+ -+ /* folder operations */ -+ -+-- (NSDictionary *)primaryFetchMailboxHierarchyForURL:(NSURL *)_url { -++- (NSDictionary *)primaryFetchMailboxHierarchyForURL:(NSURL *)_url -++ onlySubscribedFolders:(BOOL) subscribedFoldersOnly -++{ -+ NSDictionary *result; -++ NSString *prefix; -+ -+- if ((result = [self cachedHierarchyResults]) != nil) -++ if ((result = [self cachedHierarchyResultsForURL:_url]) != nil) -+ return [result isNotNull] ? result : (NSDictionary *)nil; -+ -+ if (debugCache) [self logWithFormat:@" no folders cached yet .."]; -+- -+- result = [[self client] list:(onlyFetchInbox ? @"INBOX" : @"*") -+- pattern:@"*"]; -++ -++ prefix = [_url path]; -++ if ([prefix hasPrefix: @"/"]) -++ prefix = [prefix substringFromIndex:1]; -++ if (subscribedFoldersOnly) -++ result = [[self client] lsub:(onlyFetchInbox ? @"INBOX" : prefix) -++ pattern:@"*"]; -++ else -++ result = [[self client] list:(onlyFetchInbox ? @"INBOX" : prefix) -++ pattern:@"*"]; -+ if (![[result valueForKey:@"result"] boolValue]) { -+ [self errorWithFormat:@"Could not list mailbox hierarchy!"]; -+ return nil; -+@@ -391,7 +401,7 @@ -+ /* cache results */ -+ -+ if ([result isNotNull]) { -+- [self cacheHierarchyResults:result]; -++ [self cacheHierarchyResults:result forURL:_url]; -+ if (debugCache) { -+ [self logWithFormat:@"cached results: 0x%p(%d)", -+ result, [result count]]; -+@@ -400,32 +410,55 @@ -+ return result; -+ } -+ -+-- (NSArray *)subfoldersForURL:(NSURL *)_url { -++- (NSDictionary *)primaryFetchMailboxHierarchyForURL:(NSURL *)_url -++{ -++ return [self primaryFetchMailboxHierarchyForURL: _url onlySubscribedFolders: NO]; -++} -++ -++- (NSArray *)allFoldersForURL:(NSURL *)_url -++ onlySubscribedFolders:(BOOL)_subscribedFoldersOnly -++{ -+ NSDictionary *result; -+ -+- if ((result = [self primaryFetchMailboxHierarchyForURL:_url]) == nil) -++ if ((result = [self primaryFetchMailboxHierarchyForURL:_url -++ onlySubscribedFolders:_subscribedFoldersOnly]) == nil) -+ return nil; -+ if ([result isKindOfClass:[NSException class]]) { -+ [self errorWithFormat:@"failed to retrieve hierarchy: %@", result]; -+ return nil; -+ } -+ -+- return [self extractSubfoldersForURL:_url fromResultSet:result]; -++ return [self extractFoldersFromResultSet:result]; -+ } -+ -+-- (NSArray *)allFoldersForURL:(NSURL *)_url { -++- (NSArray *)allFoldersForURL:(NSURL *)_url -++{ -++ return [self allFoldersForURL: _url onlySubscribedFolders: NO]; -++} -++ -++- (NSArray *)subfoldersForURL:(NSURL *)_url -++ onlySubscribedFolders:(BOOL)_subscribedFoldersOnly -++{ -+ NSDictionary *result; -++ NSString *baseFolder; -+ -+- if ((result = [self primaryFetchMailboxHierarchyForURL:_url]) == nil) -++ baseFolder = [self imap4FolderNameForURL:_url removeFileName:NO]; -++ if (_subscribedFoldersOnly) -++ result = [[self client] lsub:baseFolder pattern:@"%"]; -++ else -++ result = [[self client] list:baseFolder pattern:@"%"]; -++ if (![[result valueForKey:@"result"] boolValue]) { -++ [self errorWithFormat:@"Could not list mailbox hierarchy!"]; -+ return nil; -+- if ([result isKindOfClass:[NSException class]]) { -+- [self errorWithFormat:@"failed to retrieve hierarchy: %@", result]; -+- return nil; -+ } -+- -+- return [self extractFoldersFromResultSet:result]; -++ -++ return [self extractSubfoldersForURL:_url fromResultSet: result]; -+ } -+ -++- (NSArray *)subfoldersForURL:(NSURL *)_url { -++ return [self subfoldersForURL:_url onlySubscribedFolders: NO]; -++} -++ -+ /* message operations */ -+ -+ - (NSArray *)fetchUIDsInURL:(NSURL *)_url qualifier:(id)_qualifier -+@@ -646,7 +679,7 @@ -+ -+ /* store flags */ -+ -+- result = [[self client] storeFlags:_f forMSNs:result addOrRemove:YES]; -++ result = [[self client] storeFlags:_f forUIDs:result addOrRemove:YES]; -+ if (![[result valueForKey:@"result"] boolValue]) { -+ return [self errorForResult:result -+ text:@"Failed to change flags of IMAP4 message"]; -+@@ -737,14 +770,17 @@ -+ -+ - (BOOL)doesMailboxExistAtURL:(NSURL *)_url { -+ NSString *folderName; -++ NSArray *caches; -+ id result; -++ int count, max; -+ -+ /* check in hierarchy cache */ -+- -+- if ((result = [self cachedHierarchyResults]) != nil) { -++ caches = [self->subfolders allValues]; -++ max = [caches count]; -++ for (count = 0; count < max; count++) { -+ NSString *p; -+- -+- result = [(NSDictionary *)result objectForKey:@"list"]; -++ -++ result = [[caches objectAtIndex: count] objectForKey:@"list"]; -+ p = [_url path]; -+ #if __APPLE__ -+ /* normalized results already have the / in front on libFoundation?! */ -+@@ -760,11 +796,11 @@ -+ // TODO: we should probably just fetch the whole hierarchy? -+ -+ folderName = [self imap4FolderNameForURL:_url]; -+- result = [[self client] select:folderName]; -+- if (![[result valueForKey:@"result"] boolValue]) -+- return NO; -+- -+- return YES; -++ -++ result = [self->client status: folderName -++ flags: [NSArray arrayWithObject: @"UIDVALIDITY"]]; -++ -++ return ([[result valueForKey: @"result"] boolValue]); -+ } -+ -+ - (id)infoForMailboxAtURL:(NSURL *)_url { -+@@ -789,7 +825,8 @@ -+ /* construct path */ -+ -+ newPath = [self imap4FolderNameForURL:_url]; -+- newPath = [newPath stringByAppendingString:[self imap4Separator]]; -++ if ([newPath length]) -++ newPath = [newPath stringByAppendingString:[self imap4Separator]]; -+ newPath = [newPath stringByAppendingString:_mailbox]; -+ -+ /* create */ -+Index: sope-mime/NGImap4/NGImap4ResponseNormalizer.m -+=================================================================== -+--- sope-mime/NGImap4/NGImap4ResponseNormalizer.m (revision 1664) -++++ sope-mime/NGImap4/NGImap4ResponseNormalizer.m (working copy) -+@@ -76,22 +76,6 @@ -+ return self; -+ } -+ -+-/* client callbacks */ -+- -+-- (void)closeConnection { -+- [(id)self->client closeConnection]; -+-} -+- -+-- (NSString *)delimiter { -+- return [self->client delimiter]; -+-} -+- -+-/* folder handling */ -+- -+-- (NSString *)_imapFolder2Folder:(NSString *)_folder { -+- return [self->client _imapFolder2Folder:_folder]; -+-} -+- -+ /* primary */ -+ -+ - (NSMutableDictionary *)normalizeResponse:(NGHashMap *)_map { -+@@ -117,7 +101,7 @@ -+ if ((obj = [_map objectForKey:@"bye"])) { -+ [result setObject:NoNumber forKey:@"result"]; -+ [result setObject:obj forKey:@"reason"]; -+- [self closeConnection]; -++ [self->client closeConnection]; -+ return result; -+ } -+ -+@@ -157,7 +141,7 @@ -+ return result; -+ } -+ -+-- (NSDictionary *)normalizeCapabilityRespone:(NGHashMap *)_map { -++- (NSDictionary *)normalizeCapabilityResponse:(NGHashMap *)_map { -+ /* filter for capability response: capability : NSArray */ -+ id obj; -+ NSMutableDictionary *result; -+@@ -170,6 +154,51 @@ -+ return result; -+ } -+ -++- (NSArray *)_normalizeNamespace:(NSArray *)_namespace { -++ NSMutableArray *result; -++ NSDictionary *currentNS; -++ NSMutableDictionary *newNS; -++ NSString *newPrefix; -++ int count, max; -++ -++ max = [_namespace count]; -++ result = [NSMutableArray arrayWithCapacity: max]; -++ for (count = 0; count < max; count++) { -++ currentNS = [_namespace objectAtIndex: count]; -++ newNS = [currentNS mutableCopy]; -++ newPrefix = [self->client -++ _imapFolder2Folder: [currentNS objectForKey: @"prefix"]]; -++ [newNS setObject: newPrefix forKey: @"prefix"]; -++ [result addObject: newNS]; -++ [newNS release]; -++ } -++ -++ return result; -++} -++ -++- (NSDictionary *)normalizeNamespaceResponse:(NGHashMap *)_map { -++ NSMutableDictionary *result; -++ NSDictionary *rawResponse; -++ NSArray *namespace; -++ -++ result = [self normalizeResponse:_map]; -++ rawResponse = [result objectForKey: @"RawResponse"]; -++ namespace = [rawResponse objectForKey: @"personal"]; -++ if (namespace) -++ [result setObject: [self _normalizeNamespace: namespace] -++ forKey: @"personal"]; -++ namespace = [rawResponse objectForKey: @"other users"]; -++ if (namespace) -++ [result setObject: [self _normalizeNamespace: namespace] -++ forKey: @"other users"]; -++ namespace = [rawResponse objectForKey: @"shared"]; -++ if (namespace) -++ [result setObject: [self _normalizeNamespace: namespace] -++ forKey: @"shared"]; -++ -++ return result; -++} -++ -+ - (NSDictionary *)normalizeThreadResponse:(NGHashMap *)_map { -+ /* filter for thread response: thread : NSArray (msn) */ -+ id obj; -+@@ -292,7 +321,7 @@ -+ /* -+ filter for fetch response -+ fetch : NSArray (fetch responses) -+- 'header' - RFC822.HEADER -++ 'header' - RFC822.HEADER and BODY[HEADER.FIELDS (...)] -+ 'text' - RFC822.TEXT -+ 'size' - SIZE -+ 'flags' - FLAGS -+@@ -336,7 +365,12 @@ -+ switch (c) { -+ case 'b': -+ /* Note: we check for _prefix_! eg body[1] is valid too */ -+- if (klen > 3 && [key hasPrefix:@"body"]) { -++ if (klen > 17 && [key hasPrefix:@"body[header.fields"]) { -++ keys[count] = @"header"; -++ values[count] = objForKey(obj, @selector(objectForKey:), key); -++ count++; -++ } -++ else if (klen > 3 && [key hasPrefix:@"body"]) { -+ keys[count] = @"body"; -+ values[count] = objForKey(obj, @selector(objectForKey:), key); -+ count++; -+@@ -516,7 +550,7 @@ -+ } -+ continue; -+ } -+- [tmp setObject:qDesc forKey:[self _imapFolder2Folder:obj]]; -++ [tmp setObject:qDesc forKey:[self->client _imapFolder2Folder:obj]]; -+ } -+ [result setObject:tmp forKey:@"quotas"]; -+ return [[result copy] autorelease]; -+@@ -615,7 +649,7 @@ -+ -+ while ((o = [enumerator nextObject])) { -+ [folder setObject:_imapFlags2Flags(self, [o objectForKey:@"flags"]) -+- forKey:[self _imapFolder2Folder:[o objectForKey:@"folderName"]]]; -++ forKey:[self->client _imapFolder2Folder:[o objectForKey:@"folderName"]]]; -+ } -+ -+ { -+@@ -648,14 +682,13 @@ -+ enumerator = [_flags objectEnumerator]; -+ cnt = 0; -+ while ((obj = [enumerator nextObject])) { -+- if (![obj isNotEmpty]) -+- continue; -+- -+- if (![[obj substringToIndex:1] isEqualToString:@"\\"]) -+- continue; -+- -+- objs[cnt] = [obj substringFromIndex:1]; -+- cnt++; -++ if ([obj isNotEmpty]) { -++ if ([obj hasPrefix:@"\\"]) -++ objs[cnt] = [obj substringFromIndex:1]; -++ else -++ objs[cnt] = obj; -++ cnt++; -++ } -+ } -+ result = [NSArray arrayWithObjects:objs count:cnt]; -+ if (objs) free(objs); -+Index: sope-mime/NGImap4/EOQualifier+IMAPAdditions.m -+=================================================================== -+--- sope-mime/NGImap4/EOQualifier+IMAPAdditions.m (revision 1664) -++++ sope-mime/NGImap4/EOQualifier+IMAPAdditions.m (working copy) -+@@ -53,13 +53,13 @@ -+ if (FlagKeyWords) return; -+ -+ ud = [NSUserDefaults standardUserDefaults]; -+- FlagKeyWords = [[NSArray alloc] initWithObjects: @"answered", @"deleted", -+- @"draft", @"flagged", @"new", @"old", @"recent", -+- @"seen", @"unanswered", @"undeleted", @"undraft", -+- @"unflagged", @"unseen", nil]; -+- OtherKeyWords = [[NSArray alloc] initWithObjects: -+- @"bcc", @"body", @"cc", @"from", @"subject", -+- @"text", @"to", @"keyword", @"unkeyword", nil]; -++ FlagKeyWords = [[NSArray alloc] initWithObjects: @"ANSWERED", @"DELETED", -++ @"DRAFT", @"FLAGGED", @"NEW", @"OLD", @"RECENT", -++ @"SEEN", @"UNANSWERED", @"UNDELETED", @"UNDRAFT", -++ @"UNFLAGGED", @"UNSEEN", nil]; -++ OtherKeyWords = [[NSArray alloc] initWithObjects: @"ALL", @"BCC", @"BODY", -++ @"CC", @"FROM", @"SUBJECT", @"TEXT", @"TO", -++ @"KEYWORD", @"UID", @"UNKEYWORD", nil]; -+ -+ debugOn = [ud boolForKey:@"ImapDebugQualifierGeneration"]; -+ } -+@@ -266,10 +266,10 @@ -+ -+ enumerator = [lvalue objectEnumerator]; -+ while ((lvalue = [enumerator nextObject]) != nil) { -+- lvalue = [lvalue lowercaseString]; -++ lvalue = [lvalue uppercaseString]; -+ -+ if ([FlagKeyWords containsObject:lvalue]) { -+- if (insertNot) [search appendString:@"not "]; -++ if (insertNot) [search appendString:@"NOT "]; -+ [search appendString:lvalue]; -+ } -+ else { -+@@ -280,15 +280,31 @@ -+ return nil; -+ } -+ -+-- (NSString *)imap4OperatorForDateComparisonSelector:(SEL)lselector { -++- (NSString *)imap4OperatorForDateKeyword:(NSString *)dkey -++andComparisonSelector:(SEL)lselector { -++ NSString *operatorPrefix, *dateOperator, *imap4Operator; -++ -+ if (sel_eq(lselector, EOQualifierOperatorEqual)) -+- return @" senton "; -+- if (sel_eq(lselector, EOQualifierOperatorGreaterThan)) -+- return @" sentsince "; -+- if (sel_eq(lselector, EOQualifierOperatorLessThan)) -+- return @" sentbefore "; -+- -+- return nil; -++ dateOperator = @"ON"; -++ else if (sel_eq(lselector, EOQualifierOperatorGreaterThan)) -++ dateOperator = @"SINCE"; -++ else if (sel_eq(lselector, EOQualifierOperatorLessThan)) -++ dateOperator = @"BEFORE"; -++ else -++ dateOperator = nil; -++ -++ if (dateOperator) { -++ if ([dkey isEqualToString: @"DATE"]) -++ operatorPrefix = @"SENT"; -++ else -++ operatorPrefix = @""; -++ imap4Operator = [NSString stringWithFormat: @"%@%@ ", -++ operatorPrefix, dateOperator]; -++ } -++ else -++ imap4Operator = nil; -++ -++ return imap4Operator; -+ } -+ -+ - (NSException *)appendToImap4SearchString:(NSMutableString *)search -+@@ -300,11 +316,11 @@ -+ id lvalue; -+ SEL lselector; -+ -+- lkey = [[self key] lowercaseString]; -++ lkey = [[self key] uppercaseString]; -+ lvalue = [self value]; -+ lselector = [self selector]; -+ -+- if ([lkey isEqualToString:@"flags"]) { -++ if ([lkey isEqualToString:@"FLAGS"]) { -+ /* NOTE: special "not" processing! */ -+ return [self appendFlagsCheckToImap4SearchString:search -+ insertNot:insertNot]; -+@@ -312,9 +328,9 @@ -+ -+ /* not a flag */ -+ if (insertNot) -+- [search appendString:@"not "]; -++ [search appendString:@"NOT "]; -+ -+- if ([lkey isEqualToString:@"date"]) { -++ if ([lkey isEqualToString:@"DATE"] || [lkey isEqualToString:@"RECEIVE-DATE"]) { -+ NSString *s; -+ -+ if (![lvalue isKindOfClass:[NSCalendarDate class]]) { -+@@ -322,35 +338,38 @@ -+ @"expected a NSDate as value"]; -+ } -+ -+- if ((s = [self imap4OperatorForDateComparisonSelector:lselector]) == nil) -++ if ((s = [self imap4OperatorForDateKeyword:lkey -++ andComparisonSelector:lselector]) == nil) -+ return [self invalidImap4SearchQualifier:@"unexpected selector"]; -+ -+- // TODO: operator created but NOT added? -++ [search appendString:s]; -+ -+ // TODO: much faster without descriptionWithCalendarFormat:?! -+- s = [lvalue descriptionWithCalendarFormat:@"%d-%b-%Y"]; -++ s = [lvalue descriptionWithCalendarFormat:@"\"%d-%b-%Y\""]; -+ [search appendString:s]; -+ return nil; -+ } -+ -+- if ([lkey isEqualToString:@"uid"]) { -+- if (!sel_eq(lselector, EOQualifierOperatorEqual)) -++ if ([lkey isEqualToString:@"UID"]) { -++ if (!sel_eq(lselector, EOQualifierOperatorEqual)) { -+ return [self invalidImap4SearchQualifier:@"unexpected qualifier 2"]; -++ } -+ -+- [search appendString:@"uid "]; -++ [search appendString:@"UID "]; -+ [search appendString:[lvalue stringValue]]; -+ return nil; -+ } -+ -+- if ([lkey isEqualToString:@"size"]) { -++ if ([lkey isEqualToString:@"SIZE"]) { -+ if (sel_eq(lselector, EOQualifierOperatorGreaterThan)) -+- [search appendString:@"larger "]; -++ [search appendString:@"LARGER "]; -+ else if (sel_eq(lselector, EOQualifierOperatorLessThan)) -+- [search appendString:@"smaller "]; -++ [search appendString:@"SMALLER "]; -+ else -+ return [self invalidImap4SearchQualifier:@"unexpected qualifier 3"]; -+ -+ [search appendString:[lvalue stringValue]]; -++ -+ return nil; -+ } -+ -+@@ -386,7 +405,7 @@ -+ if (!sel_eq(lselector, EOQualifierOperatorEqual)) -+ return [self invalidImap4SearchQualifier:@"unexpected qualifier 5"]; -+ -+- [search appendString:@"header "]; -++ [search appendString:@"HEADER "]; -+ [search appendString:lkey]; -+ [search appendString:@" \""]; -+ [search appendString:[lvalue stringValue]]; -+Index: sope-mime/NGImap4/NGImap4ResponseParser.m -+=================================================================== -+--- sope-mime/NGImap4/NGImap4ResponseParser.m (revision 1664) -++++ sope-mime/NGImap4/NGImap4ResponseParser.m (working copy) -+@@ -31,6 +31,7 @@ -+ @interface NGImap4ResponseParser(ParsingPrivates) -+ - (BOOL)_parseNumberUntaggedResponse:(NGMutableHashMap *)result_; -+ - (NSDictionary *)_parseBodyContent; -++- (NSData *) _parseBodyHeaderFields; -+ -+ - (NSData *)_parseData; -+ -+@@ -38,6 +39,7 @@ -+ - (void)_parseContinuationResponseIntoHashMap:(NGMutableHashMap *)result_; -+ - (BOOL)_parseListOrLSubResponseIntoHashMap:(NGMutableHashMap *)result_; -+ - (BOOL)_parseCapabilityResponseIntoHashMap:(NGMutableHashMap *)result_; -++- (BOOL)_parseNamespaceResponseIntoHashMap:(NGMutableHashMap *)result_; -+ - (BOOL)_parseSearchResponseIntoHashMap:(NGMutableHashMap *)result_; -+ - (BOOL)_parseSortResponseIntoHashMap:(NGMutableHashMap *)result_; -+ - (BOOL)_parseQuotaRootResponseIntoHashMap:(NGMutableHashMap *)result_; -+@@ -84,6 +86,8 @@ -+ static NSDictionary *_parseMultipartBody(NGImap4ResponseParser *self, -+ BOOL isBodyStructure); -+ -++static NSArray *_parseLanguages(); -++ -+ static NSString *_parseBodyString(NGImap4ResponseParser *self, -+ BOOL _convertString); -+ static NSString *_parseBodyDecodeString(NGImap4ResponseParser *self, -+@@ -111,6 +115,7 @@ -+ static NSNumber *_parseUnsigned(NGImap4ResponseParser *self); -+ static NSString *_parseUntil(NGImap4ResponseParser *self, char _c); -+ static NSString *_parseUntil2(NGImap4ResponseParser *self, char _c1, char _c2); -++static BOOL _endsWithCQuote(NSString *_string); -+ -+ static __inline__ NSException *_consumeIfMatch -+ (NGImap4ResponseParser *self, unsigned char _m); -+@@ -488,6 +493,50 @@ -+ return [self _parseDataIntoRAM:size]; -+ } -+ -++/* -++ Similair to _parseData but used to parse something like this : -++ -++ BODY[HEADER.FIELDS (X-PRIORITY)] {17} -++ X-Priority: 1 -++ -++ ) -++ -++ Headers are returned as data, as is. -++*/ -++- (NSData *) _parseBodyHeaderFields -++{ -++ NSData *result; -++ unsigned size; -++ NSNumber *sizeNum; -++ -++ /* we skip until we're ready to parse {length} */ -++ _parseUntil(self, '{'); -++ -++ result = nil; -++ -++ if ((sizeNum = _parseUnsigned(self)) == nil) { -++ NSException *e; -++ -++ e = [[NGImap4ParserException alloc] -++ initWithFormat:@"expect a number between {}"]; -++ [self setLastException:[e autorelease]]; -++ return nil; -++ } -++ _consumeIfMatch(self, '}'); -++ _consumeIfMatch(self, '\n'); -++ -++ if ((size = [sizeNum intValue]) == 0) { -++ [self logWithFormat:@"ERROR(%s): got content size '0'!", -++ __PRETTY_FUNCTION__]; -++ return nil; -++ } -++ -++ if (UseMemoryMappedData && (size > Imap4MMDataBoundary)) -++ return [self _parseDataToFile:size]; -++ -++ return [self _parseDataIntoRAM:size]; -++} -++ -+ static int _parseTaggedResponse(NGImap4ResponseParser *self, -+ NGMutableHashMap *result_) -+ { -+@@ -584,6 +633,10 @@ -+ break; -+ -+ case 'N': -++ if (_matchesString(self, "NAMESPACE")) { -++ if ([self _parseNamespaceResponseIntoHashMap:result_]) -++ return; -++ } -+ if (_parseNoUntaggedResponse(self, result_)) // la: 2 -+ return; -+ break; -+@@ -648,14 +701,171 @@ -+ [result_ addObject:_parseUntil(self, '\n') forKey:@"description"]; -+ } -+ -++static inline void -++_purifyQuotedString(NSMutableString *quotedString) { -++ unichar *currentChar, *qString, *maxC, *startC; -++ unsigned int max, questionMarks; -++ BOOL possiblyQuoted, skipSpaces; -++ NSMutableString *newString; -++ -++ newString = [NSMutableString string]; -++ -++ max = [quotedString length]; -++ qString = malloc (sizeof (unichar) * max); -++ [quotedString getCharacters: qString]; -++ currentChar = qString; -++ startC = qString; -++ maxC = qString + max; -++ -++ possiblyQuoted = NO; -++ skipSpaces = NO; -++ -++ questionMarks = 0; -++ -++ while (currentChar < maxC) { -++ if (possiblyQuoted) { -++ if (questionMarks == 2) { -++ if ((*currentChar == 'Q' || *currentChar == 'q' -++ || *currentChar == 'B' || *currentChar == 'b') -++ && ((currentChar + 1) < maxC -++ && (*(currentChar + 1) == '?'))) { -++ currentChar++; -++ questionMarks = 3; -++ } -++ else { -++ possiblyQuoted = NO; -++ } -++ } -++ else if (questionMarks == 4) { -++ if (*currentChar == '=') { -++ skipSpaces = YES; -++ possiblyQuoted = NO; -++ currentChar++; -++ [newString appendString: [NSString stringWithCharacters: startC -++ length: (currentChar - startC)]]; -++ startC = currentChar; -++ } -++ else { -++ possiblyQuoted = NO; -++ } -++ } -++ else { -++ if (*currentChar == '?') { -++ questionMarks++; -++ } -++ else if (*currentChar == ' ' && questionMarks != 3) { -++ possiblyQuoted = NO; -++ } -++ } -++ } -++ else if (*currentChar == '=' -++ && ((currentChar + 1) < maxC -++ && (*(currentChar + 1) == '?'))) { -++ [newString appendString: [NSString stringWithCharacters: startC -++ length: (currentChar - startC)]]; -++ startC = currentChar; -++ possiblyQuoted = YES; -++ skipSpaces = NO; -++ currentChar++; -++ questionMarks = 1; -++ } -++ -++ currentChar++; -++ -++ if (skipSpaces) { -++ while (currentChar < maxC -++ && (*currentChar == ' ' -++ || *currentChar == '\t')) -++ currentChar++; -++ skipSpaces = NO; -++ startC = currentChar; -++ } -++ } -++ -++ if (startC < maxC) -++ [newString appendString: [NSString stringWithCharacters: startC -++ length: (currentChar - startC)]]; -++ -++ [quotedString setString: newString]; -++ free (qString); -++} -++ -+ - (NSString *)_parseQuotedString { -++ NSMutableString *quotedString; -++ NSString *tmpString; -++ BOOL stop; -++ -+ /* parse a quoted string, eg '"' */ -+ if (_la(self, 0) == '"') { -+ _consume(self, 1); -+- return _parseUntil(self, '"'); -++ quotedString = [NSMutableString string]; -++ stop = NO; -++ while (!stop) { -++ tmpString = _parseUntil(self, '"'); -++ [quotedString appendString: tmpString]; -++ if(_endsWithCQuote(tmpString)) { -++ [quotedString deleteSuffix: @"\\"]; -++ [quotedString appendString: @"\""]; -++ } -++ else { -++ stop = YES; -++ } -++ } -+ } -++ else { -++ quotedString = nil; -++ } -++ -++ _purifyQuotedString(quotedString); -++ -++ return quotedString; -++} -++- (NSString *)_parseQuotedStringOrNIL { -++ unsigned char c0; -++ -++ if ((c0 = _la(self, 0)) == '"') -++ return [self _parseQuotedString]; -++ -++ if (c0 == '{') { -++ /* a size indicator, eg '{112}\nkasdjfkja sdj fhj hasdfj hjasdf' */ -++ NSData *data; -++ NSString *s; -++ -++ if ((data = [self _parseData]) == nil) -++ return nil; -++ if (![data isNotEmpty]) -++ return @""; -++ -++ s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; -++ if (s == nil) -++ s = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding]; -++ if (s == nil) { -++ [self logWithFormat: -++ @"ERROR(%s): could not convert data (%d bytes) into string.", -++ __PRETTY_FUNCTION__, [data length]]; -++ return @"[ERROR: NGImap4 could not parse IMAP4 data string]"; -++ } -++ return [s autorelease]; -++ } -++ -++ if (c0 == 'N' && _matchesString(self, "NIL")) { -++ _consume(self, 3); -++ return (id)null; -++ } -+ return nil; -+ } -++- (id)_parseQuotedStringOrDataOrNIL { -++ if (_la(self, 0) == '"') -++ return [self _parseQuotedString]; -++ if (_la(self, 0) == '{') -++ return [self _parseData]; -++ -++ if (_matchesString(self, "NIL")) { -++ _consume(self, 3); -++ return null; -++ } -++ return nil; -++} -+ - (void)_consumeOptionalSpace { -+ if (_la(self, 0) == ' ') _consume(self, 1); -+ } -+@@ -685,6 +895,10 @@ -+ name = [self _parseQuotedString]; -+ _parseUntil(self, '\n'); -+ } -++ else if (_la(self, 0) == '{') { -++ name = [self _parseQuotedStringOrNIL]; -++ _parseUntil(self, '\n'); -++ } -+ else -+ name = _parseUntil(self, '\n'); -+ -+@@ -723,6 +937,85 @@ -+ return YES; -+ } -+ -++/* support for NAMESPACE extension - RFC2342 */ -++ -++- (NSDictionary *)_parseNamespacePart { -++ NSDictionary *namespacePart; -++ NSString *prefix, *key, *delimiter; -++ NSMutableDictionary *parameters; -++ NSMutableArray *values; -++ -++ _consume(self, 1); /* ( */ -++ prefix = [self _parseQuotedStringOrNIL]; /* "prefix" */ -++ _consume(self, 1); /* */ -++ delimiter = [self _parseQuotedStringOrNIL]; /* "delimiter" */ -++ parameters = [NSMutableDictionary dictionary]; -++ while (_la(self, 0) == ' ') { -++ _consume(self, 1); /* */ -++ key = [self _parseQuotedString]; -++ _consume(self, 1); /* */ -++ values = [NSMutableArray new]; -++ while (_la(self, 0) != ')') { -++ _consume(self, 1); /* ( or */ -++ [values addObject: [self _parseQuotedString]]; -++ } -++ _consume(self, 1); /* ) */ -++ [parameters setObject: values forKey: key]; -++ [values release]; -++ } -++ _consume(self, 1); /* ) */ -++ -++ namespacePart = [NSDictionary dictionaryWithObjectsAndKeys: -++ prefix, @"prefix", -++ delimiter, @"delimiter", -++ parameters, @"parameters", -++ nil]; -++ -++ return namespacePart; -++} -++ -++- (NSArray *)_parseNamespace { -++ NSMutableArray *namespace; -++ -++ namespace = [[NSMutableArray alloc] initWithCapacity: 3]; -++ if (_la(self, 0) == 'N') { -++ namespace = nil; -++ _consume(self, 3); -++ } else { -++ _consume(self, 1); /* ( */ -++ while (_la(self, 0) == '(') { -++ [namespace addObject: [self _parseNamespacePart]]; -++ } -++ _consume(self, 1); /* ) */ -++ } -++ -++ return namespace; -++} -++ -++- (BOOL)_parseNamespaceResponseIntoHashMap:(NGMutableHashMap *)result_ { -++ NSArray *namespace; -++ -++ if (!_matchesString(self, "NAMESPACE ")) -++ return NO; -++ -++ _parseUntil(self, ' '); -++ -++ namespace = [self _parseNamespace]; -++ if (namespace) -++ [result_ addObject:namespace forKey:@"personal"]; -++ _consume(self, 1); -++ namespace = [self _parseNamespace]; -++ if (namespace) -++ [result_ addObject:namespace forKey:@"other users"]; -++ _consume(self, 1); -++ namespace = [self _parseNamespace]; -++ if (namespace) -++ [result_ addObject:namespace forKey:@"shared"]; -++ _consume(self, 1); /* \n */ -++ -++ return YES; -++} -++ -+ - (BOOL)_parseACLResponseIntoHashMap:(NGMutableHashMap *)result_ { -+ /* -+ 21 GETACL INBOX -+@@ -1030,10 +1323,15 @@ -+ _consume(self, 7); -+ -+ if (_la(self, 0) == '"') { -+- _consume(self, 1); -+- name = _parseUntil(self, '"'); -++ name = [self _parseQuotedString]; -++// _consume(self, 1); -++// name = _parseUntil(self, '"'); -+ _consumeIfMatch(self, ' '); -+ } -++ else if (_la(self, 0) == '{') { -++ name = [self _parseQuotedStringOrNIL]; -++ _consumeIfMatch(self, ' '); -++ } -+ else { -+ name = _parseUntil(self, ' '); -+ } -+@@ -1073,51 +1371,6 @@ -+ return YES; -+ } -+ -+-- (NSString *)_parseQuotedStringOrNIL { -+- unsigned char c0; -+- -+- if ((c0 = _la(self, 0)) == '"') -+- return [self _parseQuotedString]; -+- -+- if (c0 == '{') { -+- /* a size indicator, eg '{112}\nkasdjfkja sdj fhj hasdfj hjasdf' */ -+- NSData *data; -+- NSString *s; -+- -+- if ((data = [self _parseData]) == nil) -+- return nil; -+- if (![data isNotEmpty]) -+- return @""; -+- -+- s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; -+- if (s == nil) { -+- [self logWithFormat: -+- @"ERROR(%s): could not convert data (%d bytes) into string.", -+- __PRETTY_FUNCTION__, [data length]]; -+- return @"[ERROR: NGImap4 could not parse IMAP4 data string]"; -+- } -+- return [s autorelease]; -+- } -+- -+- if (c0 == 'N' && _matchesString(self, "NIL")) { -+- _consume(self, 3); -+- return (id)null; -+- } -+- return nil; -+-} -+-- (id)_parseQuotedStringOrDataOrNIL { -+- if (_la(self, 0) == '"') -+- return [self _parseQuotedString]; -+- if (_la(self, 0) == '{') -+- return [self _parseData]; -+- -+- if (_matchesString(self, "NIL")) { -+- _consume(self, 3); -+- return null; -+- } -+- return nil; -+-} -+- -+ - (id)_decodeQP:(id)_string headerField:(NSString *)_field { -+ if (![_string isNotNull]) -+ return _string; -+@@ -1185,7 +1438,7 @@ -+ route = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; -+ mailbox = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; -+ host = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; -+- -++ -+ if (_la(self, 0) != ')') { -+ [self logWithFormat:@"WARNING: IMAP4 envelope " -+ @"address not properly closed (c0=%c,c1=%c): %@", -+@@ -1197,6 +1450,7 @@ -+ address = [[NGImap4EnvelopeAddress alloc] initWithPersonalName:pname -+ sourceRoute:route mailbox:mailbox -+ host:host]; -++ -+ return address; -+ } -+ -+@@ -1382,7 +1636,15 @@ -+ #if 0 -+ [self logWithFormat:@"PARSE KEY: %@", key]; -+ #endif -+- if ([key hasPrefix:@"body["]) { -++ if ([key hasPrefix:@"body[header.fields"]) { -++ NSData *content; -++ -++ if ((content = [self _parseBodyHeaderFields]) != nil) -++ [fetch setObject:content forKey:key]; -++ else -++ [self logWithFormat:@"ERROR: got no body content for key: '%@'",key]; -++ } -++ else if ([key hasPrefix:@"body["]) { -+ NSDictionary *content; -+ -+ if ((content = [self _parseBodyContent]) != nil) -+@@ -1594,8 +1856,11 @@ -+ if (_decode) -+ data = [data decodeQuotedPrintableValueOfMIMEHeaderField:nil]; -+ -+- return [[[StrClass alloc] initWithData:data encoding:encoding] -+- autorelease]; -++ if ([data isKindOfClass: [NSString class]]) -++ return (NSString *) data; -++ else -++ return [[[StrClass alloc] initWithData:data encoding:encoding] -++ autorelease]; -+ } -+ else { -+ str = _parseUntil2(self, ' ', ')'); -+@@ -1620,13 +1885,35 @@ -+ return str; -+ } -+ -+- -+ static NSString *_parseBodyString(NGImap4ResponseParser *self, -+ BOOL _convertString) -+ { -+ return _parseBodyDecodeString(self, _convertString, NO /* no decode */); -+ } -+ -++static NSArray *_parseLanguages(NGImap4ResponseParser *self) { -++ NSMutableArray *languages; -++ NSString *language; -++ -++ languages = [NSMutableArray array]; -++ if (_la(self, 0) == '(') { -++ while (_la(self, 0) != ')') { -++ _consume(self,1); -++ language = _parseBodyString(self, YES); -++ if ([language length]) -++ [languages addObject: language]; -++ } -++ _consume(self,1); -++ } -++ else { -++ language = _parseBodyString(self, YES); -++ if ([language length]) -++ [languages addObject: language]; -++ } -++ -++ return languages; -++} -++ -+ static NSDictionary *_parseBodyParameterList(NGImap4ResponseParser *self) -+ { -+ NSMutableDictionary *list; -+@@ -1646,7 +1933,7 @@ -+ _consumeIfMatch(self, ' '); -+ value = _parseBodyDecodeString(self, YES, YES); -+ -+- [list setObject:value forKey:[key lowercaseString]]; -++ if (value) [list setObject:value forKey:[key lowercaseString]]; -+ } -+ _consumeIfMatch(self, ')'); -+ } -+@@ -1731,13 +2018,14 @@ -+ static NSDictionary *_parseSingleBody(NGImap4ResponseParser *self, -+ BOOL isBodyStructure) { -+ NSString *type, *subtype, *bodyId, *description, -+- *encoding, *bodysize; -++ *result, *encoding, *bodysize; -+ NSDictionary *parameterList; -+ NSMutableDictionary *dict; -++ NSArray *languages; -+ -+ type = [_parseBodyString(self, YES) lowercaseString]; -+ _consumeIfMatch(self, ' '); -+- subtype = _parseBodyString(self, YES); -++ subtype = [_parseBodyString(self, YES) lowercaseString]; -+ _consumeIfMatch(self, ' '); -+ parameterList = _parseBodyParameterList(self); -+ _consumeIfMatch(self, ' '); -+@@ -1762,13 +2050,18 @@ -+ _consumeIfMatch(self, ' '); -+ [dict setObject:_parseBodyString(self, YES) forKey:@"lines"]; -+ } -+- else if ([type isEqualToString:@"message"]) { -++ else if ([type isEqualToString:@"message"] -++ && [subtype isEqualToString:@"rfc822"]) { -+ if (_la(self, 0) != ')') { -+ _consumeIfMatch(self, ' '); -+ _consumeIfMatch(self, '('); -+- [dict setObject:_parseBodyString(self, YES) forKey:@"date"]; -++ result = _parseBodyString(self, YES); -++ if (result == nil) result = @""; -++ [dict setObject:result forKey:@"date"]; -+ _consumeIfMatch(self, ' '); -+- [dict setObject:_parseBodyString(self, YES) forKey:@"subject"]; -++ result = _parseBodyString(self, YES); -++ if (result == nil) result = @""; -++ [dict setObject:result forKey:@"subject"]; -+ _consumeIfMatch(self, ' '); -+ [dict setObject:_parseParenthesizedAddressList(self) forKey:@"from"]; -+ _consumeIfMatch(self, ' '); -+@@ -1783,14 +2076,20 @@ -+ _consumeIfMatch(self, ' '); -+ [dict setObject:_parseParenthesizedAddressList(self) forKey:@"bcc"]; -+ _consumeIfMatch(self, ' '); -+- [dict setObject:_parseBodyString(self, YES) forKey:@"in-reply-to"]; -++ result = _parseBodyString(self, YES); -++ if (result == nil) result = @""; -++ [dict setObject:result forKey:@"in-reply-to"]; -+ _consumeIfMatch(self, ' '); -+- [dict setObject:_parseBodyString(self, YES) forKey:@"messageId"]; -++ result = _parseBodyString(self, YES); -++ if (result == nil) result = @""; -++ [dict setObject:result forKey:@"messageId"]; -+ _consumeIfMatch(self, ')'); -+ _consumeIfMatch(self, ' '); -+ [dict setObject:_parseBody(self, isBodyStructure) forKey:@"body"]; -+ _consumeIfMatch(self, ' '); -+- [dict setObject:_parseBodyString(self, YES) forKey:@"bodyLines"]; -++ result = _parseBodyString(self, YES); -++ if (result == nil) result = @""; -++ [dict setObject:result forKey:@"bodyLines"]; -+ } -+ } -+ -+@@ -1805,14 +2104,9 @@ -+ forKey: @"disposition"]; -+ if (_la(self, 0) != ')') { -+ _consume(self,1); -+- if (_la(self, 0) == '(') { -+- [dict setObject: _parseBodyParameterList(self) -+- forKey: @"language"]; -+- } -+- else { -+- [dict setObject: _parseBodyString(self, YES) -+- forKey: @"language"]; -+- } -++ languages = _parseLanguages(self); -++ if ([languages count]) -++ [dict setObject: languages forKey: @"languages"]; -+ if (_la(self, 0) != ')') { -+ _consume(self,1); -+ [dict setObject: _parseBodyString(self, YES) -+@@ -1829,6 +2123,7 @@ -+ static NSDictionary *_parseMultipartBody(NGImap4ResponseParser *self, -+ BOOL isBodyStructure) { -+ NSMutableArray *parts; -++ NSArray *languages; -+ NSString *kind; -+ NSMutableDictionary *dict; -+ -+@@ -1854,14 +2149,9 @@ -+ forKey: @"disposition"]; -+ if (_la(self, 0) != ')') { -+ _consume(self,1); -+- if (_la(self, 0) == '(') { -+- [dict setObject: _parseBodyParameterList(self) -+- forKey: @"language"]; -+- } -+- else { -+- [dict setObject: _parseBodyString(self, YES) -+- forKey: @"language"]; -+- } -++ languages = _parseLanguages(self); -++ if ([languages count]) -++ [dict setObject: languages forKey: @"languages"]; -+ if (_la(self, 0) != ')') { -+ _consume(self,1); -+ [dict setObject: _parseBodyString(self, YES) -+@@ -2170,6 +2460,21 @@ -+ } -+ } -+ -++static BOOL _endsWithCQuote(NSString *_string){ -++ unsigned int quoteSlashes; -++ int pos; -++ -++ quoteSlashes = 0; -++ pos = [_string length] - 1; -++ while (pos > -1 -++ && [_string characterAtIndex: pos] == '\\') { -++ quoteSlashes++; -++ pos--; -++ } -++ -++ return ((quoteSlashes % 2) == 1); -++} -++ -+ - (NSException *)exceptionForFailedMatch:(unsigned char)_match -+ got:(unsigned char)_avail -+ { -+@@ -2225,9 +2530,9 @@ -+ [s release]; -+ -+ if (c == '\n') { -+- if ([self->serverResponseDebug cStringLength] > 2) { -++ if ([self->serverResponseDebug lengthOfBytesUsingEncoding:NSISOLatin1StringEncoding] > 2) { -+ fprintf(stderr, "S[%p]: %s", self, -+- [self->serverResponseDebug cString]); -++ [self->serverResponseDebug cStringUsingEncoding:NSISOLatin1StringEncoding]); -+ } -+ [self->serverResponseDebug release]; -+ self->serverResponseDebug = -+Index: sope-mime/NGImap4/ChangeLog -+=================================================================== -+--- sope-mime/NGImap4/ChangeLog (revision 1664) -++++ sope-mime/NGImap4/ChangeLog (working copy) -+@@ -1,3 +1,92 @@ -++2010-01-05 Wolfgang Sourdeau -++ -++ * NGImap4ResponseParser.m (_parseUntaggedResponse): now accepts -++ the "NAMESPACE" response and parse accordingly by making use of -++ the appropriate new method. -++ -++ * NGImap4ResponseNormalizer.m (-normalizeNamespaceResponse): -++ self-explicit new method. -++ -++ * NGImap4Connection.m (-subfolderForURL:, -allFoldersForURL:): -++ differenciate both methods by having "subfolder..." use the "%" -++ wild card and "allFolders" the "*" wildcard. -++ (-cachedHierarchyResultsForURL): now accepts a url parameter so -++ in order to maintain multiple caches depending on the queried -++ namespace. -++ (SOGoMailGetDirectChildren): if the array count is < 2, we must -++ not return since certain implementations may not return the -++ current folder. -++ -++ * NGImap4Client.m (-namespace): new method implementing the -++ "NAMESPACE" command. -++ (-lsub:pattern:): we now sanitize the "prefix" particle of the -++ LSUB command. -++ -++2009-11-25 Wolfgang Sourdeau -++ -++ * NSString+Imap4.m (_encodeToModifiedUTF7): handle the case where -++ the leftOver is 0 by "chance" after the first 2 cycles. This -++ can happen when coding characters having a bitmask with 6 zeroes -++ in a row. -++ -++2009-10-06 Wolfgang Sourdeau -++ -++ * NGImap4Client.m (-delete:): if the folder we want to delete is -++ the same as self->selectedFolder, we unselect it first to ensure a -++ "SELECT" happens if a new folder with the same name is created. -++ -++ * EOQualifier+IMAPAdditions.m -++ (-imap4OperatorForDateKeyword:andComparisonSelector:): modified -++ operator handler to handle "receive-date" search key as well as -++ "date", prefixing the real filter with "sent" or not. -++ -++2009-09-22 Wolfgang Sourdeau -++ -++ * NGImap4Client.m (_sopeSORT:qualifier:encoding:): added support -++ for sorting by message size. -++ -++2009-07-01 Wolfgang Sourdeau -++ -++ * NGImap4Connection.m (-initWithClient:password:): we need to copy -++ the imap4Separator, otherwise it will be released when the connection -++ is deallocated. -++ -++2009-06-15 Wolfgang Sourdeau -++ -++ * NSString+Imap4.m (-stringByEncodingImap4FolderName, -++ -stringByDecodingImap4FolderName): reimplemented the original -++ methods in a unicode-safe way, thereby simplifying the code at the -++ same time. -++ -++ * NGImap4Functions.m (SaneFolderName): new function designed to -++ sanitize folder names prior to using them in IMAP commands. -++ -++2008-10-23 Wolfgang Sourdeau -++ -++ * NGImap4Client.m ([NGImap -sort:qualifier:encoding:]): message -++ without date that are sorted on servers which do not have the SORT -++ capability are now given the current date as a work-around. -++ -++2008-09-22 Wolfgang Sourdeau -++ -++ * NGImap4Connection.m ([NGImap -doesMailboxExistAtURL:]): restore -++ the previously selected folder state. -++ -++2008-09-19 Wolfgang Sourdeau -++ -++ * NGImap4Client.m ([NGImap -select:]): simplified method by -++ removing the need for storing the previous folder before releasing -++ it. This strangely seems to fix a crash with gnustep 1.14. -++ -++2008-09-01 Ludovic Marcotte -++ -++ * NGImap4ConnectionManager.m: implemented _garbageCollect. -++ -++2008-08-28 Wolfgang Sourdeau -++ -++ * NGImap4Client.m ([NGImap -unselect]): new method to send -++ "UNSELECT" to the imap server. -++ -+ 2007-08-24 Wolfgang Sourdeau -+ -+ * NGImap4Connection.m: some fix for folders ending with a slash (OGo -+Index: sope-mime/NGImap4/NGImap4ConnectionManager.m -+=================================================================== -+--- sope-mime/NGImap4/NGImap4ConnectionManager.m (revision 1664) -++++ sope-mime/NGImap4/NGImap4ConnectionManager.m (working copy) -+@@ -38,6 +38,9 @@ -+ debugCache = [ud boolForKey:@"NGImap4EnableIMAP4CacheDebug"]; -+ poolingOff = [ud boolForKey:@"NGImap4DisableIMAP4Pooling"]; -+ -++ if ([ud objectForKey:@"NGImap4PoolingCleanupInterval"]) -++ PoolScanInterval = [[ud objectForKey:@"NGImap4PoolingCleanupInterval"] doubleValue]; -++ -+ if (debugOn) NSLog(@"Note: NGImap4EnableIMAP4Debug is enabled!"); -+ if (poolingOff) NSLog(@"WARNING: IMAP4 connection pooling is disabled!"); -+ } -+@@ -53,18 +56,17 @@ -+ if ((self = [super init])) { -+ if (!poolingOff) { -+ self->urlToEntry = [[NSMutableDictionary alloc] initWithCapacity:256]; -++ self->gcTimer = [[NSTimer scheduledTimerWithTimeInterval: -++ PoolScanInterval -++ target:self selector:@selector(_garbageCollect:) -++ userInfo:nil repeats:YES] retain]; -+ } -+- -+- self->gcTimer = [[NSTimer scheduledTimerWithTimeInterval: -+- PoolScanInterval -+- target:self selector:@selector(_garbageCollect:) -+- userInfo:nil repeats:YES] retain]; -+ } -+ return self; -+ } -+ -+ - (void)dealloc { -+- if (self->gcTimer) [self->gcTimer invalidate]; -++ [self->gcTimer invalidate]; -+ [self->urlToEntry release]; -+ [self->gcTimer release]; -+ [super dealloc]; -+@@ -91,6 +93,25 @@ -+ -+ - (void)_garbageCollect:(NSTimer *)_timer { -+ // TODO: scan for old IMAP4 channels -++ NGImap4Connection *entry; -++ NSDate *now; -++ NSArray *a; -++ int i; -++ -++ a = [self->urlToEntry allKeys]; -++ now = [NSDate date]; -++ -++ for (i = 0; i < [a count]; i++) -++ { -++ entry = [self->urlToEntry objectForKey: [a objectAtIndex: i]]; -++ -++ if ([now timeIntervalSinceDate: [entry creationTime]] > PoolScanInterval) -++ { -++ [[entry client] logout]; -++ [self->urlToEntry removeObjectForKey: [a objectAtIndex: i]]; -++ } -++ } -++ -+ [self debugWithFormat:@"should collect IMAP4 channels (%d active)", -+ [self->urlToEntry count]]; -+ } -+@@ -105,34 +126,42 @@ -+ NGImap4Connection *entry; -+ NGImap4Client *client; -+ -++ if (poolingOff) { -++ client = [self imap4ClientForURL:_url password:_p]; -++ entry = [[NGImap4Connection alloc] initWithClient:client -++ password:_p]; -++ return [entry autorelease]; -++ } -++ else { -+ /* check cache */ -+ -+- if ((entry = [self entryForURL:_url]) != nil) { -+- if ([entry isValidPassword:_p]) { -++ if ((entry = [self entryForURL:_url]) != nil) { -++ if ([entry isValidPassword:_p]) { -++ if (debugCache) -++ [self logWithFormat:@"valid password, reusing cache entry ..."]; -++ return entry; -++ } -++ -++ /* different password, password could have changed! */ -+ if (debugCache) -+- [self logWithFormat:@"valid password, reusing cache entry ..."]; -+- return entry; -++ [self logWithFormat:@"different password than cached entry: %@", _url]; -++ entry = nil; -+ } -+- -+- /* different password, password could have changed! */ -+- if (debugCache) -+- [self logWithFormat:@"different password than cached entry: %@", _url]; -+- entry = nil; -+- } -+- else -+- [self debugWithFormat:@"no connection cached yet for url: %@", _url]; -++ else -++ [self debugWithFormat:@"no connection cached yet for url: %@", _url]; -+ -+- /* try to login */ -++ /* try to login */ -+ -+- client = [entry isValidPassword:_p] -+- ? [entry client] -+- : [self imap4ClientForURL:_url password:_p]; -++ client = [entry isValidPassword:_p] -++ ? [entry client] -++ : [self imap4ClientForURL:_url password:_p]; -++ -++ if (client == nil) -++ return nil; -+ -+- if (client == nil) -+- return nil; -+- -+ /* sideeffect of -imap4ClientForURL:password: is to create a cache entry */ -+- return [self entryForURL:_url]; -++ return [self entryForURL:_url]; -++ } -+ } -+ -+ /* client object */ -+Index: sope-mime/NGImap4/NSString+Imap4.m -+=================================================================== -+--- sope-mime/NGImap4/NSString+Imap4.m (revision 1664) -++++ sope-mime/NGImap4/NSString+Imap4.m (working copy) -+@@ -20,117 +20,86 @@ -+ 02111-1307, USA. -+ */ -+ -++#import -++ -+ #include -+ #include "imCommon.h" -+ -+-/* TODO: NOT UNICODE SAFE (uses cString) */ -+- -+-static void _encodeToModifiedUTF7(unsigned char *_buf, int encLen, -+- unsigned char **result_, -+- unsigned int *cntRes_); -+-static int _decodeOfModifiedUTF7(unsigned char *_target, unsigned _targetLen, -+- unsigned *usedBytes_ , -+- unsigned char **buffer_, -+- int *bufLen_, int maxBuf); -+- -+ @implementation NSString(Imap4) -+ -++static unsigned int _encodeToModifiedUTF7(unichar *_char, unsigned char *result_, -++ unsigned int *cntRes_); -++static unsigned int _decodeOfModifiedUTF7(unsigned char *_source, unichar *result_, -++ unsigned int *cntRes_ ); -++ -+ - (NSString *)stringByEncodingImap4FolderName { -+- // TBD: this is restricted to Latin1, should be fixed to UTF-8 -+- /* dude.d& --> dude.d&- */ -+- unsigned char *buf = NULL; -++ unichar *buf = NULL; -+ unsigned char *res = NULL; -+ unsigned int len = 0; -+ unsigned int cnt = 0; -+ unsigned int cntRes = 0; -+ NSString *result = nil; -+- NSData *data; -+ -+- len = [self cStringLength]; -+- buf = calloc(len + 3, sizeof(char)); -+- res = calloc((len * 6) + 3, sizeof(char)); -+- buf[len] = '\0'; -+- res[len * 6] = '\0'; -+- [self getCString:(char *)buf]; -++ len = [self length]; -++ buf = NSZoneMalloc(NULL, (len + 1) * sizeof(unichar)); -++ [self getCharacters: buf]; -++ buf[len] = 0; -+ -++ /* 1 * '&', 3 for the max bytes / char, 1 * '-' */ -++ res = NSZoneMalloc(NULL, ((len * 5) + 1) * sizeof(char)); -++ -+ while (cnt < len) { -+- int c = buf[cnt]; -++ unichar c = buf[cnt]; -+ if (((c > 31) && (c < 38)) || -+ ((c > 38) && (c < 127))) { -+ res[cntRes++] = c; -+- cnt++; -+ } -+ else { -+ if (c == '&') { -+ res[cntRes++] = '&'; -+ res[cntRes++] = '-'; -+- cnt++; -+ } -+ else { -+- int start; -+- -+- start = cnt; -+- -+- while (cnt < (len - 1)) { -+- int c = buf[cnt + 1]; -+- if (((c > 31) && (c < 38)) || -+- ((c > 38) && (c < 127)) || -+- (c == '&')) { -+- break; -+- } -+- else { -+- cnt++; -+- } -+- } -+- { -+- unsigned length; -+- -+- res[cntRes++] = '&'; -+- -+- length = cnt - start + 1; -+- -+- _encodeToModifiedUTF7(buf + start, length, &res, &cntRes); -+- -+- res[cntRes] = '-'; -+- cntRes++; -+- cnt++; -+- } -++ res[cntRes++] = '&'; -++ cnt += _encodeToModifiedUTF7(buf + cnt, res + cntRes, &cntRes); -++ res[cntRes++] = '-'; -+ } -+ } -++ cnt++; -+ } -+- if (buf != NULL) free(buf); buf = NULL; -++ if (buf != NULL) NSZoneFree(NULL, buf); -+ -+- data = [[NSData alloc] initWithBytesNoCopy:res length:cntRes -+- freeWhenDone:YES]; -+- result = [[NSString alloc] initWithData:data -+- encoding:NSISOLatin1StringEncoding]; -+- [data release]; data = nil; -+- -+- return [result autorelease]; -++ res[cntRes] = 0; -++ result = [NSString stringWithCString: (char *) res -++ encoding: NSISOLatin1StringEncoding]; -++ -++ return result; -+ } -+ -+ - (NSString *)stringByDecodingImap4FolderName { -+- // TBD: this is restricted to Latin1, should be fixed to UTF-8 -+- /* dude/d&- --> dude/d& */ -+ unsigned char *buf; -+- unsigned char *res; -++ unichar *res; -+ unsigned int len; -+ unsigned int cnt = 0; -+ unsigned int cntRes = 0; -+ NSString *result = nil; -+- NSData *data; -++// NSData *data; -+ -+- if ((len = [self cStringLength]) == 0) -++ if ((len = [self lengthOfBytesUsingEncoding: NSISOLatin1StringEncoding]) == 0) -+ return @""; -+- -+- buf = calloc(len + 3, sizeof(unsigned char)); -+- res = calloc(len + 3, sizeof(unsigned char)); -++ -++ buf = NSZoneMalloc(NULL, (len + 1) * sizeof(unsigned char)); -++ -++ if ([self getCString:(char *)buf maxLength: len + 1 -++ encoding: NSISOLatin1StringEncoding] == NO) { -++ NSZoneFree(NULL, buf); -++ return @""; -++ } -+ buf[len] = '\0'; -+- res[len] = '\0'; -+- -+- [self getCString:(char *)buf]; -+- -+- while (cnt < (len - 1)) { /* &- */ -++ -++ res = NSZoneMalloc(NULL, (len + 1) * sizeof(unichar)); -++ -++ while (cnt < len) { /* &- */ -+ unsigned char c; -+ -+ c = buf[cnt]; -+@@ -141,29 +110,7 @@ -+ cnt += 2; -+ } -+ else { -+- unsigned usedBytes = 0; -+- unsigned char *buffer; -+- int maxBuf, bufLen; -+- -+- cnt++; -+- maxBuf = 511; -+- bufLen = 0; -+- buffer = calloc(maxBuf + 3, sizeof(char)); -+- -+- if (_decodeOfModifiedUTF7(buf + cnt, len - cnt, &usedBytes , &buffer, -+- &bufLen, maxBuf) == 0) { -+- int cnt1; -+- -+- cnt1 = 0; -+- while (cnt1 < bufLen) { -+- res[cntRes++] = buffer[cnt1++]; -+- } -+- cnt += usedBytes; -+- } -+- else { -+- NSCAssert(NO, @"couldn't decode UTF-7 .."); -+- } -+- free(buffer); buffer = NULL; -++ cnt += _decodeOfModifiedUTF7(buf + cnt + 1, res + cntRes, &cntRes) + 1; -+ } -+ } -+ else { -+@@ -171,20 +118,133 @@ -+ cnt++; -+ } -+ } -+- if (cnt < len) -+- res[cntRes++] = buf[cnt++]; -+- -+- if (buf != NULL) free(buf); buf = NULL; -+ -+- data = [[NSData alloc] initWithBytesNoCopy:res length:cntRes -+- freeWhenDone:YES]; -+- result = [[NSString alloc] initWithData:data -+- encoding:NSISOLatin1StringEncoding]; -+- [data release]; data = nil; -+- -+- return [result autorelease]; -++ if (buf != NULL) NSZoneFree(NULL, buf); -++ -++ res[cntRes] = 0; -++ result = [NSString stringWithCharacters: res length: cntRes]; -++ -++ return result; -+ } -+ -++/* check metamail output for correctness */ -++ -++static unsigned char basis_64[] = -++ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -++ -++static char index_64[128] = { -++ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -++ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -++ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, -++ 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, -++ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, -++ 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, -++ -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, -++ 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 -++}; -++ -++#define char64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) -++ -++static unsigned int _encodeToModifiedUTF7(unichar *_char, unsigned char *result_, -++ unsigned int *cntRes_) -++{ -++ unsigned int processedSrc, processedDest, cycle; -++ unichar c; -++ char leftover; -++ BOOL hasLeftOver; -++ -++ processedSrc = 0; -++ processedDest = 0; -++ cycle = 0; -++ leftover = 0; -++ -++ c = *_char; -++ while (c > 126 || (c > 0 && c < 32)) { -++ if (cycle == 0) { -++ *(result_ + processedDest) = basis_64[(c >> 10) & 0x3f]; -++ *(result_ + processedDest + 1) = basis_64[(c >> 4) & 0x3f]; -++ leftover = (c << 2); -++ hasLeftOver = YES; -++ processedDest += 2; -++ cycle = 1; -++ } -++ else if (cycle == 1) { -++ *(result_ + processedDest) = basis_64[(leftover | (c >> 14)) & 0x3f]; -++ *(result_ + processedDest + 1) = basis_64[(c >> 8) & 0x3f]; -++ *(result_ + processedDest + 2) = basis_64[(c >> 2) & 0x3f]; -++ leftover = (c << 4); -++ hasLeftOver = YES; -++ processedDest += 3; -++ cycle = 2; -++ } -++ else if (cycle == 2) { -++ *(result_ + processedDest) = basis_64[(leftover | (c >> 12)) & 0x3f]; -++ *(result_ + processedDest + 1) = basis_64[(c >> 6) & 0x3f]; -++ *(result_ + processedDest + 2) = basis_64[c & 0x3f]; -++ leftover = 0; -++ hasLeftOver = NO; -++ processedDest += 3; -++ cycle = 0; -++ } -++ processedSrc++; -++ c = *(_char + processedSrc); -++ } -++ if (hasLeftOver) { -++ *(result_ + processedDest) = basis_64[leftover & 0x3f]; -++ processedDest++; -++ } -++ processedSrc--; -++ *cntRes_ += processedDest; -++ -++ return processedSrc; -++} -++ -++static unsigned int _decodeOfModifiedUTF7(unsigned char *_source, unichar *result_, -++ unsigned int *cntRes_) -++{ -++ unsigned int processedSrc, processedDest; -++ unsigned char c, decoded; -++ unichar currentRes; -++ int shift; -++ -++ processedSrc = 0; -++ processedDest = 0; -++ shift = 10; -++ currentRes = 0; -++ -++ c = *_source; -++ while (c != 0 && c != '-') { -++ decoded = index_64[c]; -++ if (shift < 0) { -++ currentRes |= (decoded >> (shift * -1)); -++ *(result_ + processedDest) = currentRes; -++ processedDest++; -++ shift += 16; -++ currentRes = (decoded << shift); -++ } else { -++ currentRes |= (decoded << shift); -++ if (shift == 0) { -++ *(result_ + processedDest) = currentRes; -++ processedDest++; -++ currentRes = 0; -++ shift = 16; -++ } -++ } -++ shift -= 6; -++ processedSrc++; -++ c = *(_source + processedSrc); -++ } -++ if (shift != 10) { -++ *(result_ + processedDest) = currentRes; -++ } -++ if (c == '-') -++ processedSrc++; -++ -++ *cntRes_ += processedDest; -++ -++ return processedSrc; -++} -++ -+ - (NSString *)stringByEscapingImap4Password { -+ // TODO: perf -+ unichar *buffer; -+@@ -193,12 +253,12 @@ -+ NSString *s; -+ -+ len = [self length]; -+- chars = calloc(len + 2, sizeof(unichar)); -++ chars = NSZoneCalloc(NULL, len + 2, sizeof(unichar)); -+ [self getCharacters:chars]; -+- -+- buffer = calloc(len * 2 + 2, sizeof(unichar)); -++ -++ buffer = NSZoneCalloc(NULL, len * 2 + 2, sizeof(unichar)); -+ buffer[len * 2] = '\0'; -+- -++ -+ for (i = 0, j = 0; i < len; i++, j++) { -+ BOOL conv = NO; -+ -+@@ -224,209 +284,11 @@ -+ } -+ buffer[j] = chars[i]; -+ } -+- if (chars != NULL) free(chars); chars = NULL; -++ if (chars != NULL) NSZoneFree(NULL, chars); -+ -+ s = [NSString stringWithCharacters:buffer length:j]; -+- if (buffer != NULL) free(buffer); buffer = NULL; -++ -+ return s; -+ } -+ -+ @end /* NSString(Imap4) */ -+- -+-static void writeChunk(int _c1, int _c2, int _c3, int _pads, -+- unsigned char **result_, -+- unsigned int *cntRes_); -+- -+-static int getChar(int _cnt, int *cnt_, unsigned char *_buf) { -+- int result; -+- -+- if ((_cnt % 2)) { -+- result = _buf[*cnt_]; -+- (*cnt_)++; -+- } -+- else { -+- result = 0; -+- } -+- return result; -+-} -+-static void _encodeToModifiedUTF7(unsigned char *_buf, int encLen, -+- unsigned char **result_, unsigned int *cntRes_) -+-{ -+- int c1, c2, c3; -+- int cnt, cntAll; -+- -+- cnt = 0; -+- cntAll = 0; -+- -+- while (cnt < encLen) { -+- c1 = getChar(cntAll++, &cnt, _buf); -+- if (cnt == encLen) { -+- writeChunk(c1, 0, 0, 2, result_, cntRes_); -+- } -+- else { -+- c2 = getChar(cntAll++, &cnt, _buf); -+- if (cnt == encLen) { -+- writeChunk(c1, c2, 0, 1, result_, cntRes_); -+- } -+- else { -+- c3 = getChar(cntAll++, &cnt, _buf); -+- writeChunk(c1, c2, c3, 0, result_, cntRes_); -+- } -+- } -+- } -+-} -+- -+-/* check metamail output for correctness */ -+- -+-static unsigned char basis_64[] = -+- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -+- -+-static void writeChunk(int c1, int c2, int c3, int pads, unsigned char **result_, -+- unsigned int *cntRes_) { -+- unsigned char c; -+- -+- c = basis_64[c1>>2]; -+- (*result_)[*cntRes_] = c; -+- (*cntRes_)++; -+- -+- c = basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)]; -+- -+- (*result_)[*cntRes_] = c; -+- (*cntRes_)++; -+- -+- -+- if (pads == 2) { -+- ; -+- } -+- else if (pads) { -+- c = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)]; -+- (*result_)[*cntRes_] = c; -+- (*cntRes_)++; -+- } -+- else { -+- c = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)]; -+- -+- (*result_)[*cntRes_] = c; -+- (*cntRes_)++; -+- -+- c = basis_64[c3 & 0x3F]; -+- (*result_)[*cntRes_] = c; -+- (*cntRes_)++; -+- } -+-} -+- -+-static char index_64[128] = { -+- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -+- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -+- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, -+- 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, -+- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, -+- 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, -+- -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, -+- 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 -+-}; -+- -+-#define char64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) -+- -+-static int _decodeOfModifiedUTF7(unsigned char *_target, unsigned _targetLen, -+- unsigned *usedBytes_ , unsigned char **buffer_, -+- int *bufLen_, int maxBuf) -+-{ -+- int c1, c2, c3, c4; -+- unsigned int cnt; -+- -+- for (cnt = 0; cnt < _targetLen; ) { -+- c1 = '='; -+- c2 = '='; -+- c3 = '='; -+- c4 = '='; -+- -+- c1 = _target[cnt++]; -+- -+- if (c1 == '-') { -+- (*usedBytes_)++; -+- return 0; -+- } -+- if (cnt < _targetLen) -+- c2 = _target[cnt++]; -+- -+- if (c2 == '-') { -+- (*usedBytes_)+=2; -+- return 0; -+- } -+- -+- (*usedBytes_) += 2; -+- -+- if (cnt < _targetLen) { -+- c3 = _target[cnt++]; -+- (*usedBytes_)++; -+- } -+- -+- if (cnt < _targetLen) { -+- c4 = _target[cnt++]; -+- if (c3 != '-') -+- (*usedBytes_)++; -+- } -+- -+- if (c2 == -1 || c3 == -1 || c4 == -1) { -+- fprintf(stderr, "Warning: base64 decoder saw premature EOF!\n"); -+- return 0; -+- } -+- -+- if (c1 == '=' || c2 == '=') { -+- continue; -+- } -+- -+- c1 = char64(c1); -+- c2 = char64(c2); -+- -+- if (*bufLen_ < maxBuf) { -+- unsigned char c; -+- -+- c = ((c1<<2) | ((c2&0x30)>>4)); -+- -+- if (c) { -+- (*buffer_)[*bufLen_] = c; -+- *bufLen_ = *bufLen_ + 1; -+- } -+- } -+- if (c3 == '-') { -+- return 0; -+- } -+- else if (c3 == '=') { -+- continue; -+- } else { -+- -+- c3 = char64(c3); -+- -+- if (*bufLen_ < maxBuf) { -+- unsigned char c; -+- c = (((c2&0XF) << 4) | ((c3&0x3C) >> 2)); -+- if (c) { -+- (*buffer_)[*bufLen_] = c; -+- *bufLen_ = *bufLen_ + 1; -+- } -+- } -+- -+- if (c4 == '-') { -+- return 0; -+- } -+- else if (c4 == '=') { -+- continue; -+- } else { -+- c4 = char64(c4); -+- -+- if (*bufLen_ < maxBuf) { -+- unsigned char c; -+- -+- c = (((c3&0x03) <<6) | c4); -+- if (c) { -+- (*buffer_)[*bufLen_] = c; -+- (*bufLen_) = (*bufLen_) + 1; -+- } -+- } -+- } -+- } -+- } -+- return 0; -+-} -+Index: sope-mime/NGImap4/NGImap4Functions.h -+=================================================================== -+--- sope-mime/NGImap4/NGImap4Functions.h (revision 1664) -++++ sope-mime/NGImap4/NGImap4Functions.h (working copy) -+@@ -58,4 +58,6 @@ -+ id_folder); -+ BOOL _createSubFolderWithName(id self, NSString *_name, BOOL _app); -+ -++NSString *SaneFolderName(NSString *folderName); -++ -+ #endif /* __NGMime_NGImap4_NGImap4Functions_H__ */ -+Index: sope-mime/NGMail/NGMailAddressParser.h -+=================================================================== -+--- sope-mime/NGMail/NGMailAddressParser.h (revision 1664) -++++ sope-mime/NGMail/NGMailAddressParser.h (working copy) -+@@ -24,7 +24,9 @@ -+ -+ #import -+ -+-@class NSData, NSString, NSArray; -++#import -++ -++@class NSData, NSArray; -+ @class NGMailAddressList; -+ -+ /* -+@@ -34,16 +36,16 @@ -+ @interface NGMailAddressParser : NSObject -+ { -+ @private -+- unsigned char *data; -+- int dataPos; -+- int errorPos; -+- int maxLength; -++ unichar *data; -++ int dataPos; -++ int errorPos; -++ int maxLength; -+ } -+ -+ + (id)mailAddressParserWithString:(NSString *)_string; -+ + (id)mailAddressParserWithData:(NSData *)_data; -+-+ (id)mailAddressParserWithCString:(char *)_cString; -+-- (id)initWithCString:(const unsigned char *)_cstr length:(int unsigned)_len; -+++ (id)mailAddressParserWithCString:(const char *)_cString; -++- (id)initWithString:(NSString *)_str; -+ -+ /* parsing */ -+ -+Index: sope-mime/NGMail/NGMimeMessageGenerator.m -+=================================================================== -+--- sope-mime/NGMail/NGMimeMessageGenerator.m (revision 1664) -++++ sope-mime/NGMail/NGMimeMessageGenerator.m (working copy) -+@@ -86,37 +86,40 @@ -+ char *des = NULL; -+ unsigned int cnt; -+ BOOL doEnc; -+- NSString *str; -++// NSString *str; -+ -+ // TODO: this s***s big time! -++// NSLog (@"class: '%@'", NSStringFromClass ([_data class])); -++// #if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY -++// str = [[NSString alloc] initWithData:_data -++// encoding:NSISOLatin1StringEncoding]; -++// str = [str autorelease]; -++ -++// #else -++// str = [[NSString alloc] initWithData:_data -++// encoding:NSISOLatin9StringEncoding]; -++// #endif -++// bytes = [str cString]; -++// length = [str cStringLength]; -+ -+-#if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY -+- str = [[NSString alloc] initWithData:_data -+- encoding:NSISOLatin1StringEncoding]; -+-#else -+- str = [[NSString alloc] initWithData:_data -+- encoding:NSISOLatin9StringEncoding]; -+-#endif -+- str = [str autorelease]; -+- -+- bytes = [str cString]; -+- length = [str cStringLength]; -+- -++ bytes = [_data bytes]; -++ length = [_data length]; -++ -+ /* check whether we need to encode */ -+- -+- for (cnt = 0, doEnc = NO; cnt < length; cnt++) { -+- if ((unsigned char)bytes[cnt] > 127) { -++ cnt = 0; -++ doEnc = NO; -++ while (!doEnc && cnt < length) -++ if ((unsigned char)bytes[cnt] > 127) -+ doEnc = YES; -+- break; -+- } -+- } -+- -++ else -++ cnt++; -++ -+ if (!doEnc) -+ return _data; -+ -+ /* encode quoted printable */ -+ { -+- char iso[] = "=?iso-8859-15?q?"; -++ char iso[] = "=?utf-8?q?"; -+ unsigned isoLen = 16; -+ char isoEnd[] = "?="; -+ unsigned isoEndLen = 2; -+Index: sope-mime/NGMail/NGMailAddressParser.m -+=================================================================== -+--- sope-mime/NGMail/NGMailAddressParser.m (revision 1664) -++++ sope-mime/NGMail/NGMailAddressParser.m (working copy) -+@@ -52,9 +52,9 @@ -+ StrClass = [NSString class]; -+ } -+ -+-static inline NSString *mkStrObj(const unsigned char *s, unsigned int l) { -++static inline NSString *mkStrObj(const unichar *s, unsigned int l) { -+ // TODO: unicode -+- return [(NSString *)[StrClass alloc] initWithCString:(char *)s length:l]; -++ return [(NSString *)[StrClass alloc] initWithCharacters:s length:l]; -+ } -+ -+ static inline id parseWhiteSpaces(NGMailAddressParser *self, BOOL _guessMode) { -+@@ -84,7 +84,7 @@ -+ int keepPos = self->dataPos; // keep reference for backtracking -+ id returnValue = nil; -+ BOOL isAtom = YES; -+- unsigned char text[self->maxLength + 2]; // token text -++ unichar text[self->maxLength + 2]; // token text -+ int length = 0; // token text length -+ BOOL done = NO; -+ -+@@ -94,7 +94,7 @@ -+ done = YES; -+ } -+ else { -+- register unsigned char c = self->data[self->dataPos]; -++ register unichar c = self->data[self->dataPos]; -+ -+ switch (c) { -+ case '(' : case ')': case '<': case '>': -+@@ -162,7 +162,7 @@ -+ int keepPos = self->dataPos; // keep reference for backtracking -+ id returnValue = nil; -+ BOOL isQText = YES; -+- unsigned char text[self->maxLength + 4]; // token text -++ unichar text[self->maxLength + 4]; // token text -+ int length = 0; // token text length -+ BOOL done = YES; -+ -+@@ -172,9 +172,9 @@ -+ done = YES; -+ } -+ else { -+- register char c = self->data[self->dataPos]; -++ register unichar c = self->data[self->dataPos]; -+ -+- switch ((int)c) { -++ switch (c) { -+ case '"' : -+ case '\\': -+ case 13 : -+@@ -215,7 +215,7 @@ -+ int keepPos = self->dataPos; // keep reference for backtracking -+ id returnValue = nil; -+ BOOL isDText = YES; -+- unsigned char text[self->maxLength]; // token text -++ unichar text[self->maxLength]; // token text -+ int length = 0; // token text length -+ BOOL done = YES; -+ -+@@ -225,9 +225,9 @@ -+ done = YES; -+ } -+ else { -+- register char c = self->data[self->dataPos]; -++ register unichar c = self->data[self->dataPos]; -+ -+- switch ((int)c) { -++ switch (c) { -+ case '[': case ']': -+ case '\\': case 13: -+ isDText = (length > 0); -+@@ -320,42 +320,47 @@ -+ /* constructors */ -+ -+ + (id)mailAddressParserWithData:(NSData *)_data { -+- return [[(NGMailAddressParser *)[self alloc] -+- initWithCString:[_data bytes] -+- length:[_data length]] autorelease]; -++ NSString *uniString; -++ -++ uniString = [NSString stringWithCharacters:(unichar *)[_data bytes] -++ length:([_data length] / sizeof(unichar))]; -++ -++ return [(NGMailAddressParser *)self mailAddressParserWithString:uniString]; -+ } -++ -+ + (id)mailAddressParserWithCString:(char *)_cString { -+- return [[(NGMailAddressParser *)[self alloc] -+- initWithCString:(unsigned char *)_cString -+- length:strlen(_cString)] autorelease]; -++ NSString *nsCString; -++ -++ nsCString = [NSString stringWithCString:_cString]; -++ -++ return [(NGMailAddressParser *)self mailAddressParserWithString:nsCString]; -+ } -+-- (id)initWithCString:(const unsigned char *)_cstr length:(int unsigned)_len { -++ -+++ (id)mailAddressParserWithString:(NSString *)_string { -++ return [[(NGMailAddressParser *)[self alloc] initWithString:_string] -++ autorelease]; -++} -++ -++- (id)initWithString:(NSString *)_str { -+ if ((self = [super init])) { -+ // TODO: remember some string encoding? -+- self->data = (unsigned char *)_cstr; -+- self->maxLength = _len; -++ self->maxLength = [_str length]; -++ self->data = malloc(self->maxLength*sizeof(unichar)); -++ [_str getCharacters:self->data]; -+ self->dataPos = 0; -+ self->errorPos = -1; -+ } -+ return self; -+ } -+ -+-- (id)initWithString:(NSString *)_str { -+- // TODO: unicode -+- return [self initWithCString:(unsigned char *)[_str cString] -+- length:[_str cStringLength]]; -+-} -+- -+ - (id)init { -+- return [self initWithCString:NULL length:0]; -++ return [self initWithString:nil]; -+ } -+ -+-+ (id)mailAddressParserWithString:(NSString *)_string { -+- return [[(NGMailAddressParser *)[self alloc] initWithString:_string] -+- autorelease]; -+-} -+- -+ - (void)dealloc { -++ if (self->data != NULL) { -++ free(self->data); -++ } -+ self->data = NULL; -+ self->maxLength = 0; -+ self->dataPos = 0; -+Index: sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m -+=================================================================== -+--- sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m (revision 1664) -++++ sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m (working copy) -+@@ -19,88 +19,45 @@ -+ 02111-1307, USA. -+ */ -+ -++#ifdef HAVE_STRNDUP -++#define _GNU_SOURCE 1 -++#endif -++ -++#include -++ -+ #include "NGMimeHeaderFieldParser.h" -+ #include "NGMimeHeaderFields.h" -+ #include "NGMimeUtilities.h" -+ #include "common.h" -+-#include -+ -++#ifndef HAVE_STRNDUP -++char *strndup(const char *str, size_t len) -++{ -++ char *dup = (char *)malloc(len+1); -++ if (dup) { -++ strncpy(dup,str,len); -++ dup[len]= '\0'; -++ } -++ return dup; -++} -++#endif -++ -+ @implementation NGMimeRFC822DateHeaderFieldParser -+ -+-static Class CalDateClass = Nil; -+-static NSTimeZone *gmt = nil; -+-static NSTimeZone *gmt01 = nil; -+-static NSTimeZone *gmt02 = nil; -+-static NSTimeZone *gmt03 = nil; -+-static NSTimeZone *gmt04 = nil; -+-static NSTimeZone *gmt05 = nil; -+-static NSTimeZone *gmt06 = nil; -+-static NSTimeZone *gmt07 = nil; -+-static NSTimeZone *gmt08 = nil; -+-static NSTimeZone *gmt09 = nil; -+-static NSTimeZone *gmt10 = nil; -+-static NSTimeZone *gmt11 = nil; -+-static NSTimeZone *gmt12 = nil; -+-static NSTimeZone *gmt0530 = nil; -+-static NSTimeZone *gmtM01 = nil; -+-static NSTimeZone *gmtM02 = nil; -+-static NSTimeZone *gmtM03 = nil; -+-static NSTimeZone *gmtM04 = nil; -+-static NSTimeZone *gmtM05 = nil; -+-static NSTimeZone *gmtM06 = nil; -+-static NSTimeZone *gmtM07 = nil; -+-static NSTimeZone *gmtM08 = nil; -+-static NSTimeZone *gmtM09 = nil; -+-static NSTimeZone *gmtM10 = nil; -+-static NSTimeZone *gmtM11 = nil; -+-static NSTimeZone *gmtM12 = nil; -+-static NSTimeZone *gmtM13 = nil; -+-static NSTimeZone *gmtM14 = nil; -+-static NSTimeZone *met = nil; -++static NSTimeZone *gmt = nil; -++static NSTimeZone *met = nil; -+ -+ + (int)version { -+ return 2; -+ } -++ -+ + (void)initialize { -+ static BOOL didInit = NO; -+- Class TzClass; -+ if (didInit) return; -+ didInit = YES; -+ -+- CalDateClass = [NSCalendarDate class]; -+- -+- /* timezones which were actually used in a maillist mailbox */ -+- TzClass = [NSTimeZone class]; -+- gmt = [[TzClass timeZoneWithName:@"GMT"] retain]; -+- met = [[TzClass timeZoneWithName:@"MET"] retain]; -+- gmt01 = [[TzClass timeZoneForSecondsFromGMT: 1 * (60 * 60)] retain]; -+- gmt02 = [[TzClass timeZoneForSecondsFromGMT: 2 * (60 * 60)] retain]; -+- gmt03 = [[TzClass timeZoneForSecondsFromGMT: 3 * (60 * 60)] retain]; -+- gmt04 = [[TzClass timeZoneForSecondsFromGMT: 4 * (60 * 60)] retain]; -+- gmt05 = [[TzClass timeZoneForSecondsFromGMT: 5 * (60 * 60)] retain]; -+- gmt06 = [[TzClass timeZoneForSecondsFromGMT: 6 * (60 * 60)] retain]; -+- gmt07 = [[TzClass timeZoneForSecondsFromGMT: 7 * (60 * 60)] retain]; -+- gmt08 = [[TzClass timeZoneForSecondsFromGMT: 8 * (60 * 60)] retain]; -+- gmt09 = [[TzClass timeZoneForSecondsFromGMT: 9 * (60 * 60)] retain]; -+- gmt10 = [[TzClass timeZoneForSecondsFromGMT: 10 * (60 * 60)] retain]; -+- gmt11 = [[TzClass timeZoneForSecondsFromGMT: 11 * (60 * 60)] retain]; -+- gmt12 = [[TzClass timeZoneForSecondsFromGMT: 12 * (60 * 60)] retain]; -+- gmtM01 = [[TzClass timeZoneForSecondsFromGMT: -1 * (60 * 60)] retain]; -+- gmtM02 = [[TzClass timeZoneForSecondsFromGMT: -2 * (60 * 60)] retain]; -+- gmtM03 = [[TzClass timeZoneForSecondsFromGMT: -3 * (60 * 60)] retain]; -+- gmtM04 = [[TzClass timeZoneForSecondsFromGMT: -4 * (60 * 60)] retain]; -+- gmtM05 = [[TzClass timeZoneForSecondsFromGMT: -5 * (60 * 60)] retain]; -+- gmtM06 = [[TzClass timeZoneForSecondsFromGMT: -6 * (60 * 60)] retain]; -+- gmtM07 = [[TzClass timeZoneForSecondsFromGMT: -7 * (60 * 60)] retain]; -+- gmtM08 = [[TzClass timeZoneForSecondsFromGMT: -8 * (60 * 60)] retain]; -+- gmtM09 = [[TzClass timeZoneForSecondsFromGMT: -9 * (60 * 60)] retain]; -+- gmtM10 = [[TzClass timeZoneForSecondsFromGMT:-10 * (60 * 60)] retain]; -+- gmtM11 = [[TzClass timeZoneForSecondsFromGMT:-11 * (60 * 60)] retain]; -+- gmtM12 = [[TzClass timeZoneForSecondsFromGMT:-12 * (60 * 60)] retain]; -+- gmtM13 = [[TzClass timeZoneForSecondsFromGMT:-13 * (60 * 60)] retain]; -+- gmtM14 = [[TzClass timeZoneForSecondsFromGMT:-14 * (60 * 60)] retain]; -+- -+- gmt0530 = [[TzClass timeZoneForSecondsFromGMT:5 * (60*60) + (30*60)] retain]; -++ gmt = [[NSTimeZone timeZoneWithName:@"GMT"] retain]; -++ met = [[NSTimeZone timeZoneWithName:@"MET"] retain]; -+ } -+ -+ /* -+@@ -111,7 +68,7 @@ -+ TODO: use an own parser for that. -+ */ -+ -+-static int parseMonthOfYear(unsigned char *s, unsigned int len) { -++static int parseMonthOfYear(char *s, unsigned int len) { -+ /* -+ This one is *extremely* forgiving, it only checks what is -+ necessary for the set below. This should work for both, English -+@@ -147,162 +104,110 @@ -+ } -+ } -+ -+-static NSTimeZone *parseTimeZone(unsigned char *s, unsigned int len) { -++static int offsetFromTZAbbreviation(const char **p) { -++ NSString *abbreviation; -++ NSTimeZone *offsetTZ; -++ unsigned int length; -++ -++ length = 0; -++ while (isalpha(*(*p+length))) -++ length++; -++ abbreviation = [[NSString alloc] initWithBytes: *p -++ length: length - 1 -++ encoding: NSISOLatin1StringEncoding]; -++ offsetTZ = [NSTimeZone timeZoneWithAbbreviation: abbreviation]; -++ [abbreviation release]; -++ *p += length; -++ -++ return [offsetTZ secondsFromGMT]; -++} -++ -++static inline char *digitsString(const char *string) { -++ const char *p; -++ unsigned int len; -++ -++ p = string; -++ while (!isdigit(*p)) -++ p++; -++ len = 0; -++ while (isdigit(*(p + len))) -++ len++; -++ -++ return strndup(p, len); -++} -++ -++static NSTimeZone *parseTimeZone(const char *s, unsigned int len) { -+ /* -+ WARNING: failed to parse RFC822 timezone: '+0530' \ -+ (value='Tue, 13 Jul 2004 21:39:28 +0530') -+ TODO: this is because libFoundation doesn't accept 'GMT+0530' as input. -+ */ -+- char *p = (char *)s; -++ char *newString, *digits; -++ const char *p; -+ NSTimeZone *tz; -+- NSString *ts; -+- -+- if (len == 0) -+- return nil; -+- -+- if (*s == '+' || *s == '-') { -+- if (len == 3) { -+- if (p[1] == '0' && p[2] == '0') // '+00' or '-00' -+- return gmt; -+- if (*s == '+') { -+- if (p[1] == '0' && p[2] == '1') // '+01' -+- return gmt01; -+- if (p[1] == '0' && p[2] == '2') // '+02' -+- return gmt02; -+- } -+- } -+- else if (len == 5) { -+- if (p[3] == '0' && p[4] == '0' && p[1] == '0') { // '?0x00' -+- if (p[2] == '0') // '+0000' -+- return gmt; -+- -+- if (*s == '+') { -+- if (p[2] == '1') return gmt01; // '+0100' -+- if (p[2] == '2') return gmt02; // '+0200' -+- if (p[2] == '3') return gmt03; // '+0300' -+- if (p[2] == '4') return gmt04; // '+0400' -+- if (p[2] == '5') return gmt05; // '+0500' -+- if (p[2] == '6') return gmt06; // '+0600' -+- if (p[2] == '7') return gmt07; // '+0700' -+- if (p[2] == '8') return gmt08; // '+0800' -+- if (p[2] == '9') return gmt09; // '+0900' -+- } -+- else if (*s == '-') { -+- if (p[2] == '1') return gmtM01; // '-0100' -+- if (p[2] == '2') return gmtM02; // '-0200' -+- if (p[2] == '3') return gmtM03; // '-0300' -+- if (p[2] == '4') return gmtM04; // '-0400' -+- if (p[2] == '5') return gmtM05; // '-0500' -+- if (p[2] == '6') return gmtM06; // '-0600' -+- if (p[2] == '7') return gmtM07; // '-0700' -+- if (p[2] == '8') return gmtM08; // '-0800' -+- if (p[2] == '9') return gmtM09; // '-0900' -+- } -+- } -+- else if (p[3] == '0' && p[4] == '0' && p[1] == '1') { // "?1x00" -+- if (*s == '+') { -+- if (p[2] == '0') return gmt10; // '+1000' -+- if (p[2] == '1') return gmt11; // '+1100' -+- if (p[2] == '2') return gmt12; // '+1200' -+- } -+- else if (*s == '-') { -+- if (p[2] == '0') return gmtM10; // '-1000' -+- if (p[2] == '1') return gmtM11; // '-1100' -+- if (p[2] == '2') return gmtM12; // '-1200' -+- if (p[2] == '3') return gmtM13; // '-1300' -+- if (p[2] == '4') return gmtM14; // '-1400' -+- } -+- } -+- -+- /* special case for GMT+0530 */ -+- if (strncmp((char *)s, "+0530", 5) == 0) -+- return gmt0530; -+- } -+- else if (len == 7) { -+- /* -+- "MultiMail" submits timezones like this: -+- "Tue, 9 Mar 2004 9:43:00 -05-500", -+- don't know what the "-500" trailer is supposed to mean? Apparently -+- Thunderbird just uses the "-05", so do we. -+- */ -+- -+- if (isdigit(p[1]) && isdigit(p[2]) && (p[3] == '-'||p[3] == '+')) { -+- unsigned char tmp[8]; -+- -+- strncpy((char *)tmp, p, 3); -+- tmp[3] = '0'; -+- tmp[4] = '0'; -+- tmp[5] = '\0'; -+- return parseTimeZone(tmp, 5); -+- } -+- } -++ unsigned int hours, minutes, seconds, remaining; -++ int sign; -++ -++ sign = 1; -++ hours = 0; -++ minutes = 0; -++ seconds = 0; -++ -++ newString = strndup(s, len); -++ p = newString; -++ -++ if (isalpha(*p)) -++ seconds = offsetFromTZAbbreviation(&p); -++ while (isspace(*p)) -++ p++; -++ while (*p == '+' || *p == '-') { -++ if (*p == '-') -++ sign = -sign; -++ p++; -+ } -+- else if (*s == '0') { -+- if (len == 2) { // '00' -+- if (p[1] == '0') return gmt; -+- if (p[1] == '1') return gmt01; -+- if (p[1] == '2') return gmt02; -+- } -+- else if (len == 4) { -+- if (p[2] == '0' && p[3] == '0') { // '0x00' -+- if (p[1] == '0') return gmt; -+- if (p[1] == '1') return gmt01; -+- if (p[1] == '2') return gmt02; -+- } -+- } -++ digits = digitsString(p); -++ p = digits; -++ remaining = strlen(p); -++ switch(remaining) { -++ case 6: /* hhmmss */ -++ seconds += (10 * (*(p + remaining - 2) - 48) -++ + *(p + remaining - 1) - 48); -++ case 4: /* hhmm */ -++ hours += 10 * (*p - 48); -++ p++; -++ case 3: /* hmm */ -++ hours += (*p - 48); -++ p++; -++ minutes += 10 * (*p - 48) + *(p + 1) - 48; -++ break; -++ case 2: /* hh */ -++ hours += 10 * (*p - 48) + *(p + 1) - 48; -++ break; -++ default: -++ NSLog (@"parseTimeZone: cannot parse time notation '%s'", newString); -+ } -+- else if (len == 3) { -+- if (strcasecmp((char *)s, "GMT") == 0) return gmt; -+- if (strcasecmp((char *)s, "UTC") == 0) return gmt; -+- if (strcasecmp((char *)s, "MET") == 0) return met; -+- if (strcasecmp((char *)s, "CET") == 0) return met; -+- } -+- -+- if (isalpha(*s)) { -+- ts = [[NSString alloc] initWithCString:(char *)s length:len]; -+- } -+- else { -+- char buf[len + 5]; -+- -+- buf[0] = 'G'; buf[1] = 'M'; buf[2] = 'T'; -+- if (*s == '+' || *s == '-') { -+- strcpy(&(buf[3]), (char *)s); -+- } -+- else { -+- buf[3] = '+'; -+- strcpy(&(buf[4]), (char *)s); -+- } -+- ts = [[NSString alloc] initWithCString:buf]; -+- } -+-#if 1 -+- NSLog(@"%s: RFC822 TZ Parser: expensive: '%@'", __PRETTY_FUNCTION__, ts); -+-#endif -+- tz = [NSTimeZone timeZoneWithAbbreviation:ts]; -+- [ts release]; -++ free(digits); -++ -++ seconds += sign * (3600 * hours + 60 * minutes); -++ tz = [NSTimeZone timeZoneForSecondsFromGMT: seconds]; -++ free(newString); -++ -+ return tz; -+ } -+ -+ - (id)parseValue:(id)_data ofHeaderField:(NSString *)_field { -+ // TODO: use UNICODE -+ NSCalendarDate *date = nil; -+- unsigned char buf[256]; -+- unsigned char *bytes = buf, *pe; -++ char *bytes, *pe; -+ unsigned length = 0; -+ NSTimeZone *tz = nil; -+ char dayOfMonth, monthOfYear, hour, minute, second; -+ short year; -+ BOOL flag; -+- -+- if ((length = [_data cStringLength]) > 254) { -+- [self logWithFormat: -+- @"header field value to large for date parsing: '%@'(%i)", -+- _data, length]; -+- length = 254; -+- } -+- -+- [_data getCString:(char *)buf maxLength:length]; -+- buf[length] = '\0'; -+- -++ -++ length = [_data lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; -++ bytes = [_data cStringUsingEncoding: NSUTF8StringEncoding]; -++ -+ /* remove leading chars (skip to first digit, the day of the month) */ -+ while (length > 0 && (!isdigit(*bytes))) { -+ bytes++; -+@@ -312,7 +217,7 @@ -+ if (length == 0) { -+ NSLog(@"WARNING(%s): empty value for header field %@ ..", -+ __PRETTY_FUNCTION__, _field); -+- return [CalDateClass date]; -++ return [NSCalendarDate date]; -+ } -+ -+ // TODO: should be a category on NSCalendarDate -+@@ -435,7 +340,8 @@ -+ for (pe = bytes; isalnum(*pe) || *pe == '-' || *pe == '+'; pe++) -+ ; -+ *pe = '\0'; -+- if ((tz = parseTimeZone(bytes, (pe - bytes))) == nil) { -++ if (pe == bytes -++ || (tz = parseTimeZone((const char *) bytes, (pe - bytes))) == nil) { -+ [self logWithFormat: -+ @"WARNING: failed to parse RFC822 timezone: '%s' (value='%@')", -+ bytes, _data]; -+@@ -444,9 +350,9 @@ -+ -+ /* construct and return */ -+ finished: -+- date = [CalDateClass dateWithYear:year month:monthOfYear day:dayOfMonth -+- hour:hour minute:minute second:second -+- timeZone:tz]; -++ date = [NSCalendarDate dateWithYear:year month:monthOfYear day:dayOfMonth -++ hour:hour minute:minute second:second -++ timeZone:tz]; -+ if (date == nil) goto failed; -+ -+ #if 0 -+Index: sope-mime/NGMime/NGMimeMultipartBodyParser.m -+=================================================================== -+--- sope-mime/NGMime/NGMimeMultipartBodyParser.m (revision 1664) -++++ sope-mime/NGMime/NGMimeMultipartBodyParser.m (working copy) -+@@ -428,6 +428,7 @@ -+ NSString *boundary = nil; -+ NSArray *rawBodyParts = nil; -+ BOOL foundError = NO; -++ NSData *boundaryBytes; -+ -+ contentType = [_part contentType]; -+ boundary = [contentType valueOfParameter:@"boundary"]; -+@@ -437,9 +438,10 @@ -+ -+ *(&foundError) = NO; -+ -++ boundaryBytes = [boundary dataUsingEncoding:NSISOLatin1StringEncoding]; -+ *(&rawBodyParts) = [self _parseBody:_body part:_part data:_data -+- boundary:[boundary cString] -+- length:[boundary cStringLength] -++ boundary:[boundaryBytes bytes] -++ length:[boundary length] -+ delegate:_d]; -+ -+ if (rawBodyParts) { -+Index: sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m -+=================================================================== -+--- sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m (revision 1664) -++++ sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m (working copy) -+@@ -77,6 +77,7 @@ -+ [rfc822Set setGenerator:gen forField:@"bcc"]; -+ [rfc822Set setGenerator:gen forField:Fields->from]; -+ [rfc822Set setGenerator:gen forField:@"reply-to"]; -++ [rfc822Set setGenerator:gen forField:@"in-reply-to"]; -+ [rfc822Set setGenerator:gen forField:@"Disposition-Notification-To"]; -+ } -+ -+Index: sope-mime/NGMime/NGMimeType.m -+=================================================================== -+--- sope-mime/NGMime/NGMimeType.m (revision 1664) -++++ sope-mime/NGMime/NGMimeType.m (working copy) -+@@ -120,30 +120,30 @@ -+ -+ /* some unsupported, but known encoding */ -+ else if ([charset isEqualToString:@"ks_c_5601-1987"]) { -+- encoding = [NSString defaultCStringEncoding]; -++ encoding = NSISOLatin1StringEncoding; -+ foundUnsupported = YES; -+ } -+ else if ([charset isEqualToString:@"euc-kr"]) { -+- encoding = [NSString defaultCStringEncoding]; -+- foundUnsupported = YES; -++ encoding = NSKoreanEUCStringEncoding; -+ } -+ else if ([charset isEqualToString:@"big5"]) { -+- encoding = [NSString defaultCStringEncoding]; -+- foundUnsupported = YES; -++ encoding = NSBIG5StringEncoding; -+ } -+ else if ([charset isEqualToString:@"iso-2022-jp"]) { -+- encoding = [NSString defaultCStringEncoding]; -+- foundUnsupported = YES; -++ encoding = NSISO2022JPStringEncoding; -+ } -+ else if ([charset isEqualToString:@"gb2312"]) { -+- encoding = [NSString defaultCStringEncoding]; -+- foundUnsupported = YES; -++ encoding = NSGB2312StringEncoding; -+ } -+ else if ([charset isEqualToString:@"koi8-r"]) { -+- encoding = [NSString defaultCStringEncoding]; -+- foundUnsupported = YES; -++ encoding = NSKOI8RStringEncoding; -+ } -+- -++ else if ([charset isEqualToString:@"windows-1250"]) { -++ encoding = NSWindowsCP1250StringEncoding; -++ } -++ else if ([charset isEqualToString:@"windows-1251"]) { -++ encoding = NSWindowsCP1251StringEncoding; -++ } -+ else if ([charset isEqualToString:@"windows-1252"]) { -+ encoding = NSWindowsCP1252StringEncoding; -+ } -+@@ -152,7 +152,7 @@ -+ } -+ else if ([charset isEqualToString:@"x-unknown"] || -+ [charset isEqualToString:@"unknown"]) { -+- encoding = NSASCIIStringEncoding; -++ encoding = NSISOLatin1StringEncoding; -+ } -+ /* ISO Latin 9 */ -+ #if !(NeXT_Foundation_LIBRARY || APPLE_Foundation_LIBRARY) -+@@ -166,7 +166,7 @@ -+ else { -+ [self logWithFormat:@"%s: unknown charset '%@'", -+ __PRETTY_FUNCTION__, _s]; -+- encoding = [NSString defaultCStringEncoding]; -++ encoding = NSISOLatin1StringEncoding; -+ } -+ return encoding; -+ } -+@@ -385,23 +385,26 @@ -+ } -+ -+ - (BOOL)valueNeedsQuotes:(NSString *)_parameterValue { -+- unsigned len = [_parameterValue cStringLength]; -+- char buf[len + 15]; -+- char *cstr; -++ NSData *stringData; -++ const char *cstr; -++ unsigned int count, max; -++ BOOL needsQuote; -+ -+- cstr = &(buf[0]); -++ needsQuote = NO; -+ -+- [_parameterValue getCString:cstr]; cstr[len] = '\0'; -+- while (*cstr) { -+- if (isMime_SpecialByte(*cstr)) -+- return YES; -++ stringData = [_parameterValue dataUsingEncoding:NSUTF8StringEncoding]; -++ cstr = [stringData bytes]; -++ max = [stringData length]; -++ count = 0; -++ while (!needsQuote && count < max) { -++ if (isMime_SpecialByte(*(cstr + count)) -++ || *(cstr + count) == 32) -++ needsQuote = YES; -++ else -++ count++; -++ } -+ -+- if (*cstr == 32) -+- return YES; -+- -+- cstr++; -+- } -+- return NO; -++ return needsQuote; -+ } -+ -+ - (NSString *)stringValue { -+Index: sope-mime/NGMime/NGMimeBodyPart.m -+=================================================================== -+--- sope-mime/NGMime/NGMimeBodyPart.m (revision 1664) -++++ sope-mime/NGMime/NGMimeBodyPart.m (working copy) -+@@ -31,18 +31,6 @@ -+ return 2; -+ } -+ -+-static NGMimeType *defaultType = nil; -+- -+-+ (void)initialize { -+- static BOOL isInitialized = NO; -+- if (!isInitialized) { -+- isInitialized = YES; -+- -+- defaultType = -+- [[NGMimeType mimeType:@"text/plain; charset=us-ascii"] retain]; -+- } -+-} -+- -+ + (id)bodyPartWithHeader:(NGHashMap *)_header { -+ return [[[self alloc] initWithHeader:_header] autorelease]; -+ } -+@@ -156,13 +144,12 @@ -+ if (!Fields) -+ Fields = (NGMimeHeaderNames *)[NGMimePartParser headerFieldNames]; -+ -+- -+ type = [self->header objectForKey:Fields->contentType]; -+ -+ if (![type isKindOfClass:[NGMimeType class]]) -+ type = [NGMimeType mimeType:[type stringValue]]; -+ -+- return (type != nil ? type : (id)defaultType); -++ return type; -+ } -+ -+ - (NSString *)contentId { -+Index: sope-mime/NGMime/ChangeLog -+=================================================================== -+--- sope-mime/NGMime/ChangeLog (revision 1664) -++++ sope-mime/NGMime/ChangeLog (working copy) -+@@ -1,3 +1,25 @@ -++2008-09-08 Wolfgang Sourdeau -++ -++ * NGMimeRFC822DateHeaderFieldParser.m ([NGMimeRFC -++ -parseValue:ofHeaderField:]): don't parse timezone with a length -++ of 0. -++ -++2008-09-01 Wolfgang Sourdeau -++ -++ * NGMimeRFC822DateHeaderFieldParser.m ([NGMimeRFC -++ -parseValue:ofHeaderField:]): use an 8-bit safe encoding when -++ parsing dates. Since we only consider 7-bits characters, we ensure -++ that bad user-agents can be handled more properly. -++ -++ * NGMimeType.m ([NGMimeType +stringEncodingForCharset:]): -++ x-unknown encoding is now translated to an 8-bit safe encoding -++ (NSISOLatin1StringEncoding). -++ -++ * NGMimeAddressHeaderFieldGenerator.m -++ ([NGMimeAddressHeaderFieldGenerator -++ -generateDataForHeaderFieldNamed:value:]): encode resulting string -++ in an 8-bit safe encoding (NSISOLatin1StringEncoding). -++ -+ 2008-01-29 Albrecht Dress -+ -+ * fixes for OGo bug #789 (reply-to QP encoding) -+Index: sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m -+=================================================================== -+--- sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m (revision 1664) -++++ sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m (working copy) -+@@ -36,8 +36,7 @@ -+ NGMimeType *type = nil; // only one content-type field -+ NSString *tmp = nil; -+ NSMutableData *data = nil; -+- unsigned char *ctmp = NULL; -+- unsigned len = 0; -++ NSData *valueData; -+ -+ type = _value; -+ -+@@ -59,21 +58,15 @@ -+ -+ tmp = [type type]; -+ NSAssert(tmp, @"type should not be nil"); -+- len = [tmp length]; -+- ctmp = malloc(len + 4); -+- [tmp getCString:(char *)ctmp]; ctmp[len] = '\0'; -+- [data appendBytes:ctmp length:len]; -+- free(ctmp); -++ valueData = [tmp dataUsingEncoding: NSISOLatin1StringEncoding]; -++ [data appendData: valueData]; -++ -++ [data appendBytes:"/" length:1]; -+ -+- [data appendBytes:"//" length:1]; -+- -+ tmp = [type subType]; -+ if (tmp != nil) { -+- len = [tmp length]; -+- ctmp = malloc(len + 4); -+- [tmp getCString:(char *)ctmp]; ctmp[len] = '\0'; -+- [data appendBytes:ctmp length:len]; -+- free(ctmp); -++ valueData = [tmp dataUsingEncoding: NSISOLatin1StringEncoding]; -++ [data appendData:valueData]; -+ } -+ else -+ [data appendBytes:"*" length:1]; -+@@ -91,12 +84,9 @@ -+ continue; -+ } -+ [data appendBytes:"; " length:2]; -+- -+- len = [name cStringLength]; -+- ctmp = malloc(len + 1); -+- [name getCString:(char *)ctmp]; ctmp[len] = '\0'; -+- [data appendBytes:ctmp length:len]; -+- free(ctmp); -++ -++ valueData = [name dataUsingEncoding: NSUTF8StringEncoding]; -++ [data appendData: valueData]; -+ -+ /* -+ this confuses GroupWise: "= \"" (a space) -+@@ -105,66 +95,30 @@ -+ -+ /* check for encoding */ -+ { -+- unsigned cnt; -++ unsigned cnt, max; -++ const char *dataBytes; -+ BOOL doEnc; -+ -+- len = [value cStringLength]; -+- ctmp = malloc(len + 4); -+- [value getCString:(char *)ctmp]; ctmp[len] = '\0'; -+- cnt = 0; -++ valueData = [value dataUsingEncoding:NSUTF8StringEncoding]; -++ dataBytes = [valueData bytes]; -++ max = [valueData length]; -++ -+ doEnc = NO; -+- while (cnt < len) { -+- if ((unsigned char)ctmp[cnt] > 127) { -++ cnt = 0; -++ while (!doEnc && cnt < max) { -++ if ((unsigned char)dataBytes[cnt] > 127) -+ doEnc = YES; -+- break; -+- } -+- cnt++; -++ else -++ cnt++; -+ } -+ if (doEnc) { -+- unsigned char iso[] = "=?iso-8859-15?q?"; -+- unsigned isoLen = 16; -+- unsigned char isoEnd[] = "?="; -+- unsigned isoEndLen = 2; -+- unsigned desLen; -+- unsigned char *des; -+- -+- if (ctmp) free(ctmp); -+- { -+- NSData *data; -+- -+-#if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY -+- data = [value dataUsingEncoding:NSISOLatin1StringEncoding]; -+-#else -+- data = [value dataUsingEncoding:NSISOLatin9StringEncoding]; -+-#endif -+- -+- len = [data length]; -+- ctmp = malloc(len + 10); -+- [data getBytes:ctmp]; ctmp[len] = '\0'; -+- } -+- -+- desLen = len * 3 + 20; -+- des = calloc(desLen + 10, sizeof(char)); -+- -+- memcpy(des, ctmp, cnt); -+- memcpy(des + cnt, iso, isoLen); -+- desLen = -+- NGEncodeQuotedPrintableMime(ctmp + cnt, len - cnt, -+- des + cnt + isoLen, -+- desLen - cnt - isoLen); -+- if ((int)desLen != -1) { -+- memcpy(des + cnt + isoLen + desLen, isoEnd, isoEndLen); -+- [data appendBytes:des length:(cnt + isoLen + desLen + isoEndLen)]; -+- } -+- else { -+- NSLog(@"WARNING: An error occour during quoted-printable decoding"); -+- } -+- if (des) free(des); -++ [data appendBytes:"=?utf-8?q?" length:10]; -++ [data appendData: [valueData dataByEncodingQuotedPrintable]]; -++ [data appendBytes:"?=" length:2]; -+ } -+ else { -+- [data appendBytes:ctmp length:len]; -++ [data appendData: valueData]; -+ } -+- free(ctmp); -+ } -+ [data appendBytes:"\"" length:1]; -+ } -+Index: sope-mime/NGMime/NGMimePartGenerator.m -+=================================================================== -+--- sope-mime/NGMime/NGMimePartGenerator.m (revision 1664) -++++ sope-mime/NGMime/NGMimePartGenerator.m (working copy) -+@@ -155,8 +155,9 @@ -+ BOOL isMultiValue, isFirst; -+ -+ /* get field name and strip leading spaces */ -+- fcname = (const unsigned char *)[_field cString]; -+- for (len = [_field cStringLength]; len > 0; fcname++, len--) { -++ fcname = (const unsigned char *)[_field cStringUsingEncoding:NSISOLatin1StringEncoding]; -++ for (len = [_field lengthOfBytesUsingEncoding:NSISOLatin1StringEncoding]; -++ len > 0; fcname++, len--) { -+ if (*fcname != ' ') -+ break; -+ } -+@@ -328,7 +329,7 @@ -+ if ([body isKindOfClass:[NSData class]]) -+ data = body; -+ else if ([body isKindOfClass:[NSString class]]) -+- data = [body dataUsingEncoding:[NSString defaultCStringEncoding]]; -++ data = [body dataUsingEncoding: NSISOLatin1StringEncoding]; -+ else -+ data = nil; -+ -+Index: sope-mime/NGMime/NGMimeBodyParser.m -+=================================================================== -+--- sope-mime/NGMime/NGMimeBodyParser.m (revision 1664) -++++ sope-mime/NGMime/NGMimeBodyParser.m (working copy) -+@@ -67,7 +67,10 @@ -+ if (_data == nil) return nil; -+ -+ ctype = [_part contentType]; -+- -++ if (!ctype -++ && [_d respondsToSelector: @selector(parser:contentTypeOfPart:)]) -++ ctype = [_d parser: self contentTypeOfPart: _part]; -++ -+ if (![ctype isKindOfClass:[NGMimeType class]]) -+ ctype = [NGMimeType mimeType:[ctype stringValue]]; -+ -+@@ -88,10 +91,20 @@ -+ NSStringEncoding encoding; -+ -+ encoding = [NGMimeType stringEncodingForCharset:charset]; -+- -++ -++ // If we nave no encoding here, let's not simply return nil. -++ // We SHOULD try at least UTF-8 and after, Latin1. -++ if (!encoding) -++ encoding = NSUTF8StringEncoding; -++ -+ body = [[[NSString alloc] -+- initWithData:_data -++ initWithData:_data -+ encoding:encoding] autorelease]; -++ -++ if (!body) -++ body = [[[NSString alloc] initWithData:_data -++ encoding:NSISOLatin1StringEncoding] -++ autorelease]; -+ } -+ return body; -+ } -+Index: sope-mime/NGMime/NGMimePartParser.h -+=================================================================== -+--- sope-mime/NGMime/NGMimePartParser.h (revision 1664) -++++ sope-mime/NGMime/NGMimePartParser.h (working copy) -+@@ -117,6 +117,7 @@ -+ BOOL parserParseRawBodyDataOfPart:1; -+ BOOL parserBodyParserForPart:1; -+ BOOL parserDecodeBodyOfPart:1; -++ BOOL parserContentTypeOfPart:1; -+ } delegateRespondsTo; -+ -+ -+@@ -275,6 +276,9 @@ -+ - (id)parser:(NGMimePartParser *)_parser -+ bodyParserForPart:(id)_part; -+ -++- (NGMimeType *)parser:(id)_parser -++ contentTypeOfPart:(id)_part; -++ -+ @end /* NSObject(NGMimePartParserDelegate) */ -+ -+ @interface NSObject(NGMimePartParser) -+Index: sope-mime/NGMime/NGMimePartParser.m -+=================================================================== -+--- sope-mime/NGMime/NGMimePartParser.m (revision 1664) -++++ sope-mime/NGMime/NGMimePartParser.m (working copy) -+@@ -227,7 +227,7 @@ -+ } -+ -+ + (NSStringEncoding)defaultHeaderFieldEncoding { -+- return NSISOLatin1StringEncoding; -++ return NSUTF8StringEncoding; -+ } -+ -+ - (id)valueOfHeaderField:(NSString *)_name data:(id)_data { -+@@ -1091,7 +1091,10 @@ -+ id bodyParser = nil; -+ -+ ctype = [_p contentType]; -+- -++ if (!ctype -++ && self->delegateRespondsTo.parserContentTypeOfPart) -++ ctype = [self->delegate parser: self contentTypeOfPart: _p]; -++ -+ contentType = ([ctype isKindOfClass:[NGMimeType class]]) -+ ? ctype -+ : [NGMimeType mimeType:[ctype stringValue]]; -+Index: sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m -+=================================================================== -+--- sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m (revision 1664) -++++ sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m (working copy) -+@@ -105,10 +105,10 @@ -+ } -+ -+ tmp = [obj displayName]; -+- bufLen = [tmp cStringLength]; -++ bufLen = [tmp lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; -+ -+- buffer = calloc(bufLen + 10, sizeof(char)); -+- [tmp getCString:buffer]; -++ buffer = calloc(bufLen, sizeof(char)); -++ [tmp getCString: buffer maxLength: bufLen encoding: NSUTF8StringEncoding]; -+ -+ cnt = 0; -+ doEnc = NO; -+@@ -117,11 +117,11 @@ -+ /* must encode chars outside ASCII 33..60, 62..126 ranges [RFC 2045, Sect. 6.7] -+ * RFC 2047, Sect. 4.2 also requires chars 63 and 95 to be encoded -+ * For spaces, quotation is fine */ -+- if ((unsigned char)buffer[cnt] < 32 || -+- (unsigned char)buffer[cnt] == 61 || -+- (unsigned char)buffer[cnt] == 63 || -+- (unsigned char)buffer[cnt] == 95 || -+- (unsigned char)buffer[cnt] > 126) { -++ if ((unichar)buffer[cnt] < 32 || -++ (unichar)buffer[cnt] == 61 || -++ (unichar)buffer[cnt] == 63 || -++ (unichar)buffer[cnt] == 95 || -++ (unichar)buffer[cnt] > 126) { -+ doEnc = YES; -+ break; -+ } -+@@ -130,8 +130,13 @@ -+ -+ if (doEnc) { -+ /* FIXME - better use UTF8 encoding! */ -++#if NeXT_Foundation_LIBRARY -+ unsigned char iso[] = "=?iso-8859-15?q?"; -+ unsigned isoLen = 16; -++#else -++ unsigned char iso[] = "=?utf-8?q?"; -++ unsigned isoLen = 10; -++#endif -+ unsigned char isoEnd[] = "?="; -+ unsigned isoEndLen = 2; -+ unsigned desLen; -+@@ -141,10 +146,10 @@ -+ { -+ NSData *data; -+ -+-#if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY -++#if NeXT_Foundation_LIBRARY -+ data = [tmp dataUsingEncoding:NSISOLatin1StringEncoding]; -+ #else -+- data = [tmp dataUsingEncoding:NSISOLatin9StringEncoding]; -++ data = [tmp dataUsingEncoding:NSUTF8StringEncoding]; -+ #endif -+ -+ bufLen = [data length]; -+@@ -162,8 +167,9 @@ -+ des + isoLen, desLen - isoLen); -+ if ((int)desLen != -1) { -+ memcpy(des + isoLen + desLen, isoEnd, isoEndLen); -+- tmp = [NSString stringWithCString:(char *)des -+- length:(isoLen + desLen + isoEndLen)]; -++ tmp = [[NSString alloc] initWithData: [NSData dataWithBytes:(char *)des length:(isoLen + desLen + isoEndLen)] -++ encoding: NSISOLatin1StringEncoding]; -++ [tmp autorelease]; -+ } -+ else { -+ [self warnWithFormat: -+@@ -190,11 +196,7 @@ -+ } -+ } -+ -+-#if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY -+ data = [result dataUsingEncoding:NSISOLatin1StringEncoding]; -+-#else -+- data = [result dataUsingEncoding:NSISOLatin9StringEncoding]; -+-#endif -+ [result release]; -+ -+ return data; -+Index: sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m -+=================================================================== -+--- sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m (revision 1664) -++++ sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m (working copy) -+@@ -49,80 +49,70 @@ -+ -+ // TODO: move the stuff below to some NSString or NSData category? -+ -+- data = [NSMutableData dataWithCapacity:64]; -++ data = [NSMutableData dataWithCapacity: 64]; -+ tmp = [field type]; -+ [data appendBytes:[tmp cString] length:[tmp length]]; -+ tmp = [field filename]; -+ if (tmp != nil) { -+ [data appendBytes:"; " length:2]; -+ [data appendBytes:"filename=\"" length:10]; -+- { -+- unsigned char *ctmp; -+- int cnt, len; -+- BOOL doEnc; -+- -+- // TODO: unicode? -+- len = [tmp cStringLength]; -+- ctmp = malloc(len + 3); -+- [tmp getCString:(char *)ctmp]; ctmp[len] = '\0'; -+- cnt = 0; -+- doEnc = NO; -+- while (cnt < len) { -+- if ((unsigned char)ctmp[cnt] > 127) { -+- doEnc = YES; -+- break; -+- } -+- cnt++; -++ -++ NSData *d; -++ unsigned char* bytes; -++ unsigned length; -++ int cnt; -++ BOOL doEnc; -++ -++ //d = [tmp dataUsingEncoding: NSUTF8StringEncoding]; -++ //bytes = [d bytes]; -++ //length = [d length]; -++ bytes = [tmp cStringUsingEncoding: NSUTF8StringEncoding]; -++ length = strlen(bytes); -++ -++ cnt = 0; -++ doEnc = NO; -++ while (cnt < length) { -++ if ((unsigned char)bytes[cnt] > 127) { -++ doEnc = YES; -++ break; -+ } -+- if (doEnc) { -+- char iso[] = "=?iso-8859-15?q?"; -+- unsigned isoLen = 16; -+- char isoEnd[] = "?="; -+- unsigned isoEndLen = 2; -+- unsigned desLen; -+- char *des; -+- -+- if (ctmp) free(ctmp); -+- { -+- NSData *data; -++ cnt++; -++ } -+ -+-#if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY -+- data = [tmp dataUsingEncoding:NSISOLatin1StringEncoding]; -+-#else -+- data = [tmp dataUsingEncoding:NSISOLatin9StringEncoding]; -+-#endif -+- -+- len = [data length]; -+- ctmp = malloc(len+1); -+- [data getBytes:ctmp]; ctmp[len] = '\0'; -+- } -+- -+- desLen = len * 3 + 20; -+- des = calloc(desLen + 10, sizeof(char)); -+- -+- memcpy(des, ctmp, cnt); -+- memcpy(des + cnt, iso, isoLen); -+- desLen = -+- NGEncodeQuotedPrintableMime((unsigned char *)ctmp + cnt, len - cnt, -+- (unsigned char *)des + cnt + isoLen, -+- desLen - cnt - isoLen); -+- if ((int)desLen != -1) { -+- memcpy(des + cnt + isoLen + desLen, isoEnd, isoEndLen); -+- [data appendBytes:des length:(cnt + isoLen + desLen + isoEndLen)]; -+- } -+- else { -++ if (doEnc) -++ { -++ char iso[] = "=?utf-8?q?"; -++ unsigned isoLen = 10; -++ char isoEnd[] = "?="; -++ unsigned isoEndLen = 2; -++ int desLen; -++ char *des; -++ -++ desLen = length * 3 + 20; -++ -++ des = calloc(desLen + 2, sizeof(char)); -++ -++ memcpy(des, iso, isoLen); -++ desLen = NGEncodeQuotedPrintableMime((unsigned char *)bytes, length, -++ (unsigned char *)(des + isoLen), -++ desLen - isoLen); -++ if (desLen != -1) { -++ memcpy(des + isoLen + desLen, isoEnd, isoEndLen); -++ [data appendBytes:des length:(isoLen + desLen + isoEndLen)]; -++ } -++ else { -+ [self logWithFormat:@"WARNING(%s:%i): An error occour during " -+ @"quoted-printable decoding", -+ __PRETTY_FUNCTION__, __LINE__]; -+- } -+- if (des) free(des); -++ if (des != NULL) free(des); -++ } -+ } -+- else { -+- [data appendBytes:ctmp length:len]; -++ else -++ { -++ [data appendBytes:[tmp cString] length:[tmp length]]; -+ } -+- } -+- // [data appendBytes:[tmp cString] length:[tmp length]]; -+- [data appendBytes:"\"" length:1]; -++ -++ [data appendBytes:"\"" length:1]; -+ } -+ return data; -+ } -+Index: sope-core/NGExtensions/NGExtensions/NSString+Ext.h -+=================================================================== -+--- sope-core/NGExtensions/NGExtensions/NSString+Ext.h (revision 1664) -++++ sope-core/NGExtensions/NGExtensions/NSString+Ext.h (working copy) -+@@ -30,6 +30,7 @@ -+ -+ @interface NSString(GSAdditions) -+ -++#if !GNUSTEP -+ - (NSString *)stringWithoutPrefix:(NSString *)_prefix; -+ - (NSString *)stringWithoutSuffix:(NSString *)_suffix; -+ -+@@ -39,6 +40,7 @@ -+ - (NSString *)stringByTrimmingLeadSpaces; -+ - (NSString *)stringByTrimmingTailSpaces; -+ - (NSString *)stringByTrimmingSpaces; -++#endif /* !GNUSTEP */ -+ -+ /* the following are not available in gstep-base 1.6 ? */ -+ - (NSString *)stringByTrimmingLeadWhiteSpaces; -+@@ -47,6 +49,8 @@ -+ -+ @end /* NSString(GSAdditions) */ -+ -++#if !GNUSTEP -++ -+ @interface NSMutableString(GNUstepCompatibility) -+ -+ - (void)trimLeadSpaces; -+@@ -55,6 +59,8 @@ -+ -+ @end /* NSMutableString(GNUstepCompatibility) */ -+ -++#endif /* !GNUSTEP */ -++ -+ #endif -+ -+ /* specific to libFoundation */ -+Index: sope-core/NGExtensions/FdExt.subproj/NSString+Ext.m -+=================================================================== -+--- sope-core/NGExtensions/FdExt.subproj/NSString+Ext.m (revision 1664) -++++ sope-core/NGExtensions/FdExt.subproj/NSString+Ext.m (working copy) -+@@ -39,18 +39,6 @@ -+ : (NSString *)[[self copy] autorelease]; -+ } -+ -+-- (NSString *)stringByReplacingString:(NSString *)_orignal -+- withString:(NSString *)_replacement -+-{ -+- /* very slow solution .. */ -+- -+- if ([self rangeOfString:_orignal].length == 0) -+- return [[self copy] autorelease]; -+- -+- return [[self componentsSeparatedByString:_orignal] -+- componentsJoinedByString:_replacement]; -+-} -+- -+ - (NSString *)stringByTrimmingLeadWhiteSpaces -+ { -+ // should check 'whitespaceAndNewlineCharacterSet' .. -+@@ -96,6 +84,25 @@ -+ return [[self copy] autorelease]; -+ } -+ -++- (NSString *)stringByTrimmingWhiteSpaces -++{ -++ return [[self stringByTrimmingTailWhiteSpaces] -++ stringByTrimmingLeadWhiteSpaces]; -++} -++ -++#ifndef GNUSTEP -++- (NSString *)stringByReplacingString:(NSString *)_orignal -++ withString:(NSString *)_replacement -++{ -++ /* very slow solution .. */ -++ -++ if ([self rangeOfString:_orignal].length == 0) -++ return [[self copy] autorelease]; -++ -++ return [[self componentsSeparatedByString:_orignal] -++ componentsJoinedByString:_replacement]; -++} -++ -+ - (NSString *)stringByTrimmingLeadSpaces -+ { -+ unsigned len; -+@@ -117,6 +124,7 @@ -+ else -+ return [[self copy] autorelease]; -+ } -++ -+ - (NSString *)stringByTrimmingTailSpaces -+ { -+ unsigned len; -+@@ -139,19 +147,17 @@ -+ return [[self copy] autorelease]; -+ } -+ -+-- (NSString *)stringByTrimmingWhiteSpaces -+-{ -+- return [[self stringByTrimmingTailWhiteSpaces] -+- stringByTrimmingLeadWhiteSpaces]; -+-} -+ - (NSString *)stringByTrimmingSpaces -+ { -+ return [[self stringByTrimmingTailSpaces] -+ stringByTrimmingLeadSpaces]; -+ } -++#endif -+ -+ @end /* NSString(GSAdditions) */ -+ -++#if !GNUSTEP -++ -+ @implementation NSMutableString(GNUstepCompatibility) -+ -+ - (void)trimLeadSpaces -+@@ -169,6 +175,8 @@ -+ -+ @end /* NSMutableString(GNUstepCompatibility) */ -+ -++#endif /* !GNUSTEP */ -++ -+ @implementation NSString(lfNSURLUtilities) -+ -+ - (BOOL)isAbsoluteURL -+Index: sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m -+=================================================================== -+--- sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m (revision 1664) -++++ sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m (working copy) -+@@ -140,8 +140,12 @@ -+ -+ -+ #ifdef __linux__ -++#if __BYTE_ORDER == __LITTLE_ENDIAN -+ static NSString *unicharEncoding = @"UCS-2LE"; -+ #else -++static NSString *unicharEncoding = @"UCS-2BE"; -++#endif /* __BYTE_ORDER */ -++#else -+ static NSString *unicharEncoding = @"UCS-2-INTERNAL"; -+ #endif -+ static int IconvLogEnabled = -1; -+@@ -149,21 +153,12 @@ -+ static void checkDefaults(void) { -+ NSUserDefaults *ud; -+ -+- if (IconvLogEnabled != -1) -+- return; -+- ud = [NSUserDefaults standardUserDefaults]; -+- IconvLogEnabled = [ud boolForKey:@"IconvLogEnabled"]?1:0; -++ if (IconvLogEnabled == -1) { -++ ud = [NSUserDefaults standardUserDefaults]; -++ IconvLogEnabled = [ud boolForKey:@"IconvLogEnabled"]?1:0; -+ -+-#ifdef __linux__ -+- if (NSHostByteOrder() == NS_BigEndian) { -+- NSLog(@"Note: using UCS-2 big endian on Linux."); -+- unicharEncoding = @"UCS-2BE"; -++ NSLog(@"Note: using '%@' on Linux.", unicharEncoding); -+ } -+- else { -+- NSLog(@"Note: using UCS-2 little endian on Linux."); -+- unicharEncoding = @"UCS-2LE"; -+- } -+-#endif -+ } -+ -+ static char *iconv_wrapper(id self, char *_src, unsigned _srcLen, -+Index: sope-core/NGExtensions/EOExt.subproj/EOGlobalID+Ext.m -+=================================================================== -+--- sope-core/NGExtensions/EOExt.subproj/EOGlobalID+Ext.m (revision 1664) -++++ sope-core/NGExtensions/EOExt.subproj/EOGlobalID+Ext.m (working copy) -+@@ -19,6 +19,7 @@ -+ 02111-1307, USA. -+ */ -+ -++#import -+ #import -+ #import -+ -+Index: sope-core/NGStreams/NGStream+serialization.m -+=================================================================== -+--- sope-core/NGStreams/NGStream+serialization.m (revision 1664) -++++ sope-core/NGStreams/NGStream+serialization.m (working copy) -+@@ -282,10 +282,10 @@ -+ else { -+ char *result = NULL; -+ -+-#if NeXT_Foundation_LIBRARY -++#if LIB_FOUNDATION_LIBRARY -++ result = NSZoneMallocAtomic(NULL, len + 1); -++#else -+ result = NSZoneMalloc(NULL, len + 1); -+-#else -+- result = NSZoneMallocAtomic(NULL, len + 1); -+ #endif -+ result[len] = '\0'; -+ -+Index: sope-core/NGStreams/NGStreams/NGDatagramSocket.h -+=================================================================== -+--- sope-core/NGStreams/NGStreams/NGDatagramSocket.h (revision 1664) -++++ sope-core/NGStreams/NGStreams/NGDatagramSocket.h (working copy) -+@@ -69,7 +69,7 @@ -+ + (id)socketBoundToAddress:(id)_address; -+ -+ #if !defined(WIN32) -+-+ (BOOL)socketPair:(id[2])_pair inDomain:(id)_domain; -+++ (BOOL)socketPair:(id[2])_pair; -+ #endif -+ -+ // accessors -+Index: sope-core/NGStreams/NGStreams/NGActiveSocket.h -+=================================================================== -+--- sope-core/NGStreams/NGStreams/NGActiveSocket.h (revision 1664) -++++ sope-core/NGStreams/NGStreams/NGActiveSocket.h (working copy) -+@@ -60,7 +60,7 @@ -+ - (id)initWithDomain:(id)_domain; // designated initializer -+ -+ #if !defined(WIN32) -+-+ (BOOL)socketPair:(id[2])_pair inDomain:(id)_domain; -+++ (BOOL)socketPair:(id[2])_pair; -+ #endif -+ -+ // ******************** operations ******************** -+Index: sope-core/NGStreams/NGGZipStream.m -+=================================================================== -+--- sope-core/NGStreams/NGGZipStream.m (revision 1664) -++++ sope-core/NGStreams/NGGZipStream.m (working copy) -+@@ -52,7 +52,7 @@ -+ @"invalid compression level %i (0-9)", _level); -+ -+ self->outBufLen = 2048; -+-#if GNU_RUNTIME -++#if LIB_FOUNDATION_LIBRARY -+ self->outBuf = NSZoneMallocAtomic([self zone], self->outBufLen); -+ self->outp = NSZoneMallocAtomic([self zone], sizeof(z_stream)); -+ #else -+Index: sope-core/NGStreams/NGDatagramSocket.m -+=================================================================== -+--- sope-core/NGStreams/NGDatagramSocket.m (revision 1664) -++++ sope-core/NGStreams/NGDatagramSocket.m (working copy) -+@@ -25,6 +25,8 @@ -+ #endif -+ -+ #include -++#include -++#include -+ #include "NGDatagramSocket.h" -+ #include "NGDatagramPacket.h" -+ #include "NGSocketExceptions.h" -+@@ -55,19 +57,21 @@ -+ -+ #if !defined(WIN32) || defined(__CYGWIN32__) -+ -+-+ (BOOL)socketPair:(id[2])_pair inDomain:(id)_domain { -+++ (BOOL)socketPair:(id[2])_pair { -+ int fds[2]; -++ NGLocalSocketDomain *domain; -+ -+ _pair[0] = nil; -+ _pair[1] = nil; -+ -+- if (socketpair([_domain socketDomain], SOCK_DGRAM, [_domain protocol], -++ domain = [NGLocalSocketDomain domain]; -++ if (socketpair([domain socketDomain], SOCK_DGRAM, [domain protocol], -+ fds) == 0) { -+ NGDatagramSocket *s1 = nil; -+ NGDatagramSocket *s2 = nil; -+ -+- s1 = [[self alloc] _initWithDomain:_domain descriptor:fds[0]]; -+- s2 = [[self alloc] _initWithDomain:_domain descriptor:fds[1]]; -++ s1 = [[self alloc] _initWithDomain:domain descriptor:fds[0]]; -++ s2 = [[self alloc] _initWithDomain:domain descriptor:fds[1]]; -+ s1 = AUTORELEASE(s1); -+ s2 = AUTORELEASE(s2); -+ -+@@ -112,7 +116,7 @@ -+ break; -+ } -+ [[[NGCouldNotCreateSocketException alloc] -+- initWithReason:reason domain:_domain] raise]; -++ initWithReason:reason domain:domain] raise]; -+ return NO; -+ } -+ } -+Index: sope-core/NGStreams/GNUmakefile.preamble -+=================================================================== -+--- sope-core/NGStreams/GNUmakefile.preamble (revision 1664) -++++ sope-core/NGStreams/GNUmakefile.preamble (working copy) -+@@ -1,6 +1,7 @@ -+ # compilation settings -+ -+-MACHCPU = $(shell echo $$MACHTYPE | cut -f 1 -d '-') -++# MACHCPU = $(shell echo $$MACHTYPE | cut -f 1 -d '-') -++MACHCPU = $(shell uname -m) -+ -+ libNGStreams_INCLUDE_DIRS += \ -+ -I$(GNUSTEP_TARGET_CPU)/$(GNUSTEP_TARGET_OS) \ -+Index: sope-core/NGStreams/ChangeLog -+=================================================================== -+--- sope-core/NGStreams/ChangeLog (revision 1664) -++++ sope-core/NGStreams/ChangeLog (working copy) -+@@ -1,3 +1,14 @@ -++2009-11-11 Wolfgang Sourdeau -++ -++ * NGActiveSocket.m (+socketPair): removed the domain: parameter as -++ only AF_LOCAL is permitted. Assign a default instance of -++ NGLocalSocketAddress to the sockets to "declare" the sockets as -++ connected. -++ -++ * NGActiveSocket.m (-setSendTimeout, -setReceiveTimeout): make use -++ of those methods to actually configure the timeouts on the socket -++ objects (via setsockopt and SO_RCVTIMEO and SO_SNDTIMEO). -++ -+ 2009-03-24 Wolfgang Sourdeau -+ -+ * GNUmakefile.preamble: add machine-type to include path (eg i386) (v4.7.57) -+Index: sope-core/NGStreams/NGCharBuffer.m -+=================================================================== -+--- sope-core/NGStreams/NGCharBuffer.m (revision 1664) -++++ sope-core/NGStreams/NGCharBuffer.m (working copy) -+@@ -46,11 +46,11 @@ -+ // Find first power of 2 >= to requested size -+ for (size = 2; size < _la; size *=2); -+ -+-#if NeXT_Foundation_LIBRARY -+- self->la = NSZoneMalloc([self zone], sizeof(LA_NGCharBuffer) * size); -+-#else -++#if LIB_FOUNDATION_LIBRARY -+ self->la = NSZoneMallocAtomic([self zone], -+ sizeof(LA_NGCharBuffer) * size); -++#else -++ self->la = NSZoneMalloc([self zone], sizeof(LA_NGCharBuffer) * size); -+ #endif -+ memset(self->la, 0, sizeof(LA_NGCharBuffer) * size); -+ -+Index: sope-core/NGStreams/NGActiveSocket.m -+=================================================================== -+--- sope-core/NGStreams/NGActiveSocket.m (revision 1664) -++++ sope-core/NGStreams/NGActiveSocket.m (working copy) -+@@ -62,6 +62,8 @@ -+ #include "common.h" -+ -+ #include -++#include -++#include -+ #include "NGActiveSocket.h" -+ #include "NGSocketExceptions.h" -+ #include "NGSocket+private.h" -+@@ -83,29 +85,35 @@ -+ -+ #if !defined(WIN32) || defined(__CYGWIN32__) -+ -+-+ (BOOL)socketPair:(id[2])_pair inDomain:(id)_domain { -+++ (BOOL)socketPair:(id[2])_pair { -+ int fds[2]; -++ NGLocalSocketDomain *domain; -+ -+ _pair[0] = nil; -+ _pair[1] = nil; -+ -+- if (socketpair([_domain socketDomain], SOCK_STREAM, [_domain protocol], -++ domain = [NGLocalSocketDomain domain]; -++ if (socketpair([domain socketDomain], SOCK_STREAM, [domain protocol], -+ fds) == 0) { -+ NGActiveSocket *s1 = nil; -+ NGActiveSocket *s2 = nil; -++ NGLocalSocketAddress *address; -+ -+- s1 = [[self alloc] _initWithDomain:_domain descriptor:fds[0]]; -+- s2 = [[self alloc] _initWithDomain:_domain descriptor:fds[1]]; -++ s1 = [[self alloc] _initWithDomain:domain descriptor:fds[0]]; -++ s2 = [[self alloc] _initWithDomain:domain descriptor:fds[1]]; -+ s1 = [s1 autorelease]; -+ s2 = [s2 autorelease]; -+ -++ address = [NGLocalSocketAddress address]; -+ if ((s1 != nil) && (s2 != nil)) { -+ s1->mode = NGStreamMode_readWrite; -+ s1->receiveTimeout = 0.0; -+ s1->sendTimeout = 0.0; -++ ASSIGN(s1->remoteAddress, address); -+ s2->mode = NGStreamMode_readWrite; -+ s2->receiveTimeout = 0.0; -+ s2->sendTimeout = 0.0; -++ ASSIGN(s2->remoteAddress, address); -+ -+ _pair[0] = s1; -+ _pair[1] = s2; -+@@ -152,7 +160,7 @@ -+ break; -+ } -+ [[[NGCouldNotCreateSocketException alloc] -+- initWithReason:reason domain:_domain] raise]; -++ initWithReason:reason domain:domain] raise]; -+ return NO; -+ } -+ } -+@@ -507,6 +515,13 @@ -+ } -+ -+ - (void)setSendTimeout:(NSTimeInterval)_timeout { -++ struct timeval tv; -++ -++ if ([self isConnected]) { -++ tv.tv_sec = (int) _timeout; -++ tv.tv_usec = 0; -++ setsockopt(self->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof (struct timeval)); -++ } -+ self->sendTimeout = _timeout; -+ } -+ - (NSTimeInterval)sendTimeout { -+@@ -514,6 +529,13 @@ -+ } -+ -+ - (void)setReceiveTimeout:(NSTimeInterval)_timeout { -++ struct timeval tv; -++ -++ if ([self isConnected]) { -++ tv.tv_sec = (int) _timeout; -++ tv.tv_usec = 0; -++ setsockopt(self->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof (struct timeval)); -++ } -+ self->receiveTimeout = _timeout; -+ } -+ - (NSTimeInterval)receiveTimeout { -+Index: sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.h -+=================================================================== -+--- sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.h (revision 1664) -++++ sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.h (working copy) -+@@ -19,6 +19,8 @@ -+ 02111-1307, USA. -+ */ -+ -++#include -++ -+ #include -+ #include -+ #include -+@@ -34,7 +36,7 @@ -+ -+ @interface libxmlHTMLSAXDriver : NSObject < SaxXMLReader > -+ { -+- id contentHandler; -++ NSObject *contentHandler; -+ id dtdHandler; -+ id errorHandler; -+ id entityResolver; -+Index: sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.m -+=================================================================== -+--- sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.m (revision 1664) -++++ sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.m (working copy) -+@@ -200,10 +200,10 @@ -+ return self->entityResolver; -+ } -+ -+-- (void)setContentHandler:(id)_handler { -++- (void)setContentHandler:(NSObject *)_handler { -+ ASSIGN(self->contentHandler, _handler); -+ } -+-- (id)contentHandler { -++- (NSObject *)contentHandler { -+ return self->contentHandler; -+ } -+ -+Index: sope-appserver/mod_ngobjweb/GNUmakefile -+=================================================================== -+--- sope-appserver/mod_ngobjweb/GNUmakefile (revision 1664) -++++ sope-appserver/mod_ngobjweb/GNUmakefile (working copy) -+@@ -82,7 +82,7 @@ -+ -+ CFLAGS = -Wall -I. -fPIC \ -+ $(APXS_CFLAGS) $(APR_CFLAGS) \ -+- $(APXS_INCLUDE_DIRS) $(APR_INCLUDE_DIRS) -++ $(APXS_INCLUDE_DIRS) $(APR_INCLUDE_DIRS) -O0 -ggdb -+ -+ LDFLAGS = $(APXS_LDFLAGS) $(APR_LDFLAGS) -shared -fPIC -+ LDLIBS = $(APXS_LIBS) $(APR_LIBS) -+@@ -111,8 +111,7 @@ -+ apache-dir : -+ $(MKDIRS) $(GNUSTEP_INSTALLATION_DIR) -+ -+-install :: apache-dir all -+- $(INSTALL_PROGRAM) $(product) $(GNUSTEP_INSTALLATION_DIR) -++install :: -+ -+ install-usr-libexec :: all -+ $(INSTALL_PROGRAM) $(product) /usr/libexec/httpd/ -+Index: sope-appserver/NGObjWeb/WOWatchDogApplicationMain.m -+=================================================================== -+--- sope-appserver/NGObjWeb/WOWatchDogApplicationMain.m (revision 1664) -++++ sope-appserver/NGObjWeb/WOWatchDogApplicationMain.m (working copy) -+@@ -1,5 +1,6 @@ -+ /* -+ Copyright (C) 2000-2005 SKYRIX Software AG -++ Copyright (C) 2009 Inverse inc. -+ -+ This file is part of SOPE. -+ -+@@ -19,9 +20,29 @@ -+ 02111-1307, USA. -+ */ -+ -+-#import -+-#include -++#import -++#import -++#import -++#import -++#import -++#import -++#import -++#import -++#import -++#import -++#import -+ -++#import -++#import -++#import -++#import -++#import -++#import -++#import -++#import -++ -++#import "UnixSignalHandler.h" -++ -+ #if defined(__CYGWIN32__) || defined(__MINGW32__) -+ -+ int WOWatchDogApplicationMain -+@@ -39,201 +60,911 @@ -+ #include -+ #include -+ -+-static pid_t child = -1; -+-static NSString *pidFile = nil; -+-static time_t lastFailExit = 0; -+-static unsigned failExitCount = 0; -+-static BOOL killedChild = NO; -++static NSTimeInterval respawnDelay; /* seconds */ -++static const char *pidFile = NULL; -+ -+-static void killChild(void) { -+- if (child > 0) { -+- int status; -+- -+- fprintf(stderr, "watchdog[%i]: terminating child %i ..\n", getpid(), child); -+- -+- if (kill(child, SIGTERM) == 0) { -+- waitpid(child, &status, 0); -+- killedChild = YES; -+- -+- fprintf(stderr, " terminated child %i", child); -+- -+- if (WIFEXITED(status)) -+- fprintf(stderr, " exit=%i", WEXITSTATUS(status)); -+- if (WIFSIGNALED(status)) -+- fprintf(stderr, " signal=%i", WTERMSIG(status)); -+- -+- fprintf(stderr, ".\n"); -+- fflush(stderr); -+- -+- child = -1; -+- return; -++typedef enum { -++ WOChildStatusDown = 0, -++ WOChildStatusSpawning, -++ WOChildStatusReady, -++ WOChildStatusBusy, -++ WOChildStatusExcessive, -++ WOChildStatusTerminating, -++ WOChildStatusMax -++} WOChildStatus; -++ -++@class WOWatchDog; -++ -++@interface WOWatchDogChild : NSObject -++{ -++ int pid; -++ int SIGCHLDStatus; -++ int counter; -++ NGActiveSocket *controlSocket; -++ WOChildStatus status; -++ WOWatchDog *watchDog; -++ NSCalendarDate *lastSpawn; -++ BOOL loggedNotRespawn; -++} -++ -++- (void) setWatchDog: (WOWatchDog *) newWatchDog; -++ -++- (void) setPid: (int) newPid; -++- (int) pid; -++ -++- (void) setSIGCHLDStatus: (int) newSIGCHLDStatus; -++- (int) SIGCHLDStatus; -++- (void) handleSIGCHLDStatus; -++ -++- (void) setControlSocket: (NGActiveSocket *) newSocket; -++- (NGActiveSocket *) controlSocket; -++ -++- (void) setStatus: (WOChildStatus) newStatus; -++- (WOChildStatus) status; -++ -++- (void) setLastSpawn: (NSCalendarDate *) newLastSpawn; -++- (NSCalendarDate *) lastSpawn; -++- (NSCalendarDate *) nextSpawn; -++- (void) logNotRespawn; -++ -++- (BOOL) readMessage; -++ -++- (void) notify; -++- (void) terminate; -++ -++@end -++ -++@interface WOWatchDog : NSObject -++{ -++ NSString *appName; -++ int argc; -++ const char **argv; -++ -++ BOOL terminate; -++ BOOL willTerminate; -++ NSNumber *terminationSignal; -++ int pendingSIGCHLD; -++ int pendingSIGHUP; -++ -++ NGPassiveSocket *listeningSocket; -++ -++ int numberOfChildren; -++ NSMutableArray *children; -++ NSMutableArray *readyChildren; -++ NSMutableArray *downChildren; -++} -++ -+++ (id) sharedWatchDog; -++ -++- (void) declareChildReady: (WOWatchDogChild *) readyChild; -++- (void) declareChildDown: (WOWatchDogChild *) readyChild; -++ -++- (int) run: (NSString *) appName -++ argc: (int) argc -++ argv: (const char **) argv; -++ -++@end -++ -++@implementation WOWatchDogChild -++ -+++ (WOWatchDogChild *) watchDogChild -++{ -++ WOWatchDogChild *newChild; -++ -++ newChild = [self new]; -++ [newChild autorelease]; -++ -++ return newChild; -++} -++ -++- (id) init -++{ -++ if ((self = [super init])) -++ { -++ pid = -1; -++ controlSocket = nil; -++ SIGCHLDStatus = -1; -++ status = WOChildStatusDown; -++ counter = 0; -++ lastSpawn = nil; -++ loggedNotRespawn = NO; -+ } -+- else if (kill(child, SIGKILL)) { -+- waitpid(child, &status, 0); -+- killedChild = YES; -+- -+- fprintf(stderr, " killed child %i", child); -+- -+- if (WIFEXITED(status)) -+- fprintf(stderr, " exit=%i", WEXITSTATUS(status)); -+- if (WIFSIGNALED(status)) -+- fprintf(stderr, " signal=%i", WTERMSIG(status)); -+- -+- fprintf(stderr, ".\n"); -+- fflush(stderr); -+- -+- child = -1; -+- return; -++ -++ return self; -++} -++ -++- (void) dealloc -++{ -++ [self setControlSocket: nil]; -++ [lastSpawn release]; -++ [super dealloc]; -++} -++ -++- (void) setWatchDog: (WOWatchDog *) newWatchDog -++{ -++ watchDog = newWatchDog; -++} -++ -++- (void) setPid: (int) newPid -++{ -++ pid = newPid; -++} -++ -++- (int) pid -++{ -++ return pid; -++} -++ -++- (void) setSIGCHLDStatus: (int) newSIGCHLDStatus -++{ -++ SIGCHLDStatus = newSIGCHLDStatus; -++} -++ -++- (int) SIGCHLDStatus -++{ -++ return SIGCHLDStatus; -++} -++ -++- (void) handleSIGCHLDStatus -++{ -++ int code; -++ -++ [self logWithFormat: @"received SIGCHLD from pid %d", pid]; -++ code = WEXITSTATUS (SIGCHLDStatus); -++ if (code != 0) -++ [self logWithFormat: @"child %d exited with code %i", pid, code]; -++ if (WIFSIGNALED (SIGCHLDStatus)) -++ [self logWithFormat: @" (terminated due to signal %i%@)", -++ WTERMSIG (SIGCHLDStatus), -++ WCOREDUMP (SIGCHLDStatus) ? @", coredump" : @""]; -++ if (WIFSTOPPED (SIGCHLDStatus)) -++ [self logWithFormat: @" (stopped due to signal %i)", WSTOPSIG (SIGCHLDStatus)]; -++ SIGCHLDStatus = -1; -++ [self setStatus: WOChildStatusDown]; -++ [self setControlSocket: nil]; -++} -++ -++- (void) setControlSocket: (NGActiveSocket *) newSocket -++{ -++ NSRunLoop *runLoop; -++ -++ runLoop = [NSRunLoop currentRunLoop]; -++ if (controlSocket) -++ [runLoop removeEvent: (void *) [controlSocket fileDescriptor] -++ type: ET_RDESC -++ forMode: NSDefaultRunLoopMode -++ all: YES]; -++ [controlSocket close]; -++ ASSIGN (controlSocket, newSocket); -++ if (controlSocket) -++ [runLoop addEvent: (void *) [controlSocket fileDescriptor] -++ type: ET_RDESC -++ watcher: self -++ forMode: NSDefaultRunLoopMode]; -++} -++ -++- (NGActiveSocket *) controlSocket -++{ -++ return controlSocket; -++} -++ -++- (void) setStatus: (WOChildStatus) newStatus -++{ -++ status = newStatus; -++} -++ -++- (WOChildStatus) status -++{ -++ return status; -++} -++ -++- (void) setLastSpawn: (NSCalendarDate *) newLastSpawn -++{ -++ ASSIGN (lastSpawn, newLastSpawn); -++ loggedNotRespawn = NO; -++} -++ -++- (NSCalendarDate *) lastSpawn -++{ -++ return lastSpawn; -++} -++ -++- (NSCalendarDate *) nextSpawn -++{ -++ return [lastSpawn addYear: 0 month: 0 day: 0 -++ hour: 0 minute: 0 -++ second: respawnDelay]; -++} -++ -++- (void) logNotRespawn -++{ -++ if (!loggedNotRespawn) -++ { -++ [self logWithFormat: -++ @"avoiding to respawn child before %@", [self nextSpawn]]; -++ loggedNotRespawn = YES; -+ } -++} -++ -++- (BOOL) readMessage -++{ -++ WOChildMessage message; -++ BOOL rc; -++ -++ if ([controlSocket readBytes: &message -++ count: sizeof (WOChildMessage)] == NGStreamError) { -++ rc = NO; -++ [self errorWithFormat: @"FAILURE receiving status for child %d", pid]; -++ [self errorWithFormat: @" socket: %@", controlSocket]; -+ } -++ else { -++ rc = YES; -++ if (message == WOChildMessageAccept) { -++ status = WOChildStatusBusy; -++ } -++ else if (message == WOChildMessageReady) { -++ status = WOChildStatusReady; -++ [watchDog declareChildReady: self]; -++ } -++ // else if (message == WOChildMessageShutdown) { -++ // status = WOChildStatusDown; -++ // [watchDog declareChildDown: self]; -++ // } -++ // [self logStatus]; -++ } -++ -++ return rc; -+ } -+ -+-static void _writePid(NSString *pidFile) { -+- if ([pidFile length] > 0) { -+- FILE *pf; -+- -+- if ((pf = fopen([pidFile cString], "w"))) { -+- fprintf(pf, "%i\n", getpid()); -+- fflush(pf); -+- fclose(pf); -++- (BOOL) _sendMessage: (WOChildMessage) message -++{ -++ return ([controlSocket writeBytes: &message -++ count: sizeof (WOChildMessage)] != NGStreamError -++ && [self readMessage]); -++} -++ -++- (void) _killKill -++{ -++ if (status != WOChildStatusDown) { -++ [self warnWithFormat: @"sending KILL signal to pid %d", pid]; -++ kill (pid, SIGKILL); -++ } -++} -++ -++- (void) _kill -++{ -++ if (status != WOChildStatusDown) { -++ [self logWithFormat: @"sending terminate signal to pid %d", pid]; -++ status = WOChildStatusTerminating; -++ kill (pid, SIGTERM); -++ /* We hardcode a 5 minutes delay before ensuring that all children are -++ terminated. This enables long requests to finish properly while -++ avoiding 100% CPU usage for deadlocked children. */ -++ [NSTimer scheduledTimerWithTimeInterval: 5.0 * 60 -++ target: self -++ selector: @selector (_killKill) -++ userInfo: nil -++ repeats: NO]; -++ } -++} -++ -++- (void) notify -++{ -++ WOChildMessage message; -++ -++ counter++; -++ message = WOChildMessageAccept; -++ if (![self _sendMessage: message]) { -++ [self errorWithFormat: @"FAILURE notifying child %d", pid]; -++ [self _kill]; -++ } -++} -++ -++- (void) terminate -++{ -++ if (status == WOChildStatusDown) { -++ [self logWithFormat: @"child is already down"]; -++ } else { -++ [self setControlSocket: nil]; -++ [self _kill]; -++ } -++} -++ -++- (void) receivedEvent: (void*)data -++ type: (RunLoopEventType)type -++ extra: (void*)extra -++ forMode: (NSString*)mode -++{ -++ if ([controlSocket isAlive]) -++ [self readMessage]; -++ else { -++ /* This happens when a socket has been closed by the child but the child -++ has not terminated yet. */ -++ [[NSRunLoop currentRunLoop] removeEvent: data -++ type: ET_RDESC -++ forMode: NSDefaultRunLoopMode -++ all: YES]; -++ [self setControlSocket: nil]; -++ } -++} -++ -++@end -++ -++@implementation WOWatchDog -++ -+++ (id) sharedWatchDog -++{ -++ static WOWatchDog *sharedWatchDog = nil; -++ -++ if (!sharedWatchDog) -++ sharedWatchDog = [self new]; -++ -++ return sharedWatchDog; -++} -++ -++- (id) init -++{ -++ if ((self = [super init])) -++ { -++ listeningSocket = nil; -++ terminate = NO; -++ willTerminate = NO; -++ terminationSignal = nil; -++ pendingSIGCHLD = 0; -++ pendingSIGHUP = 0; -++ -++ numberOfChildren = 0; -++ children = [[NSMutableArray alloc] initWithCapacity: 10]; -++ readyChildren = [[NSMutableArray alloc] initWithCapacity: 10]; -++ downChildren = [[NSMutableArray alloc] initWithCapacity: 10]; -+ } -++ -++ return self; -++} -++ -++- (void) _releaseListeningSocket -++{ -++ if (listeningSocket) { -++ [[NSRunLoop currentRunLoop] removeEvent: (void *) [listeningSocket fileDescriptor] -++ type: ET_RDESC -++ forMode: NSDefaultRunLoopMode -++ all: YES]; -++ [listeningSocket close]; -++ [listeningSocket release]; -++ listeningSocket = nil; -+ } -+ } -+-static void _delPid(void) { -+- if ([pidFile length] > 0) { -+- if (unlink([pidFile cString]) == 0) -+- pidFile = nil; -++ -++- (void) dealloc -++{ -++ [self _releaseListeningSocket]; -++ [terminationSignal release]; -++ [appName release]; -++ [children release]; -++ [super dealloc]; -++} -++ -++- (void) _runChildWithControlSocket: (NGActiveSocket *) controlSocket -++{ -++ WOApplication *app; -++ extern char **environ; -++ -++ [NSProcessInfo initializeWithArguments: (char **) argv -++ count: argc -++ environment: environ]; -++ NGInitTextStdio(); -++ app = [NSClassFromString(appName) new]; -++ [app autorelease]; -++ [app setListeningSocket: listeningSocket]; -++ [app setControlSocket: controlSocket]; -++ [app run]; -++} -++ -++- (void) receivedEvent: (void*)data -++ type: (RunLoopEventType)type -++ extra: (void*)extra -++ forMode: (NSString*)mode -++{ -++ int nextId; -++ WOWatchDogChild *child; -++ -++ // NSLog (@"have a child accept the connection"); -++ nextId = [readyChildren count] - 1; -++ if (nextId > -1) -++ { -++ child = [readyChildren objectAtIndex: nextId]; -++ [readyChildren removeObjectAtIndex: nextId]; -++ [child notify]; -++ } -++ // else -++ // NSLog (@"all children busy"); -++} -++ -++- (void) _cleanupSignalAndEventHandlers -++{ -++ int count; -++ NSRunLoop *runLoop; -++ -++ [[UnixSignalHandler sharedHandler] removeObserver: self]; -++ -++ runLoop = [NSRunLoop currentRunLoop]; -++ [runLoop removeEvent: (void *) [listeningSocket fileDescriptor] -++ type: ET_RDESC -++ forMode: NSDefaultRunLoopMode -++ all: YES]; -++ -++ for (count = 0; count < numberOfChildren; count++) { -++ [[children objectAtIndex: count] setControlSocket: nil]; -++ // controlSocket = [[children objectAtIndex: count] controlSocket]; -++ // if (controlSocket) -++ // [runLoop removeEvent: (void *) [controlSocket fileDescriptor] -++ // type: ET_RDESC -++ // forMode: NSDefaultRunLoopMode -++ // all: YES]; -+ } -+ } -+ -+-static void exitWatchdog(void) { -+- killChild(); -+- _delPid(); -++- (BOOL) _spawnChild: (WOWatchDogChild *) child -++{ -++ NGActiveSocket *pair[2]; -++ BOOL isChild; -++ int childPid; -++ extern char **environ; -++ -++ isChild = NO; -++ -++ if ([NGActiveSocket socketPair: pair]) { -++ childPid = fork (); -++ if (childPid == 0) { -++ setsid (); -++ isChild = YES; -++ [self _cleanupSignalAndEventHandlers]; -++ [self _runChildWithControlSocket: pair[0]]; -++ } else if (childPid > 0) { -++ [self logWithFormat: @"child spawned with pid %d", childPid]; -++ [child setPid: childPid]; -++ [child setStatus: WOChildStatusSpawning]; -++ [child setControlSocket: pair[1]]; -++ [child setLastSpawn: [NSCalendarDate date]]; -++ // [self logWithFormat: @"parent ready for child: %d", childPid]; -++ } else { -++ perror ("fork"); -++ } -++ } -++ -++ return isChild; -+ } -+ -+-static void wsignalHandler(int _signal) { -+- switch (_signal) { -+- case SIGINT: -+- /* Control-C */ -+- fprintf(stderr, "[%i]: watchdog handling signal ctrl-c ..\n", getpid()); -+- killChild(); -+- exit(0); -+- /* shouldn't get here */ -+- abort(); -++- (void) _ensureNumberOfChildren -++{ -++ int currentNumber, delta, count, min, max; -++ WOWatchDogChild *child; -+ -+- case SIGSEGV: -+- /* Coredump ! */ -+- fprintf(stderr, -+- "[%i]: watchdog handling segmentation fault " -+- "(SERIOUS PROBLEM) ..\n", -+- getpid()); -+- killChild(); -+- exit(123); -+- /* shouldn't get here */ -+- abort(); -++ currentNumber = [children count]; -++ if (currentNumber < numberOfChildren) { -++ delta = numberOfChildren - currentNumber; -++ for (count = 0; count < delta; count++) { -++ child = [WOWatchDogChild watchDogChild]; -++ [child setWatchDog: self]; -++ [children addObject: child]; -++ [downChildren addObject: child]; -++ } -++ [self logWithFormat: @"preparing %d children", delta]; -++ } -++ else if (currentNumber > numberOfChildren) { -++ delta = currentNumber - numberOfChildren; -++ max = [downChildren count]; -++ if (max > delta) -++ min = max - delta; -++ else -++ min = 0; -++ for (count = max - 1; count >= min; count--) { -++ child = [downChildren objectAtIndex: count]; -++ [downChildren removeObjectAtIndex: count]; -++ [children removeObject: child]; -++ delta--; -++ [self logWithFormat: @"%d processes purged from pool", delta]; -++ } -+ -+- case SIGTERM: -+- /* TERM signal (kill 'pid') */ -+- fprintf(stderr, "[%i]: watchdog handling SIGTERM ..\n", getpid()); -+- killChild(); -+- exit(0); -+- /* shouldn't get here */ -+- abort(); -+- -+- case SIGHUP: -+- /* HUP signal (restart children) */ -+- fprintf(stderr, "[%i]: watchdog handling SIGHUP ..\n", getpid()); -+- killChild(); -+- killedChild = YES; -+- signal(_signal, wsignalHandler); -+- return; -+- -+- case SIGCHLD: -+- break; -+- -+- default: -+- fprintf(stderr, "[%i]: watchdog handling signal %i ..\n", -+- getpid(), _signal); -+- break; -++ max = [readyChildren count]; -++ if (max > delta) -++ max -= delta; -++ for (count = max - 1; count > -1; count--) { -++ child = [readyChildren objectAtIndex: count]; -++ [readyChildren removeObjectAtIndex: count]; -++ [child terminate]; -++ [child setStatus: WOChildStatusExcessive]; -++ delta--; -++ } -++ [self logWithFormat: @"%d processes left to terminate", delta]; -+ } -+- fflush(stderr); -+- -+- switch (_signal) { -+- case SIGTERM: -+- case SIGINT: -+- case SIGKILL: -+- case SIGILL: -+- killChild(); -+- exit(0); -+- break; -+- -+- case SIGHUP: -+- killChild(); -+- break; -+- -+- case SIGCHLD: { -+- int returnStatus; -+- pid_t result; -+- -+- // NSLog(@"SIGNAL: SIGCHLD"); -+- // fetch return state -+- -+- do { -+- result = waitpid(-1, &returnStatus, WNOHANG); -+- if (result > 0) { -+- fprintf(stderr, "[%i]: process %i exited with code %i", -+- getpid(), (int)result, WEXITSTATUS(returnStatus)); -++} -+ -+- if (WIFSIGNALED(returnStatus)) { -+- fprintf(stderr, " (terminated due to signal %i%s)", -+- WTERMSIG(returnStatus), -+- WCOREDUMP(returnStatus) ? ", coredump" : ""); -+- } -+- if (WIFSTOPPED(returnStatus)) { -+- fprintf(stderr, " (stopped due to signal %i)", -+- WSTOPSIG(returnStatus)); -+- } -+- -+- fprintf(stderr, "\n"); -+- fflush(stderr); -++- (void) _noop -++{ -++} -++ -++- (BOOL) _ensureChildren -++{ -++ int count, max; -++ WOWatchDogChild *child; -++ BOOL isChild, delayed; -++ NSCalendarDate *now, *nextSpawn; -++ -++ isChild = NO; -++ -++ if (!willTerminate) { -++ [self _ensureNumberOfChildren]; -++ max = [downChildren count]; -++ for (count = max - 1; !isChild && count > -1; count--) { -++ delayed = NO; -++ child = [downChildren objectAtIndex: count]; -++ -++ if ([child status] == WOChildStatusExcessive) -++ [children removeObject: child]; -++ else { -++ now = [NSCalendarDate date]; -++ nextSpawn = [child nextSpawn]; -++ if ([nextSpawn earlierDate: now] == nextSpawn) -++ isChild = [self _spawnChild: child]; -++ else { -++ delayed = YES; -++ [child logNotRespawn]; -+ } -+ } -+- while (result > 0); -+- -+- break; -++ if (!delayed) -++ [downChildren removeObjectAtIndex: count]; -+ } -+- -+- default: -+- fprintf(stderr, "watchdog[%i]: caught signal %i\n", getpid(), _signal); -+- break; -+ } -+- signal(_signal, wsignalHandler); -++ -++ return isChild; -+ } -+ -+-static void signalHandler(int _signal) { -+- fprintf(stderr, "[%i]: handling signal %i ..\n", -+- getpid(), _signal); -+- fflush(stderr); -+- -+- switch (_signal) { -+- case SIGPIPE: -+- fprintf(stderr, "[%i]: caught signal SIGPIPE\n", getpid()); -+- break; -+- -+- default: -+- fprintf(stderr, "[%i]: caught signal %i\n", getpid(), _signal); -+- break; -++/* SOPE on GNUstep does not need to parse the argument line, since the -++ arguments will be put in the NSArgumentDomain. I don't know about -++ libFoundation but OSX is supposed to act the same way. */ -++- (NGInternetSocketAddress *) _listeningAddress -++{ -++ NGInternetSocketAddress *listeningAddress; -++ NSUserDefaults *ud; -++ id port, allow; -++ -++ listeningAddress = nil; -++ -++ ud = [NSUserDefaults standardUserDefaults]; -++ port = [ud objectForKey:@"p"]; -++ if (!port) { -++ port = [ud objectForKey:@"WOPort"]; -++ if (!port) -++ port = @"auto"; -+ } -+- signal(_signal, signalHandler); -++ allow = [ud objectForKey:@"WOHttpAllowHost"]; -++ if (allow) -++ [self warnWithFormat: @"'WOHttpAllowHost' is ignored in watchdog mode, use a real firewall instead"]; -++ if ([port isKindOfClass: [NSString class]]) { -++ if ([port isEqualToString: @"auto"]) { -++ listeningAddress -++ = [[NGInternetSocketAddress alloc] initWithPort:0 onHost:@"127.0.0.1"]; -++ [listeningAddress autorelease]; -++ } else if ([port rangeOfString: @":"].location == NSNotFound) { -++ if (allow) -++ listeningAddress = -++ [NGInternetSocketAddress wildcardAddressWithPort:[port intValue]]; -++ else -++ port = [NSString stringWithFormat: @"127.0.0.1:%d", [port intValue]]; -++ } -++ } -++ else { -++ if (allow) -++ listeningAddress = -++ [NGInternetSocketAddress wildcardAddressWithPort:[port intValue]]; -++ else { -++ port = [NSString stringWithFormat: @"127.0.0.1:%@", port]; -++ } -++ } -++ -++ if (!listeningAddress) -++ listeningAddress = (NGInternetSocketAddress *) NGSocketAddressFromString(port); -++ -++ return listeningAddress; -+ } -+ -++- (BOOL) _prepareListeningSocket -++{ -++ NGInternetSocketAddress *addr; -++ NSString *address; -++ BOOL rc; -++ int backlog; -++ -++ addr = [self _listeningAddress]; -++ NS_DURING { -++ [listeningSocket release]; -++ listeningSocket = [[NGPassiveSocket alloc] initWithDomain: [addr domain]]; -++ [listeningSocket bindToAddress: addr]; -++ backlog = [[NSUserDefaults standardUserDefaults] -++ integerForKey: @"WOListenQueueSize"]; -++ if (!backlog) -++ backlog = 5; -++ [listeningSocket listenWithBacklog: backlog]; -++ address = [addr address]; -++ if (!address) -++ address = @"*"; -++ [self logWithFormat: @"listening on %@:%d", address, [addr port]]; -++ [[NSRunLoop currentRunLoop] addEvent: (void *) [listeningSocket fileDescriptor] -++ type: ET_RDESC -++ watcher: self -++ forMode: NSDefaultRunLoopMode]; -++ rc = YES; -++ } -++ NS_HANDLER { -++ // [self logWithFormat:@"failure listening on address 127.0.0.1:%d", port]; -++ rc = NO; -++ } -++ NS_ENDHANDLER; -++ -++ return rc; -++} -++ -++- (WOWatchDogChild *) _childWithPID: (pid_t) childPid -++{ -++ WOWatchDogChild *currentChild, *child; -++ int count; -++ -++ child = nil; -++ for (count = 0; !child && count < numberOfChildren; count++) { -++ currentChild = [children objectAtIndex: count]; -++ if ([currentChild pid] == childPid) -++ child = currentChild; -++ } -++ -++ return child; -++} -++ -++- (void) _handleSIGPIPE:(NSNumber *)_signal { -++ [self logWithFormat: @"received SIGPIPE (unhandled)"]; -++} -++ -++- (void) _handleSIGCHLD:(NSNumber *)_signal { -++ WOWatchDogChild *child; -++ pid_t childPid; -++ int status; -++ -++ childPid = wait (&status); -++ if (childPid > -1) { -++ pendingSIGCHLD++; -++ child = [self _childWithPID: childPid]; -++ [child setSIGCHLDStatus: status]; -++ } -++} -++ -++- (void) _handleTermination:(NSNumber *)_signal { -++ if (!terminationSignal) { -++ ASSIGN (terminationSignal, _signal); -++ if (pidFile) -++ unlink (pidFile); -++ } -++} -++ -++- (void) _handleSIGHUP:(NSNumber *)_signal { -++ pendingSIGHUP++; -++} -++ -++- (void) _setupSignals -++{ -++#if !defined(__MINGW32__) && !defined(NeXT_Foundation_LIBRARY) -++ UnixSignalHandler *us; -++ -++ us = [UnixSignalHandler sharedHandler]; -++ [us addObserver:self selector:@selector(_handleSIGPIPE:) -++ forSignal:SIGPIPE immediatelyNotifyOnSignal:YES]; -++ [us addObserver:self selector:@selector(_handleSIGCHLD:) -++ forSignal:SIGCHLD immediatelyNotifyOnSignal:YES]; -++ [us addObserver:self selector:@selector(_handleTermination:) -++ forSignal:SIGINT immediatelyNotifyOnSignal:YES]; -++ [us addObserver:self selector:@selector(_handleTermination:) -++ forSignal:SIGTERM immediatelyNotifyOnSignal:YES]; -++ // [us addObserver:self selector:@selector(_handleSIGKILL:) -++ // forSignal:SIGKILL immediatelyNotifyOnSignal:YES]; -++ [us addObserver:self selector:@selector(_handleSIGHUP:) -++ forSignal:SIGHUP immediatelyNotifyOnSignal:YES]; -++#endif -++} -++ -++- (void) declareChildReady: (WOWatchDogChild *) readyChild -++{ -++ [readyChildren addObject: readyChild]; -++} -++ -++- (void) declareChildDown: (WOWatchDogChild *) downChild -++{ -++ if (![downChildren containsObject: downChild]) -++ [downChildren addObject: downChild]; -++} -++ -++- (void) _ensureWorkersCount -++{ -++ int newNumberOfChildren; -++ NSUserDefaults *ud; -++ -++ ud = [NSUserDefaults standardUserDefaults]; -++ [ud synchronize]; -++ newNumberOfChildren = [ud integerForKey: @"WOHttpAdaptorForkCount"]; -++ if (newNumberOfChildren) -++ [self logWithFormat: @"user default 'WOHttpAdaptorForkCount' has been" -++ " replaced with 'WOWorkersCount'"]; -++ else -++ newNumberOfChildren = [ud integerForKey: @"WOWorkersCount"]; -++ if (newNumberOfChildren < 1) -++ newNumberOfChildren = 1; -++ numberOfChildren = newNumberOfChildren; -++} -++ -++- (void) _handlePostTerminationSignal -++{ -++ WOWatchDogChild *child; -++ int count; -++ -++ [self logWithFormat: @"Terminating with signal %@", terminationSignal]; -++ [self _releaseListeningSocket]; -++ for (count = 0; count < numberOfChildren; count++) { -++ child = [children objectAtIndex: count]; -++ if ([child status] != WOChildStatusDown -++ && [child status] != WOChildStatusTerminating) -++ [child terminate]; -++ } -++ [terminationSignal release]; -++ terminationSignal = nil; -++ if ([downChildren count] == numberOfChildren) { -++ [self logWithFormat: @"all children exited. We now terminate."]; -++ terminate = YES; -++ } -++ else -++ willTerminate = YES; -++} -++ -++- (void) _handlePostSIGCHLDStatus -++{ -++ int status, count; -++ WOWatchDogChild *child; -++ -++ for (count = 0; pendingSIGCHLD && count < numberOfChildren; count++) { -++ child = [children objectAtIndex: count]; -++ status = [child SIGCHLDStatus]; -++ if (status != -1) { -++ [child handleSIGCHLDStatus]; -++ pendingSIGCHLD--; -++ [self declareChildDown: child]; -++ if (willTerminate && [downChildren count] == numberOfChildren) { -++ [self logWithFormat: @"all children exited. We now terminate."]; -++ terminate = YES; -++ } -++ } -++ } -++} -++ -++- (void) _setupProcessName -++{ -++ NSProcessInfo *processInfo; -++ NSString *name; -++ -++ /* this does not seem to work */ -++ processInfo = [NSProcessInfo processInfo]; -++ name = [processInfo processName]; -++ if (!name) -++ name = @""; -++ [processInfo setProcessName: [NSString stringWithFormat: @"%@: %@ watchdog", -++ name, appName]]; -++} -++ -++- (int) run: (NSString *) newAppName -++ argc: (int) newArgC argv: (const char **) newArgV -++{ -++ NSAutoreleasePool *pool; -++ NSRunLoop *runLoop; -++ NSDate *limitDate; -++ BOOL listening; -++ int retries; -++ -++ willTerminate = NO; -++ -++ ASSIGN (appName, newAppName); -++ [self _setupProcessName]; -++ -++ argc = newArgC; -++ argv = newArgV; -++ -++ listening = NO; -++ retries = 0; -++ while (!listening && retries < 5) { -++ listening = [self _prepareListeningSocket]; -++ retries++; -++ if (!listening) { -++ [self warnWithFormat: @"listening socket: attempt %d failed", retries]; -++ [NSThread sleepForTimeInterval: 1.0]; -++ } -++ } -++ if (listening) { -++ [self logWithFormat: @"watchdog process pid: %d", getpid ()]; -++ [self _setupSignals]; -++ [self _ensureWorkersCount]; -++ -++ // NSLog (@"ready to process requests"); -++ runLoop = [NSRunLoop currentRunLoop]; -++ -++ /* This timer ensures the looping of the runloop at reasonable intervals -++ for correct processing of signal handlers. */ -++ [NSTimer scheduledTimerWithTimeInterval: 0.5 -++ target: self -++ selector: @selector (_noop) -++ userInfo: nil -++ repeats: YES]; -++ terminate = NO; -++ while (!terminate) { -++ pool = [NSAutoreleasePool new]; -++ -++ while (pendingSIGHUP) { -++ [self logWithFormat: @"received SIGHUP"]; -++ [self _ensureWorkersCount]; -++ pendingSIGHUP--; -++ } -++ -++ // [self logWithFormat: @"watchdog loop"]; -++ NS_DURING { -++ terminate = [self _ensureChildren]; -++ if (!terminate) { -++ limitDate = [runLoop limitDateForMode:NSDefaultRunLoopMode]; -++ [runLoop runMode: NSDefaultRunLoopMode beforeDate: limitDate]; -++ } -++ } -++ NS_HANDLER { -++ terminate = YES; -++ [self errorWithFormat: -++ @"an exception occured in runloop %@", localException]; -++ } -++ NS_ENDHANDLER; -++ -++ if (!terminate) { -++ if (terminationSignal) -++ [self _handlePostTerminationSignal]; -++ while (pendingSIGCHLD) -++ [self _handlePostSIGCHLDStatus]; -++ } -++ [pool release]; -++ } -++ -++ [[UnixSignalHandler sharedHandler] removeObserver: self]; -++ } -++ else -++ [self errorWithFormat: @"unable to listen on specified port," -++ @" check that no other process is already using it"]; -++ -++ return 0; -++} -++ -++@end -++ -++static BOOL _writePid(NSString *nsPidFile) { -++ NSString *pid; -++ BOOL rc; -++ -++ pid = [NSString stringWithFormat: @"%d", getpid()]; -++ rc = [pid writeToFile: nsPidFile atomically: NO]; -++ -++ return rc; -++} -++ -+ int WOWatchDogApplicationMain -+ (NSString *appName, int argc, const char *argv[]) -+ { -+ NSAutoreleasePool *pool; -+ NSUserDefaults *ud; -++ NSString *logFile, *nsPidFile; -++ int rc, stdErrNo; -++ pid_t childPid; -++ NSProcessInfo *processInfo; -+ -+ pool = [[NSAutoreleasePool alloc] init]; -++ -+ #if LIB_FOUNDATION_LIBRARY || defined(GS_PASS_ARGUMENTS) -+ { -+ extern char **environ; -+@@ -241,179 +972,68 @@ -+ environment:(void*)environ]; -+ } -+ #endif -+- -++ -++ /* This invocation forces the class initialization of WOCoreApplication, -++ which causes the NSUserDefaults to be initialized as well with -++ Defaults.plist. */ -++ [NSClassFromString (appName) class]; -++ -+ ud = [NSUserDefaults standardUserDefaults]; -+- -+- /* default is to use the watch dog! */ -+- /* Note: the Defaults.plist is not yet loaded at this stage! */ -+- if ([ud objectForKey:@"WOUseWatchDog"] != nil) { -+- if (![ud boolForKey:@"WOUseWatchDog"]) -+- return WOApplicationMain(appName, argc, argv); -++ processInfo = [NSProcessInfo processInfo]; -++ -++ logFile = [ud objectForKey: @"WOLogFile"]; -++ if (!logFile) -++ logFile = [NSString stringWithFormat: @"/var/log/%@/%@.log", -++ [processInfo processName], -++ [processInfo processName]]; -++ if (![logFile isEqualToString: @"-"]) { -++ stdErrNo = dup(fileno(stderr)); -++ stdout = freopen([logFile cString], "a", stdout); -++ stderr = freopen([logFile cString], "a", stderr); -+ } -+- -+- /* watch dog */ -+- { -+- int failCount = 0; -+- int forkCount = 0; -+- BOOL repeat = YES; -+- BOOL isVerbose = NO; -+- -+- isVerbose = [[ud objectForKey:@"watchdog_verbose"] boolValue]; -+- pidFile = [[[ud objectForKey:@"watchdog_pidfile"] stringValue] copy]; -+- -+- /* write current pid to pidfile */ -+- _writePid(pidFile); -+- -+- /* register exit handler */ -+- atexit(exitWatchdog); -+- -+- /* register signal handlers of watch dog */ -+- signal(SIGPIPE, wsignalHandler); -+- signal(SIGCHLD, wsignalHandler); -+- signal(SIGINT, wsignalHandler); -+- signal(SIGTERM, wsignalHandler); -+- signal(SIGKILL, wsignalHandler); -+- signal(SIGHUP, wsignalHandler); -+- -+- /* loop */ -+- -+- while (repeat) { -+- time_t clientStartTime; -+- -+- clientStartTime = time(NULL); -+- killedChild = NO; -+- -+- if ((child = fork()) == -1) { -+- fprintf(stderr, "[%i]: fork failed: %s\n", getpid(), strerror(errno)); -+- failCount++; -+- -+- if (failCount > 5) { -+- fprintf(stderr, " fork failed %i times, sleeping 60 seconds ..\n", -+- failCount); -+- sleep(60); -+- } -+- else { -+- sleep(1); -+- } -++ if (stdout && stderr) { -++ if ([ud boolForKey: @"WONoDetach"]) -++ childPid = 0; -++ else -++ childPid = fork(); -++ -++ if (childPid) { -++ rc = 0; -++ } -++ else { -++ nsPidFile = [ud objectForKey: @"WOPidFile"]; -++ if (!nsPidFile) -++ nsPidFile = [NSString stringWithFormat: @"/var/run/%@/%@.pid", -++ [processInfo processName], -++ [processInfo processName]]; -++ pidFile = [nsPidFile UTF8String]; -++ if (_writePid(nsPidFile)) { -++ respawnDelay = [ud integerForKey: @"WORespawnDelay"]; -++ if (!respawnDelay) -++ respawnDelay = 5; -++ /* default is to use the watch dog! */ -++ if ([ud objectForKey:@"WOUseWatchDog"] != nil -++ && ![ud boolForKey:@"WOUseWatchDog"]) -++ rc = WOApplicationMain(appName, argc, argv); -++ else -++ rc = [[WOWatchDog sharedWatchDog] run: appName argc: argc argv: argv]; -+ } -+ else { -+- if (child == 0) { -+- /* child process */ -+- signal(SIGPIPE, SIG_DFL); -+- signal(SIGCHLD, SIG_DFL); -+- signal(SIGINT, SIG_DFL); -+- signal(SIGTERM, SIG_DFL); -+- signal(SIGKILL, SIG_DFL); -+- -+- if (isVerbose) -+- fprintf(stderr, "starting child %i ..\n", getpid()); -+- -+- pidFile = [pidFile stringByAppendingPathExtension:@"child"]; -+- _writePid(pidFile); -+- -+- atexit(_delPid); -+- -+- exit(WOApplicationMain(appName, argc, argv)); -+- -+- /* shouldn't even get here ! */ -+- fprintf(stderr, "internal server error !\n"); -+- abort(); -+- } -+- else { -+- /* parent (watch dog) */ -+- int status = 0; -+- pid_t result = 0; -+- time_t clientStopTime; -+- unsigned uptime; -+- -+- forkCount++; -+- -+- if (isVerbose) { -+- fprintf(stderr, "forked child process %i (#%i) ..\n", -+- child, forkCount); -+- } -+- -+- failCount = 0; -+- status = 0; -+- -+- if ((result = waitpid(child, &status, 0)) == -1) { -+- if (killedChild) { -+- killedChild = NO; -+- continue; -+- } -+- -+- fprintf(stderr, -+- "### waiting for child %i (#%i) failed: %s\n", -+- child, forkCount, strerror(errno)); -+- continue; -+- } -+- -+- clientStopTime = time(NULL); -+- uptime = clientStopTime - clientStartTime; -+- -+- if (WIFSIGNALED(status)) { -+- fprintf(stderr, -+- "### child %i (#%i) was terminated by signal %i " -+- "(uptime=%ds).\n", -+- child, forkCount, WTERMSIG(status), uptime); -+- -+- lastFailExit = time(NULL); -+- failExitCount++; -+- } -+- else if (WIFEXITED(status)) { -+- unsigned exitCode; -+- -+- if ((exitCode = WEXITSTATUS(status)) != 0) { -+- time_t now; -+- -+- now = time(NULL); -+- -+- if (uptime < 3) { -+- if (failExitCount > 0) { -+- unsigned secsSinceLastFail; -+- -+- secsSinceLastFail = (now - lastFailExit); -+- -+- if (secsSinceLastFail > 120) { -+- /* reset fail count */ -+- failExitCount = 0; -+- } -+- else if (failExitCount > 20) { -+- printf("### child %i (#%i) already failed %i times " -+- "in the last %i seconds, stopping watchdog !\n", -+- child, forkCount, failExitCount, secsSinceLastFail); -+- repeat = NO; -+- } -+- } -+- } -+- failExitCount++; -+- lastFailExit = now; -+- -+- fprintf(stderr, -+- "### child %i (#%i) exited with status %i " -+- "(#fails=%i, uptime=%ds).\n", -+- child, forkCount, exitCode, failExitCount, uptime); -+- } -+- else { -+- fprintf(stderr, -+- "### child %i (#%i) exited successfully (uptime=%ds).\n", -+- child, forkCount, uptime); -+- } -+- -+- if (exitCode == 123) // ??? -+- repeat = NO; -+- } -+- else { -+- fprintf(stderr, -+- "### abnormal termination of child %i (#%i) status=%i" -+- "(was not signaled nor exited).", -+- child, forkCount, status); -+- } -+- } -++ [ud errorWithFormat: @"unable to open pid file: %@", pidFile]; -++ rc = -1; -+ } -+ } -+- return 0; -+ } -++ else { -++ stdout = fdopen(stdErrNo, "a"); -++ stderr = fdopen(stdErrNo, "a"); -++ fprintf(stderr, "failed to redirect output channels to log file '%s'\n", -++ [logFile cString]); -++ } -++ -++ [pool release]; -++ -++ return rc; -+ } -+ #endif -+ -+@@ -421,8 +1041,8 @@ -+ -+ @interface NSUserDefaults(ServerDefaults) -+ + (id)hackInServerDefaults:(NSUserDefaults *)_ud -+- withAppDomainPath:(NSString *)_appDomainPath -+- globalDomainPath:(NSString *)_globalDomainPath; -++ withAppDomainPath:(NSString *)_appDomainPath -++ globalDomainPath:(NSString *)_globalDomainPath; -+ @end -+ -+ int WOWatchDogApplicationMainWithServerDefaults -+@@ -437,7 +1057,7 @@ -+ { -+ extern char **environ; -+ [NSProcessInfo initializeWithArguments:(void*)argv count:argc -+- environment:(void*)environ]; -++ environment:(void*)environ]; -+ } -+ #endif -+ -+@@ -446,8 +1066,8 @@ -+ -+ ud = [NSUserDefaults standardUserDefaults]; -+ sd = [defClass hackInServerDefaults:ud -+- withAppDomainPath:appDomainPath -+- globalDomainPath:globalDomainPath]; -++ withAppDomainPath:appDomainPath -++ globalDomainPath:globalDomainPath]; -+ -+ #if 0 -+ if (((sd == nil) || (sd == ud)) && (appDomainPath != nil)) { -+Index: sope-appserver/NGObjWeb/GNUmakefile.postamble -+=================================================================== -+--- sope-appserver/NGObjWeb/GNUmakefile.postamble (revision 1664) -++++ sope-appserver/NGObjWeb/GNUmakefile.postamble (working copy) -+@@ -23,14 +23,20 @@ -+ -+ # install makefiles -+ -+-after-install :: -+- $(MKDIRS) $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/Additional/ -+- $(INSTALL_DATA) ngobjweb.make $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/Additional/ngobjweb.make -++after-install :: $(DESTDIR)/$(GNUSTEP_MAKEFILES)/Additional/ngobjweb.make -+ -+ ifneq ($(GNUSTEP_MAKE_VERSION),1.3.0) -+-after-install :: -++after-install :: $(DESTDIR)/$(GNUSTEP_MAKEFILES)/woapp.make $(DESTDIR)/$(GNUSTEP_MAKEFILES)/wobundle.make -++endif -++ -++$(DESTDIR)/$(GNUSTEP_MAKEFILES)/Additional/ngobjweb.make: ngobjweb.make -++ $(MKDIRS) $(DESTDIR)/$(GNUSTEP_MAKEFILES)/Additional/ -++ $(INSTALL_DATA) ngobjweb.make $(DESTDIR)/$(GNUSTEP_MAKEFILES)/Additional/ngobjweb.make -++ -++$(DESTDIR)/$(GNUSTEP_MAKEFILES)/woapp.make: woapp-gs.make -+ $(INSTALL_DATA) woapp-gs.make \ -+- $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/woapp.make -++ $(DESTDIR)/$(GNUSTEP_MAKEFILES)/woapp.make -++ -++$(DESTDIR)/$(GNUSTEP_MAKEFILES)/wobundle.make: wobundle-gs.make -+ $(INSTALL_DATA) wobundle-gs.make \ -+- $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/wobundle.make -+-endif -++ $(DESTDIR)/$(GNUSTEP_MAKEFILES)/wobundle.make -+Index: sope-appserver/NGObjWeb/WOMessage+XML.m -+=================================================================== -+--- sope-appserver/NGObjWeb/WOMessage+XML.m (revision 1664) -++++ sope-appserver/NGObjWeb/WOMessage+XML.m (working copy) -+@@ -84,7 +84,7 @@ -+ id builder; -+ -+ builder = [[[NSClassFromString(@"DOMSaxBuilder") alloc] init] autorelease]; -+- dom = [[builder buildFromData:data] retain]; -++ dom = [builder buildFromData:data]; -+ } -+ -+ /* cache DOM structure */ -+Index: sope-appserver/NGObjWeb/ChangeLog -+=================================================================== -+--- sope-appserver/NGObjWeb/ChangeLog (revision 1664) -++++ sope-appserver/NGObjWeb/ChangeLog (working copy) -+@@ -1,3 +1,97 @@ -++2009-12-22 Wolfgang Sourdeau -++ -++ * WOWatchDogApplicationMain.m (_listeningAddress): read "WOPort" -++ from the user defaults rather than by invoking [WOApplication -++ port], which returns an NSNumber. -++ -++2009-12-14 Wolfgang Sourdeau -++ -++ * WOWatchDogApplicationMain.m (-run:argc:argv:): added a -++ repeatable timer, triggered every 0.5 seconds, that ensures the -++ proper looping of the runloop when a signal was received. -++ -++2009-12-09 Wolfgang Sourdeau -++ -++ * WOWatchDogApplicationMain.m (_handleSIGCHLD:) -++ (_handleTermination:, _handleSIGHUP:): the actual handling is now -++ done elsewhere, in order to avoid messing with memory allocation -++ and risking a dead lock. -++ (-_handlePostTerminationSignal): we set "terminate" to YES if all -++ children are already down, in order to avoid another deadlock -++ where the process termination would stall waiting for SIGCHLD. -++ (-receivedEvent:type:extra:forMode:): check that the control -++ socket is still "alive" before reading from it. If not, we -++ unregister the filedescriptor passed as "data" from the runloop -++ listener. -++ -++2009-12-07 Wolfgang Sourdeau -++ -++ * WOCoreApplication.m (+initialize): we invoke -++ "registerUserDefaults" from here now. This enables Defaults.plist -++ to be registered as soon as the watchdog is active. -++ -++ * WOWatchDogApplicationMain.m (-terminate): we use a SIGTERM to -++ terminate the children instead of passing a message. We also setup -++ a timer that will send a SIGKILL after 5 minutes. -++ (-_releaseListeningSocket): we close the socket here so that other -++ processes can start listening. -++ (WOWatchDogApplicationMain): we accept "-" as argument to -++ "WOLogFile" so that we avoid redirecting the output and the error -++ channels. -++ -++2009-11-11 Wolfgang Sourdeau -++ -++ * WOCoreApplication.m (-setControlSocket, -controlSocket) -++ (-setListeningSocket, -listeningSocke): new helper accessors for -++ the new watchdog mechanism. -++ -++ * WOHttpAdaptor/WOHttpAdaptor.m: slightly refactored to use the -++ control socket provided by the watchdog. -++ -++ * WOWatchDogApplicationMain.m: rewritten the watchdog mechanism: -++ - added WOWatchDog and WOWatchDogChild classes -++ - make use of UnixSignalHandler -++ - added support for preforked preocesses (WOWorkersCount) -++ - detach watchdog processes from terminal by default (WONoDetach) -++ - redirect stderr and stdout to file -++ (WOLogFile = /var/log/[name]/[name].log) -++ - write pid file -++ (WOPidFile = /var/run/[name]/[name].pid) -++ - use "127.0.0.1:port" as default bind address, unless -++ WOHTTPAllowHost is specified -++ - added support for delaying process respawning -++ (WORespawnDelay = 5 seconds) -++ -++2009-10-26 Wolfgang Sourdeau -++ -++ * WOMessage+XML.m (-contentAsDOMDocument): do not retain "dom" as -++ it will be assigned to self->domCache, to avoid a leak. -++ -++2009-10-21 Wolfgang Sourdeau -++ -++ * WebDAV/SoObjectResultEntry.m (-valueForKey:): we now take -++ WOUseRelativeURLs into account when the "href" key is requested, -++ to work around a bug in iCal 4. -++ -++2009-07-02 Wolfgang Sourdeau -++ -++ * WOMessage.m (-setHeaders:, -setHeader:forKey:, headerForKey:, -++ -appendHeader:forKey:, -appendHeaders:forKey:, setHeaders:forKey:, -++ -headersForKey:): convert the specified header key to lowercase, -++ to ensure they are managed case-insensitively. -++ * WOHttpAdaptor/WOHttpTransaction.m -++ (-deliverResponse:toRequest:onStream:): if the content-type is -++ specified and already has "text/plain" as prefix, we don't -++ override it. -++ -++2009-07-01 Wolfgang Sourdeau -++ -++ * WOHttpAdaptor/WOHttpTransaction.m -++ (-deliverResponse:toRequest:onStream:): we test the content-length -++ and impose a content-type of text/plain when 0. This work-arounds -++ a bug in Mozilla clients where empty responses with a content-type -++ set to X/xml will trigger an exception. -++ -+ 2009-06-10 Helge Hess -+ -+ * DAVPropMap.plist: mapped {DAV:}current-user-principal (v4.9.37) -+Index: sope-appserver/NGObjWeb/DAVPropMap.plist -+=================================================================== -+--- sope-appserver/NGObjWeb/DAVPropMap.plist (revision 1664) -++++ sope-appserver/NGObjWeb/DAVPropMap.plist (working copy) -+@@ -157,6 +157,7 @@ -+ "{urn:ietf:params:xml:ns:caldav}supported-calendar-data" = -+ davSupportedCalendarDataTypes; -+ "{urn:ietf:params:xml:ns:caldav}calendar-description" = davDescription; -++ "{urn:ietf:params:xml:ns:caldav}calendar-timezone" = davCalendarTimeZone; -+ -+ /* CardDAV */ -+ "{urn:ietf:params:xml:ns:carddav}addressbook-home-set" = davAddressbookHomeSet; -+Index: sope-appserver/NGObjWeb/WebDAV/SoObjectResultEntry.m -+=================================================================== -+--- sope-appserver/NGObjWeb/WebDAV/SoObjectResultEntry.m (revision 1664) -++++ sope-appserver/NGObjWeb/WebDAV/SoObjectResultEntry.m (working copy) -+@@ -25,7 +25,14 @@ -+ @implementation SoObjectResultEntry -+ -+ static BOOL debugOn = NO; -++static BOOL useRelativeURLs = NO; -+ -+++ (void) initialize -++{ -++ useRelativeURLs = [[NSUserDefaults standardUserDefaults] -++ boolForKey: @"WOUseRelativeURLs"]; -++} -++ -+ - (id)initWithURI:(NSString *)_href object:(id)_o values:(NSDictionary *)_d { -+ if ((self = [super init])) { -+ if (debugOn) { -+@@ -85,10 +92,36 @@ -+ return YES; -+ } -+ -++- (NSString *)_relativeHREF { -++ NSString *newHREF; -++ NSRange hostRange; -++ -++ if ([self->href hasPrefix: @"/"]) -++ return self->href; -++ else { -++ hostRange = [self->href rangeOfString: @"://"]; -++ if (hostRange.length > 0) { -++ newHREF = [self->href substringFromIndex: NSMaxRange (hostRange)]; -++ hostRange = [newHREF rangeOfString: @"/"]; -++ if (hostRange.length > 0) { -++ newHREF = [newHREF substringFromIndex: hostRange.location]; -++ } -++ } else { -++ newHREF = self->href; -++ } -++ -++ return newHREF; -++ } -++} -++ -+ - (id)valueForKey:(NSString *)_key { -+- if ([_key isEqualToString:@"{DAV:}href"]) -+- return self->href; -+- -++ if ([_key isEqualToString:@"{DAV:}href"]) { -++ if (useRelativeURLs) -++ return [self _relativeHREF]; -++ else -++ return self->href; -++ } -++ -+ if ([_key isEqualToString:@"{DAV:}status"]) -+ return nil; -+ -+Index: sope-appserver/NGObjWeb/WebDAV/SoWebDAVRenderer.m -+=================================================================== -+--- sope-appserver/NGObjWeb/WebDAV/SoWebDAVRenderer.m (revision 1664) -++++ sope-appserver/NGObjWeb/WebDAV/SoWebDAVRenderer.m (working copy) -+@@ -49,6 +49,8 @@ -+ #define XMLNS_INTTASK \ -+ @"{http://schemas.microsoft.com/mapi/id/{00062003-0000-0000-C000-000000000046}/}" -+ -++static Class NSURLKlass = Nil; -++ -+ @interface SoWebDAVRenderer(Privates) -+ - (BOOL)renderStatusResult:(id)_object withDefaultStatus:(int)_defStatus -+ inContext:(WOContext *)_ctx; -+@@ -79,6 +81,8 @@ -+ -+ if ((debugOn = [ud boolForKey:@"SoRendererDebugEnabled"])) -+ NSLog(@"enabled debugging in SoWebDAVRenderer (SoRendererDebugEnabled)"); -++ -++ NSURLKlass = [NSURL class]; -+ } -+ -+ + (id)sharedRenderer { -+@@ -616,16 +620,19 @@ -+ [r appendContentString:s]; -+ } -+ else { -++ s = [self stringForValue:value ofProperty:_key prefixes:nsToPrefix]; -+ [r appendContentCharacter:'<']; -+ [r appendContentString:extName]; -+- [r appendContentCharacter:'>']; -+- -+- s = [self stringForValue:value ofProperty:_key prefixes:nsToPrefix]; -+- [r appendContentString:s]; -+- -+- [r appendContentString:@""]; -++ if ([s length] > 0) { -++ [r appendContentCharacter:'>']; -++ [r appendContentString:s]; -++ [r appendContentString:@""]; -++ } -++ else { -++ [r appendContentString:@"/>"]; -++ } -+ if (formatOutput) [r appendContentCharacter:'\n']; -+ } -+ } -+@@ -694,8 +701,13 @@ -+ } -+ -+ /* tidy href */ -+- href = [self tidyHref:href baseURL:baseURL]; -+- -++ if (useRelativeURLs) { -++ if ([href isKindOfClass: NSURLKlass]) -++ href = [href path]; -++ } -++ else -++ href = [self tidyHref:href baseURL:baseURL]; -++ -+ /* tidy status */ -+ stat = [self tidyStatus:stat]; -+ } -+Index: sope-appserver/NGObjWeb/WODirectAction.m -+=================================================================== -+--- sope-appserver/NGObjWeb/WODirectAction.m (revision 1664) -++++ sope-appserver/NGObjWeb/WODirectAction.m (working copy) -+@@ -46,7 +46,7 @@ -+ } -+ - (id)initWithContext:(WOContext *)_ctx { -+ if ((self = [self initWithRequest:[_ctx request]])) { -+- self->context = [_ctx retain]; -++ self->context = _ctx; -+ } -+ return self; -+ } -+@@ -54,16 +54,16 @@ -+ return [self initWithRequest:nil]; -+ } -+ -+-- (void)dealloc { -+- [self->context release]; -+- [super dealloc]; -+-} -++// - (void)dealloc { -++// [self->context release]; -++// [super dealloc]; -++// } -+ -+ /* accessors */ -+ -+ - (WOContext *)context { -+ if (self->context == nil) -+- self->context = [[[WOApplication application] context] retain]; -++ self->context = [[WOApplication application] context]; -+ return self->context; -+ } -+ -+Index: sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m -+=================================================================== -+--- sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m (revision 1664) -++++ sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m (working copy) -+@@ -216,6 +216,12 @@ -+ assocCount++; -+ } -+ } -++ if (count > 0) { -++ if ((self->isAbsolute = OWGetProperty(_config, @"absolute"))) { -++ count--; -++ assocCount++; -++ } -++ } -+ -+ self->rest = _config; -+ -+Index: sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m -+=================================================================== -+--- sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m (revision 1664) -++++ sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m (working copy) -+@@ -41,6 +41,7 @@ -+ WOAssociation *string; -+ WOAssociation *target; -+ WOAssociation *disabled; -++ WOAssociation *isAbsolute; -+ WOElement *template; -+ -+ /* new in WO4: */ -+@@ -360,6 +361,7 @@ -+ { -+ if ((self = [super initWithName:_name hyperlinkInfo:_info template:_t])) { -+ self->href = _info->href; -++ self->isAbsolute = _info->isAbsolute; -+ } -+ return self; -+ } -+@@ -375,8 +377,11 @@ -+ // TODO: we need a binding to disable rewriting! -+ NSRange r; -+ -++ if ([[self->isAbsolute valueInContext:_ctx] boolValue] == YES) -++ return NO; -++ -+ r.length = [_s length]; -+- -++ -+ /* do not rewrite pure fragment URLs */ -+ if (r.length > 0 && [_s characterAtIndex:0] == '#') -+ return NO; -+Index: sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h -+=================================================================== -+--- sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h (revision 1664) -++++ sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h (working copy) -+@@ -41,7 +41,8 @@ -+ WOAssociation *pageName; -+ WOAssociation *actionClass; -+ WOAssociation *directActionName; -+- -++ WOAssociation *isAbsolute; -++ -+ BOOL sidInUrl; -+ -+ /* 'ivar' associations */ -+Index: sope-appserver/NGObjWeb/WOMessage.m -+=================================================================== -+--- sope-appserver/NGObjWeb/WOMessage.m (revision 1664) -++++ sope-appserver/NGObjWeb/WOMessage.m (working copy) -+@@ -182,7 +182,7 @@ -+ NSString *key; -+ -+ keys = [_headers keyEnumerator]; -+- while ((key = [keys nextObject])) { -++ while ((key = [[keys nextObject] lowercaseString])) { -+ id value; -+ -+ value = [_headers objectForKey:key]; -+@@ -198,34 +198,39 @@ -+ } -+ -+ - (void)setHeader:(NSString *)_header forKey:(NSString *)_key { -+- [self->header setObject:[_header stringValue] forKey:_key]; -++ [self->header setObject:[_header stringValue] -++ forKey:[_key lowercaseString]]; -+ } -+ - (NSString *)headerForKey:(NSString *)_key { -+- return [[self->header objectEnumeratorForKey:_key] nextObject]; -++ return [[self->header objectEnumeratorForKey:[_key lowercaseString]] -++ nextObject]; -+ } -+ -+ - (void)appendHeader:(NSString *)_header forKey:(NSString *)_key { -+- [self->header addObject:_header forKey:_key]; -++ [self->header addObject:_header forKey:[_key lowercaseString]]; -+ } -+ - (void)appendHeaders:(NSArray *)_headers forKey:(NSString *)_key { -+- [self->header addObjects:_headers forKey:_key]; -++ [self->header addObjects:_headers forKey:[_key lowercaseString]]; -+ } -+ -+ - (void)setHeaders:(NSArray *)_headers forKey:(NSString *)_key { -+ NSEnumerator *e; -+ id value; -++ NSString *lowerKey; -+ -++ lowerKey = [_key lowercaseString]; -+ e = [_headers objectEnumerator]; -+ -+- [self->header removeAllObjectsForKey:_key]; -++ [self->header removeAllObjectsForKey:lowerKey]; -+ -+ while ((value = [e nextObject])) -+- [self->header addObject:value forKey:_key]; -++ [self->header addObject:value forKey:lowerKey]; -+ } -+ - (NSArray *)headersForKey:(NSString *)_key { -+ NSEnumerator *values; -+ -+- if ((values = [self->header objectEnumeratorForKey:_key])) { -++ if ((values -++ = [self->header objectEnumeratorForKey:[_key lowercaseString]])) { -+ NSMutableArray *array = nil; -+ id value = nil; -+ -+@@ -243,17 +248,14 @@ -+ NSEnumerator *values; -+ -+ if ((values = [self->header keyEnumerator])) { -+- NSMutableArray *array = nil; -++ NSMutableArray *array; -+ id name = nil; -+- array = [[NSMutableArray alloc] init]; -+- -++ array = [NSMutableArray array]; -++ -+ while ((name = [values nextObject])) -+ [array addObject:name]; -+ -+- name = [array copy]; -+- [array release]; -+- -+- return [name autorelease]; -++ return array; -+ } -+ return nil; -+ } -+Index: sope-appserver/NGObjWeb/SoObjects/SoObject.m -+=================================================================== -+--- sope-appserver/NGObjWeb/SoObjects/SoObject.m (revision 1664) -++++ sope-appserver/NGObjWeb/SoObjects/SoObject.m (working copy) -+@@ -39,22 +39,34 @@ -+ static int debugLookup = -1; -+ static int debugBaseURL = -1; -+ static int useRelativeURLs = -1; -++static int redirectInitted = -1; -++static NSURL *redirectURL = nil; -++ -+ static void _initialize(void) { -++ NSString *url; -++ NSUserDefaults *ud; -++ -++ ud = [NSUserDefaults standardUserDefaults]; -++ -+ if (debugLookup == -1) { -+- debugLookup = [[NSUserDefaults standardUserDefaults] -+- boolForKey:@"SoDebugKeyLookup"] ? 1 : 0; -++ debugLookup = [ud boolForKey:@"SoDebugKeyLookup"] ? 1 : 0; -+ NSLog(@"Note(SoObject): SoDebugKeyLookup is enabled!"); -+ } -+ if (debugBaseURL == -1) { -+- debugBaseURL = [[NSUserDefaults standardUserDefaults] -+- boolForKey:@"SoDebugBaseURL"] ? 1 : 0; -++ debugBaseURL = [ud boolForKey:@"SoDebugBaseURL"] ? 1 : 0; -+ NSLog(@"Note(SoObject): SoDebugBaseURL is enabled!"); -+ } -+ if (useRelativeURLs == -1) { -+- useRelativeURLs = [[NSUserDefaults standardUserDefaults] -+- boolForKey:@"WOUseRelativeURLs"] ?1:0; -++ useRelativeURLs = [ud boolForKey:@"WOUseRelativeURLs"] ?1:0; -+ NSLog(@"Note(SoObject): relative base URLs are enabled."); -+ } -++ if (redirectInitted == -1) { -++ url = [ud stringForKey:@"WOApplicationRedirectURL"]; -++ if ([url length]) { -++ redirectURL = [[NSURL alloc] initWithString: url]; -++ } -++ redirectInitted = 1; -++ } -+ } -+ -+ /* classes */ -+@@ -318,56 +330,61 @@ -+ -+ rq = [_ctx request]; -+ ms = [[NSMutableString alloc] initWithCapacity:128]; -++ -++ if (redirectURL) { -++ [ms appendString: [redirectURL absoluteString]]; -++ } -++ else { -++ if (!useRelativeURLs) { -++ port = [[rq headerForKey:@"x-webobjects-server-port"] intValue]; -+ -+- if (!useRelativeURLs) { -+- port = [[rq headerForKey:@"x-webobjects-server-port"] intValue]; -+- -+- /* this is actually a bug in Apache */ -+- if (port == 0) { -+- static BOOL didWarn = NO; -+- if (!didWarn) { -+- [self warnWithFormat:@"(%s:%i): got an empty port from Apache!", -+- __PRETTY_FUNCTION__, __LINE__]; -+- didWarn = YES; -++ /* this is actually a bug in Apache */ -++ if (port == 0) { -++ static BOOL didWarn = NO; -++ if (!didWarn) { -++ [self warnWithFormat:@"(%s:%i): got an empty port from Apache!", -++ __PRETTY_FUNCTION__, __LINE__]; -++ didWarn = YES; -++ } -++ port = 80; -+ } -+- port = 80; -+- } -+ -+- if ((tmp = [rq headerForKey:@"host"]) != nil) { -+- /* check whether we have a host header with port */ -+- if ([tmp rangeOfString:@":"].length == 0) -+- tmp = nil; -+- } -+- if (tmp != nil) { /* we have a host header with port */ -+- isHTTPS = -+- [[rq headerForKey:@"x-webobjects-server-url"] hasPrefix:@"https"]; -+- [ms appendString:isHTTPS ? @"https://" : @"http://"]; -+- [ms appendString:tmp]; -+- } -+- else if ((tmp = [rq headerForKey:@"x-webobjects-server-url"]) != nil) { -+- /* sometimes the URL is just wrong! (suggests port 80) */ -+- if ([tmp hasSuffix:@":0"] && [tmp length] > 2) { // TODO: bad bad bad -+- [self warnWithFormat:@"%s: got incorrect URL from Apache: '%@'", -+- __PRETTY_FUNCTION__, tmp]; -+- tmp = [tmp substringToIndex:([tmp length] - 2)]; -++ if ((tmp = [rq headerForKey:@"host"]) != nil) { -++ /* check whether we have a host header with port */ -++ if ([tmp rangeOfString:@":"].length == 0) -++ tmp = nil; -+ } -+- else if ([tmp hasSuffix:@":443"] && [tmp hasPrefix:@"http://"]) { -+- /* see OGo bug #1435, Debian Apache hack */ -+- [self warnWithFormat:@"%s: got 'http' protocol but 443 port, " -+- @"assuming Debian/Apache bug (OGo #1435): '%@'", -+- __PRETTY_FUNCTION__, tmp]; -+- tmp = [tmp substringWithRange:NSMakeRange(4, [tmp length] - 4 - 4)]; -+- tmp = [@"https" stringByAppendingString:tmp]; -++ if (tmp != nil) { /* we have a host header with port */ -++ isHTTPS = -++ [[rq headerForKey:@"x-webobjects-server-url"] hasPrefix:@"https"]; -++ [ms appendString:isHTTPS ? @"https://" : @"http://"]; -++ [ms appendString:tmp]; -+ } -+- [ms appendString:tmp]; -+- } -+- else { -+- // TODO: isHTTPS always no in this case? -+- [ms appendString:isHTTPS ? @"https://" : @"http://"]; -++ else if ((tmp = [rq headerForKey:@"x-webobjects-server-url"]) != nil) { -++ /* sometimes the URL is just wrong! (suggests port 80) */ -++ if ([tmp hasSuffix:@":0"] && [tmp length] > 2) { // TODO: bad bad bad -++ [self warnWithFormat:@"%s: got incorrect URL from Apache: '%@'", -++ __PRETTY_FUNCTION__, tmp]; -++ tmp = [tmp substringToIndex:([tmp length] - 2)]; -++ } -++ else if ([tmp hasSuffix:@":443"] && [tmp hasPrefix:@"http://"]) { -++ /* see OGo bug #1435, Debian Apache hack */ -++ [self warnWithFormat:@"%s: got 'http' protocol but 443 port, " -++ @"assuming Debian/Apache bug (OGo #1435): '%@'", -++ __PRETTY_FUNCTION__, tmp]; -++ tmp = [tmp substringWithRange:NSMakeRange(4, [tmp length] - 4 - 4)]; -++ tmp = [@"https" stringByAppendingString:tmp]; -++ } -++ [ms appendString:tmp]; -++ } -++ else { -++ // TODO: isHTTPS always no in this case? -++ [ms appendString:isHTTPS ? @"https://" : @"http://"]; -+ -+- [ms appendString:[rq headerForKey:@"x-webobjects-server-name"]]; -+- if ((isHTTPS ? (port != 443) : (port != 80)) && port != 0) -+- [ms appendFormat:@":%i", port]; -++ [ms appendString:[rq headerForKey:@"x-webobjects-server-name"]]; -++ if ((isHTTPS ? (port != 443) : (port != 80)) && port != 0) -++ [ms appendFormat:@":%i", port]; -++ } -+ } -+ } -+ -+Index: sope-appserver/NGObjWeb/NGObjWeb/WOAdaptor.h -+=================================================================== -+--- sope-appserver/NGObjWeb/NGObjWeb/WOAdaptor.h (revision 1664) -++++ sope-appserver/NGObjWeb/NGObjWeb/WOAdaptor.h (working copy) -+@@ -27,6 +27,13 @@ -+ @class NSString, NSDictionary; -+ @class WOCoreApplication; -+ -++typedef enum { -++ WOChildMessageAccept = 0, -++ WOChildMessageReady, -++ WOChildMessageShutdown, -++ WOChildMessageMax -++} WOChildMessage; -++ -+ @interface WOAdaptor : NSObject -+ { -+ @protected -+Index: sope-appserver/NGObjWeb/NGObjWeb/WOCoreApplication.h -+=================================================================== -+--- sope-appserver/NGObjWeb/NGObjWeb/WOCoreApplication.h (revision 1664) -++++ sope-appserver/NGObjWeb/NGObjWeb/WOCoreApplication.h (working copy) -+@@ -31,6 +31,8 @@ -+ @class WOAdaptor, WORequest, WOResponse, WORequestHandler; -+ @class NSBundle; -+ -++@class NGActiveSocket, NGPassiveSocket; -++ -+ NGObjWeb_EXPORT NSString *WOApplicationWillFinishLaunchingNotification; -+ NGObjWeb_EXPORT NSString *WOApplicationDidFinishLaunchingNotification; -+ NGObjWeb_EXPORT NSString *WOApplicationWillTerminateNotification; -+@@ -41,6 +43,9 @@ -+ NSRecursiveLock *lock; -+ NSLock *requestLock; -+ -++ NGActiveSocket *controlSocket; -++ NGPassiveSocket *listeningSocket; -++ -+ struct { -+ BOOL isTerminating:1; -+ } cappFlags; -+@@ -55,6 +60,14 @@ -+ - (void)activateApplication; -+ - (void)deactivateApplication; -+ -++/* Watchdog helpers */ -++ -++- (void)setControlSocket: (NGActiveSocket *) newSocket; -++- (NGActiveSocket *)controlSocket; -++ -++- (void)setListeningSocket: (NGPassiveSocket *) newSocket; -++- (NGPassiveSocket *)listeningSocket; -++ -+ /* adaptors */ -+ -+ - (NSArray *)adaptors; -+Index: sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpAdaptor.h -+=================================================================== -+--- sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpAdaptor.h (revision 1664) -++++ sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpAdaptor.h (working copy) -+@@ -46,7 +46,6 @@ -+ NSMutableArray *delayedResponses; -+ } -+ -+-+ (BOOL)optionLogStream; -+ + (BOOL)optionLogPerf; -+ -+ @end -+Index: sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m -+=================================================================== -+--- sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m (revision 1664) -++++ sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m (working copy) -+@@ -48,8 +48,8 @@ -+ NSString *WOAsyncResponseReadyNotificationName = -+ @"WOAsyncResponseReadyNotification"; -+ NSString *WOAsyncResponse = @"WOAsyncResponse"; -++static BOOL WOHttpAdaptor_LogStream = NO; -+ -+- -+ @interface WOCoreApplication(SimpleParserSelection) -+ -+ - (BOOL)shouldUseSimpleHTTPParserForTransaction:(id)_tx; -+@@ -85,13 +85,14 @@ -+ ud = [NSUserDefaults standardUserDefaults]; -+ useSimpleParser = [ud boolForKey:@"WOHttpTransactionUseSimpleParser"]; -+ doCore = [[ud objectForKey:@"WOCoreOnHTTPAdaptorException"] boolValue]?1:0; -++ WOHttpAdaptor_LogStream = [ud boolForKey:@"WOHttpAdaptor_LogStream"]; -+ -+ adLogPath = [[ud stringForKey:@"WOAdaptorLogPath"] copy]; -+ if (adLogPath == nil) adLogPath = @""; -+ } -+ -+ - (BOOL)optionLogStream { -+- return [WOHttpAdaptor optionLogStream]; -++ return WOHttpAdaptor_LogStream; -+ } -+ - (BOOL)optionLogPerf { -+ return perfLogger ? YES : NO; -+@@ -108,6 +109,9 @@ -+ NSAssert(_app, @"missing application ..."); -+ self->socket = [_socket retain]; -+ self->application = [_app retain]; -++ if ([[_app recordingPath] length] > 0) -++ WOHttpAdaptor_LogStream = YES; -++ -+ return self; -+ } -+ -+@@ -696,7 +700,7 @@ -+ *(&out) = nil; -+ -+ [self _httpValidateResponse:_response]; -+- -++ -+ out = [(NGCTextStream *)[NGCTextStream alloc] initWithSource:_out]; -+ -+ NS_DURING { -+@@ -705,6 +709,7 @@ -+ id body; -+ BOOL doZip; -+ BOOL isok = YES; -++ int length; -+ -+ doZip = [_response shouldZipResponseToRequest:_request]; -+ -+@@ -738,7 +743,11 @@ -+ -+ /* add content length header */ -+ -+- snprintf((char *)buf, sizeof(buf), "%d", [body length]); -++ if ((length = [body length]) == 0 -++ && ![[_response headerForKey: @"content-type"] hasPrefix:@"text/plain"]) { -++ [_response setHeader:@"text/plain" forKey:@"content-type"]; -++ } -++ snprintf((char *)buf, sizeof(buf), "%d", length); -+ t1 = [[NSString alloc] initWithCString:(char *)buf]; -+ [_response setHeader:t1 forKey:@"content-length"]; -+ [t1 release]; t1 = nil; -+@@ -766,7 +775,7 @@ -+ NSString *value; -+ -+ if (!hasConnectionHeader) { -+- if ([fieldName caseInsensitiveCompare:@"connection"]==NSOrderedSame) -++ if ([fieldName isEqualToString:@"connection"]) -+ hasConnectionHeader = YES; -+ } -+ -+Index: sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpAdaptor.m -+=================================================================== -+--- sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpAdaptor.m (revision 1664) -++++ sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpAdaptor.m (working copy) -+@@ -71,18 +71,13 @@ -+ -+ static NGLogger *logger = nil; -+ static NGLogger *perfLogger = nil; -+-static BOOL WOHttpAdaptor_LogStream = NO; -+ static BOOL WOContactSNS = NO; -+ static BOOL WOCoreOnHTTPAdaptorException = NO; -+ static int WOHttpAdaptorSendTimeout = 10; -+ static int WOHttpAdaptorReceiveTimeout = 10; -+-static int WOHttpAdaptorForkCount = 0; -+ static id allow = nil; -+ static BOOL debugOn = NO; -+ -+-+ (BOOL)optionLogStream { -+- return WOHttpAdaptor_LogStream; -+-} -+ + (BOOL)optionLogPerf { -+ return perfLogger != nil ? YES : NO; -+ } -+@@ -108,8 +103,6 @@ -+ logger = [lm loggerForClass:self]; -+ perfLogger = [lm loggerForDefaultKey:@"WOProfileHttpAdaptor"]; -+ -+- WOHttpAdaptor_LogStream = [ud boolForKey:@"WOHttpAdaptor_LogStream"]; -+- -+ // TODO: this should be queried on demand to allow different defaults -+ WOContactSNS = [[ud objectForKey:@"WOContactSNS"] boolValue]; -+ -+@@ -134,9 +127,6 @@ -+ allow = [allow copy]; -+ } -+ -+- WOHttpAdaptorForkCount = -+- [[ud objectForKey:@"WOHttpAdaptorForkCount"] intValue]; -+- -+ if (WOCoreOnHTTPAdaptorException) -+ [logger warnWithFormat:@"will dump core on HTTP adaptor exception!"]; -+ } -+@@ -219,33 +209,31 @@ -+ application:_application])) { -+ id arg = nil; -+ -+- if ([[_application recordingPath] length] > 0) -+- WOHttpAdaptor_LogStream = YES; -+- -+ [self _registerForSignals]; -++ if (![_application controlSocket]) { -++ if ([_args count] < 1) -++ self->address = [self addressFromDefaultsOfApplication:_application]; -++ else -++ self->address = [self addressFromArguments:_args]; -+ -+- if ([_args count] < 1) -+- self->address = [self addressFromDefaultsOfApplication:_application]; -+- else -+- self->address = [self addressFromArguments:_args]; -++ self->address = [self->address retain]; -+ -+- self->address = [self->address retain]; -++ if (self->address == nil) { -++ [_application errorWithFormat: -++ @"got no address for HTTP server (using arg '%@')", arg]; -++ [self release]; -++ return nil; -++ } -+ -+- if (self->address == nil) { -+- [_application errorWithFormat: -+- @"got no address for HTTP server (using arg '%@')", arg]; -+- [self release]; -+- return nil; -+- } -+- -+- if (!WOContactSNS) { -+- [_application logWithFormat:@"%@ listening on address %@", -++ if (!WOContactSNS) { -++ [_application logWithFormat:@"%@ listening on address %@", -+ NSStringFromClass([self class]), -+ [(id)self->address stringValue]]; -++ } -+ } -+ -+ self->lock = [[NSRecursiveLock alloc] init]; -+- -++ -+ self->maxThreadCount = [[WOCoreApplication workerThreadCount] intValue]; -+ -+ [self setSendTimeout:WOHttpAdaptorSendTimeout]; -+@@ -270,145 +258,76 @@ -+ return self->address; -+ } -+ -+-/* forking */ -+- -+-static pid_t *childPIDs = NULL; -+-static BOOL isForkMaster = YES; -+- -+-- (void)forkChildren { -+- unsigned i; -+- -+- if (WOHttpAdaptorForkCount == 0) -+- return; -+- -+- [self logWithFormat:@"Note: forking %d children for socket processing.", -+- WOHttpAdaptorForkCount]; -+- -+-#if !defined(__MINGW32__) -+- [[UnixSignalHandler sharedHandler] -+- addObserver:self selector:@selector(handleSIGCHLD:) -+- forSignal:SIGCHLD immediatelyNotifyOnSignal:NO]; -+-#endif -+- -+- childPIDs = calloc(WOHttpAdaptorForkCount + 1, sizeof(pid_t)); -+- for (i = 0; i < WOHttpAdaptorForkCount; i++) { -+- childPIDs[i] = fork(); -+- -+- if (childPIDs[i] == 0) { -+- /* child */ -+- isForkMaster = NO; -+- return; -+- } -+- else if (childPIDs[i] > 0) -+- printf("Note: successfully forked child: %i\n", childPIDs[i]); -+- else -+- [self errorWithFormat:@"failed to fork child %i.", i]; -+- } -+-} -+-- (void)killChildren { -+- int i; -+- -+- if (!isForkMaster) -+- return; -+- -+- for (i = 0; i < WOHttpAdaptorForkCount; i++) { -+- if (childPIDs[i] != 0) -+- kill(childPIDs[i], SIGKILL); -+- } -+-} -+- -+-- (void)checkStatusOfChildren { -+- /* -+- Note: currently this does not refork crashed processes. Reforking is harder -+- than it may sound because the crash can happen at arbitary execution -+- states. -+- That is, the "master process" is not virgin anymore, eg it might have -+- open database connections. -+- -+- So the solution might be to refork the whole cluster once a minimum -+- backend threshold is reached. -+- */ -+- unsigned int i; -+- -+- if (!isForkMaster) -+- return; -+- -+- for (i = 0; i < WOHttpAdaptorForkCount; i++) { -+- pid_t result; -+- int status; -+- -+- if (childPIDs[i] == 0) -+- continue; -+- -+- result = waitpid(childPIDs[i], &status, WNOHANG); -+- if (result == 0) /* did not exit yet */ -+- continue; -+- -+- if (result == -1) { /* error */ -+- [self errorWithFormat:@"failed to get status of child %i: %s", -+- childPIDs[i], strerror(errno)]; -+- continue; -+- } -+- -+- [self logWithFormat:@"Note: child %i terminated.", childPIDs[i]]; -+- childPIDs[i] = 0; -+- } -+-} -+- -+ /* events */ -+ -+ - (void)handleSIGPIPE:(int)_signal { -+ [self warnWithFormat:@"caught SIGPIPE !"]; -+ } -+-- (void)handleSIGCHLD:(int)_signal { -+- [self checkStatusOfChildren]; -+-} -+ -+ - (void)registerForEvents { -+ int backlog; -++ NGActiveSocket *controlSocket; -++ WOChildMessage message; -++ -++ controlSocket = [[WOCoreApplication application] controlSocket]; -++ if (controlSocket) { -++ ASSIGN(self->socket, [[WOCoreApplication application] listeningSocket]); -++ [[NSNotificationCenter defaultCenter] -++ addObserver:self -++ selector:@selector(acceptControlMessage:) -++ name:NSFileObjectBecameActiveNotificationName -++ object:nil]; -++ [(WORunLoop *)[WORunLoop currentRunLoop] -++ addFileObject:controlSocket -++ activities:NSPosixReadableActivity -++ forMode:NSDefaultRunLoopMode]; -++ message = WOChildMessageReady; -++ [controlSocket safeWriteBytes: &message -++ count: sizeof (WOChildMessage)]; -++ // [self logWithFormat: @"notified the watchdog that we are ready"]; -++ } -++ else { -++ backlog = [[WOCoreApplication listenQueueSize] intValue]; -+ -+- backlog = [[WOCoreApplication listenQueueSize] intValue]; -++ if (backlog == 0) -++ backlog = 5; -+ -+- if (backlog == 0) -+- backlog = 5; -++ [self->socket release]; self->socket = nil; -+ -+- [self->socket release]; self->socket = nil; -++ self->socket = -++ [[NGPassiveSocket alloc] initWithDomain:[self->address domain]]; -+ -+- self->socket = -+- [[NGPassiveSocket alloc] initWithDomain:[self->address domain]]; -++ [self->socket bindToAddress:self->address]; -+ -+- [self->socket bindToAddress:self->address]; -+- -+- if ([[self->address domain] isEqual:[NGInternetSocketDomain domain]]) { -+- if ([(NGInternetSocketAddress *)self->address port] == 0) { -+- /* let the kernel choose an IP address */ -++ if ([[self->address domain] isEqual:[NGInternetSocketDomain domain]]) { -++ if ([(NGInternetSocketAddress *)self->address port] == 0) { -++ /* let the kernel choose an IP address */ -+ -+- [self debugWithFormat:@"bound to wildcard: %@", self->address]; -+- [self debugWithFormat:@"got local: %@", [self->socket localAddress]]; -++ [self debugWithFormat:@"bound to wildcard: %@", self->address]; -++ [self debugWithFormat:@"got local: %@", [self->socket localAddress]]; -+ -+- self->address = [[self->socket localAddress] retain]; -++ self->address = [[self->socket localAddress] retain]; -+ -+- [self logWithFormat:@"bound to kernel assigned address %@: %@", -++ [self logWithFormat:@"bound to kernel assigned address %@: %@", -+ self->address, self->socket]; -++ } -+ } -+- } -+ -+- [self->socket listenWithBacklog:backlog]; -++ [self->socket listenWithBacklog:backlog]; -+ -+- [[NSNotificationCenter defaultCenter] -++ [[NSNotificationCenter defaultCenter] -+ addObserver:self selector:@selector(acceptConnection:) -+- name:NSFileObjectBecameActiveNotificationName -+- object:self->socket]; -+- [(WORunLoop *)[WORunLoop currentRunLoop] -++ name:NSFileObjectBecameActiveNotificationName -++ object:self->socket]; -++ -++ [(WORunLoop *)[WORunLoop currentRunLoop] -+ addFileObject:self->socket -+ activities:NSPosixReadableActivity -+ forMode:NSDefaultRunLoopMode]; -+- -+- [self forkChildren]; -++ } -+ } -++ -+ - (void)unregisterForEvents { -+- [self killChildren]; -+- -+ [(WORunLoop *)[WORunLoop currentRunLoop] -+ removeFileObject:self->socket forMode:NSDefaultRunLoopMode]; -+ [[NSNotificationCenter defaultCenter] removeObserver:self]; -+@@ -603,52 +522,91 @@ -+ return _connection; -+ } -+ -++- (NGActiveSocket *)_accept { -++ NGActiveSocket *connection; -++ -++ NS_DURING { -++ connection = [self->socket accept]; -++ if (!connection) -++ [self _serverCatched:[self->socket lastException]]; -++ else -++ [self debugWithFormat:@"accepted connection: %@", connection]; -++ } -++ NS_HANDLER { -++ connection = nil; -++ [self _serverCatched:localException]; -++ } -++ NS_ENDHANDLER; -++ -++ return connection; -++} -++ -++- (void)_handleConnection:(NGActiveSocket *)connection { -++ if (connection != nil) { -++ if (self->maxThreadCount <= 1) { -++ NS_DURING -++ [self _handleAcceptedConnection:[connection retain]]; -++ NS_HANDLER -++ [self _serverCatched:localException]; -++ NS_ENDHANDLER; -++ } -++ else { -++ [NSThread detachNewThreadSelector: -++ @selector(_handleAcceptedConnectionInThread:) -++ toTarget:self -++ withObject:[connection retain]]; -++ [self logWithFormat:@"detached new thread for request."]; -++ //[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]]; -++ } -++ connection = nil; -++ } -++} -++ -++- (void) acceptControlMessage: (NSNotification *) aNotification -++{ -++ NGActiveSocket *controlSocket, *connection; -++ WOChildMessage message; -++ NSAutoreleasePool *pool; -++ -++ // NSLog (@"received control message"); -++ controlSocket = [aNotification object]; -++ // [self logWithFormat:@"child accepting message from socket: %@", controlSocket]; -++ while (![controlSocket safeReadBytes: &message -++ count: sizeof (WOChildMessage)]) -++ NSLog (@"renotifying watchdog"); -++ if (message == WOChildMessageAccept) { -++ pool = [NSAutoreleasePool new]; -++ connection = [self _accept]; -++ if ([controlSocket safeWriteBytes: &message -++ count: sizeof (WOChildMessage)]) -++ ; -++ [self _handleConnection: connection]; -++ message = WOChildMessageReady; -++ [controlSocket safeWriteBytes: &message count: sizeof (WOChildMessage)]; -++ [pool release]; -++ } -++ else if (message == WOChildMessageShutdown) { -++ [controlSocket safeWriteBytes: &message -++ count: sizeof (WOChildMessage)]; -++ [[WOCoreApplication application] terminate]; -++ } -++} -++ -+ - (void)acceptConnection:(id)_notification { -++ NGActiveSocket *connection; -+ #if USE_POOLS -+ NSAutoreleasePool *pool; -+- *(&pool) = [[NSAutoreleasePool alloc] init]; -++ -++ pool = [[NSAutoreleasePool alloc] init]; -+ #endif -+ { -+- NGActiveSocket *connection; -+- -+- NS_DURING { -+- *(&connection) = (NGActiveSocket *)[self->socket accept]; -+- if (connection == nil) -+- [self _serverCatched:[self->socket lastException]]; -+- else -+- [self debugWithFormat:@"accepted connection: %@", connection]; -+- } -+- NS_HANDLER { -+- connection = nil; -+- [self _serverCatched:localException]; -+- } -+- NS_ENDHANDLER; -+- -+- connection = (NGActiveSocket *)[self _checkAccessOnConnection:connection]; -+- -+- if (connection != nil) { -+- if (self->maxThreadCount <= 1) { -+- NS_DURING -+- [self _handleAcceptedConnection:[connection retain]]; -+- NS_HANDLER -+- [self _serverCatched:localException]; -+- NS_ENDHANDLER; -+- } -+- else { -+- [NSThread detachNewThreadSelector: -+- @selector(_handleAcceptedConnectionInThread:) -+- toTarget:self -+- withObject:[connection retain]]; -+- [self logWithFormat:@"detached new thread for request."]; -+- //[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]]; -+- } -+- connection = nil; -+- } -++ connection = [self _checkAccessOnConnection:[self _accept]]; -++ [self _handleConnection: connection]; -+ } -+ #if USE_POOLS -+ [pool release]; pool = nil; -+ #endif -+- -++ -+ if (self->isTerminated) { -+ if (self->socket) { -+ [[NSNotificationCenter defaultCenter] -+Index: sope-appserver/NGObjWeb/WOCoreApplication.m -+=================================================================== -+--- sope-appserver/NGObjWeb/WOCoreApplication.m (revision 1664) -++++ sope-appserver/NGObjWeb/WOCoreApplication.m (working copy) -+@@ -75,6 +75,43 @@ -+ NGObjWeb_DECLARE id WOApp = nil; -+ static NSMutableArray *activeApps = nil; // THREAD -+ -+++ (void)registerUserDefaults { -++ NSDictionary *owDefaults = nil; -++ NSString *apath; -++ -++ apath = [[self class] findNGObjWebResource:@"Defaults" ofType:@"plist"]; -++ if (apath == nil) -++ [self errorWithFormat:@"Cannot find Defaults.plist resource of " -++ @"NGObjWeb library!"]; -++#if HEAVY_DEBUG -++ else -++ [self debugWithFormat:@"Note: loading default defaults: %@", apath]; -++#endif -++ -++ owDefaults = [NSDictionary dictionaryWithContentsOfFile:apath]; -++ if (owDefaults) { -++ [[NSUserDefaults standardUserDefaults] registerDefaults:owDefaults]; -++#if HEAVY_DEBUG -++ [self debugWithFormat:@"did register NGObjWeb defaults: %@\n%@", -++ apath, owDefaults]; -++#endif -++ } -++ else { -++ [self errorWithFormat:@"could not load NGObjWeb defaults: '%@'", -++ apath]; -++ } -++} -++ -+++ (void)initialize -++{ -++ static BOOL initialized = NO; -++ -++ if (!initialized) { -++ [self registerUserDefaults]; -++ initialized = YES; -++ } -++} -++ -+ + (id)application { -+ if (WOApp == nil) { -+ [self warnWithFormat:@"%s: some code called +application without an " -+@@ -115,33 +152,6 @@ -+ } -+ } -+ -+-- (void)registerUserDefaults { -+- NSDictionary *owDefaults = nil; -+- NSString *apath; -+- -+- apath = [[self class] findNGObjWebResource:@"Defaults" ofType:@"plist"]; -+- if (apath == nil) -+- [self errorWithFormat:@"Cannot find Defaults.plist resource of " -+- @"NGObjWeb library!"]; -+-#if HEAVY_DEBUG -+- else -+- [self debugWithFormat:@"Note: loading default defaults: %@", apath]; -+-#endif -+- -+- owDefaults = [NSDictionary dictionaryWithContentsOfFile:apath]; -+- if (owDefaults) { -+- [[NSUserDefaults standardUserDefaults] registerDefaults:owDefaults]; -+-#if HEAVY_DEBUG -+- [self debugWithFormat:@"did register NGObjWeb defaults: %@\n%@", -+- apath, owDefaults]; -+-#endif -+- } -+- else { -+- [self errorWithFormat:@"could not load NGObjWeb defaults: '%@'", -+- apath]; -+- } -+-} -+- -+ - (id)init { -+ #if COCOA_Foundation_LIBRARY -+ /* -+@@ -157,7 +167,6 @@ -+ NSUserDefaults *ud; -+ NGLoggerManager *lm; -+ -+- [self registerUserDefaults]; -+ ud = [NSUserDefaults standardUserDefaults]; -+ lm = [NGLoggerManager defaultLoggerManager]; -+ logger = [lm loggerForClass:[self class]]; -+@@ -190,6 +199,9 @@ -+ forSignal:SIGHUP immediatelyNotifyOnSignal:NO]; -+ } -+ #endif -++ -++ controlSocket = nil; -++ listeningSocket = nil; -+ } -+ return self; -+ } -+@@ -202,9 +214,32 @@ -+ [self->adaptors release]; -+ [self->requestLock release]; -+ [self->lock release]; -++ [self->listeningSocket release]; -++ [self->controlSocket release]; -+ [super dealloc]; -+ } -+ -++/* Watchdog helpers */ -++- (void)setControlSocket: (NGActiveSocket *) newSocket -++{ -++ ASSIGN(self->controlSocket, newSocket); -++} -++ -++- (NGActiveSocket *)controlSocket -++{ -++ return self->controlSocket; -++} -++ -++- (void)setListeningSocket: (NGPassiveSocket *) newSocket -++{ -++ ASSIGN(self->listeningSocket, newSocket); -++} -++ -++- (NGPassiveSocket *)listeningSocket -++{ -++ return self->listeningSocket; -++} -++ -+ /* NGLogging */ -+ -+ + (id)logger { -+@@ -225,6 +260,7 @@ -+ /* STDIO is forbidden in signal handlers !!! no malloc !!! */ -+ #if 1 -+ self->cappFlags.isTerminating = 1; -++ [self->listeningSocket close]; -+ #else -+ static int termCount = 0; -+ unsigned pid; -+@@ -786,7 +822,9 @@ -+ id woport; -+ id addr; -+ -+- woport = [[self userDefaults] objectForKey:@"WOPort"]; -++ woport = [[self userDefaults] objectForKey:@"p"]; -++ if (!woport) -++ woport = [[self userDefaults] objectForKey:@"WOPort"]; -+ if ([woport isKindOfClass:[NSNumber class]]) -+ return woport; -+ woport = [woport stringValue]; ---- sope-4.9.r1664.orig/debian/patches/sope-gsmake2.diff -+++ sope-4.9.r1664/debian/patches/sope-gsmake2.diff -@@ -0,0 +1,3144 @@ -+Index: configure -+=================================================================== -+--- configure (révision 1632) -++++ configure (copie de travail) -+@@ -15,8 +15,9 @@ -+ ARG_NOCREATE=0 -+ ARG_PREFIX="" -+ ARG_FRAMEWORK_DIR="" -+-ARG_GSMAKE="$GNUSTEP_MAKEFILES" -++ARG_GSMAKE=`gnustep-config --variable=GNUSTEP_MAKEFILES` -+ ARG_CFGMAKE="$PWD/config.make" -++ARG_FHSMAKE="$PWD/fhs-postinstall.make" -+ ARG_WITH_GNUSTEP=0 -+ ARG_WITH_DEBUG=1 -+ ARG_WITH_STRIP=1 -+@@ -30,12 +31,20 @@ -+ INTERNAL_MAKEDIR="${SOPE_SRCDIR}/.gsmake" -+ USES_INTERNAL_MAKE=no -+ -++# detect GNU make, needed at least on *BSD -++make -v 2>/dev/null | grep GNU >/dev/null 2>/dev/null -++if [ $? -eq 0 ];then -++ MAKE=make -++else -++ MAKE=gmake -++fi -++ -+ # TODO: add pg_config, mysql_config etc! -+ LINK_SYSLIBDIRS="-L/usr/local/pgsql/lib -L/usr/local/lib -L/usr/lib" -+ -+ # ******************** usage ******************** -+ -+-function usage() { -++usage() { -+ cat <<_ACEOF -+ \`configure' configures a GNUstep-make based sourcetree for installation. -+ -+@@ -66,7 +75,7 @@ -+ -+ # ******************** running ******************** -+ -+-function printParas() { -++printParas() { -+ echo "Configuration:" -+ if test $ARG_BEQUIET = 1; then echo " will be quite."; fi -+ if test $ARG_NOCREATE = 1; then echo " won't create files"; fi -+@@ -97,7 +106,7 @@ -+ echo "" -+ } -+ -+-function warnOnFHSPrefix() { -++warnOnFHSPrefix() { -+ cat <<_ACEOFWARN -+ Warning: you are configuring for a non standard FHS style prefix. -+ prefix: $ARG_PREFIX -+@@ -114,7 +123,7 @@ -+ _ACEOFWARN -+ } -+ -+-function setupInternalGSMake() { -++setupInternalGSMake() { -+ if test -f ${INTERNAL_MAKEDIR}/Library/Makefiles/GNUstep.sh; then -+ ARG_GSMAKE="${INTERNAL_MAKEDIR}/Library/Makefiles/" -+ ARG_IS_FHS=1 -+@@ -149,7 +158,7 @@ -+ --with-library-combo="${SETUP_COMBO}" -+ -+ echo -n ".. install .." -+- make install >>${pregsmdir}/${SETUP_LOGNAME} -++ $MAKE install >>${pregsmdir}/${SETUP_LOGNAME} -+ -+ ARG_GSMAKE="${INTERNAL_MAKEDIR}/Library/Makefiles/" -+ ARG_IS_FHS=1 -+@@ -174,7 +183,7 @@ -+ fi -+ } -+ -+-function validateGNUstepArgs() { -++validateGNUstepArgs() { -+ # GNUstep make -+ if test "x$ARG_GSMAKE" = "x"; then -+ if test -f $HOME/OGoRoot/Library/Makefiles/GNUstep.sh; then -+@@ -203,7 +212,7 @@ -+ fi -+ } -+ -+-function setupAppleArgs() { -++setupAppleArgs() { -+ ARG_WITH_STRIP=0 -+ if test "x${USES_INTERNAL_MAKE}" = "no"; then -+ ARG_WITH_GNUSTEP=1 -+@@ -218,7 +227,7 @@ -+ #fi -+ } -+ -+-function validateArgs() { -++validateArgs() { -+ # validate prefix (could be better?) -+ case "x$ARG_PREFIX" in -+ "x/usr/local"|"x/usr/local/") -+@@ -273,7 +282,7 @@ -+ fi -+ } -+ -+-function printGNUstepSetup() { -++printGNUstepSetup() { -+ echo "GNUstep environment:" -+ echo " system: ${GNUSTEP_SYSTEM_ROOT}" -+ echo " local: ${GNUSTEP_LOCAL_ROOT}" -+@@ -285,11 +294,11 @@ -+ echo "" -+ } -+ -+-function cfgwrite() { -++cfgwrite() { -+ echo "$1" >> $ARG_CFGMAKE -+ } -+ -+-function genConfigMake() { -++genConfigMake() { -+ # we ignore the following vars also patches by gstep-make: -+ # PATH -+ # DYLD_LIBRARY_PATH -+@@ -303,6 +312,8 @@ -+ echo "# GNUstep environment configuration" > $ARG_CFGMAKE -+ cfgwrite "# created by: '$CFG_ARGS'" -+ cfgwrite "" -++ cfgwrite "SOPE_ROOT=`pwd`" -++ cfgwrite "include \${SOPE_ROOT}/Version" -+ -+ cfgwrite "# Note: you can override any option as a 'make' parameter, eg:" -+ cfgwrite "# make debug=yes" -+@@ -313,7 +324,27 @@ -+ #cfgwrite " @echo Local GNUstep config.make is active" -+ #cfgwrite "" -+ -+- # TODO: should be also write a GNUSTEP_INSTALLATION_DIR / BUNDLE_INSTALL_DIR? -++ # Note: GNUSTEP_TARGET_CPU is not yet available (set by common.make), so we -++ # only have environment variables -++ # Note: we can't set SYSTEM_LIB_DIR in this location, it gets overridden by -++ # common.make -++ UNAME=`uname` -++ if [ "X${UNAME}" = "XLinux" ];then -++ UNAME=`uname -p` -++ if [ ${UNAME} = x86_64 -o ${UNAME} = sparc64 -o ${UNAME} = ppc64 ];then -++ cfgwrite "CGS_LIBDIR_NAME:=lib64" -++ else -++ cfgwrite "CGS_LIBDIR_NAME:=lib" -++ fi -++ else -++ cfgwrite "CGS_LIBDIR_NAME:=lib" -++ fi -++ cfgwrite "ifneq (\$(FHS_INSTALL_ROOT),)" -++ cfgwrite "CONFIGURE_FHS_INSTALL_LIBDIR:=\$(FHS_INSTALL_ROOT)/\$(CGS_LIBDIR_NAME)/" -++ cfgwrite "CONFIGURE_SYSTEM_LIB_DIR += -L\$(CONFIGURE_FHS_INSTALL_LIBDIR)" -++ cfgwrite "endif" -++ cfgwrite "GNUSTEP_INSTALLATION_DOMAIN:=LOCAL" -++ cfgwrite "CONFIGURE_SYSTEM_LIB_DIR += -L/usr/\$(CGS_LIBDIR_NAME)/" -+ -+ -+ if test "x$ARG_FRAMEWORK_DIR" != "x"; then -+@@ -325,13 +356,38 @@ -+ cfgwrite "# configured for FHS install" -+ cfgwrite "FHS_INSTALL_ROOT:=$ARG_PREFIX" -+ cfgwrite "" -++ cfgwrite "SOPE_SYSLIBDIR=\${DESTDIR}\${FHS_INSTALL_ROOT}/\$(CGS_LIBDIR_NAME)" -++ cfgwrite "SOPE_LIBDIR=\${SOPE_SYSLIBDIR}/sope-\${MAJOR_VERSION}.\${MINOR_VERSION}" -++ cfgwrite "SOPE_SYSSHAREDIR=\${DESTDIR}\${FHS_INSTALL_ROOT}/share" -++ cfgwrite "SOPE_SHAREDIR=\${SOPE_SYSSHAREDIR}/sope-\${MAJOR_VERSION}.\${MINOR_VERSION}" -++ cfgwrite "SOPE_DBADAPTORS=\${SOPE_LIBDIR}/dbadaptors" -++ cfgwrite "SOPE_PRODUCTS=\${SOPE_LIBDIR}/products" -++ cfgwrite "SOPE_SAXDRIVERS=\${SOPE_LIBDIR}/saxdrivers" -++ cfgwrite "SOPE_WOXBUILDERS=\${SOPE_LIBDIR}/wox-builders" -++ cfgwrite "SOPE_NGOBJWEB=\${SOPE_SHAREDIR}/ngobjweb" -++ cfgwrite "SOPE_SAXMAPPINGS=\${SOPE_SHAREDIR}/saxmappings" -++ cfgwrite "SOPE_TOOLS=\${DESTDIR}\${FHS_INSTALL_ROOT}/bin" -++ cfgwrite "SOPE_ADMIN_TOOLS=\${DESTDIR}\${FHS_INSTALL_ROOT}/sbin" -++ cfgwrite "" -+ else -+ cfgwrite "# configured for GNUstep install" -++ cfgwrite "" -++ cfgwrite "SOPE_SYSLIBDIR=\${GNUSTEP_LIBRARIES}" -++ cfgwrite "SOPE_LIBDIR=\${GNUSTEP_LIBRARY}" -++ cfgwrite "SOPE_DBADAPTORS=\${SOPE_LIBDIR}/GDLAdaptors-\${MAJOR_VERSION}.\${MINOR_VERSION}" -++ cfgwrite "SOPE_PRODUCTS=\${SOPE_LIBDIR}/SoProducts-\${MAJOR_VERSION}.\${MINOR_VERSION}" -++ cfgwrite "SOPE_SAXDRIVERS=\${SOPE_LIBDIR}/SaxDrivers-\${MAJOR_VERSION}.\${MINOR_VERSION}" -++ cfgwrite "SOPE_NGOBJWEB=\${GNUSTEP_RESOURCES}/NGObjWeb" -++ cfgwrite "SOPE_WOXBUILDERS=\${GNUSTEP_LIBRARY}/WOxElemBuilders-\${MAJOR_VERSION}.\${MINOR_VERSION}" -++ cfgwrite "SOPE_SAXMAPPINGS=\${GNUSTEP_LIBRARY}/SaxMappings" -++ cfgwrite "SOPE_TOOLS=\${GNUSTEP_TOOLS}" -++ cfgwrite "SOPE_ADMIN_TOOLS=\${GNUSTEP_ADMIN_TOOLS}" -+ fi -+ -+ if test $ARG_WITH_DEBUG = 1; then -+ cfgwrite "# configured to produce debugging code"; -+ cfgwrite "debug:=yes" -++ -+ else -+ cfgwrite "# configured to produce non-debugging code"; -+ cfgwrite "debug:=no" -+@@ -358,29 +414,9 @@ -+ done -+ cfgwrite "LIBRARY_COMBO=$LIBRARY_COMBO" -+ cfgwrite "" -+- -+- # Note: GNUSTEP_TARGET_CPU is not yet available (set by common.make), so we -+- # only have environment variables -+- # Note: we can't set SYSTEM_LIB_DIR in this location, it gets overridden by -+- # common.make -+- cfgwrite "ifeq (\$(findstring _64, \$(GNUSTEP_HOST_CPU)), _64)" -+- cfgwrite "CONFIGURE_64BIT:=yes" -+- cfgwrite "CGS_LIBDIR_NAME:=lib64" -+- cfgwrite "else" -+- cfgwrite "CGS_LIBDIR_NAME:=lib" -+- cfgwrite "endif" -+- -+- cfgwrite "ifneq (\$(FHS_INSTALL_ROOT),)" -+- cfgwrite "CONFIGURE_FHS_INSTALL_LIBDIR:=\$(FHS_INSTALL_ROOT)/\$(CGS_LIBDIR_NAME)/" -+- cfgwrite "CONFIGURE_SYSTEM_LIB_DIR += -L\$(CONFIGURE_FHS_INSTALL_LIBDIR)" -+- cfgwrite "endif" -+- cfgwrite "CONFIGURE_SYSTEM_LIB_DIR += -L/usr/\$(CGS_LIBDIR_NAME)/" -+- -+- cfgwrite "# avoid a gstep-make warning" -+- cfgwrite "PATH:=\$(GNUSTEP_SYSTEM_ROOT)/Tools:\$(PATH)" -+ } -+ -+-function checkLinking() { -++checkLinking() { -+ # library-name => $1, type => $2 -+ local oldpwd=$PWD -+ local tmpdir=".configure-test-$$" -+@@ -388,18 +424,26 @@ -+ mkdir $tmpdir -+ cd $tmpdir -+ cp ../maintenance/dummytool.c . -++ -++ for LIB in $1;do -++ LIBS="$LIBS -l${LIB}" -++ done -+ -+ tmpmake="GNUmakefile" -+- echo >$tmpmake "include ../config.make" -++ echo >$tmpmake "-include ../config.make" -+ echo >>$tmpmake "include \$(GNUSTEP_MAKEFILES)/common.make" -+ echo >>$tmpmake "CTOOL_NAME := linktest" -+ echo >>$tmpmake "linktest_C_FILES := dummytool.c" -+- echo >>$tmpmake "linktest_TOOL_LIBS += -l$1" -++ echo >>$tmpmake "ifeq (\$(findstring openbsd, \$(GNUSTEP_HOST_OS)), openbsd)" -++ echo >>$tmpmake "linktest_TOOL_LIBS += $LIBS -liconv" -++ echo >>$tmpmake "else" -++ echo >>$tmpmake "linktest_TOOL_LIBS += $LIBS" -++ echo >>$tmpmake "endif" -+ echo >>$tmpmake "SYSTEM_LIB_DIR += \$(CONFIGURE_SYSTEM_LIB_DIR)" -+ echo >>$tmpmake "SYSTEM_LIB_DIR += ${LINK_SYSLIBDIRS}" -+ echo >>$tmpmake "include \$(GNUSTEP_MAKEFILES)/ctool.make" -+ -+- make -s messages=yes -f $tmpmake linktest >out.log 2>err.log -++ $MAKE -s messages=yes -f $tmpmake linktest >out.log 2>err.log -+ LINK_RESULT=$? -+ -+ if test $LINK_RESULT = 0; then -+@@ -420,18 +464,22 @@ -+ rm -rf $tmpdir -+ } -+ -+-function checkDependencies() { -++checkDependencies() { -+ cfgwrite "" -+ cfgwrite "# library dependencies" -+ checkLinking "xml2" optional; -+ checkLinking "ldap" optional; -+- checkLinking "ssl" required; # TODO: make optional -++ if [ `uname` = "OpenBSD" ];then -++ checkLinking "ssl crypto" required; # TODO: make optional -++ else -++ checkLinking "ssl" required; # TODO: make optional -++ fi -+ checkLinking "pq" optional; -+ checkLinking "sqlite3" optional; -+ checkLinking "mysqlclient" optional; -+ } -+ -+-function runIt() { -++runIt() { -+ if test $ARG_BEQUIET != 1; then -+ printParas; -+ fi -+@@ -459,11 +507,11 @@ -+ -+ # ******************** options ******************** -+ -+-function extractFuncValue() { -++extractFuncValue() { -+ VALUE="`echo "$1" | sed "s/[^=]*=//g"`" -+ } -+ -+-function processOption() { -++processOption() { -+ case "x$1" in -+ "x--help"|"x-h") -+ usage; -+@@ -518,7 +566,7 @@ -+ # load GNUstep environment -+ validateGNUstepArgs -+ # first we load the GNUstep.sh environment -+-source $DARG_GNUSTEP_SH -++. $DARG_GNUSTEP_SH -+ if test $ARG_BEQUIET != 1; then -+ printGNUstepSetup; -+ fi -+Index: sope-ldap/samples/GNUmakefile -+=================================================================== -+--- sope-ldap/samples/GNUmakefile (révision 1632) -++++ sope-ldap/samples/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ TOOL_NAME = \ -+@@ -9,8 +9,11 @@ -+ ldapchkpwd \ -+ -+ ldapls_OBJC_FILES = ldapls.m -++ldapls_INSTALL_DIR = $(SOPE_TOOLS)/ -+ ldap2dsml_OBJC_FILES = ldap2dsml.m -++ldap2dsml_INSTALL_DIR = $(SOPE_TOOLS)/ -+ ldapchkpwd_OBJC_FILES = ldapchkpwd.m -++ldapchkpwd_INSTALL_DIR = $(SOPE_TOOLS)/ -+ -+ #TOOL_NAME = #pwd-check -+ #pwd-check_OBJC_FILES = pwd-check.m -+@@ -19,4 +22,3 @@ -+ -include GNUmakefile.preamble -+ include $(GNUSTEP_MAKEFILES)/tool.make -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-ldap/NGLdap/GNUmakefile -+=================================================================== -+--- sope-ldap/NGLdap/GNUmakefile (révision 1632) -++++ sope-ldap/NGLdap/GNUmakefile (copie de travail) -+@@ -1,11 +1,9 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ./Version -+ -+-GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -+- -+ ifneq ($(frameworks),yes) -+ LIBRARY_NAME = libNGLdap -+ else -+@@ -15,7 +13,8 @@ -+ libNGLdap_PCH_FILE = common.h -+ libNGLdap_HEADER_FILES_DIR = . -+ libNGLdap_HEADER_FILES_INSTALL_DIR = /NGLdap -+-libNGLdap_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libNGLdap_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libNGLdap_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libNGLdap_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ libNGLdap_HEADER_FILES = \ -+@@ -61,10 +60,12 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ else -+ include $(GNUSTEP_MAKEFILES)/framework.make -+ endif -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-ldap/GNUmakefile -+=================================================================== -+--- sope-ldap/GNUmakefile (révision 1632) -++++ sope-ldap/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../config.make -++include ../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ PACKAGE_NAME=sope-ldap -+Index: GNUmakefile -+=================================================================== -+--- GNUmakefile (révision 1632) -++++ GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ./config.make -++include ./config.make -+ -+ ifeq ($(GNUSTEP_MAKEFILES),) -+ -+@@ -35,8 +35,6 @@ -+ include $(GNUSTEP_MAKEFILES)/aggregate.make -+ -include $(GNUSTEP_MAKEFILES)/GNUmakefile.postamble -+ -+-include ./Version -+- -+ endif -+ -+ distclean :: -+Index: sope-gdl1/PostgreSQL/GNUmakefile.preamble -+=================================================================== -+--- sope-gdl1/PostgreSQL/GNUmakefile.preamble (révision 1632) -++++ sope-gdl1/PostgreSQL/GNUmakefile.preamble (copie de travail) -+@@ -27,7 +27,7 @@ -+ ifeq ($(frameworks),yes) -+ BUNDLE_INSTALL_DIR := $(FRAMEWORK_INSTALL_DIR)/GDLAccess.framework/Resources/GDLAdaptors/ -+ else -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/GDLAdaptors-$(MAJOR_VERSION).$(MINOR_VERSION)/ -++BUNDLE_INSTALL_DIR = $(SOPE_DBADAPTORS)/ -+ endif -+ -+ -+Index: sope-gdl1/PostgreSQL/GNUmakefile -+=================================================================== -+--- sope-gdl1/PostgreSQL/GNUmakefile (révision 1632) -++++ sope-gdl1/PostgreSQL/GNUmakefile (copie de travail) -+@@ -22,7 +22,7 @@ -+ # If not, write to the Free Software Foundation, -+ # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ include ./Version -+@@ -70,4 +70,3 @@ -+ include $(GNUSTEP_MAKEFILES)/bundle.make -+ #include $(GNUSTEP_MAKEFILES)/tool.make -+ -include GNUmakefile.postamble -+-include fhs.make -+Index: sope-gdl1/SQLite3/GNUmakefile.preamble -+=================================================================== -+--- sope-gdl1/SQLite3/GNUmakefile.preamble (révision 1632) -++++ sope-gdl1/SQLite3/GNUmakefile.preamble (copie de travail) -+@@ -27,7 +27,7 @@ -+ ifeq ($(frameworks),yes) -+ BUNDLE_INSTALL_DIR := $(FRAMEWORK_INSTALL_DIR)/GDLAccess.framework/Resources/GDLAdaptors/ -+ else -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/GDLAdaptors-$(MAJOR_VERSION).$(MINOR_VERSION)/ -++BUNDLE_INSTALL_DIR = $(SOPE_DBADAPTORS)/ -+ endif -+ -+ -+Index: sope-gdl1/SQLite3/GNUmakefile -+=================================================================== -+--- sope-gdl1/SQLite3/GNUmakefile (révision 1632) -++++ sope-gdl1/SQLite3/GNUmakefile (copie de travail) -+@@ -22,7 +22,7 @@ -+ # If not, write to the Free Software Foundation, -+ # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ include ./Version -+@@ -67,4 +67,3 @@ -+ include $(GNUSTEP_MAKEFILES)/tool.make -+ endif -+ -include GNUmakefile.postamble -+-include fhs.make -+Index: sope-gdl1/FrontBase2/GNUmakefile -+=================================================================== -+--- sope-gdl1/FrontBase2/GNUmakefile (révision 1632) -++++ sope-gdl1/FrontBase2/GNUmakefile (copie de travail) -+@@ -22,7 +22,7 @@ -+ # If not, write to the Free Software Foundation, -+ # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ CAN_COMPILE_FB = \ -+@@ -30,8 +30,6 @@ -+ -+ ifeq ($(CAN_COMPILE_FB),yes) -+ -+-GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -+- -+ BUNDLE_NAME = FrontBase2 -+ -+ FrontBase2_OBJC_FILES = \ -+@@ -51,7 +49,7 @@ -+ FrontBase2_RESOURCE_FILES = Info.plist Version -+ -+ BUNDLE_INSTALL = FrontBase2 -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_SYSTEM_ROOT)/Libraries/Adaptors -++BUNDLE_INSTALL_DIR = $(SOPE_DBADAPTORS)/ -+ -+ # Use .gdladaptor as the bundle extension -+ BUNDLE_EXTENSION = .gdladaptor -+Index: sope-gdl1/MySQL/GNUmakefile.preamble -+=================================================================== -+--- sope-gdl1/MySQL/GNUmakefile.preamble (révision 1632) -++++ sope-gdl1/MySQL/GNUmakefile.preamble (copie de travail) -+@@ -27,7 +27,7 @@ -+ ifeq ($(frameworks),yes) -+ BUNDLE_INSTALL_DIR := $(FRAMEWORK_INSTALL_DIR)/GDLAccess.framework/Resources/GDLAdaptors/ -+ else -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/GDLAdaptors-$(MAJOR_VERSION).$(MINOR_VERSION)/ -++BUNDLE_INSTALL_DIR = $(SOPE_DBADAPTORS)/ -+ endif -+ -+ -+Index: sope-gdl1/MySQL/GNUmakefile -+=================================================================== -+--- sope-gdl1/MySQL/GNUmakefile (révision 1632) -++++ sope-gdl1/MySQL/GNUmakefile (copie de travail) -+@@ -22,7 +22,7 @@ -+ # If not, write to the Free Software Foundation, -+ # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ include ./Version -+@@ -67,4 +67,3 @@ -+ include $(GNUSTEP_MAKEFILES)/tool.make -+ endif -+ -include GNUmakefile.postamble -+-include fhs.make -+Index: sope-gdl1/GNUmakefile -+=================================================================== -+--- sope-gdl1/GNUmakefile (révision 1632) -++++ sope-gdl1/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../config.make -++include ../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ PACKAGE_NAME=sope-gdl1 -+Index: sope-gdl1/GDLAccess/GNUmakefile.preamble -+=================================================================== -+--- sope-gdl1/GDLAccess/GNUmakefile.preamble (révision 1632) -++++ sope-gdl1/GDLAccess/GNUmakefile.preamble (copie de travail) -+@@ -21,17 +21,12 @@ -+ -I$(SOPE_ROOT)/sope-core/NGExtensions/ -+ -+ -+-# Parameters for EOAdaptor lookup -+ -+-ifneq ($(FHS_INSTALL_ROOT),) -+-ADDITIONAL_CPPFLAGS += -DFHS_INSTALL_ROOT=\@\"$(FHS_INSTALL_ROOT)\" -++ifneq ($(CGS_LIBDIR_NAME),) -++ADDITIONAL_CPPFLAGS += -DCGS_LIBDIR_NAME=\@\"$(CGS_LIBDIR_NAME)\" -+ endif -+ -+-ifeq ($(CONFIGURE_64BIT),yes) -+-ADDITIONAL_CPPFLAGS += -DCONFIGURE_64BIT=1 -+-endif -+ -+- -+ # dependencies -+ -+ libGDLAccess_LIBRARIES_DEPEND_UPON += -lEOControl -+Index: sope-gdl1/GDLAccess/GNUmakefile -+=================================================================== -+--- sope-gdl1/GDLAccess/GNUmakefile (révision 1632) -++++ sope-gdl1/GDLAccess/GNUmakefile (copie de travail) -+@@ -1,12 +1,10 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include ../common.make -+ -include ../Version -+ -include ./Version -+ -+-GNUSTEP_INSTALLATION_DIR = ${GNUSTEP_LOCAL_ROOT} -+- -+ ifneq ($(frameworks),yes) -+ LIBRARY_NAME = libGDLAccess -+ else -+@@ -14,7 +12,8 @@ -+ endif -+ -+ libGDLAccess_PCH_FILE = common.h -+-libGDLAccess_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libGDLAccess_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libGDLAccess_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libGDLAccess_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ libGDLAccess_DLL_DEF = libGDLAccess.def -+@@ -123,6 +122,8 @@ -+ connect-EOAdaptor_OBJC_FILES = connect-EOAdaptor.m -+ load-EOAdaptor_PCH_FILE = common.h -+ connect-EOAdaptor_PCH_FILE = common.h -++load-EOAdaptor_INSTALL_DIR = $(SOPE_TOOLS)/ -++connect-EOAdaptor_INSTALL_DIR = $(SOPE_TOOLS)/ -+ -+ -+ # framework support -+@@ -136,6 +137,9 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ else -+@@ -143,4 +147,3 @@ -+ endif -+ include $(GNUSTEP_MAKEFILES)/tool.make -+ -include GNUmakefile.postamble -+-include fhs.make -+Index: sope-gdl1/GDLAccess/EOAdaptor.h -+=================================================================== -+--- sope-gdl1/GDLAccess/EOAdaptor.h (révision 1632) -++++ sope-gdl1/GDLAccess/EOAdaptor.h (copie de travail) -+@@ -62,11 +62,14 @@ -+ + (id)adaptorWithModel:(EOModel *)aModel; -+ + (id)adaptorWithName:(NSString *)aName; -+ + (id)adaptorForURL:(id)_url; -+++ (NSString *)libraryDriversSubDir; -+ - (id)initWithName:(NSString *)aName; -+ -+ /* Getting an adaptor's name */ -+ - (NSString*)name; -+ -++/* Get the library subdir name */ -++ -+ /* Setting connection information */ -+ - (void)setConnectionDictionary:(NSDictionary*)aDictionary; -+ - (NSDictionary*)connectionDictionary; -+Index: sope-gdl1/GDLAccess/EOAdaptor.m -+=================================================================== -+--- sope-gdl1/GDLAccess/EOAdaptor.m (révision 1632) -++++ sope-gdl1/GDLAccess/EOAdaptor.m (copie de travail) -+@@ -53,14 +53,23 @@ -+ + (NSArray *)adaptorSearchPathes { -+ // TODO: add support for Cocoa -+ static NSArray *searchPathes = nil; -+- NSDictionary *env; -+ NSMutableArray *ma; -+ id tmp; -+ -+ if (searchPathes != nil) return searchPathes; -+ -++ ma = [NSMutableArray arrayWithCapacity:8]; -++ -++#if GNUSTEP_BASE_LIBRARY -++ NSEnumerator *libraryPaths; -++ NSString *directory, *suffix; -++ suffix = [self libraryDriversSubDir]; -++ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -++ while ((directory = [libraryPaths nextObject])) -++ [ma addObject: [directory stringByAppendingPathComponent: suffix]]; -++#else -++ NSDictionary *env; -+ env = [[NSProcessInfo processInfo] environment]; -+- ma = [NSMutableArray arrayWithCapacity:8]; -+ -+ if ((tmp = [env objectForKey:@"GNUSTEP_PATHPREFIX_LIST"]) == nil) -+ tmp = [env objectForKey:@"GNUSTEP_PATHLIST"]; -+@@ -79,10 +88,11 @@ -+ [ma addObject:tmp]; -+ } -+ } -++#endif -+ -+ tmp = [NSString stringWithFormat: -+-#if CONFIGURE_64BIT -+- @"/lib64/sope-%i.%i/dbadaptors", -++#ifdef CGS_LIBDIR_NAME -++ [CGS_LIBDIR_NAME stringByAppendingString:@"/sope-%i.%i/dbadaptors"], -+ #else -+ @"/lib/sope-%i.%i/dbadaptors", -+ #endif -+@@ -92,9 +102,8 @@ -+ [ma addObject:[FHS_INSTALL_ROOT stringByAppendingPathComponent:tmp]]; -+ #endif -+ -+- [ma addObject:[@"/usr/local" stringByAppendingString:tmp]]; -+- [ma addObject:[@"/usr" stringByAppendingString:tmp]]; -+- -++ [ma addObject:[@"/usr/local/" stringByAppendingString:tmp]]; -++ [ma addObject:[@"/usr/" stringByAppendingString:tmp]]; -+ searchPathes = [ma copy]; -+ if ([searchPathes count] == 0) -+ NSLog(@"%s: empty library search path !", __PRETTY_FUNCTION__); -+@@ -213,6 +222,11 @@ -+ return _scheme; -+ } -+ -+++ (NSString *)libraryDriversSubDir { -++ return [NSString stringWithFormat:@"GDLAdaptors-%i.%i", -++ GDL_MAJOR_VERSION, GDL_MINOR_VERSION]; -++} -++ -+ - (NSDictionary *)connectionDictionaryForNSURL:(NSURL *)_url { -+ /* -+ "Database URLs" -+Index: sope-gdl1/GDLAccess/FoundationExt/GNUmakefile -+=================================================================== -+--- sope-gdl1/GDLAccess/FoundationExt/GNUmakefile (révision 1632) -++++ sope-gdl1/GDLAccess/FoundationExt/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../../Version -+ include ../Version -+Index: sope-gdl1/GDLAccess/common.h -+=================================================================== -+--- sope-gdl1/GDLAccess/common.h (révision 1632) -++++ sope-gdl1/GDLAccess/common.h (copie de travail) -+@@ -42,7 +42,7 @@ -+ #import -+ #import -+ -+-#if !(COCOA_Foundation_LIBRARY || NeXT_Foundation_LIBRARY) -++#if !(COCOA_Foundation_LIBRARY || NeXT_Foundation_LIBRARY || GNUSTEP_BASE_LIBRARY) -+ # import -+ #endif -+ -+Index: sope-gdl1/Oracle8/GNUmakefile -+=================================================================== -+--- sope-gdl1/Oracle8/GNUmakefile (révision 1632) -++++ sope-gdl1/Oracle8/GNUmakefile (copie de travail) -+@@ -19,7 +19,7 @@ -+ # License along with this library; if not, write to the Free Software -+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ # -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ include ./Version -+@@ -51,7 +51,7 @@ -+ ifeq ($(frameworks),yes) -+ BUNDLE_INSTALL_DIR := $(FRAMEWORK_INSTALL_DIR)/GDLAccess.framework/Resources/GDLAdaptors/ -+ else -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/GDLAdaptors-$(MAJOR_VERSION).$(MINOR_VERSION)/ -++BUNDLE_INSTALL_DIR = $(SOPE_DBADAPTORS)/ -+ endif -+ -+ Oracle8_OBJC_FILES = \ -+Index: sope-mime/NGImap4/GNUmakefile -+=================================================================== -+--- sope-mime/NGImap4/GNUmakefile (révision 1632) -++++ sope-mime/NGImap4/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ -+@@ -63,7 +63,10 @@ -+ NGImap4MailboxInfo.m \ -+ NGImap4ConnectionManager.m \ -+ -+--include GNUmakefile.preamble -++include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/subproject.make -+ else -+Index: sope-mime/samples/GNUmakefile -+=================================================================== -+--- sope-mime/samples/GNUmakefile (révision 1632) -++++ sope-mime/samples/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ TOOL_NAME = \ -+@@ -14,16 +14,24 @@ -+ imapcontest \ -+ -+ imapquota_OBJC_FILES = ImapQuotaTool.m ImapTool.m imapquota.m -++imapquota_INSTALL_DIR = $(SOPE_TOOLS) -+ imapacl_OBJC_FILES = ImapQuotaTool.m ImapTool.m imapacl.m -++imapctl_INSTALL_DIR = $(SOPE_TOOLS) -+ imapget_OBJC_FILES = ImapTool.m imapget.m -++imapget_INSTALL_DIR = $(SOPE_TOOLS) -+ imap_tool_OBJC_FILES = imap_tool.m -++imap_tool_INSTALL_DIR = $(SOPE_TOOLS) -+ mime2xml_OBJC_FILES = Mime2XmlTool.m mime2xml.m -++mime2xml_INSTALL_DIR = $(SOPE_TOOLS) -+ imapls_OBJC_FILES = ImapTool.m ImapListTool.m imapls.m -++imapls_INSTALL_DIR = $(SOPE_TOOLS) -+ test_qpdecode_OBJC_FILES = test_qpdecode.m -++test_qpdecode_INSTALL_DIR= $(SOPE_TOOLS) -+ sievetool_OBJC_FILES = sievetool.m -++sievetool_INSTALL_DIR = $(SOPE_TOOLS) -+ imapcontest_OBJC_FILES = imapcontest.m -++imapcontest_INSTALL_DIR = $(SOPE_TOOLS) -+ -+ -include GNUmakefile.preamble -+ include $(GNUSTEP_MAKEFILES)/tool.make -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-mime/NGMail/GNUmakefile -+=================================================================== -+--- sope-mime/NGMail/GNUmakefile (révision 1632) -++++ sope-mime/NGMail/GNUmakefile (copie de travail) -+@@ -1,10 +1,8 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+-GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -+- -+ ifneq ($(frameworks),yes) -+ SUBPROJECT_NAME = NGMail -+ else -+@@ -55,6 +53,9 @@ -+ NSData+MimeQP.m \ -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/subproject.make -+ else -+Index: sope-mime/GNUmakefile -+=================================================================== -+--- sope-mime/GNUmakefile (révision 1632) -++++ sope-mime/GNUmakefile (copie de travail) -+@@ -1,11 +1,9 @@ -+ # GNUstep makefile -+ -+--include ../config.make -++include ../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ./Version -+ -+-GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -+- -+ ifneq ($(frameworks),yes) -+ LIBRARY_NAME = libNGMime -+ else -+@@ -14,7 +12,8 @@ -+ -+ libNGMime_HEADER_FILES_DIR = . -+ libNGMime_HEADER_FILES_INSTALL_DIR = /NGMime -+-libNGMime_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libNGMime_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libNGMime_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libNGMime_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ ifneq ($(frameworks),yes) -+@@ -35,6 +34,9 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ else -+@@ -42,7 +44,6 @@ -+ include $(GNUSTEP_MAKEFILES)/aggregate.make -+ endif -+ -include GNUmakefile.postamble -+--include fhs.make -+ -+ -+ # package -+Index: sope-mime/NGMime/GNUmakefile.preamble -+=================================================================== -+--- sope-mime/NGMime/GNUmakefile.preamble (révision 1632) -++++ sope-mime/NGMime/GNUmakefile.preamble (copie de travail) -+@@ -5,6 +5,15 @@ -+ -DLIBRARY_MINOR_VERSION=${MINOR_VERSION} \ -+ -DLIBRARY_SUBMINOR_VERSION=${SUBMINOR_VERSION} \ -+ -++ifeq ($(patsubstr GNU/%,glibc,$(shell uname -o)),glibc) -++ADDITIONAL_CPPFLAGS += \ -++ -DHAVE_STRNDUP -++endif -++ -++ifneq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd) -++ ADDITIONAL_CPPFLAGS += -DHAVE_STRNDUP -++endif -++ -+ NGMime_INCLUDE_DIRS += \ -+ -I.. -I../.. \ -+ -I../../sope-core/NGStreams/ \ -+Index: sope-mime/NGMime/GNUmakefile -+=================================================================== -+--- sope-mime/NGMime/GNUmakefile (révision 1632) -++++ sope-mime/NGMime/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ -+@@ -76,5 +76,8 @@ -+ NGMimeRfc822BodyGenerator.m \ -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ include $(GNUSTEP_MAKEFILES)/subproject.make -+ -include GNUmakefile.postamble -+Index: sope-core/NGExtensions/NGExtensions/NGResourceLocator.h -+=================================================================== -+--- sope-core/NGExtensions/NGExtensions/NGResourceLocator.h (révision 1632) -++++ sope-core/NGExtensions/NGExtensions/NGResourceLocator.h (copie de travail) -+@@ -52,23 +52,54 @@ -+ int reserved:29; -+ } flags; -+ } -+- -++/* The 'GNUstepPath' is a string describing the required path. This -++ * is the relative location of the path in a standard GNUstep -++ * hierarchy when a standard GNUstep hierarchy is being used; but if -++ * gnustep-base (which supports arbitrary filesystem layouts) is being -++ * used, the path is heuristically mapped to the standard paths -++ * accepted by NSSearchPathForDirectoriesInDomains using the following -++ * logic: -++ * -++ * "Library/WebApplications" --> GSWebApplicationsDirectory -++ * "Library/Libraries" --> GSLibrariesDirectory -++ * "Tools" --> GSToolsDirectory -++ * "Tools/Admin" --> GSAdminToolsDirectory -++ * "Applications" --> GSApplicationsDirectory -++ * "Applications/Admin" --> GSAdminApplicationsDirectory -++ * "Library/xxx" --> NSLibraryDirectory/xxx -++ * "yyy" --> NSLibraryDirectory/yyy -++ * -++ * In the last two cases 'xxx' and 'yyy' are arbitrary strings/paths -++ * that don't match anything else. Eg, if you create an -++ * NGResourceLocators to look up files in "Library/Resources" you will -++ * get one that looks them up in NSLibraryDirectory/Resources (which -++ * means a list of directories containing -++ * GNUSTEP_USER_LIBRARY/Resources, GNUSTEP_LOCAL_LIBRARY/Resources, -++ * GNUSTEP_NETWORK_LIBRARY/Resources, -++ * GNUSTEP_SYSTEM_LIBRARY/Resources). -++ */ -+ + (id)resourceLocatorForGNUstepPath:(NSString *)_path fhsPath:(NSString *)_fhs; -+ - (id)initWithGNUstepPath:(NSString *)_path fhsPath:(NSString *)_fhs; -+ -+ /* resource pathes */ -+ -++/* It's not a good idea to access these directly if you want portable -++ * code. More logical to use directly the 'operations' lookup methods -++ * below which encapsulate all the internal filesystem details. -++ */ -+ - (NSArray *)gsRootPathes; /* GNUSTEP_PATHPREFIX_LIST or MacOSX */ -+ - (NSArray *)fhsRootPathes; -+ - (NSArray *)searchPathes; -+ -+ /* operations */ -+ -++/* These are public and work across all types of filesystems, it's how you find resources. */ -+ - (NSString *)lookupFileWithName:(NSString *)_name; -+ - (NSString *)lookupFileWithName:(NSString *)_name extension:(NSString *)_ext; -+ -+ - (NSArray *)lookupAllFilesWithExtension:(NSString *)_ext -+ doReturnFullPath:(BOOL)_withPath; -++/* End public */ -+ -+ @end -+ -+Index: sope-core/NGExtensions/NGBundleManager.m -+=================================================================== -+--- sope-core/NGExtensions/NGBundleManager.m (révision 1632) -++++ sope-core/NGExtensions/NGBundleManager.m (copie de travail) -+@@ -332,10 +332,7 @@ -+ } -+ -+ - (void)_addGNUstepPathsToPathArray:(NSMutableArray *)_paths { -+-#if !GNUSTEP -+-#else -+- // TODO: whats that supposed to do? -+- // TODO: replace with proper path locator function! -++ /* Old code for old gstep-make and gstep-base. */ -+ NSDictionary *env; -+ NSString *p; -+ unsigned i, count; -+@@ -355,7 +352,19 @@ -+ -+ if (p) [self->bundleSearchPaths addObject:p]; -+ } -+-#endif -++ -++ /* New code for new gstep-make and gstep-base. */ -++ tmp = NSStandardLibraryPaths(); -++ { -++ NSEnumerator *e = [tmp objectEnumerator]; -++ while ((tmp = [e nextObject]) != nil) { -++ tmp = [tmp stringByAppendingPathComponent:@"Bundles"]; -++ if ([self->bundleSearchPaths containsObject:tmp]) -++ continue; -++ -++ [self->bundleSearchPaths addObject:tmp]; -++ } -++ } -+ } -+ -+ - (void)_setupBundleSearchPathes { -+Index: sope-core/NGExtensions/FdExt.subproj/GNUmakefile -+=================================================================== -+--- sope-core/NGExtensions/FdExt.subproj/GNUmakefile (révision 1632) -++++ sope-core/NGExtensions/FdExt.subproj/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include ../../common.make -+ -+ SUBPROJECT_NAME = FdExt -+Index: sope-core/NGExtensions/XmlExt.subproj/GNUmakefile -+=================================================================== -+--- sope-core/NGExtensions/XmlExt.subproj/GNUmakefile (révision 1632) -++++ sope-core/NGExtensions/XmlExt.subproj/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include ../../common.make -+ -+ SUBPROJECT_NAME = XmlExt -+Index: sope-core/NGExtensions/EOExt.subproj/GNUmakefile -+=================================================================== -+--- sope-core/NGExtensions/EOExt.subproj/GNUmakefile (révision 1632) -++++ sope-core/NGExtensions/EOExt.subproj/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include ../../common.make -+ -+ SUBPROJECT_NAME = EOExt -+Index: sope-core/NGExtensions/GNUmakefile -+=================================================================== -+--- sope-core/NGExtensions/GNUmakefile (révision 1632) -++++ sope-core/NGExtensions/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include ../common.make -+ -+ ifneq ($(frameworks),yes) -+@@ -11,7 +11,8 @@ -+ -+ libNGExtensions_PCH_FILE = common.h -+ libNGExtensions_DLL_DEF = libNGExtensions.def -+-libNGExtensions_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libNGExtensions_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libNGExtensions_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libNGExtensions_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ libNGExtensions_HEADER_FILES_DIR = ./NGExtensions -+@@ -157,10 +158,12 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ else -+ include $(GNUSTEP_MAKEFILES)/framework.make -+ endif -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-core/NGExtensions/NGResourceLocator.m -+=================================================================== -+--- sope-core/NGExtensions/NGResourceLocator.m (révision 1632) -++++ sope-core/NGExtensions/NGResourceLocator.m (copie de travail) -+@@ -43,7 +43,11 @@ -+ return self; -+ } -+ - (id)init { -++#if GNUSTEP_BASE_LIBRARY -++ return [self initWithGNUstepPath:@"Resources" fhsPath:@"share"]; -++#else -+ return [self initWithGNUstepPath:@"Library/Resources" fhsPath:@"share"]; -++#endif -+ } -+ -+ - (void)dealloc { -+@@ -93,19 +97,30 @@ -+ NSString *p; -+ -+ ma = [NSMutableArray arrayWithCapacity:6]; -+- -+- e = ([self->gsSubPath length] > 0) -+- ? [[self gsRootPathes] objectEnumerator] -+- : (NSEnumerator *)nil; -+- while ((p = [e nextObject]) != nil) { -+- p = [p stringByAppendingPathComponent:self->gsSubPath]; -+- if ([ma containsObject:p]) -+- continue; -++ -++ if ([self->gsSubPath length] > 0) { -+ -+- if (![self->fileManager fileExistsAtPath:p]) -+- continue; -++#if GNUSTEP_BASE_LIBRARY -++ NSString *directory; -+ -+- [ma addObject:p]; -++ e = [NSStandardLibraryPaths() objectEnumerator]; -++ while ((directory = [e nextObject])) -++ [ma addObject: [directory stringByAppendingPathComponent:self->gsSubPath]]; -++#else -++ -++ /* Old hack using GNUSTEP_PATHLIST. Should be removed at some point. */ -++ e = [[self gsRootPathes] objectEnumerator]; -++ while ((p = [e nextObject]) != nil) { -++ p = [p stringByAppendingPathComponent:self->gsSubPath]; -++ if ([ma containsObject:p]) -++ continue; -++ -++ if (![self->fileManager fileExistsAtPath:p]) -++ continue; -++ -++ [ma addObject:p]; -++ } -++#endif -+ } -+ -+ e = ([self->fhsSubPath length] > 0) -+Index: sope-core/NGExtensions/NGLogging.subproj/GNUmakefile -+=================================================================== -+--- sope-core/NGExtensions/NGLogging.subproj/GNUmakefile (révision 1632) -++++ sope-core/NGExtensions/NGLogging.subproj/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include ../../common.make -+ -+ SUBPROJECT_NAME = NGLogging -+Index: sope-core/NGExtensions/NGRuleEngine.subproj/GNUmakefile -+=================================================================== -+--- sope-core/NGExtensions/NGRuleEngine.subproj/GNUmakefile (révision 1632) -++++ sope-core/NGExtensions/NGRuleEngine.subproj/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include ../../common.make -+ -+ SUBPROJECT_NAME = NGRuleEngine -+Index: sope-core/GNUmakefile -+=================================================================== -+--- sope-core/GNUmakefile (révision 1632) -++++ sope-core/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../config.make -++include ../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ PACKAGE_NAME=sope-core -+@@ -32,4 +32,4 @@ -+ # package -+ -+ macosx-pkg :: all -+- ../maintenance/make-osxpkg.sh sope-core -++ ../maintenance/make-osxpkg.sh $(PACKAGE_NAME) -+Index: sope-core/NGStreams/GNUmakefile.preamble -+=================================================================== -+--- sope-core/NGStreams/GNUmakefile.preamble (révision 1632) -++++ sope-core/NGStreams/GNUmakefile.preamble (copie de travail) -+@@ -38,7 +38,11 @@ -+ endif -+ -+ ifeq ($(findstring _64, $(GNUSTEP_TARGET_CPU)), _64) -++ifeq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd) -++SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib -++else -+ SYSTEM_LIB_DIR += -L/usr/local/lib64 -L/usr/lib64 -++endif -+ else -+ SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib -+ endif -+Index: sope-core/NGStreams/GNUmakefile -+=================================================================== -+--- sope-core/NGStreams/GNUmakefile (révision 1632) -++++ sope-core/NGStreams/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include ../common.make -+ include ./Version -+ -+@@ -12,7 +12,8 @@ -+ -+ libNGStreams_PCH_FILE = common.h -+ libNGStreams_DLL_DEF = libNGStreams.def -+-libNGStreams_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libNGStreams_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libNGStreams_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libNGStreams_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ libNGStreams_HEADER_FILES_DIR = NGStreams -+@@ -106,10 +107,12 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ else -+ include $(GNUSTEP_MAKEFILES)/framework.make -+ endif -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-core/samples/GNUmakefile -+=================================================================== -+--- sope-core/samples/GNUmakefile (révision 1632) -++++ sope-core/samples/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ TOOL_NAME = \ -+@@ -36,4 +36,3 @@ -+ -include GNUmakefile.preamble -+ include $(GNUSTEP_MAKEFILES)/tool.make -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-core/EOControl/GNUmakefile -+=================================================================== -+--- sope-core/EOControl/GNUmakefile (révision 1632) -++++ sope-core/EOControl/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include ../common.make -+ -+ ifneq ($(frameworks),yes) -+@@ -11,7 +11,8 @@ -+ -+ libEOControl_PCH_FILE = common.h -+ libEOControl_DLL_DEF = libEOControl.def -+-libEOControl_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libEOControl_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libEOControl_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libEOControl_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ libEOControl_HEADER_FILES_DIR = . -+@@ -73,10 +74,12 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ else -+ include $(GNUSTEP_MAKEFILES)/framework.make -+ endif -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-core/common.make -+=================================================================== -+--- sope-core/common.make (révision 1632) -++++ sope-core/common.make (copie de travail) -+@@ -6,8 +6,6 @@ -+ include $(SKYROOT)/Version -+ -include ./Version -+ -+-GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -+- -+ ADDITIONAL_CPPFLAGS += -pipe -Wall -Wno-protocol -+ ifeq ($(reentrant),yes) -+ ADDITIONAL_CPPFLAGS += -D_REENTRANT=1 -+Index: sope-core/EOCoreData/GNUmakefile -+=================================================================== -+--- sope-core/EOCoreData/GNUmakefile (révision 1632) -++++ sope-core/EOCoreData/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include ../common.make -+ -+ ifneq ($(frameworks),yes) -+@@ -10,7 +10,8 @@ -+ endif -+ -+ libEOCoreData_PCH_FILE = common.h -+-libEOCoreData_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libEOCoreData_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libEOCoreData_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libEOCoreData_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ libEOCoreData_HEADER_FILES_DIR = . -+@@ -67,10 +68,12 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ else -+ include $(GNUSTEP_MAKEFILES)/framework.make -+ endif -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: xmlrpc_call/GNUmakefile -+=================================================================== -+--- xmlrpc_call/GNUmakefile (révision 1632) -++++ xmlrpc_call/GNUmakefile (copie de travail) -+@@ -1,10 +1,11 @@ -+ # GNUstep makefile -+ -+--include ../config.make -++include ../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ -+ TOOL_NAME = xmlrpc_call -++xmlrpc_call_INSTALL_DIR = $(SOPE_TOOLS) -+ -+ xmlrpc_call_PCH_FILE = common.h -+ -+@@ -17,7 +18,6 @@ -+ -include GNUmakefile.preamble -+ include $(GNUSTEP_MAKEFILES)/tool.make -+ -include GNUmakefile.postamble -+--include fhs.make -+ -+ macosx-pkg :: -+ # do not build a pkg just for this tool -+Index: xmlrpc_call/GNUmakefile.preamble -+=================================================================== -+--- xmlrpc_call/GNUmakefile.preamble (révision 1632) -++++ xmlrpc_call/GNUmakefile.preamble (copie de travail) -+@@ -1,5 +1,6 @@ -+ # compilation settings -+ -++include ../config.make -+ SOPE_ROOT=.. -+ CORE_ROOT=$(SOPE_ROOT)/sope-core -+ APPSERVER_ROOT=$(SOPE_ROOT)/sope-appserver -+@@ -57,14 +58,13 @@ -+ $(foreach dir,$(DEP_DIRS),-F$(GNUSTEP_BUILD_DIR)/$(dir)) -+ endif -+ -+-ifeq ($(findstring _64, $(GNUSTEP_TARGET_CPU)), _64) -+-SYSTEM_LIB_DIR += -L/usr/local/lib64 -L/usr/lib64 -++ifneq ($(CGS_LIBDIR_NAME),) -++SYSTEM_LIB_DIR += -L/usr/local/$(CGS_LIBDIR_NAME) -L/usr/$(CGS_LIBDIR_NAME) -+ else -+ SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib -+ endif -+ -+- -+ # OS dependend stuff -+-ifeq ($(findstring openbsd3, $(GNUSTEP_HOST_OS)), openbsd3) -++ifeq ($(findstring openbsd, $(GNUSTEP_HOST_OS)), openbsd) -+ xmlrpc_call_TOOL_LIBS += -liconv -+ endif -+Index: sope-xml/libxmlSAXDriver/GNUmakefile -+=================================================================== -+--- sope-xml/libxmlSAXDriver/GNUmakefile (révision 1632) -++++ sope-xml/libxmlSAXDriver/GNUmakefile (copie de travail) -+@@ -1,13 +1,13 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ include ./Version -+ -+ BUNDLE_NAME = libxmlSAXDriver -+ BUNDLE_EXTENSION = .sax -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/SaxDrivers-$(MAJOR_VERSION).$(MINOR_VERSION)/ -++BUNDLE_INSTALL_DIR = $(SOPE_SAXDRIVERS) -+ -+ libxmlSAXDriver_PCH_FILE = common.h -+ -+@@ -24,4 +24,3 @@ -+ -include GNUmakefile.preamble -+ include $(GNUSTEP_MAKEFILES)/bundle.make -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-xml/DOM/GNUmakefile.preamble -+=================================================================== -+--- sope-xml/DOM/GNUmakefile.preamble (révision 1632) -++++ sope-xml/DOM/GNUmakefile.preamble (copie de travail) -+@@ -1,10 +1,13 @@ -+ # compilation settings -+ -++include ./Version -++ -+ libDOM_HEADER_FILES_DIR = . -+ libDOM_HEADER_FILES_INSTALL_DIR = /DOM -+-libDOM_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libDOM_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libDOM_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libDOM_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+-DOM_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++DOM_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+ DOM_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ -+Index: sope-xml/DOM/GNUmakefile -+=================================================================== -+--- sope-xml/DOM/GNUmakefile (révision 1632) -++++ sope-xml/DOM/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include ../common.make -+ -+ ifneq ($(frameworks),yes) -+@@ -98,10 +98,12 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ else -+ include $(GNUSTEP_MAKEFILES)/framework.make -+ endif -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-xml/ChangeLogSaxDriver/GNUmakefile -+=================================================================== -+--- sope-xml/ChangeLogSaxDriver/GNUmakefile (révision 1632) -++++ sope-xml/ChangeLogSaxDriver/GNUmakefile (copie de travail) -+@@ -1,13 +1,13 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -include ../../Version -+ -include ./Version -+ -+ BUNDLE_NAME = ChangeLogSaxDriver -+ BUNDLE_EXTENSION = .sax -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/SaxDrivers-$(MAJOR_VERSION).$(MINOR_VERSION)/ -++BUNDLE_INSTALL_DIR = ${SOPE_SAXDRIVERS}/ -+ -+ ChangeLogSaxDriver_OBJC_FILES = \ -+ ChangeLogSaxDriver.m \ -+@@ -20,4 +20,3 @@ -+ -include GNUmakefile.preamble -+ include $(GNUSTEP_MAKEFILES)/bundle.make -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-xml/GNUmakefile -+=================================================================== -+--- sope-xml/GNUmakefile (révision 1632) -++++ sope-xml/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../config.make -++include ../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ PACKAGE_NAME=sope-xml -+Index: sope-xml/SaxObjC/SaxXMLReaderFactory.m -+=================================================================== -+--- sope-xml/SaxObjC/SaxXMLReaderFactory.m (révision 1632) -++++ sope-xml/SaxObjC/SaxXMLReaderFactory.m (copie de travail) -+@@ -137,11 +137,19 @@ -+ -+ - (void)addSearchPathesForGNUstepEnv:(NSMutableArray *)ma { -+ /* for libFoundation */ -++#if GNUSTEP_BASE_LIBRARY -++NSEnumerator *libraryPaths; -++ NSString *directory, *suffix; -++ -++ suffix = [self libraryDriversSubDir]; -++ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -++ while ((directory = [libraryPaths nextObject])) -++ [ma addObject: [directory stringByAppendingPathComponent: suffix]]; -++#else -++ NSString *subdir; -++ NSEnumerator *e; -+ NSDictionary *env; -+- NSEnumerator *e; -+- NSString *subdir; -+ id tmp; -+- -+ env = [[NSProcessInfo processInfo] environment]; -+ -+ if ((tmp = [env objectForKey:@"GNUSTEP_PATHPREFIX_LIST"]) == nil) -+@@ -159,6 +167,7 @@ -+ -+ [ma addObject:tmp]; -+ } -++#endif -+ } -+ -+ - (NSArray *)saxReaderSearchPathes { -+@@ -182,8 +191,8 @@ -+ /* FHS fallback */ -+ -+ tmp = [[NSString alloc] initWithFormat: -+-#if CONFIGURE_64BIT -+- @"lib64/sope-%i.%i/saxdrivers/", -++#ifdef CGS_LIBDIR_NAME -++ [CGS_LIBDIR_NAME stringByAppendingString:@"/sope-%i.%i/saxdrivers/"], -+ #else -+ @"lib/sope-%i.%i/saxdrivers/", -+ #endif -+Index: sope-xml/SaxObjC/SaxObjectModel.h -+=================================================================== -+--- sope-xml/SaxObjC/SaxObjectModel.h (révision 1632) -++++ sope-xml/SaxObjC/SaxObjectModel.h (copie de travail) -+@@ -34,6 +34,7 @@ -+ -+ + (id)modelWithName:(NSString *)_name; -+ + (id)modelWithContentsOfFile:(NSString *)_path; -+++ (NSString *)libraryDriversSubDir; -+ -+ - (id)initWithDictionary:(NSDictionary *)_dict; -+ -+Index: sope-xml/SaxObjC/SaxObjectModel.m -+=================================================================== -+--- sope-xml/SaxObjC/SaxObjectModel.m (révision 1632) -++++ sope-xml/SaxObjC/SaxObjectModel.m (copie de travail) -+@@ -67,12 +67,12 @@ -+ if (searchPathes == nil) { -+ NSMutableArray *ma; -+ NSDictionary *env; -+- id tmp; -+ -+ env = [[NSProcessInfo processInfo] environment]; -+ ma = [NSMutableArray arrayWithCapacity:6]; -+ -+ #if COCOA_Foundation_LIBRARY -++ id tmp; -+ tmp = NSSearchPathForDirectoriesInDomains(NSAllLibrariesDirectory, -+ NSAllDomainsMask, -+ YES); -+@@ -86,7 +86,16 @@ -+ [ma addObject:tmp]; -+ } -+ } -++#elif GNUSTEP_BASE_LIBRARY -++ NSEnumerator *libraryPaths; -++ NSString *directory, *suffix; -++ -++ suffix = [self libraryDriversSubDir]; -++ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -++ while ((directory = [libraryPaths nextObject])) -++ [ma addObject: [directory stringByAppendingPathComponent: suffix]]; -+ #else -++ id tmp; -+ if ((tmp = [env objectForKey:@"GNUSTEP_PATHPREFIX_LIST"]) == nil) -+ tmp = [env objectForKey:@"GNUSTEP_PATHLIST"]; -+ tmp = [tmp componentsSeparatedByString:@":"]; -+@@ -122,6 +131,10 @@ -+ return searchPathes; -+ } -+ -+++ (NSString *)libraryDriversSubDir { -++ return [NSString stringWithFormat:@"SaxMappings"]; -++} -++ -+ + (id)modelWithName:(NSString *)_name { -+ NSFileManager *fileManager; -+ NSEnumerator *pathes; -+Index: sope-xml/SaxObjC/GNUmakefile.preamble -+=================================================================== -+--- sope-xml/SaxObjC/GNUmakefile.preamble (révision 1632) -++++ sope-xml/SaxObjC/GNUmakefile.preamble (copie de travail) -+@@ -1,9 +1,12 @@ -+ # compilation settings -+ -++include ./Version -++ -+ libSaxObjC_DLL_DEF = libSaxObjC.def -+-libSaxObjC_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libSaxObjC_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libSaxObjC_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libSaxObjC_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+-SaxObjC_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++SaxObjC_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+ SaxObjC_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ libSaxObjC_HEADER_FILES_DIR = . -+@@ -48,8 +51,8 @@ -+ ADDITIONAL_CPPFLAGS += -DFHS_INSTALL_ROOT=\@\"$(FHS_INSTALL_ROOT)\" -+ endif -+ -+-ifeq ($(CONFIGURE_64BIT),yes) -+-ADDITIONAL_CPPFLAGS += -DCONFIGURE_64BIT=1 -++ifneq ($(CGS_LIBDIR_NAME),) -++ADDITIONAL_CPPFLAGS += -DCGS_LIBDIR_NAME=\@\"$(CGS_LIBDIR_NAME)\" -+ endif -+ -+ # Apple -+Index: sope-xml/SaxObjC/GNUmakefile -+=================================================================== -+--- sope-xml/SaxObjC/GNUmakefile (révision 1632) -++++ sope-xml/SaxObjC/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include ../common.make -+ -+ ifneq ($(frameworks),yes) -+@@ -56,10 +56,12 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ else -+ include $(GNUSTEP_MAKEFILES)/framework.make -+ endif -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-xml/common.make -+=================================================================== -+--- sope-xml/common.make (révision 1632) -++++ sope-xml/common.make (copie de travail) -+@@ -1,13 +1,7 @@ -+ # GNUstep makefile -+ -+-SKYROOT=.. -+- -+ include $(GNUSTEP_MAKEFILES)/common.make -+-include $(SKYROOT)/Version -+--include ./Version -+ -+-GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -+- -+ ADDITIONAL_CPPFLAGS += -pipe -Wall -Wno-protocol -+ -+ ADDITIONAL_INCLUDE_DIRS += -I.. -+Index: sope-xml/samples/PlistSaxDriver/GNUmakefile -+=================================================================== -+--- sope-xml/samples/PlistSaxDriver/GNUmakefile (révision 1632) -++++ sope-xml/samples/PlistSaxDriver/GNUmakefile (copie de travail) -+@@ -1,11 +1,11 @@ -+ # GNUstep Makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ BUNDLE_NAME = PlistSaxDriver -+ BUNDLE_EXTENSION = .sax -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_USER_ROOT)/Library/Bundles -++BUNDLE_INSTALL_DIR = $(GNUSTEP_BUNDLES) -+ -+ PlistSaxDriver_OBJC_FILES = \ -+ PlistSaxDriver.m -+Index: sope-xml/samples/GNUmakefile -+=================================================================== -+--- sope-xml/samples/GNUmakefile (révision 1632) -++++ sope-xml/samples/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ TOOL_NAME = \ -+@@ -13,14 +13,20 @@ -+ testqp \ -+ -+ rss2plist1_OBJC_FILES = rss2plist1.m -++rss2plist1_INSTALL_DIR = $(SOPE_TOOLS)/ -+ rss2plist2_OBJC_FILES = rss2plist2.m -++rss2plist2_INSTALL_DIR = $(SOPE_TOOLS)/ -+ rssparse_OBJC_FILES = rssparse.m -++rssparse_INSTALL_DIR = $(SOPE_TOOLS)/ -+ saxxml_OBJC_FILES = saxxml.m -++saxxml_INSTALL_DIR = $(SOPE_TOOLS)/ -+ xmln_OBJC_FILES = xmln.m -++xmln_INSTALL_DIR = $(SOPE_TOOLS)/ -+ domxml_OBJC_FILES = domxml.m -++domxml_INSTALL_DIR = $(SOPE_TOOLS)/ -+ testqp_OBJC_FILES = testqp.m -++testqp_INSTALL_DIR = $(SOPE_TOOLS)/ -+ -+ -include GNUmakefile.preamble -+ include $(GNUSTEP_MAKEFILES)/tool.make -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-xml/samples/GNUmakefile.preamble -+=================================================================== -+--- sope-xml/samples/GNUmakefile.preamble (révision 1632) -++++ sope-xml/samples/GNUmakefile.preamble (copie de travail) -+@@ -1,5 +1,6 @@ -+ # compilation settings -+ -++include ../../config.make -+ -+ rss2plist1_PCH_FILE = common.h -+ rss2plist2_PCH_FILE = common.h -+@@ -42,8 +43,8 @@ -+ $(foreach dir,$(DEP_DIRS),-F$(GNUSTEP_BUILD_DIR)/$(dir)) -+ endif -+ -+-ifeq ($(findstring _64, $(GNUSTEP_TARGET_CPU)), _64) -+-SYSTEM_LIB_DIR += -L/usr/local/lib64 -L/usr/lib64 -++ifneq ($(CGS_LIBDIR_NAME),) -++SYSTEM_LIB_DIR += -L/usr/local/$(CGS_LIBDIR_NAME) -L/usr/$(CGS_LIBDIR_NAME) -+ else -+ SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib -+ endif -+Index: sope-xml/XmlRpc/GNUmakefile.preamble -+=================================================================== -+--- sope-xml/XmlRpc/GNUmakefile.preamble (révision 1632) -++++ sope-xml/XmlRpc/GNUmakefile.preamble (copie de travail) -+@@ -1,10 +1,13 @@ -+ # compilation settings -+ -++include ./Version -++ -+ libXmlRpc_HEADER_FILES_DIR = . -+ libXmlRpc_HEADER_FILES_INSTALL_DIR = /XmlRpc -+-libXmlRpc_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libXmlRpc_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libXmlRpc_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libXmlRpc_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+-XmlRpc_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++XmlRpc_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+ XmlRpc_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ -+Index: sope-xml/XmlRpc/GNUmakefile -+=================================================================== -+--- sope-xml/XmlRpc/GNUmakefile (révision 1632) -++++ sope-xml/XmlRpc/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include ../common.make -+ -+ ifneq ($(frameworks),yes) -+@@ -43,10 +43,12 @@ -+ -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ else -+ include $(GNUSTEP_MAKEFILES)/framework.make -+ endif -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-xml/STXSaxDriver/ExtraSTX/GNUmakefile -+=================================================================== -+--- sope-xml/STXSaxDriver/ExtraSTX/GNUmakefile (révision 1632) -++++ sope-xml/STXSaxDriver/ExtraSTX/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ SUBPROJECT_NAME = ExtraSTX -+Index: sope-xml/STXSaxDriver/GNUmakefile -+=================================================================== -+--- sope-xml/STXSaxDriver/GNUmakefile (révision 1632) -++++ sope-xml/STXSaxDriver/GNUmakefile (copie de travail) -+@@ -1,13 +1,13 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ include ./Version -+ -+ BUNDLE_NAME = STXSaxDriver -+ BUNDLE_EXTENSION = .sax -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/SaxDrivers-$(SOPE_MAJOR_VERSION).$(SOPE_MINOR_VERSION)/ -++BUNDLE_INSTALL_DIR = $(SOPE_SAXDRIVERS) -+ -+ STXSaxDriver_PCH_FILE = common.h -+ -+@@ -24,4 +24,3 @@ -+ -include GNUmakefile.preamble -+ include $(GNUSTEP_MAKEFILES)/bundle.make -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-xml/STXSaxDriver/Model/GNUmakefile -+=================================================================== -+--- sope-xml/STXSaxDriver/Model/GNUmakefile (révision 1632) -++++ sope-xml/STXSaxDriver/Model/GNUmakefile (copie de travail) -+@@ -6,7 +6,7 @@ -+ # Date: 24 November 2003 -+ # -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ SUBPROJECT_NAME = Model -+Index: sope-xml/pyxSAXDriver/GNUmakefile -+=================================================================== -+--- sope-xml/pyxSAXDriver/GNUmakefile (révision 1632) -++++ sope-xml/pyxSAXDriver/GNUmakefile (copie de travail) -+@@ -1,17 +1,16 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ include ./Version -+ -+ BUNDLE_NAME = pyxSAXDriver -+ BUNDLE_EXTENSION = .sax -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_USER_ROOT)/Library/SaxDrivers-$(SOPE_MAJOR_VERSION).$(SOPE_MINOR_VERSION)/ -++BUNDLE_INSTALL_DIR = ${SOPE_SAXDRIVERS}/ -+ -+ pyxSAXDriver_OBJC_FILES = pyxSAXDriver.m -+ -+ -include GNUmakefile.preamble -+ include $(GNUSTEP_MAKEFILES)/bundle.make -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-appserver/GNUmakefile -+=================================================================== -+--- sope-appserver/GNUmakefile (révision 1632) -++++ sope-appserver/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../config.make -++include ../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ PACKAGE_NAME=sope-appserver -+@@ -38,4 +38,4 @@ -+ # package -+ -+ macosx-pkg :: all -+- ../maintenance/make-osxpkg.sh sope-appserver -++ ../maintenance/make-osxpkg.sh $(PACKAGE_NAME) -+Index: sope-appserver/SoOFS/GNUmakefile.preamble -+=================================================================== -+--- sope-appserver/SoOFS/GNUmakefile.preamble (révision 1632) -++++ sope-appserver/SoOFS/GNUmakefile.preamble (copie de travail) -+@@ -76,17 +76,9 @@ -+ $(foreach dir,$(DEP_DIRS),-F$(GNUSTEP_BUILD_DIR)/$(dir)) -+ endif -+ -+-ifeq ($(findstring _64, $(GNUSTEP_TARGET_CPU)), _64) -+-SYSTEM_LIB_DIR += -L/usr/local/lib64 -L/usr/lib64 -+-else -+-SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib -+-endif -+- -+- -+- -+ # platform specific settings -+ -+-ifneq ($(findstring openbsd3, $(GNUSTEP_TARGET_OS)), openbsd3) -++ifneq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd) -+ # OpenBSD does not require libcrypt -+ ifneq ($(findstring darwin, $(GNUSTEP_TARGET_OS)), darwin) -+ # and neither does MacOSX? ... -+@@ -94,6 +86,6 @@ -+ endif -+ endif -+ -+-ifeq ($(findstring openbsd3, $(GNUSTEP_TARGET_OS)), openbsd3) -++ifeq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd) -+ $(SOPED_NAME)_TOOL_LIBS += -liconv -+ endif -+Index: sope-appserver/SoOFS/GNUmakefile -+=================================================================== -+--- sope-appserver/SoOFS/GNUmakefile (révision 1632) -++++ sope-appserver/SoOFS/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ include ./Version -+@@ -14,7 +14,8 @@ -+ -+ -+ libSoOFS_PCH_FILE = common.h -+-libSoOFS_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libSoOFS_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libSoOFS_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libSoOFS_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ libSoOFS_HEADER_FILES_DIR = . -+@@ -75,7 +76,7 @@ -+ -+ BUNDLE_NAME = SoOFS -+ BUNDLE_EXTENSION = .sxp -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/SoProducts-$(MAJOR_VERSION).$(MINOR_VERSION)/ -++BUNDLE_INSTALL_DIR = $(SOPE_PRODUCTS)/ -+ -+ SoOFS_OBJC_FILES = SoOFSProduct.m -+ SoOFS_RESOURCE_FILES = product.plist Version -+@@ -91,9 +92,13 @@ -+ TOOL_NAME = $(SOPED_NAME) -+ -+ $(SOPED_NAME)_OBJC_FILES = sope.m -++$(SOPED_NAME)_INSTALL_DIR = $(SOPE_ADMIN_TOOLS) -+ -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ include $(GNUSTEP_MAKEFILES)/bundle.make -+@@ -102,4 +107,3 @@ -+ endif -+ include $(GNUSTEP_MAKEFILES)/tool.make -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-appserver/NGXmlRpc/GNUmakefile -+=================================================================== -+--- sope-appserver/NGXmlRpc/GNUmakefile (révision 1632) -++++ sope-appserver/NGXmlRpc/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ include ./Version -+@@ -12,7 +12,8 @@ -+ endif -+ -+ libNGXmlRpc_PCH_FILE = common.h -+-libNGXmlRpc_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libNGXmlRpc_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libNGXmlRpc_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libNGXmlRpc_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ libNGXmlRpc_HEADER_FILES_DIR = . -+@@ -65,6 +66,9 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ else -+@@ -72,4 +76,3 @@ -+ endif -+ include $(GNUSTEP_MAKEFILES)/tool.make -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-appserver/WEExtensions/GNUmakefile.preamble -+=================================================================== -+--- sope-appserver/WEExtensions/GNUmakefile.preamble (révision 1632) -++++ sope-appserver/WEExtensions/GNUmakefile.preamble (copie de travail) -+@@ -21,7 +21,8 @@ -+ cp ../bundle-info.plist .) -+ endif -+ -+-libWEExtensions_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libWEExtensions_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libWEExtensions_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libWEExtensions_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ -+Index: sope-appserver/WEExtensions/GNUmakefile -+=================================================================== -+--- sope-appserver/WEExtensions/GNUmakefile (révision 1632) -++++ sope-appserver/WEExtensions/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ include ./Version -+@@ -11,7 +11,7 @@ -+ -+ BUNDLE_NAME = WEExtensions -+ BUNDLE_EXTENSION = .wox -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/WOxElemBuilders-$(MAJOR_VERSION).$(MINOR_VERSION)/ -++BUNDLE_INSTALL_DIR = $(SOPE_WOXBUILDERS)/ -+ -+ else -+ FRAMEWORK_NAME = WEExtensions -+@@ -99,6 +99,9 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ include $(GNUSTEP_MAKEFILES)/bundle.make -+@@ -106,4 +109,3 @@ -+ include $(GNUSTEP_MAKEFILES)/framework.make -+ endif -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-appserver/WEExtensions/WEResourceManager.m -+=================================================================== -+--- sope-appserver/WEExtensions/WEResourceManager.m (révision 1632) -++++ sope-appserver/WEExtensions/WEResourceManager.m (copie de travail) -+@@ -53,28 +53,43 @@ -+ -+ + (NSString *)gsTemplatesSubpath { -+ NSString *p; -+- -+ p = [[WOApplication application] gsTemplatesDirectoryName]; -++#if ! GNUSTEP_BASE_LIBRARY -++ // for GNUSTEP_BASE_LIBRARY this is already there in rootPathesInGNUstep -+ p = [@"Library/" stringByAppendingString:p]; -++#endif -+ return p; -+ } -+ + (NSString *)gsWebSubpath { -+ NSString *p; -+ -+ p = [[WOApplication application] gsWebDirectoryName]; -++#if ! GNUSTEP_BASE_LIBRARY -++ // for GNUSTEP_BASE_LIBRARY this is already there in rootPathesInGNUstep -+ p = [@"Library/" stringByAppendingString:p]; -++#endif -+ return p; -+ } -+ -+ /* locate resource directories */ -+ -+ + (NSArray *)rootPathesInGNUstep { -++ id tmp; -++#if GNUSTEP_BASE_LIBRARY -++ NSEnumerator *libraryPaths; -++ NSString *directory; -++ -++ tmp = [[NSMutableArray alloc] init]; -++ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -++ while ((directory = [libraryPaths nextObject])) -++ [tmp addObject: directory]; -++ return tmp; -++#else -+ NSDictionary *env; -+- id tmp; -+- -+ env = [[NSProcessInfo processInfo] environment]; -+ if ((tmp = [env objectForKey:@"GNUSTEP_PATHPREFIX_LIST"]) == nil) -+ tmp = [env objectForKey:@"GNUSTEP_PATHLIST"]; -++#endif -+ -+ return [tmp componentsSeparatedByString:@":"]; -+ } -+@@ -95,9 +110,17 @@ -+ NSMutableArray *ma; -+ BOOL isDir; -+ id tmp; -+- -+ fm = [NSFileManager defaultManager]; -+ ma = [NSMutableArray arrayWithCapacity:8]; -++ -++#ifdef GNUSTEP_BASE_LIBRARY -++ NSEnumerator *libraryPaths; -++ NSString *directory; -++ -++ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -++ while ((directory = [libraryPaths nextObject])) -++ [ma addObject: [directory stringByAppendingPathComponent: _name]]; -++#else -+ -+ e = [[self rootPathesInGNUstep] objectEnumerator]; -+ while ((tmp = [e nextObject]) != nil) { -+@@ -115,6 +138,7 @@ -+ -+ [ma addObject:tmp]; -+ } -++#endif -+ -+ /* hack in FHS pathes */ -+ -+Index: sope-appserver/WEExtensions/WETableView/GNUmakefile -+=================================================================== -+--- sope-appserver/WEExtensions/WETableView/GNUmakefile (révision 1632) -++++ sope-appserver/WEExtensions/WETableView/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ SUBPROJECT_NAME = WETableView -+Index: sope-appserver/NGObjWeb/WOCoreApplication+Bundle.m -+=================================================================== -+--- sope-appserver/NGObjWeb/WOCoreApplication+Bundle.m (révision 1632) -++++ sope-appserver/NGObjWeb/WOCoreApplication+Bundle.m (copie de travail) -+@@ -50,8 +50,6 @@ -+ } -+ else { -+ NSDictionary *env; -+- NSEnumerator *e; -+- id tmp; -+ -+ env = [[NSProcessInfo processInfo] environment]; -+ -+@@ -67,7 +65,20 @@ -+ bp = @"/System/Library"; -+ bp = [bp stringByAppendingPathComponent:_domain]; -+ [chkPathes addObject:bp]; -++#elif GNUSTEP_BASE_LIBRARY -++ NSEnumerator *libraryPaths; -++ NSString *directory; -++ -++ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -++ while ((directory = [libraryPaths nextObject])) { -++ directory = [directory stringByAppendingPathComponent:_domain]; -++ if ([chkPathes containsObject:directory]) continue; -++ [chkPathes addObject:directory]; -++ -++ } -+ #else -++ NSEnumerator *e; -++ id tmp; -+ if ((tmp = [env objectForKey:@"GNUSTEP_PATHPREFIX_LIST"]) == nil) -+ tmp = [env objectForKey:@"GNUSTEP_PATHLIST"]; -+ tmp = [tmp componentsSeparatedByString:@":"]; -+Index: sope-appserver/NGObjWeb/wobundle-gs.make -+=================================================================== -+--- sope-appserver/NGObjWeb/wobundle-gs.make (révision 1632) -++++ sope-appserver/NGObjWeb/wobundle-gs.make (copie de travail) -+@@ -85,7 +85,7 @@ -+ endif -+ -+ ifeq ($(WOBUNDLE_INSTALL_DIR),) -+-WOBUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Libraries -++WOBUNDLE_INSTALL_DIR = $(GNUSTEP_WEB_APPS) -+ endif -+ # The name of the bundle is in the BUNDLE_NAME variable. -+ # The list of languages the bundle is localized in are in xxx_LANGUAGES -+@@ -287,8 +287,10 @@ -+ @$(MKDIRS) $@ -+ -+ internal-wobundle-install_:: $(WOBUNDLE_INSTALL_DIR) shared-instance-headers-install -+- rm -rf $(WOBUNDLE_INSTALL_DIR)/$(WOBUNDLE_DIR_NAME); \ -+- $(TAR) chf - --exclude=CVS --exclude=.svn --to-stdout $(WOBUNDLE_DIR_NAME) | (cd $(WOBUNDLE_INSTALL_DIR); $(TAR) xf -) -++# rm -rf $(WOBUNDLE_INSTALL_DIR)/$(WOBUNDLE_DIR_NAME); \ -++# $(TAR) chf - --exclude=CVS --exclude=.svn --to-stdout $(WOBUNDLE_DIR_NAME) | (cd $(WOBUNDLE_INSTALL_DIR); $(TAR) xf -) -++ if [ -e $(WOBUNDLE_INSTALL_DIR)/$(WOBUNDLE_DIR_NAME) ]; then rm -rf $(WOBUNDLE_INSTALL_DIR)/$(WOBUNDLE_DIR_NAME); fi; \ -++ cp -LR $(WOBUNDLE_DIR_NAME) $(WOBUNDLE_INSTALL_DIR) -+ ifneq ($(CHOWN_TO),) -+ $(CHOWN) -R $(CHOWN_TO) $(WOBUNDLE_INSTALL_DIR)/$(WOBUNDLE_DIR_NAME) -+ endif -+Index: sope-appserver/NGObjWeb/GNUmakefile.preamble -+=================================================================== -+--- sope-appserver/NGObjWeb/GNUmakefile.preamble (révision 1632) -++++ sope-appserver/NGObjWeb/GNUmakefile.preamble (copie de travail) -+@@ -50,9 +50,6 @@ -+ $(foreach dir,$(DEP_DIRS),-F$(GNUSTEP_BUILD_DIR)/$(dir)) -+ endif -+ -+-SYSTEM_LIB_DIR += $(CONFIGURE_SYSTEM_LIB_DIR) -+- -+- -+ # dependencies -+ -+ ifneq ($(frameworks),yes) -+@@ -85,6 +82,7 @@ -+ $(sope-mime-libs) \ -+ $(sope-core-libs) \ -+ $(sope-xml-libs) -++wod_INSTALL_DIR = $(SOPE_TOOLS) -+ SoCore_BUNDLE_LIBS += \ -+ $(sope-ngobjweb-libs) \ -+ $(sope-mime-libs) \ -+@@ -94,7 +92,7 @@ -+ -+ # platform specific settings -+ -+-ifneq ($(findstring openbsd3, $(GNUSTEP_TARGET_OS)), openbsd3) -++ifneq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd) -+ # OpenBSD does not require libcrypt -+ ifneq ($(findstring darwin, $(GNUSTEP_TARGET_OS)), darwin) -+ # and neither does MacOSX? ... -+@@ -116,6 +114,6 @@ -+ libNGObjWeb_LIBRARIES_DEPEND_UPON += -lFoundationExt -+ endif -+ -+-ifeq ($(findstring openbsd3, $(GNUSTEP_TARGET_OS)), openbsd3) -++ifeq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd) -+ wod_TOOL_LIBS += -liconv -+ endif -+Index: sope-appserver/NGObjWeb/GNUmakefile -+=================================================================== -+--- sope-appserver/NGObjWeb/GNUmakefile (révision 1632) -++++ sope-appserver/NGObjWeb/GNUmakefile (copie de travail) -+@@ -1,11 +1,9 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include ../common.make -+ include ./Version -+ -+-GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -+- -+ ifneq ($(frameworks),yes) -+ LIBRARY_NAME = libNGObjWeb -+ else -+@@ -14,15 +12,12 @@ -+ -+ -+ ifneq ($(frameworks),yes) -+-ifeq ($(FHS_INSTALL_ROOT),) -+-RESOURCES_DIR = $(GNUSTEP_RESOURCES)/NGObjWeb -+-else -+-RESOURCES_DIR = $(FHS_INSTALL_ROOT)/share/sope-$(MAJOR_VERSION).$(MINOR_VERSION)/ngobjweb -++RESOURCES_DIR = $(SOPE_NGOBJWEB)/ -+ endif -+-endif -+ -+ libNGObjWeb_PCH_FILE = common.h -+-libNGObjWeb_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libNGObjWeb_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libNGObjWeb_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libNGObjWeb_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ libNGObjWeb_SUBPROJECTS = \ -+@@ -40,7 +35,7 @@ -+ libNGObjWeb_RESOURCES = \ -+ Defaults.plist \ -+ Languages.plist \ -+- DAVPropMap.plist \ -++ DAVPropMap.plist -+ -+ FHS_MANPAGES += \ -+ sope-ngobjweb-defaults.5 \ -+@@ -167,7 +162,7 @@ -+ -+ BUNDLE_NAME = SoCore -+ BUNDLE_EXTENSION = .sxp -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/SoProducts-$(MAJOR_VERSION).$(MINOR_VERSION)/ -++BUNDLE_INSTALL_DIR = $(SOPE_PRODUCTS)/ -+ -+ SoCore_PCH_FILE = common.h -+ SoCore_OBJC_FILES = SoCoreProduct.m -+@@ -190,6 +185,9 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ else -+@@ -198,4 +196,3 @@ -+ include $(GNUSTEP_MAKEFILES)/bundle.make -+ include $(GNUSTEP_MAKEFILES)/tool.make -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-appserver/NGObjWeb/WebDAV/GNUmakefile -+=================================================================== -+--- sope-appserver/NGObjWeb/WebDAV/GNUmakefile (révision 1632) -++++ sope-appserver/NGObjWeb/WebDAV/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include ../../Version -+ include ../Version -+ include $(GNUSTEP_MAKEFILES)/common.make -+Index: sope-appserver/NGObjWeb/DynamicElements/GNUmakefile -+=================================================================== -+--- sope-appserver/NGObjWeb/DynamicElements/GNUmakefile (révision 1632) -++++ sope-appserver/NGObjWeb/DynamicElements/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ SUBPROJECT_NAME = DynamicElements -+Index: sope-appserver/NGObjWeb/SoObjects/SoProductLoader.m -+=================================================================== -+--- sope-appserver/NGObjWeb/SoObjects/SoProductLoader.m (révision 1632) -++++ sope-appserver/NGObjWeb/SoObjects/SoProductLoader.m (copie de travail) -+@@ -74,6 +74,14 @@ -+ } -+ -+ - (void)_addGNUstepSearchPathesToArray:(NSMutableArray *)ma { -++#if GNUSTEP_BASE_LIBRARY -++ NSEnumerator *libraryPaths; -++ NSString *directory; -++ -++ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -++ while ((directory = [libraryPaths nextObject])) -++ [ma addObject: [directory stringByAppendingPathComponent: self->productDirectoryName]]; -++#else -+ NSDictionary *env; -+ id tmp; -+ -+@@ -97,6 +105,7 @@ -+ [self logWithFormat:@"%s: empty library search path !", -+ __PRETTY_FUNCTION__]; -+ } -++#endif -+ } -+ -+ - (void)_addFHSPathesToArray:(NSMutableArray *)ma { -+Index: sope-appserver/NGObjWeb/SoObjects/SoProductRegistry.m -+=================================================================== -+--- sope-appserver/NGObjWeb/SoObjects/SoProductRegistry.m (révision 1632) -++++ sope-appserver/NGObjWeb/SoObjects/SoProductRegistry.m (copie de travail) -+@@ -231,7 +231,7 @@ -+ -+ fm = [NSFileManager defaultManager]; -+ pi = [NSProcessInfo processInfo]; -+- -++#if ! GNUSTEP_BASE_LIBRARY -+ #if COCOA_Foundation_LIBRARY && !COMPILE_FOR_GNUSTEP -+ /* -+ TODO: (like COMPILE_FOR_GNUSTEP) -+@@ -250,12 +250,9 @@ -+ pathes = [[pathes stringValue] componentsSeparatedByString:@":"]; -+ relPath = @"Library/"; -+ #endif -+- -+- [self debugWithFormat:@"scanning for products ..."]; -+- -+ relPath = [relPath stringByAppendingFormat:@"SoProducts-%i.%i/", -+ SOPE_MAJOR_VERSION, SOPE_MINOR_VERSION]; -+- -++ [self debugWithFormat:@"scanning for products ..."]; -+ for (i = 0; i < [pathes count]; i++) { -+ NSString *lPath; -+ BOOL isDir; -+@@ -271,7 +268,38 @@ -+ [self debugWithFormat:@" directory %@", lPath]; -+ [self scanForProductsInDirectory:lPath]; -+ } -++#else -++ NSEnumerator *libraryPaths; -++ NSString *directory; -++ NSMutableArray *tmppath; -+ -++ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -++ tmppath = [[NSMutableArray alloc] init]; -++ while ((directory = [libraryPaths nextObject])) -++ [tmppath addObject: [directory stringByAppendingPathComponent: -++ [NSString stringWithFormat:@"SoProducts-%i.%i/", -++ SOPE_MAJOR_VERSION, SOPE_MINOR_VERSION]]]; -++ pathes = [tmppath mutableCopy]; -++ [self debugWithFormat:@"scanning for products ..."]; -++ for (i = 0; i < [pathes count]; i++) { -++ NSString *lPath; -++ BOOL isDir; -++ -++ lPath = [pathes objectAtIndex:i]; -++ [self debugWithFormat:@" scan: %@", lPath]; -++ -++ if (![fm fileExistsAtPath:lPath isDirectory:&isDir]) -++ continue; -++ if (!isDir) -++ continue; -++ -++ [self debugWithFormat:@" directory %@", lPath]; -++ [self scanForProductsInDirectory:lPath]; -++ } -++ [tmppath release]; -++#endif -++ -++ -+ #if COCOA_Foundation_LIBRARY -+ /* look in wrapper places */ -+ bundle = [NSBundle bundleForClass:[self class]]; -+@@ -282,8 +310,8 @@ -+ /* look into FHS pathes */ -+ -+ relPath = [NSString stringWithFormat: -+-#if CONFIGURE_64BIT -+- @"lib64/sope-%i.%i/products/", -++#ifdef CGS_LIBDIR_NAME -++ [CGS_LIBDIR_NAME stringByAppendingString:@"/sope-%i.%i/products/"], -+ #else -+ @"lib/sope-%i.%i/products/", -+ #endif -+Index: sope-appserver/NGObjWeb/SoObjects/GNUmakefile.preamble -+=================================================================== -+--- sope-appserver/NGObjWeb/SoObjects/GNUmakefile.preamble (révision 1632) -++++ sope-appserver/NGObjWeb/SoObjects/GNUmakefile.preamble (copie de travail) -+@@ -1,5 +1,7 @@ -+ # compilation settings -+ -++include ../../../config.make -++ -+ ADDITIONAL_INCLUDE_DIRS += -I../WebDAV/ -+ -+ ADDITIONAL_CPPFLAGS += -DCOMPILING_NGOBJWEB=1 -DCOMPILE_FOR_GNUSTEP=1 -+@@ -10,6 +12,6 @@ -+ ADDITIONAL_CPPFLAGS += -DFHS_INSTALL_ROOT=\@\"$(FHS_INSTALL_ROOT)\" -+ endif -+ -+-ifeq ($(CONFIGURE_64BIT),yes) -+-ADDITIONAL_CPPFLAGS += -DCONFIGURE_64BIT=1 -++ifneq ($(CGS_LIBDIR_NAME),) -++ADDITIONAL_CPPFLAGS += -DCGS_LIBDIR_NAME=\@\"$(CGS_LIBDIR_NAME)\" -+ endif -+Index: sope-appserver/NGObjWeb/SoObjects/GNUmakefile -+=================================================================== -+--- sope-appserver/NGObjWeb/SoObjects/GNUmakefile (révision 1632) -++++ sope-appserver/NGObjWeb/SoObjects/GNUmakefile (copie de travail) -+@@ -1,7 +1,7 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -+ include ../subdirs.make -++include ../../../config.make -+ -+ SUBPROJECT_NAME = SoObjects -+ -+Index: sope-appserver/NGObjWeb/Templates/GNUmakefile -+=================================================================== -+--- sope-appserver/NGObjWeb/Templates/GNUmakefile (révision 1632) -++++ sope-appserver/NGObjWeb/Templates/GNUmakefile (copie de travail) -+@@ -1,7 +1,7 @@ -+ # GNUmakefile makefile -+ -+--include ../../../config.make -+ include ../subdirs.make -++include ../../../config.make -+ -+ SUBPROJECT_NAME = Templates -+ -+Index: sope-appserver/NGObjWeb/Templates/WOApplication+Builders.m -+=================================================================== -+--- sope-appserver/NGObjWeb/Templates/WOApplication+Builders.m (révision 1632) -++++ sope-appserver/NGObjWeb/Templates/WOApplication+Builders.m (copie de travail) -+@@ -76,7 +76,7 @@ -+ -+ fm = [NSFileManager defaultManager]; -+ pi = [NSProcessInfo processInfo]; -+- -++#if ! GNUSTEP_BASE_LIBRARY -+ #if COCOA_Foundation_LIBRARY -+ /* -+ TODO: (like COMPILE_FOR_GNUSTEP) -+@@ -121,16 +121,43 @@ -+ [self debugWithFormat:@" directory %@", lPath]; -+ [self scanForBuilderBundlesInDirectory:lPath]; -+ } -++#else -++ NSEnumerator *libraryPaths; -++ NSString *directory; -++ NSMutableArray *tmppathes; -++ -++ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -++ tmppathes = [[NSMutableArray alloc] init]; -++ while ((directory = [libraryPaths nextObject])) -++ [tmppathes addObject: [directory stringByAppendingPathComponent: -++ [NSString stringWithFormat:@"WOxElemBuilders-%i.%i/", -++ SOPE_MAJOR_VERSION, SOPE_MINOR_VERSION]]]; -++ pathes = [tmppathes mutableCopy]; -++ for (i = 0; i < [pathes count]; i++) { -++ NSString *lPath; -++ BOOL isDir; -++ -++ lPath = [pathes objectAtIndex:i]; -++ if (![fm fileExistsAtPath:lPath isDirectory:&isDir]) -++ continue; -++ if (!isDir) -++ continue; -++ -++ [self debugWithFormat:@" directory %@", lPath]; -++ [self scanForBuilderBundlesInDirectory:lPath]; -++ } -++ [tmppathes release]; -++#endif -+ -+ /* look into FHS pathes */ -+ -+ relPath = [NSString stringWithFormat: -+-#if CONFIGURE_64BIT -+- @"lib/sope-%i.%i/wox-builders/", -++#ifdef CGS_LIBDIR_NAME -++ [CGS_LIBDIR_NAME stringByAppendingString:@"/sope-%i.%i/wox-builders/"], -+ #else -+- @"lib64/sope-%i.%i/wox-builders/", -++ @"lib/sope-%i.%i/wox-builders/", -+ #endif -+- SOPE_MAJOR_VERSION, SOPE_MINOR_VERSION]; -++ SOPE_MAJOR_VERSION, SOPE_MINOR_VERSION]; -+ pathes = [NSArray arrayWithObjects: -+ #ifdef FHS_INSTALL_ROOT -+ [FHS_INSTALL_ROOT stringByAppendingString:relPath], -+Index: sope-appserver/NGObjWeb/Templates/GNUmakefile.preamble -+=================================================================== -+--- sope-appserver/NGObjWeb/Templates/GNUmakefile.preamble (révision 1632) -++++ sope-appserver/NGObjWeb/Templates/GNUmakefile.preamble (copie de travail) -+@@ -6,6 +6,6 @@ -+ ADDITIONAL_CPPFLAGS += -DFHS_INSTALL_ROOT=\@\"$(FHS_INSTALL_ROOT)\" -+ endif -+ -+-ifeq ($(CONFIGURE_64BIT),yes) -+-ADDITIONAL_CPPFLAGS += -DCONFIGURE_64BIT=1 -++ifneq ($(CGS_LIBDIR_NAME),) -++ADDITIONAL_CPPFLAGS += -DCGS_LIBDIR_NAME=\@\"$(CGS_LIBDIR_NAME)\" -+ endif -+Index: sope-appserver/NGObjWeb/Associations/GNUmakefile -+=================================================================== -+--- sope-appserver/NGObjWeb/Associations/GNUmakefile (révision 1632) -++++ sope-appserver/NGObjWeb/Associations/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ SUBPROJECT_NAME = Associations -+Index: sope-appserver/NGObjWeb/WOHttpAdaptor/GNUmakefile -+=================================================================== -+--- sope-appserver/NGObjWeb/WOHttpAdaptor/GNUmakefile (révision 1632) -++++ sope-appserver/NGObjWeb/WOHttpAdaptor/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ SUBPROJECT_NAME = WOHttpAdaptor -+Index: sope-appserver/NGObjWeb/woapp-gs.make -+=================================================================== -+--- sope-appserver/NGObjWeb/woapp-gs.make (révision 1632) -++++ sope-appserver/NGObjWeb/woapp-gs.make (copie de travail) -+@@ -103,7 +103,7 @@ -+ # Determine the application directory extension -+ WOAPP_EXTENSION = woa -+ -+-GNUSTEP_WOAPPS = $(GNUSTEP_INSTALLATION_DIR)/WOApps -++GNUSTEP_WOAPPS = $(GNUSTEP_WEB_APPS) -+ -+ .PHONY: internal-woapp-all_ \ -+ internal-woapp-install_ \ -+@@ -372,8 +372,9 @@ -+ -+ internal-woapp-install_:: -+ @($(MKINSTALLDIRS) $(GNUSTEP_WOAPPS); \ -+- rm -rf $(GNUSTEP_WOAPPS)/$(WOAPP_DIR_NAME); \ -+- $(TAR) chf - --exclude=CVS --exclude=.svn --to-stdout $(WOAPP_DIR_NAME) | (cd $(GNUSTEP_WOAPPS); $(TAR) xf -)) -++ if [ -e $(GNUSTEP_WOAPPS)/$(WOAPP_DIR_NAME) ]; then rm -rf $(GNUSTEP_WOAPPS)/$(WOAPP_DIR_NAME); fi; \ -++# $(TAR) chf - --exclude=CVS --exclude=.svn --to-stdout $(WOAPP_DIR_NAME) | (cd $(GNUSTEP_WOAPPS); $(TAR) xf -)) -++ cp -LR $(WOAPP_DIR_NAME) $(GNUSTEP_WOAPPS) -+ ifneq ($(CHOWN_TO),) -+ $(CHOWN) -R $(CHOWN_TO) $(GNUSTEP_WOAPPS)/$(WOAPP_DIR_NAME) -+ endif -+Index: sope-appserver/NGObjWeb/WOCoreApplication.m -+=================================================================== -+--- sope-appserver/NGObjWeb/WOCoreApplication.m (révision 1632) -++++ sope-appserver/NGObjWeb/WOCoreApplication.m (copie de travail) -+@@ -730,9 +730,15 @@ -+ [self sopeMajorVersion], [self sopeMinorVersion]]; -+ } -+ + (NGResourceLocator *)ngobjwebResourceLocator { -++#if GNUSTEP_BASE_LIBRARY -+ return [NGResourceLocator resourceLocatorForGNUstepPath: -++ @"Libraries/Resources/NGObjWeb" -++ fhsPath:[self ngobjwebShareDirectorySubPath]]; -++#else -++ return [NGResourceLocator resourceLocatorForGNUstepPath: -+ @"Library/Libraries/Resources/NGObjWeb" -+ fhsPath:[self ngobjwebShareDirectorySubPath]]; -++#endif -+ } -+ -+ + (NSArray *)resourcesSearchPathes { -+Index: sope-appserver/NGObjWeb/NGHttp/GNUmakefile -+=================================================================== -+--- sope-appserver/NGObjWeb/NGHttp/GNUmakefile (révision 1632) -++++ sope-appserver/NGObjWeb/NGHttp/GNUmakefile (copie de travail) -+@@ -1,10 +1,8 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+-GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -+- -+ SUBPROJECT_NAME = NGHttp -+ -+ NGHttp_PCH_FILE = common.h -+@@ -37,5 +35,8 @@ -+ NGUrlFormCoder.m \ -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ include $(GNUSTEP_MAKEFILES)/subproject.make -+ -include GNUmakefile.postamble -+Index: sope-appserver/WEPrototype/GNUmakefile -+=================================================================== -+--- sope-appserver/WEPrototype/GNUmakefile (révision 1632) -++++ sope-appserver/WEPrototype/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ include ./Version -+@@ -10,7 +10,7 @@ -+ -+ BUNDLE_NAME = WEPrototype -+ BUNDLE_EXTENSION = .wox -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/WOxElemBuilders-$(MAJOR_VERSION).$(MINOR_VERSION)/ -++BUNDLE_INSTALL_DIR = $(SOPE_WOXBUILDERS)/ -+ else -+ FRAMEWORK_NAME = WEPrototype -+ endif -+@@ -46,6 +46,9 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ include $(GNUSTEP_MAKEFILES)/bundle.make -+@@ -53,4 +56,3 @@ -+ include $(GNUSTEP_MAKEFILES)/framework.make -+ endif -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-appserver/WEPrototype/doc/GNUmakefile -+=================================================================== -+--- sope-appserver/WEPrototype/doc/GNUmakefile (révision 1632) -++++ sope-appserver/WEPrototype/doc/GNUmakefile (copie de travail) -+@@ -2,7 +2,7 @@ -+ -+ SOPE_ROOT=../../.. -+ -+--include $(SOPE_ROOT)/config.make -++include $(SOPE_ROOT)/config.make -+ include $(SOPE_ROOT)/Version -+ include ../Version -+ -+Index: sope-appserver/WEPrototype/GNUmakefile.preamble -+=================================================================== -+--- sope-appserver/WEPrototype/GNUmakefile.preamble (révision 1632) -++++ sope-appserver/WEPrototype/GNUmakefile.preamble (copie de travail) -+@@ -1,4 +1,4 @@ -+-# compiler flags -++# GNUstep makefile -+ -+ SOPE_ROOT=../.. -+ -+@@ -21,7 +21,8 @@ -+ -I$(SOPE_ROOT)/sope-xml -+ -+ -+-libWEPrototype_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libWEPrototype_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libWEPrototype_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libWEPrototype_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ libWEPrototype_LIBRARIES_DEPEND_UPON += \ -+Index: sope-appserver/common.make -+=================================================================== -+--- sope-appserver/common.make (révision 1632) -++++ sope-appserver/common.make (copie de travail) -+@@ -4,8 +4,6 @@ -+ include ../Version -+ -include ./Version -+ -+-GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -+- -+ ADDITIONAL_CPPFLAGS += -pipe -Wall -Wno-protocol -+ -+ ADDITIONAL_INCLUDE_DIRS += \ -+Index: sope-appserver/samples/CoreDataBlog/GNUmakefile -+=================================================================== -+--- sope-appserver/samples/CoreDataBlog/GNUmakefile (révision 1632) -++++ sope-appserver/samples/CoreDataBlog/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ WOAPP_NAME = CoreDataBlog -+Index: sope-appserver/samples/HelloForm/GNUmakefile -+=================================================================== -+--- sope-appserver/samples/HelloForm/GNUmakefile (révision 1632) -++++ sope-appserver/samples/HelloForm/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ WOAPP_NAME = HelloForm -+Index: sope-appserver/samples/GNUmakefile -+=================================================================== -+--- sope-appserver/samples/GNUmakefile (révision 1632) -++++ sope-appserver/samples/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ SUBPROJECTS += \ -+Index: sope-appserver/samples/iCalPortal/GNUmakefile.preamble -+=================================================================== -+--- sope-appserver/samples/iCalPortal/GNUmakefile.preamble (révision 1632) -++++ sope-appserver/samples/iCalPortal/GNUmakefile.preamble (copie de travail) -+@@ -7,7 +7,9 @@ -+ -lEOControl \ -+ -lXmlRpc -lDOM -lSaxObjC -+ else -++ifneq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd) -+ ADDITIONAL_TOOL_LIBS += -lcrypt -+ endif -++endif -+ -+ SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib -+Index: sope-appserver/samples/iCalPortal/GNUmakefile -+=================================================================== -+--- sope-appserver/samples/iCalPortal/GNUmakefile (révision 1632) -++++ sope-appserver/samples/iCalPortal/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ WOAPP_NAME = iCalPortal -+Index: sope-appserver/samples/iCalPortal/Pages/GNUmakefile -+=================================================================== -+--- sope-appserver/samples/iCalPortal/Pages/GNUmakefile (révision 1632) -++++ sope-appserver/samples/iCalPortal/Pages/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../../config.make -++include ../../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ SUBPROJECT_NAME = Pages -+Index: sope-appserver/samples/iCalPortal/WebDAV/GNUmakefile -+=================================================================== -+--- sope-appserver/samples/iCalPortal/WebDAV/GNUmakefile (révision 1632) -++++ sope-appserver/samples/iCalPortal/WebDAV/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../../config.make -++include ../../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ SUBPROJECT_NAME = DAV -+Index: sope-appserver/samples/SoCookieAuth/GNUmakefile -+=================================================================== -+--- sope-appserver/samples/SoCookieAuth/GNUmakefile (révision 1632) -++++ sope-appserver/samples/SoCookieAuth/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ WOAPP_NAME = SoCookieAuth -+Index: sope-appserver/samples/WOxExtTest/GNUmakefile -+=================================================================== -+--- sope-appserver/samples/WOxExtTest/GNUmakefile (révision 1632) -++++ sope-appserver/samples/WOxExtTest/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ WOAPP_NAME = WOxExtTest -+Index: sope-appserver/samples/TestPages/GNUmakefile -+=================================================================== -+--- sope-appserver/samples/TestPages/GNUmakefile (révision 1632) -++++ sope-appserver/samples/TestPages/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ WOAPP_NAME = TestPages -+Index: sope-appserver/samples/parsedav/GNUmakefile -+=================================================================== -+--- sope-appserver/samples/parsedav/GNUmakefile (révision 1632) -++++ sope-appserver/samples/parsedav/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ TOOL_NAME = parsedav -+Index: sope-appserver/samples/xmlrpc/GNUmakefile -+=================================================================== -+--- sope-appserver/samples/xmlrpc/GNUmakefile (révision 1632) -++++ sope-appserver/samples/xmlrpc/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ TOOL_NAME = \ -+Index: sope-appserver/samples/TestPrototype/GNUmakefile -+=================================================================== -+--- sope-appserver/samples/TestPrototype/GNUmakefile (révision 1632) -++++ sope-appserver/samples/TestPrototype/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ WOAPP_NAME = TestPrototype -+Index: sope-appserver/samples/HelloWorld/GNUmakefile -+=================================================================== -+--- sope-appserver/samples/HelloWorld/GNUmakefile (révision 1632) -++++ sope-appserver/samples/HelloWorld/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ WOAPP_NAME = HelloWorld -+Index: sope-appserver/samples/davpropget/GNUmakefile -+=================================================================== -+--- sope-appserver/samples/davpropget/GNUmakefile (révision 1632) -++++ sope-appserver/samples/davpropget/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../../config.make -++include ../../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ TOOL_NAME = davpropget -+Index: sope-appserver/WOExtensions/GNUmakefile.preamble -+=================================================================== -+--- sope-appserver/WOExtensions/GNUmakefile.preamble (révision 1632) -++++ sope-appserver/WOExtensions/GNUmakefile.preamble (copie de travail) -+@@ -12,7 +12,8 @@ -+ -I$(SOPE_ROOT)/sope-xml -+ -+ -+-libWOExtensions_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libWOExtensions_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libWOExtensions_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libWOExtensions_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ -+Index: sope-appserver/WOExtensions/GNUmakefile -+=================================================================== -+--- sope-appserver/WOExtensions/GNUmakefile (révision 1632) -++++ sope-appserver/WOExtensions/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ../Version -+ include ./Version -+@@ -9,7 +9,7 @@ -+ LIBRARY_NAME = libWOExtensions -+ BUNDLE_NAME = WOExtensions -+ BUNDLE_EXTENSION = .wox -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/WOxElemBuilders-$(MAJOR_VERSION).$(MINOR_VERSION)/ -++BUNDLE_INSTALL_DIR = $(SOPE_WOXBUILDERS)/ -+ -+ else -+ FRAMEWORK_NAME = WOExtensions -+@@ -71,6 +71,9 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ include $(GNUSTEP_MAKEFILES)/bundle.make -+@@ -78,4 +81,3 @@ -+ include $(GNUSTEP_MAKEFILES)/framework.make -+ endif -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-appserver/WOXML/GNUmakefile -+=================================================================== -+--- sope-appserver/WOXML/GNUmakefile (révision 1632) -++++ sope-appserver/WOXML/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include ../common.make -+ include ../Version -+ include ./Version -+@@ -15,6 +15,7 @@ -+ libWOXML_PCH_FILE = common.h -+ libWOXML_HEADER_FILES_DIR = . -+ libWOXML_HEADER_FILES_INSTALL_DIR = /WOXML -++libWOXML_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ -+ -+ libWOXML_HEADER_FILES += \ -+@@ -42,10 +43,12 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ else -+ include $(GNUSTEP_MAKEFILES)/framework.make -+ endif -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-appserver/WOXML/GNUmakefile.preamble -+=================================================================== -+--- sope-appserver/WOXML/GNUmakefile.preamble (révision 1632) -++++ sope-appserver/WOXML/GNUmakefile.preamble (copie de travail) -+@@ -2,7 +2,7 @@ -+ -+ SOPE_ROOT=../.. -+ -+-libWOXML_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libWOXML_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+ libWOXML_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ libWOXML_INCLUDE_DIRS += -I. -I.. -+Index: sope-ical/samples/GNUmakefile -+=================================================================== -+--- sope-ical/samples/GNUmakefile (révision 1632) -++++ sope-ical/samples/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ TOOL_NAME = icalparsetest icalds vcf2xml vcfparsetest ievalrrule -+@@ -14,4 +14,3 @@ -+ -include GNUmakefile.preamble -+ include $(GNUSTEP_MAKEFILES)/tool.make -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-ical/versitSaxDriver/GNUmakefile -+=================================================================== -+--- sope-ical/versitSaxDriver/GNUmakefile (révision 1632) -++++ sope-ical/versitSaxDriver/GNUmakefile (copie de travail) -+@@ -1,13 +1,13 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -include ../../Version -+ -include ./Version -+ -+ BUNDLE_NAME = versitSaxDriver -+ BUNDLE_EXTENSION = .sax -+-BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/SaxDrivers-$(MAJOR_VERSION).$(MINOR_VERSION)/ -++BUNDLE_INSTALL_DIR = $(SOPE_SAXDRIVERS)/ -+ -+ versitSaxDriver_PRINCIPAL_CLASS = VSSaxDriver -+ -+@@ -24,4 +24,3 @@ -+ -include GNUmakefile.preamble -+ include $(GNUSTEP_MAKEFILES)/bundle.make -+ -include GNUmakefile.postamble -+--include fhs.make -+Index: sope-ical/GNUmakefile -+=================================================================== -+--- sope-ical/GNUmakefile (révision 1632) -++++ sope-ical/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../config.make -++include ../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ -+ PACKAGE_NAME=sope-ical -+Index: sope-ical/NGiCal/GNUmakefile.postamble -+=================================================================== -+--- sope-ical/NGiCal/GNUmakefile.postamble (révision 1632) -++++ sope-ical/NGiCal/GNUmakefile.postamble (copie de travail) -+@@ -1,10 +1,6 @@ -+ # compilation settings -+ -+-ifeq ($(FHS_INSTALL_ROOT),) -+-MAPDIR="$(GNUSTEP_INSTALLATION_DIR)/Library/SaxMappings/" -+-else -+-MAPDIR="$(FHS_INSTALL_ROOT)/share/sope-$(MAJOR_VERSION).$(MINOR_VERSION)/saxmappings/" -+-endif -++MAPDIR="$(SOPE_SAXMAPPINGS)/" -+ -+ mappings-dir :: -+ $(MKDIRS) $(MAPDIR) -+Index: sope-ical/NGiCal/GNUmakefile -+=================================================================== -+--- sope-ical/NGiCal/GNUmakefile (révision 1632) -++++ sope-ical/NGiCal/GNUmakefile (copie de travail) -+@@ -1,6 +1,6 @@ -+ # GNUstep makefile -+ -+--include ../../config.make -++include ../../config.make -+ include $(GNUSTEP_MAKEFILES)/common.make -+ include ./Version -+ -+@@ -14,7 +14,8 @@ -+ libNGiCal_PCH_FILE = common.h -+ libNGiCal_HEADER_FILES_DIR = . -+ libNGiCal_HEADER_FILES_INSTALL_DIR = /NGiCal -+-libNGiCal_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libNGiCal_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -++libNGiCal_INSTALL_DIR=$(SOPE_SYSLIBDIR) -+ libNGiCal_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) -+ -+ libNGiCal_HEADER_FILES = \ -+@@ -107,10 +108,12 @@ -+ # building -+ -+ -include GNUmakefile.preamble -++ifneq ($(FHS_INSTALL_ROOT),) -++GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -++endif -+ ifneq ($(frameworks),yes) -+ include $(GNUSTEP_MAKEFILES)/library.make -+ else -+ include $(GNUSTEP_MAKEFILES)/framework.make -+ endif -+ -include GNUmakefile.postamble -+--include fhs.make ---- sope-4.9.r1664.orig/debian/patches/debian-build-mysql.diff -+++ sope-4.9.r1664/debian/patches/debian-build-mysql.diff -@@ -0,0 +1,13 @@ -+diff -durpN sope-4.9.r1660.orig/configure sope-4.9.r1660/configure -+--- configure.orig 2009-10-28 09:46:53.000000000 -0400 -++++ configure 2009-10-28 09:48:41.000000000 -0400 -+@@ -475,8 +475,8 @@ checkDependencies() { -+ checkLinking "ssl" required; # TODO: make optional -+ fi -+ checkLinking "pq" optional; -+- checkLinking "sqlite3" optional; -+ checkLinking "mysqlclient" optional; -++ checkLinking "sqlite3" optional; -+ } -+ -+ runIt() { diff --git a/SOPE/sope-debugleaks.diff b/SOPE/sope-debugleaks.diff deleted file mode 100644 index 39cea24f8..000000000 --- a/SOPE/sope-debugleaks.diff +++ /dev/null @@ -1,29 +0,0 @@ -Index: sope-appserver/NGObjWeb/WOCoreApplication.m -=================================================================== ---- sope-appserver/NGObjWeb/WOCoreApplication.m (révision 1632) -+++ sope-appserver/NGObjWeb/WOCoreApplication.m (copie de travail) -@@ -157,6 +157,10 @@ - NSUserDefaults *ud; - NGLoggerManager *lm; - -+ GSDebugAllocationActive (YES); -+ GSDebugAllocationList (NO); -+ -+// GSDebugAllocationActiveRecordingObjects - [self registerUserDefaults]; - ud = [NSUserDefaults standardUserDefaults]; - lm = [NGLoggerManager defaultLoggerManager]; -@@ -535,10 +539,12 @@ - - if ([self isTerminating]) - break; -- -+ - [self activateApplication]; - [loop runMode:NSDefaultRunLoopMode beforeDate:limitDate]; - [self deactivateApplication]; -+ -+ NSLog (@"allocated classes:\n%s", GSDebugAllocationList (YES)); - } - - [pool release]; diff --git a/SOPE/sope-gsmake2.diff b/SOPE/sope-gsmake2.diff deleted file mode 100644 index b8b67757b..000000000 --- a/SOPE/sope-gsmake2.diff +++ /dev/null @@ -1,3144 +0,0 @@ -Index: configure -=================================================================== ---- configure (révision 1632) -+++ configure (copie de travail) -@@ -15,8 +15,9 @@ - ARG_NOCREATE=0 - ARG_PREFIX="" - ARG_FRAMEWORK_DIR="" --ARG_GSMAKE="$GNUSTEP_MAKEFILES" -+ARG_GSMAKE=`gnustep-config --variable=GNUSTEP_MAKEFILES` - ARG_CFGMAKE="$PWD/config.make" -+ARG_FHSMAKE="$PWD/fhs-postinstall.make" - ARG_WITH_GNUSTEP=0 - ARG_WITH_DEBUG=1 - ARG_WITH_STRIP=1 -@@ -30,12 +31,20 @@ - INTERNAL_MAKEDIR="${SOPE_SRCDIR}/.gsmake" - USES_INTERNAL_MAKE=no - -+# detect GNU make, needed at least on *BSD -+make -v 2>/dev/null | grep GNU >/dev/null 2>/dev/null -+if [ $? -eq 0 ];then -+ MAKE=make -+else -+ MAKE=gmake -+fi -+ - # TODO: add pg_config, mysql_config etc! - LINK_SYSLIBDIRS="-L/usr/local/pgsql/lib -L/usr/local/lib -L/usr/lib" - - # ******************** usage ******************** - --function usage() { -+usage() { - cat <<_ACEOF - \`configure' configures a GNUstep-make based sourcetree for installation. - -@@ -66,7 +75,7 @@ - - # ******************** running ******************** - --function printParas() { -+printParas() { - echo "Configuration:" - if test $ARG_BEQUIET = 1; then echo " will be quite."; fi - if test $ARG_NOCREATE = 1; then echo " won't create files"; fi -@@ -97,7 +106,7 @@ - echo "" - } - --function warnOnFHSPrefix() { -+warnOnFHSPrefix() { - cat <<_ACEOFWARN - Warning: you are configuring for a non standard FHS style prefix. - prefix: $ARG_PREFIX -@@ -114,7 +123,7 @@ - _ACEOFWARN - } - --function setupInternalGSMake() { -+setupInternalGSMake() { - if test -f ${INTERNAL_MAKEDIR}/Library/Makefiles/GNUstep.sh; then - ARG_GSMAKE="${INTERNAL_MAKEDIR}/Library/Makefiles/" - ARG_IS_FHS=1 -@@ -149,7 +158,7 @@ - --with-library-combo="${SETUP_COMBO}" - - echo -n ".. install .." -- make install >>${pregsmdir}/${SETUP_LOGNAME} -+ $MAKE install >>${pregsmdir}/${SETUP_LOGNAME} - - ARG_GSMAKE="${INTERNAL_MAKEDIR}/Library/Makefiles/" - ARG_IS_FHS=1 -@@ -174,7 +183,7 @@ - fi - } - --function validateGNUstepArgs() { -+validateGNUstepArgs() { - # GNUstep make - if test "x$ARG_GSMAKE" = "x"; then - if test -f $HOME/OGoRoot/Library/Makefiles/GNUstep.sh; then -@@ -203,7 +212,7 @@ - fi - } - --function setupAppleArgs() { -+setupAppleArgs() { - ARG_WITH_STRIP=0 - if test "x${USES_INTERNAL_MAKE}" = "no"; then - ARG_WITH_GNUSTEP=1 -@@ -218,7 +227,7 @@ - #fi - } - --function validateArgs() { -+validateArgs() { - # validate prefix (could be better?) - case "x$ARG_PREFIX" in - "x/usr/local"|"x/usr/local/") -@@ -273,7 +282,7 @@ - fi - } - --function printGNUstepSetup() { -+printGNUstepSetup() { - echo "GNUstep environment:" - echo " system: ${GNUSTEP_SYSTEM_ROOT}" - echo " local: ${GNUSTEP_LOCAL_ROOT}" -@@ -285,11 +294,11 @@ - echo "" - } - --function cfgwrite() { -+cfgwrite() { - echo "$1" >> $ARG_CFGMAKE - } - --function genConfigMake() { -+genConfigMake() { - # we ignore the following vars also patches by gstep-make: - # PATH - # DYLD_LIBRARY_PATH -@@ -303,6 +312,8 @@ - echo "# GNUstep environment configuration" > $ARG_CFGMAKE - cfgwrite "# created by: '$CFG_ARGS'" - cfgwrite "" -+ cfgwrite "SOPE_ROOT=`pwd`" -+ cfgwrite "include \${SOPE_ROOT}/Version" - - cfgwrite "# Note: you can override any option as a 'make' parameter, eg:" - cfgwrite "# make debug=yes" -@@ -313,7 +324,27 @@ - #cfgwrite " @echo Local GNUstep config.make is active" - #cfgwrite "" - -- # TODO: should be also write a GNUSTEP_INSTALLATION_DIR / BUNDLE_INSTALL_DIR? -+ # Note: GNUSTEP_TARGET_CPU is not yet available (set by common.make), so we -+ # only have environment variables -+ # Note: we can't set SYSTEM_LIB_DIR in this location, it gets overridden by -+ # common.make -+ UNAME=`uname` -+ if [ "X${UNAME}" = "XLinux" ];then -+ UNAME=`uname -p` -+ if [ ${UNAME} = x86_64 -o ${UNAME} = sparc64 -o ${UNAME} = ppc64 ];then -+ cfgwrite "CGS_LIBDIR_NAME:=lib64" -+ else -+ cfgwrite "CGS_LIBDIR_NAME:=lib" -+ fi -+ else -+ cfgwrite "CGS_LIBDIR_NAME:=lib" -+ fi -+ cfgwrite "ifneq (\$(FHS_INSTALL_ROOT),)" -+ cfgwrite "CONFIGURE_FHS_INSTALL_LIBDIR:=\$(FHS_INSTALL_ROOT)/\$(CGS_LIBDIR_NAME)/" -+ cfgwrite "CONFIGURE_SYSTEM_LIB_DIR += -L\$(CONFIGURE_FHS_INSTALL_LIBDIR)" -+ cfgwrite "endif" -+ cfgwrite "GNUSTEP_INSTALLATION_DOMAIN:=LOCAL" -+ cfgwrite "CONFIGURE_SYSTEM_LIB_DIR += -L/usr/\$(CGS_LIBDIR_NAME)/" - - - if test "x$ARG_FRAMEWORK_DIR" != "x"; then -@@ -325,13 +356,38 @@ - cfgwrite "# configured for FHS install" - cfgwrite "FHS_INSTALL_ROOT:=$ARG_PREFIX" - cfgwrite "" -+ cfgwrite "SOPE_SYSLIBDIR=\${DESTDIR}\${FHS_INSTALL_ROOT}/\$(CGS_LIBDIR_NAME)" -+ cfgwrite "SOPE_LIBDIR=\${SOPE_SYSLIBDIR}/sope-\${MAJOR_VERSION}.\${MINOR_VERSION}" -+ cfgwrite "SOPE_SYSSHAREDIR=\${DESTDIR}\${FHS_INSTALL_ROOT}/share" -+ cfgwrite "SOPE_SHAREDIR=\${SOPE_SYSSHAREDIR}/sope-\${MAJOR_VERSION}.\${MINOR_VERSION}" -+ cfgwrite "SOPE_DBADAPTORS=\${SOPE_LIBDIR}/dbadaptors" -+ cfgwrite "SOPE_PRODUCTS=\${SOPE_LIBDIR}/products" -+ cfgwrite "SOPE_SAXDRIVERS=\${SOPE_LIBDIR}/saxdrivers" -+ cfgwrite "SOPE_WOXBUILDERS=\${SOPE_LIBDIR}/wox-builders" -+ cfgwrite "SOPE_NGOBJWEB=\${SOPE_SHAREDIR}/ngobjweb" -+ cfgwrite "SOPE_SAXMAPPINGS=\${SOPE_SHAREDIR}/saxmappings" -+ cfgwrite "SOPE_TOOLS=\${DESTDIR}\${FHS_INSTALL_ROOT}/bin" -+ cfgwrite "SOPE_ADMIN_TOOLS=\${DESTDIR}\${FHS_INSTALL_ROOT}/sbin" -+ cfgwrite "" - else - cfgwrite "# configured for GNUstep install" -+ cfgwrite "" -+ cfgwrite "SOPE_SYSLIBDIR=\${GNUSTEP_LIBRARIES}" -+ cfgwrite "SOPE_LIBDIR=\${GNUSTEP_LIBRARY}" -+ cfgwrite "SOPE_DBADAPTORS=\${SOPE_LIBDIR}/GDLAdaptors-\${MAJOR_VERSION}.\${MINOR_VERSION}" -+ cfgwrite "SOPE_PRODUCTS=\${SOPE_LIBDIR}/SoProducts-\${MAJOR_VERSION}.\${MINOR_VERSION}" -+ cfgwrite "SOPE_SAXDRIVERS=\${SOPE_LIBDIR}/SaxDrivers-\${MAJOR_VERSION}.\${MINOR_VERSION}" -+ cfgwrite "SOPE_NGOBJWEB=\${GNUSTEP_RESOURCES}/NGObjWeb" -+ cfgwrite "SOPE_WOXBUILDERS=\${GNUSTEP_LIBRARY}/WOxElemBuilders-\${MAJOR_VERSION}.\${MINOR_VERSION}" -+ cfgwrite "SOPE_SAXMAPPINGS=\${GNUSTEP_LIBRARY}/SaxMappings" -+ cfgwrite "SOPE_TOOLS=\${GNUSTEP_TOOLS}" -+ cfgwrite "SOPE_ADMIN_TOOLS=\${GNUSTEP_ADMIN_TOOLS}" - fi - - if test $ARG_WITH_DEBUG = 1; then - cfgwrite "# configured to produce debugging code"; - cfgwrite "debug:=yes" -+ - else - cfgwrite "# configured to produce non-debugging code"; - cfgwrite "debug:=no" -@@ -358,29 +414,9 @@ - done - cfgwrite "LIBRARY_COMBO=$LIBRARY_COMBO" - cfgwrite "" -- -- # Note: GNUSTEP_TARGET_CPU is not yet available (set by common.make), so we -- # only have environment variables -- # Note: we can't set SYSTEM_LIB_DIR in this location, it gets overridden by -- # common.make -- cfgwrite "ifeq (\$(findstring _64, \$(GNUSTEP_HOST_CPU)), _64)" -- cfgwrite "CONFIGURE_64BIT:=yes" -- cfgwrite "CGS_LIBDIR_NAME:=lib64" -- cfgwrite "else" -- cfgwrite "CGS_LIBDIR_NAME:=lib" -- cfgwrite "endif" -- -- cfgwrite "ifneq (\$(FHS_INSTALL_ROOT),)" -- cfgwrite "CONFIGURE_FHS_INSTALL_LIBDIR:=\$(FHS_INSTALL_ROOT)/\$(CGS_LIBDIR_NAME)/" -- cfgwrite "CONFIGURE_SYSTEM_LIB_DIR += -L\$(CONFIGURE_FHS_INSTALL_LIBDIR)" -- cfgwrite "endif" -- cfgwrite "CONFIGURE_SYSTEM_LIB_DIR += -L/usr/\$(CGS_LIBDIR_NAME)/" -- -- cfgwrite "# avoid a gstep-make warning" -- cfgwrite "PATH:=\$(GNUSTEP_SYSTEM_ROOT)/Tools:\$(PATH)" - } - --function checkLinking() { -+checkLinking() { - # library-name => $1, type => $2 - local oldpwd=$PWD - local tmpdir=".configure-test-$$" -@@ -388,18 +424,26 @@ - mkdir $tmpdir - cd $tmpdir - cp ../maintenance/dummytool.c . -+ -+ for LIB in $1;do -+ LIBS="$LIBS -l${LIB}" -+ done - - tmpmake="GNUmakefile" -- echo >$tmpmake "include ../config.make" -+ echo >$tmpmake "-include ../config.make" - echo >>$tmpmake "include \$(GNUSTEP_MAKEFILES)/common.make" - echo >>$tmpmake "CTOOL_NAME := linktest" - echo >>$tmpmake "linktest_C_FILES := dummytool.c" -- echo >>$tmpmake "linktest_TOOL_LIBS += -l$1" -+ echo >>$tmpmake "ifeq (\$(findstring openbsd, \$(GNUSTEP_HOST_OS)), openbsd)" -+ echo >>$tmpmake "linktest_TOOL_LIBS += $LIBS -liconv" -+ echo >>$tmpmake "else" -+ echo >>$tmpmake "linktest_TOOL_LIBS += $LIBS" -+ echo >>$tmpmake "endif" - echo >>$tmpmake "SYSTEM_LIB_DIR += \$(CONFIGURE_SYSTEM_LIB_DIR)" - echo >>$tmpmake "SYSTEM_LIB_DIR += ${LINK_SYSLIBDIRS}" - echo >>$tmpmake "include \$(GNUSTEP_MAKEFILES)/ctool.make" - -- make -s messages=yes -f $tmpmake linktest >out.log 2>err.log -+ $MAKE -s messages=yes -f $tmpmake linktest >out.log 2>err.log - LINK_RESULT=$? - - if test $LINK_RESULT = 0; then -@@ -420,18 +464,22 @@ - rm -rf $tmpdir - } - --function checkDependencies() { -+checkDependencies() { - cfgwrite "" - cfgwrite "# library dependencies" - checkLinking "xml2" optional; - checkLinking "ldap" optional; -- checkLinking "ssl" required; # TODO: make optional -+ if [ `uname` = "OpenBSD" ];then -+ checkLinking "ssl crypto" required; # TODO: make optional -+ else -+ checkLinking "ssl" required; # TODO: make optional -+ fi - checkLinking "pq" optional; - checkLinking "sqlite3" optional; - checkLinking "mysqlclient" optional; - } - --function runIt() { -+runIt() { - if test $ARG_BEQUIET != 1; then - printParas; - fi -@@ -459,11 +507,11 @@ - - # ******************** options ******************** - --function extractFuncValue() { -+extractFuncValue() { - VALUE="`echo "$1" | sed "s/[^=]*=//g"`" - } - --function processOption() { -+processOption() { - case "x$1" in - "x--help"|"x-h") - usage; -@@ -518,7 +566,7 @@ - # load GNUstep environment - validateGNUstepArgs - # first we load the GNUstep.sh environment --source $DARG_GNUSTEP_SH -+. $DARG_GNUSTEP_SH - if test $ARG_BEQUIET != 1; then - printGNUstepSetup; - fi -Index: sope-ldap/samples/GNUmakefile -=================================================================== ---- sope-ldap/samples/GNUmakefile (révision 1632) -+++ sope-ldap/samples/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - TOOL_NAME = \ -@@ -9,8 +9,11 @@ - ldapchkpwd \ - - ldapls_OBJC_FILES = ldapls.m -+ldapls_INSTALL_DIR = $(SOPE_TOOLS)/ - ldap2dsml_OBJC_FILES = ldap2dsml.m -+ldap2dsml_INSTALL_DIR = $(SOPE_TOOLS)/ - ldapchkpwd_OBJC_FILES = ldapchkpwd.m -+ldapchkpwd_INSTALL_DIR = $(SOPE_TOOLS)/ - - #TOOL_NAME = #pwd-check - #pwd-check_OBJC_FILES = pwd-check.m -@@ -19,4 +22,3 @@ - -include GNUmakefile.preamble - include $(GNUSTEP_MAKEFILES)/tool.make - -include GNUmakefile.postamble ---include fhs.make -Index: sope-ldap/NGLdap/GNUmakefile -=================================================================== ---- sope-ldap/NGLdap/GNUmakefile (révision 1632) -+++ sope-ldap/NGLdap/GNUmakefile (copie de travail) -@@ -1,11 +1,9 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ./Version - --GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -- - ifneq ($(frameworks),yes) - LIBRARY_NAME = libNGLdap - else -@@ -15,7 +13,8 @@ - libNGLdap_PCH_FILE = common.h - libNGLdap_HEADER_FILES_DIR = . - libNGLdap_HEADER_FILES_INSTALL_DIR = /NGLdap --libNGLdap_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libNGLdap_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libNGLdap_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libNGLdap_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - libNGLdap_HEADER_FILES = \ -@@ -61,10 +60,12 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - else - include $(GNUSTEP_MAKEFILES)/framework.make - endif - -include GNUmakefile.postamble ---include fhs.make -Index: sope-ldap/GNUmakefile -=================================================================== ---- sope-ldap/GNUmakefile (révision 1632) -+++ sope-ldap/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../config.make -+include ../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - PACKAGE_NAME=sope-ldap -Index: GNUmakefile -=================================================================== ---- GNUmakefile (révision 1632) -+++ GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ./config.make -+include ./config.make - - ifeq ($(GNUSTEP_MAKEFILES),) - -@@ -35,8 +35,6 @@ - include $(GNUSTEP_MAKEFILES)/aggregate.make - -include $(GNUSTEP_MAKEFILES)/GNUmakefile.postamble - --include ./Version -- - endif - - distclean :: -Index: sope-gdl1/PostgreSQL/GNUmakefile.preamble -=================================================================== ---- sope-gdl1/PostgreSQL/GNUmakefile.preamble (révision 1632) -+++ sope-gdl1/PostgreSQL/GNUmakefile.preamble (copie de travail) -@@ -27,7 +27,7 @@ - ifeq ($(frameworks),yes) - BUNDLE_INSTALL_DIR := $(FRAMEWORK_INSTALL_DIR)/GDLAccess.framework/Resources/GDLAdaptors/ - else --BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/GDLAdaptors-$(MAJOR_VERSION).$(MINOR_VERSION)/ -+BUNDLE_INSTALL_DIR = $(SOPE_DBADAPTORS)/ - endif - - -Index: sope-gdl1/PostgreSQL/GNUmakefile -=================================================================== ---- sope-gdl1/PostgreSQL/GNUmakefile (révision 1632) -+++ sope-gdl1/PostgreSQL/GNUmakefile (copie de travail) -@@ -22,7 +22,7 @@ - # If not, write to the Free Software Foundation, - # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - include ./Version -@@ -70,4 +70,3 @@ - include $(GNUSTEP_MAKEFILES)/bundle.make - #include $(GNUSTEP_MAKEFILES)/tool.make - -include GNUmakefile.postamble --include fhs.make -Index: sope-gdl1/SQLite3/GNUmakefile.preamble -=================================================================== ---- sope-gdl1/SQLite3/GNUmakefile.preamble (révision 1632) -+++ sope-gdl1/SQLite3/GNUmakefile.preamble (copie de travail) -@@ -27,7 +27,7 @@ - ifeq ($(frameworks),yes) - BUNDLE_INSTALL_DIR := $(FRAMEWORK_INSTALL_DIR)/GDLAccess.framework/Resources/GDLAdaptors/ - else --BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/GDLAdaptors-$(MAJOR_VERSION).$(MINOR_VERSION)/ -+BUNDLE_INSTALL_DIR = $(SOPE_DBADAPTORS)/ - endif - - -Index: sope-gdl1/SQLite3/GNUmakefile -=================================================================== ---- sope-gdl1/SQLite3/GNUmakefile (révision 1632) -+++ sope-gdl1/SQLite3/GNUmakefile (copie de travail) -@@ -22,7 +22,7 @@ - # If not, write to the Free Software Foundation, - # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - include ./Version -@@ -67,4 +67,3 @@ - include $(GNUSTEP_MAKEFILES)/tool.make - endif - -include GNUmakefile.postamble --include fhs.make -Index: sope-gdl1/FrontBase2/GNUmakefile -=================================================================== ---- sope-gdl1/FrontBase2/GNUmakefile (révision 1632) -+++ sope-gdl1/FrontBase2/GNUmakefile (copie de travail) -@@ -22,7 +22,7 @@ - # If not, write to the Free Software Foundation, - # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - CAN_COMPILE_FB = \ -@@ -30,8 +30,6 @@ - - ifeq ($(CAN_COMPILE_FB),yes) - --GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -- - BUNDLE_NAME = FrontBase2 - - FrontBase2_OBJC_FILES = \ -@@ -51,7 +49,7 @@ - FrontBase2_RESOURCE_FILES = Info.plist Version - - BUNDLE_INSTALL = FrontBase2 --BUNDLE_INSTALL_DIR = $(GNUSTEP_SYSTEM_ROOT)/Libraries/Adaptors -+BUNDLE_INSTALL_DIR = $(SOPE_DBADAPTORS)/ - - # Use .gdladaptor as the bundle extension - BUNDLE_EXTENSION = .gdladaptor -Index: sope-gdl1/MySQL/GNUmakefile.preamble -=================================================================== ---- sope-gdl1/MySQL/GNUmakefile.preamble (révision 1632) -+++ sope-gdl1/MySQL/GNUmakefile.preamble (copie de travail) -@@ -27,7 +27,7 @@ - ifeq ($(frameworks),yes) - BUNDLE_INSTALL_DIR := $(FRAMEWORK_INSTALL_DIR)/GDLAccess.framework/Resources/GDLAdaptors/ - else --BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/GDLAdaptors-$(MAJOR_VERSION).$(MINOR_VERSION)/ -+BUNDLE_INSTALL_DIR = $(SOPE_DBADAPTORS)/ - endif - - -Index: sope-gdl1/MySQL/GNUmakefile -=================================================================== ---- sope-gdl1/MySQL/GNUmakefile (révision 1632) -+++ sope-gdl1/MySQL/GNUmakefile (copie de travail) -@@ -22,7 +22,7 @@ - # If not, write to the Free Software Foundation, - # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - include ./Version -@@ -67,4 +67,3 @@ - include $(GNUSTEP_MAKEFILES)/tool.make - endif - -include GNUmakefile.postamble --include fhs.make -Index: sope-gdl1/GNUmakefile -=================================================================== ---- sope-gdl1/GNUmakefile (révision 1632) -+++ sope-gdl1/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../config.make -+include ../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - PACKAGE_NAME=sope-gdl1 -Index: sope-gdl1/GDLAccess/GNUmakefile.preamble -=================================================================== ---- sope-gdl1/GDLAccess/GNUmakefile.preamble (révision 1632) -+++ sope-gdl1/GDLAccess/GNUmakefile.preamble (copie de travail) -@@ -21,17 +21,12 @@ - -I$(SOPE_ROOT)/sope-core/NGExtensions/ - - --# Parameters for EOAdaptor lookup - --ifneq ($(FHS_INSTALL_ROOT),) --ADDITIONAL_CPPFLAGS += -DFHS_INSTALL_ROOT=\@\"$(FHS_INSTALL_ROOT)\" -+ifneq ($(CGS_LIBDIR_NAME),) -+ADDITIONAL_CPPFLAGS += -DCGS_LIBDIR_NAME=\@\"$(CGS_LIBDIR_NAME)\" - endif - --ifeq ($(CONFIGURE_64BIT),yes) --ADDITIONAL_CPPFLAGS += -DCONFIGURE_64BIT=1 --endif - -- - # dependencies - - libGDLAccess_LIBRARIES_DEPEND_UPON += -lEOControl -Index: sope-gdl1/GDLAccess/GNUmakefile -=================================================================== ---- sope-gdl1/GDLAccess/GNUmakefile (révision 1632) -+++ sope-gdl1/GDLAccess/GNUmakefile (copie de travail) -@@ -1,12 +1,10 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include ../common.make - -include ../Version - -include ./Version - --GNUSTEP_INSTALLATION_DIR = ${GNUSTEP_LOCAL_ROOT} -- - ifneq ($(frameworks),yes) - LIBRARY_NAME = libGDLAccess - else -@@ -14,7 +12,8 @@ - endif - - libGDLAccess_PCH_FILE = common.h --libGDLAccess_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libGDLAccess_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libGDLAccess_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libGDLAccess_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - libGDLAccess_DLL_DEF = libGDLAccess.def -@@ -123,6 +122,8 @@ - connect-EOAdaptor_OBJC_FILES = connect-EOAdaptor.m - load-EOAdaptor_PCH_FILE = common.h - connect-EOAdaptor_PCH_FILE = common.h -+load-EOAdaptor_INSTALL_DIR = $(SOPE_TOOLS)/ -+connect-EOAdaptor_INSTALL_DIR = $(SOPE_TOOLS)/ - - - # framework support -@@ -136,6 +137,9 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - else -@@ -143,4 +147,3 @@ - endif - include $(GNUSTEP_MAKEFILES)/tool.make - -include GNUmakefile.postamble --include fhs.make -Index: sope-gdl1/GDLAccess/EOAdaptor.h -=================================================================== ---- sope-gdl1/GDLAccess/EOAdaptor.h (révision 1632) -+++ sope-gdl1/GDLAccess/EOAdaptor.h (copie de travail) -@@ -62,11 +62,14 @@ - + (id)adaptorWithModel:(EOModel *)aModel; - + (id)adaptorWithName:(NSString *)aName; - + (id)adaptorForURL:(id)_url; -++ (NSString *)libraryDriversSubDir; - - (id)initWithName:(NSString *)aName; - - /* Getting an adaptor's name */ - - (NSString*)name; - -+/* Get the library subdir name */ -+ - /* Setting connection information */ - - (void)setConnectionDictionary:(NSDictionary*)aDictionary; - - (NSDictionary*)connectionDictionary; -Index: sope-gdl1/GDLAccess/EOAdaptor.m -=================================================================== ---- sope-gdl1/GDLAccess/EOAdaptor.m (révision 1632) -+++ sope-gdl1/GDLAccess/EOAdaptor.m (copie de travail) -@@ -53,14 +53,23 @@ - + (NSArray *)adaptorSearchPathes { - // TODO: add support for Cocoa - static NSArray *searchPathes = nil; -- NSDictionary *env; - NSMutableArray *ma; - id tmp; - - if (searchPathes != nil) return searchPathes; - -+ ma = [NSMutableArray arrayWithCapacity:8]; -+ -+#if GNUSTEP_BASE_LIBRARY -+ NSEnumerator *libraryPaths; -+ NSString *directory, *suffix; -+ suffix = [self libraryDriversSubDir]; -+ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -+ while ((directory = [libraryPaths nextObject])) -+ [ma addObject: [directory stringByAppendingPathComponent: suffix]]; -+#else -+ NSDictionary *env; - env = [[NSProcessInfo processInfo] environment]; -- ma = [NSMutableArray arrayWithCapacity:8]; - - if ((tmp = [env objectForKey:@"GNUSTEP_PATHPREFIX_LIST"]) == nil) - tmp = [env objectForKey:@"GNUSTEP_PATHLIST"]; -@@ -79,10 +88,11 @@ - [ma addObject:tmp]; - } - } -+#endif - - tmp = [NSString stringWithFormat: --#if CONFIGURE_64BIT -- @"/lib64/sope-%i.%i/dbadaptors", -+#ifdef CGS_LIBDIR_NAME -+ [CGS_LIBDIR_NAME stringByAppendingString:@"/sope-%i.%i/dbadaptors"], - #else - @"/lib/sope-%i.%i/dbadaptors", - #endif -@@ -92,9 +102,8 @@ - [ma addObject:[FHS_INSTALL_ROOT stringByAppendingPathComponent:tmp]]; - #endif - -- [ma addObject:[@"/usr/local" stringByAppendingString:tmp]]; -- [ma addObject:[@"/usr" stringByAppendingString:tmp]]; -- -+ [ma addObject:[@"/usr/local/" stringByAppendingString:tmp]]; -+ [ma addObject:[@"/usr/" stringByAppendingString:tmp]]; - searchPathes = [ma copy]; - if ([searchPathes count] == 0) - NSLog(@"%s: empty library search path !", __PRETTY_FUNCTION__); -@@ -213,6 +222,11 @@ - return _scheme; - } - -++ (NSString *)libraryDriversSubDir { -+ return [NSString stringWithFormat:@"GDLAdaptors-%i.%i", -+ GDL_MAJOR_VERSION, GDL_MINOR_VERSION]; -+} -+ - - (NSDictionary *)connectionDictionaryForNSURL:(NSURL *)_url { - /* - "Database URLs" -Index: sope-gdl1/GDLAccess/FoundationExt/GNUmakefile -=================================================================== ---- sope-gdl1/GDLAccess/FoundationExt/GNUmakefile (révision 1632) -+++ sope-gdl1/GDLAccess/FoundationExt/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../../Version - include ../Version -Index: sope-gdl1/GDLAccess/common.h -=================================================================== ---- sope-gdl1/GDLAccess/common.h (révision 1632) -+++ sope-gdl1/GDLAccess/common.h (copie de travail) -@@ -42,7 +42,7 @@ - #import - #import - --#if !(COCOA_Foundation_LIBRARY || NeXT_Foundation_LIBRARY) -+#if !(COCOA_Foundation_LIBRARY || NeXT_Foundation_LIBRARY || GNUSTEP_BASE_LIBRARY) - # import - #endif - -Index: sope-gdl1/Oracle8/GNUmakefile -=================================================================== ---- sope-gdl1/Oracle8/GNUmakefile (révision 1632) -+++ sope-gdl1/Oracle8/GNUmakefile (copie de travail) -@@ -19,7 +19,7 @@ - # License along with this library; if not, write to the Free Software - # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - # ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - include ./Version -@@ -51,7 +51,7 @@ - ifeq ($(frameworks),yes) - BUNDLE_INSTALL_DIR := $(FRAMEWORK_INSTALL_DIR)/GDLAccess.framework/Resources/GDLAdaptors/ - else --BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/GDLAdaptors-$(MAJOR_VERSION).$(MINOR_VERSION)/ -+BUNDLE_INSTALL_DIR = $(SOPE_DBADAPTORS)/ - endif - - Oracle8_OBJC_FILES = \ -Index: sope-mime/NGImap4/GNUmakefile -=================================================================== ---- sope-mime/NGImap4/GNUmakefile (révision 1632) -+++ sope-mime/NGImap4/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - -@@ -63,7 +63,10 @@ - NGImap4MailboxInfo.m \ - NGImap4ConnectionManager.m \ - ---include GNUmakefile.preamble -+include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/subproject.make - else -Index: sope-mime/samples/GNUmakefile -=================================================================== ---- sope-mime/samples/GNUmakefile (révision 1632) -+++ sope-mime/samples/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - TOOL_NAME = \ -@@ -14,16 +14,24 @@ - imapcontest \ - - imapquota_OBJC_FILES = ImapQuotaTool.m ImapTool.m imapquota.m -+imapquota_INSTALL_DIR = $(SOPE_TOOLS) - imapacl_OBJC_FILES = ImapQuotaTool.m ImapTool.m imapacl.m -+imapctl_INSTALL_DIR = $(SOPE_TOOLS) - imapget_OBJC_FILES = ImapTool.m imapget.m -+imapget_INSTALL_DIR = $(SOPE_TOOLS) - imap_tool_OBJC_FILES = imap_tool.m -+imap_tool_INSTALL_DIR = $(SOPE_TOOLS) - mime2xml_OBJC_FILES = Mime2XmlTool.m mime2xml.m -+mime2xml_INSTALL_DIR = $(SOPE_TOOLS) - imapls_OBJC_FILES = ImapTool.m ImapListTool.m imapls.m -+imapls_INSTALL_DIR = $(SOPE_TOOLS) - test_qpdecode_OBJC_FILES = test_qpdecode.m -+test_qpdecode_INSTALL_DIR= $(SOPE_TOOLS) - sievetool_OBJC_FILES = sievetool.m -+sievetool_INSTALL_DIR = $(SOPE_TOOLS) - imapcontest_OBJC_FILES = imapcontest.m -+imapcontest_INSTALL_DIR = $(SOPE_TOOLS) - - -include GNUmakefile.preamble - include $(GNUSTEP_MAKEFILES)/tool.make - -include GNUmakefile.postamble ---include fhs.make -Index: sope-mime/NGMail/GNUmakefile -=================================================================== ---- sope-mime/NGMail/GNUmakefile (révision 1632) -+++ sope-mime/NGMail/GNUmakefile (copie de travail) -@@ -1,10 +1,8 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - --GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -- - ifneq ($(frameworks),yes) - SUBPROJECT_NAME = NGMail - else -@@ -55,6 +53,9 @@ - NSData+MimeQP.m \ - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/subproject.make - else -Index: sope-mime/GNUmakefile -=================================================================== ---- sope-mime/GNUmakefile (révision 1632) -+++ sope-mime/GNUmakefile (copie de travail) -@@ -1,11 +1,9 @@ - # GNUstep makefile - ---include ../config.make -+include ../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ./Version - --GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -- - ifneq ($(frameworks),yes) - LIBRARY_NAME = libNGMime - else -@@ -14,7 +12,8 @@ - - libNGMime_HEADER_FILES_DIR = . - libNGMime_HEADER_FILES_INSTALL_DIR = /NGMime --libNGMime_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libNGMime_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libNGMime_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libNGMime_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - ifneq ($(frameworks),yes) -@@ -35,6 +34,9 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - else -@@ -42,7 +44,6 @@ - include $(GNUSTEP_MAKEFILES)/aggregate.make - endif - -include GNUmakefile.postamble ---include fhs.make - - - # package -Index: sope-mime/NGMime/GNUmakefile.preamble -=================================================================== ---- sope-mime/NGMime/GNUmakefile.preamble (révision 1632) -+++ sope-mime/NGMime/GNUmakefile.preamble (copie de travail) -@@ -5,6 +5,15 @@ - -DLIBRARY_MINOR_VERSION=${MINOR_VERSION} \ - -DLIBRARY_SUBMINOR_VERSION=${SUBMINOR_VERSION} \ - -+ifeq ($(patsubstr GNU/%,glibc,$(shell uname -o)),glibc) -+ADDITIONAL_CPPFLAGS += \ -+ -DHAVE_STRNDUP -+endif -+ -+ifneq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd) -+ ADDITIONAL_CPPFLAGS += -DHAVE_STRNDUP -+endif -+ - NGMime_INCLUDE_DIRS += \ - -I.. -I../.. \ - -I../../sope-core/NGStreams/ \ -Index: sope-mime/NGMime/GNUmakefile -=================================================================== ---- sope-mime/NGMime/GNUmakefile (révision 1632) -+++ sope-mime/NGMime/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - -@@ -76,5 +76,8 @@ - NGMimeRfc822BodyGenerator.m \ - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - include $(GNUSTEP_MAKEFILES)/subproject.make - -include GNUmakefile.postamble -Index: sope-core/NGExtensions/NGExtensions/NGResourceLocator.h -=================================================================== ---- sope-core/NGExtensions/NGExtensions/NGResourceLocator.h (révision 1632) -+++ sope-core/NGExtensions/NGExtensions/NGResourceLocator.h (copie de travail) -@@ -52,23 +52,54 @@ - int reserved:29; - } flags; - } -- -+/* The 'GNUstepPath' is a string describing the required path. This -+ * is the relative location of the path in a standard GNUstep -+ * hierarchy when a standard GNUstep hierarchy is being used; but if -+ * gnustep-base (which supports arbitrary filesystem layouts) is being -+ * used, the path is heuristically mapped to the standard paths -+ * accepted by NSSearchPathForDirectoriesInDomains using the following -+ * logic: -+ * -+ * "Library/WebApplications" --> GSWebApplicationsDirectory -+ * "Library/Libraries" --> GSLibrariesDirectory -+ * "Tools" --> GSToolsDirectory -+ * "Tools/Admin" --> GSAdminToolsDirectory -+ * "Applications" --> GSApplicationsDirectory -+ * "Applications/Admin" --> GSAdminApplicationsDirectory -+ * "Library/xxx" --> NSLibraryDirectory/xxx -+ * "yyy" --> NSLibraryDirectory/yyy -+ * -+ * In the last two cases 'xxx' and 'yyy' are arbitrary strings/paths -+ * that don't match anything else. Eg, if you create an -+ * NGResourceLocators to look up files in "Library/Resources" you will -+ * get one that looks them up in NSLibraryDirectory/Resources (which -+ * means a list of directories containing -+ * GNUSTEP_USER_LIBRARY/Resources, GNUSTEP_LOCAL_LIBRARY/Resources, -+ * GNUSTEP_NETWORK_LIBRARY/Resources, -+ * GNUSTEP_SYSTEM_LIBRARY/Resources). -+ */ - + (id)resourceLocatorForGNUstepPath:(NSString *)_path fhsPath:(NSString *)_fhs; - - (id)initWithGNUstepPath:(NSString *)_path fhsPath:(NSString *)_fhs; - - /* resource pathes */ - -+/* It's not a good idea to access these directly if you want portable -+ * code. More logical to use directly the 'operations' lookup methods -+ * below which encapsulate all the internal filesystem details. -+ */ - - (NSArray *)gsRootPathes; /* GNUSTEP_PATHPREFIX_LIST or MacOSX */ - - (NSArray *)fhsRootPathes; - - (NSArray *)searchPathes; - - /* operations */ - -+/* These are public and work across all types of filesystems, it's how you find resources. */ - - (NSString *)lookupFileWithName:(NSString *)_name; - - (NSString *)lookupFileWithName:(NSString *)_name extension:(NSString *)_ext; - - - (NSArray *)lookupAllFilesWithExtension:(NSString *)_ext - doReturnFullPath:(BOOL)_withPath; -+/* End public */ - - @end - -Index: sope-core/NGExtensions/NGBundleManager.m -=================================================================== ---- sope-core/NGExtensions/NGBundleManager.m (révision 1632) -+++ sope-core/NGExtensions/NGBundleManager.m (copie de travail) -@@ -332,10 +332,7 @@ - } - - - (void)_addGNUstepPathsToPathArray:(NSMutableArray *)_paths { --#if !GNUSTEP --#else -- // TODO: whats that supposed to do? -- // TODO: replace with proper path locator function! -+ /* Old code for old gstep-make and gstep-base. */ - NSDictionary *env; - NSString *p; - unsigned i, count; -@@ -355,7 +352,19 @@ - - if (p) [self->bundleSearchPaths addObject:p]; - } --#endif -+ -+ /* New code for new gstep-make and gstep-base. */ -+ tmp = NSStandardLibraryPaths(); -+ { -+ NSEnumerator *e = [tmp objectEnumerator]; -+ while ((tmp = [e nextObject]) != nil) { -+ tmp = [tmp stringByAppendingPathComponent:@"Bundles"]; -+ if ([self->bundleSearchPaths containsObject:tmp]) -+ continue; -+ -+ [self->bundleSearchPaths addObject:tmp]; -+ } -+ } - } - - - (void)_setupBundleSearchPathes { -Index: sope-core/NGExtensions/FdExt.subproj/GNUmakefile -=================================================================== ---- sope-core/NGExtensions/FdExt.subproj/GNUmakefile (révision 1632) -+++ sope-core/NGExtensions/FdExt.subproj/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include ../../common.make - - SUBPROJECT_NAME = FdExt -Index: sope-core/NGExtensions/XmlExt.subproj/GNUmakefile -=================================================================== ---- sope-core/NGExtensions/XmlExt.subproj/GNUmakefile (révision 1632) -+++ sope-core/NGExtensions/XmlExt.subproj/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include ../../common.make - - SUBPROJECT_NAME = XmlExt -Index: sope-core/NGExtensions/EOExt.subproj/GNUmakefile -=================================================================== ---- sope-core/NGExtensions/EOExt.subproj/GNUmakefile (révision 1632) -+++ sope-core/NGExtensions/EOExt.subproj/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include ../../common.make - - SUBPROJECT_NAME = EOExt -Index: sope-core/NGExtensions/GNUmakefile -=================================================================== ---- sope-core/NGExtensions/GNUmakefile (révision 1632) -+++ sope-core/NGExtensions/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include ../common.make - - ifneq ($(frameworks),yes) -@@ -11,7 +11,8 @@ - - libNGExtensions_PCH_FILE = common.h - libNGExtensions_DLL_DEF = libNGExtensions.def --libNGExtensions_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libNGExtensions_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libNGExtensions_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libNGExtensions_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - libNGExtensions_HEADER_FILES_DIR = ./NGExtensions -@@ -157,10 +158,12 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - else - include $(GNUSTEP_MAKEFILES)/framework.make - endif - -include GNUmakefile.postamble ---include fhs.make -Index: sope-core/NGExtensions/NGResourceLocator.m -=================================================================== ---- sope-core/NGExtensions/NGResourceLocator.m (révision 1632) -+++ sope-core/NGExtensions/NGResourceLocator.m (copie de travail) -@@ -43,7 +43,11 @@ - return self; - } - - (id)init { -+#if GNUSTEP_BASE_LIBRARY -+ return [self initWithGNUstepPath:@"Resources" fhsPath:@"share"]; -+#else - return [self initWithGNUstepPath:@"Library/Resources" fhsPath:@"share"]; -+#endif - } - - - (void)dealloc { -@@ -93,19 +97,30 @@ - NSString *p; - - ma = [NSMutableArray arrayWithCapacity:6]; -- -- e = ([self->gsSubPath length] > 0) -- ? [[self gsRootPathes] objectEnumerator] -- : (NSEnumerator *)nil; -- while ((p = [e nextObject]) != nil) { -- p = [p stringByAppendingPathComponent:self->gsSubPath]; -- if ([ma containsObject:p]) -- continue; -+ -+ if ([self->gsSubPath length] > 0) { - -- if (![self->fileManager fileExistsAtPath:p]) -- continue; -+#if GNUSTEP_BASE_LIBRARY -+ NSString *directory; - -- [ma addObject:p]; -+ e = [NSStandardLibraryPaths() objectEnumerator]; -+ while ((directory = [e nextObject])) -+ [ma addObject: [directory stringByAppendingPathComponent:self->gsSubPath]]; -+#else -+ -+ /* Old hack using GNUSTEP_PATHLIST. Should be removed at some point. */ -+ e = [[self gsRootPathes] objectEnumerator]; -+ while ((p = [e nextObject]) != nil) { -+ p = [p stringByAppendingPathComponent:self->gsSubPath]; -+ if ([ma containsObject:p]) -+ continue; -+ -+ if (![self->fileManager fileExistsAtPath:p]) -+ continue; -+ -+ [ma addObject:p]; -+ } -+#endif - } - - e = ([self->fhsSubPath length] > 0) -Index: sope-core/NGExtensions/NGLogging.subproj/GNUmakefile -=================================================================== ---- sope-core/NGExtensions/NGLogging.subproj/GNUmakefile (révision 1632) -+++ sope-core/NGExtensions/NGLogging.subproj/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include ../../common.make - - SUBPROJECT_NAME = NGLogging -Index: sope-core/NGExtensions/NGRuleEngine.subproj/GNUmakefile -=================================================================== ---- sope-core/NGExtensions/NGRuleEngine.subproj/GNUmakefile (révision 1632) -+++ sope-core/NGExtensions/NGRuleEngine.subproj/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include ../../common.make - - SUBPROJECT_NAME = NGRuleEngine -Index: sope-core/GNUmakefile -=================================================================== ---- sope-core/GNUmakefile (révision 1632) -+++ sope-core/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../config.make -+include ../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - PACKAGE_NAME=sope-core -@@ -32,4 +32,4 @@ - # package - - macosx-pkg :: all -- ../maintenance/make-osxpkg.sh sope-core -+ ../maintenance/make-osxpkg.sh $(PACKAGE_NAME) -Index: sope-core/NGStreams/GNUmakefile.preamble -=================================================================== ---- sope-core/NGStreams/GNUmakefile.preamble (révision 1632) -+++ sope-core/NGStreams/GNUmakefile.preamble (copie de travail) -@@ -38,7 +38,11 @@ - endif - - ifeq ($(findstring _64, $(GNUSTEP_TARGET_CPU)), _64) -+ifeq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd) -+SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib -+else - SYSTEM_LIB_DIR += -L/usr/local/lib64 -L/usr/lib64 -+endif - else - SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib - endif -Index: sope-core/NGStreams/GNUmakefile -=================================================================== ---- sope-core/NGStreams/GNUmakefile (révision 1632) -+++ sope-core/NGStreams/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include ../common.make - include ./Version - -@@ -12,7 +12,8 @@ - - libNGStreams_PCH_FILE = common.h - libNGStreams_DLL_DEF = libNGStreams.def --libNGStreams_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libNGStreams_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libNGStreams_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libNGStreams_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - libNGStreams_HEADER_FILES_DIR = NGStreams -@@ -106,10 +107,12 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - else - include $(GNUSTEP_MAKEFILES)/framework.make - endif - -include GNUmakefile.postamble ---include fhs.make -Index: sope-core/samples/GNUmakefile -=================================================================== ---- sope-core/samples/GNUmakefile (révision 1632) -+++ sope-core/samples/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - TOOL_NAME = \ -@@ -36,4 +36,3 @@ - -include GNUmakefile.preamble - include $(GNUSTEP_MAKEFILES)/tool.make - -include GNUmakefile.postamble ---include fhs.make -Index: sope-core/EOControl/GNUmakefile -=================================================================== ---- sope-core/EOControl/GNUmakefile (révision 1632) -+++ sope-core/EOControl/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include ../common.make - - ifneq ($(frameworks),yes) -@@ -11,7 +11,8 @@ - - libEOControl_PCH_FILE = common.h - libEOControl_DLL_DEF = libEOControl.def --libEOControl_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libEOControl_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libEOControl_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libEOControl_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - libEOControl_HEADER_FILES_DIR = . -@@ -73,10 +74,12 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - else - include $(GNUSTEP_MAKEFILES)/framework.make - endif - -include GNUmakefile.postamble ---include fhs.make -Index: sope-core/common.make -=================================================================== ---- sope-core/common.make (révision 1632) -+++ sope-core/common.make (copie de travail) -@@ -6,8 +6,6 @@ - include $(SKYROOT)/Version - -include ./Version - --GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -- - ADDITIONAL_CPPFLAGS += -pipe -Wall -Wno-protocol - ifeq ($(reentrant),yes) - ADDITIONAL_CPPFLAGS += -D_REENTRANT=1 -Index: sope-core/EOCoreData/GNUmakefile -=================================================================== ---- sope-core/EOCoreData/GNUmakefile (révision 1632) -+++ sope-core/EOCoreData/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include ../common.make - - ifneq ($(frameworks),yes) -@@ -10,7 +10,8 @@ - endif - - libEOCoreData_PCH_FILE = common.h --libEOCoreData_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libEOCoreData_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libEOCoreData_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libEOCoreData_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - libEOCoreData_HEADER_FILES_DIR = . -@@ -67,10 +68,12 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - else - include $(GNUSTEP_MAKEFILES)/framework.make - endif - -include GNUmakefile.postamble ---include fhs.make -Index: xmlrpc_call/GNUmakefile -=================================================================== ---- xmlrpc_call/GNUmakefile (révision 1632) -+++ xmlrpc_call/GNUmakefile (copie de travail) -@@ -1,10 +1,11 @@ - # GNUstep makefile - ---include ../config.make -+include ../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - - TOOL_NAME = xmlrpc_call -+xmlrpc_call_INSTALL_DIR = $(SOPE_TOOLS) - - xmlrpc_call_PCH_FILE = common.h - -@@ -17,7 +18,6 @@ - -include GNUmakefile.preamble - include $(GNUSTEP_MAKEFILES)/tool.make - -include GNUmakefile.postamble ---include fhs.make - - macosx-pkg :: - # do not build a pkg just for this tool -Index: xmlrpc_call/GNUmakefile.preamble -=================================================================== ---- xmlrpc_call/GNUmakefile.preamble (révision 1632) -+++ xmlrpc_call/GNUmakefile.preamble (copie de travail) -@@ -1,5 +1,6 @@ - # compilation settings - -+include ../config.make - SOPE_ROOT=.. - CORE_ROOT=$(SOPE_ROOT)/sope-core - APPSERVER_ROOT=$(SOPE_ROOT)/sope-appserver -@@ -57,14 +58,13 @@ - $(foreach dir,$(DEP_DIRS),-F$(GNUSTEP_BUILD_DIR)/$(dir)) - endif - --ifeq ($(findstring _64, $(GNUSTEP_TARGET_CPU)), _64) --SYSTEM_LIB_DIR += -L/usr/local/lib64 -L/usr/lib64 -+ifneq ($(CGS_LIBDIR_NAME),) -+SYSTEM_LIB_DIR += -L/usr/local/$(CGS_LIBDIR_NAME) -L/usr/$(CGS_LIBDIR_NAME) - else - SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib - endif - -- - # OS dependend stuff --ifeq ($(findstring openbsd3, $(GNUSTEP_HOST_OS)), openbsd3) -+ifeq ($(findstring openbsd, $(GNUSTEP_HOST_OS)), openbsd) - xmlrpc_call_TOOL_LIBS += -liconv - endif -Index: sope-xml/libxmlSAXDriver/GNUmakefile -=================================================================== ---- sope-xml/libxmlSAXDriver/GNUmakefile (révision 1632) -+++ sope-xml/libxmlSAXDriver/GNUmakefile (copie de travail) -@@ -1,13 +1,13 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - include ./Version - - BUNDLE_NAME = libxmlSAXDriver - BUNDLE_EXTENSION = .sax --BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/SaxDrivers-$(MAJOR_VERSION).$(MINOR_VERSION)/ -+BUNDLE_INSTALL_DIR = $(SOPE_SAXDRIVERS) - - libxmlSAXDriver_PCH_FILE = common.h - -@@ -24,4 +24,3 @@ - -include GNUmakefile.preamble - include $(GNUSTEP_MAKEFILES)/bundle.make - -include GNUmakefile.postamble ---include fhs.make -Index: sope-xml/DOM/GNUmakefile.preamble -=================================================================== ---- sope-xml/DOM/GNUmakefile.preamble (révision 1632) -+++ sope-xml/DOM/GNUmakefile.preamble (copie de travail) -@@ -1,10 +1,13 @@ - # compilation settings - -+include ./Version -+ - libDOM_HEADER_FILES_DIR = . - libDOM_HEADER_FILES_INSTALL_DIR = /DOM --libDOM_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libDOM_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libDOM_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libDOM_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) --DOM_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+DOM_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) - DOM_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - -Index: sope-xml/DOM/GNUmakefile -=================================================================== ---- sope-xml/DOM/GNUmakefile (révision 1632) -+++ sope-xml/DOM/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include ../common.make - - ifneq ($(frameworks),yes) -@@ -98,10 +98,12 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - else - include $(GNUSTEP_MAKEFILES)/framework.make - endif - -include GNUmakefile.postamble ---include fhs.make -Index: sope-xml/ChangeLogSaxDriver/GNUmakefile -=================================================================== ---- sope-xml/ChangeLogSaxDriver/GNUmakefile (révision 1632) -+++ sope-xml/ChangeLogSaxDriver/GNUmakefile (copie de travail) -@@ -1,13 +1,13 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - -include ../../Version - -include ./Version - - BUNDLE_NAME = ChangeLogSaxDriver - BUNDLE_EXTENSION = .sax --BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/SaxDrivers-$(MAJOR_VERSION).$(MINOR_VERSION)/ -+BUNDLE_INSTALL_DIR = ${SOPE_SAXDRIVERS}/ - - ChangeLogSaxDriver_OBJC_FILES = \ - ChangeLogSaxDriver.m \ -@@ -20,4 +20,3 @@ - -include GNUmakefile.preamble - include $(GNUSTEP_MAKEFILES)/bundle.make - -include GNUmakefile.postamble ---include fhs.make -Index: sope-xml/GNUmakefile -=================================================================== ---- sope-xml/GNUmakefile (révision 1632) -+++ sope-xml/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../config.make -+include ../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - PACKAGE_NAME=sope-xml -Index: sope-xml/SaxObjC/SaxXMLReaderFactory.m -=================================================================== ---- sope-xml/SaxObjC/SaxXMLReaderFactory.m (révision 1632) -+++ sope-xml/SaxObjC/SaxXMLReaderFactory.m (copie de travail) -@@ -137,11 +137,19 @@ - - - (void)addSearchPathesForGNUstepEnv:(NSMutableArray *)ma { - /* for libFoundation */ -+#if GNUSTEP_BASE_LIBRARY -+NSEnumerator *libraryPaths; -+ NSString *directory, *suffix; -+ -+ suffix = [self libraryDriversSubDir]; -+ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -+ while ((directory = [libraryPaths nextObject])) -+ [ma addObject: [directory stringByAppendingPathComponent: suffix]]; -+#else -+ NSString *subdir; -+ NSEnumerator *e; - NSDictionary *env; -- NSEnumerator *e; -- NSString *subdir; - id tmp; -- - env = [[NSProcessInfo processInfo] environment]; - - if ((tmp = [env objectForKey:@"GNUSTEP_PATHPREFIX_LIST"]) == nil) -@@ -159,6 +167,7 @@ - - [ma addObject:tmp]; - } -+#endif - } - - - (NSArray *)saxReaderSearchPathes { -@@ -182,8 +191,8 @@ - /* FHS fallback */ - - tmp = [[NSString alloc] initWithFormat: --#if CONFIGURE_64BIT -- @"lib64/sope-%i.%i/saxdrivers/", -+#ifdef CGS_LIBDIR_NAME -+ [CGS_LIBDIR_NAME stringByAppendingString:@"/sope-%i.%i/saxdrivers/"], - #else - @"lib/sope-%i.%i/saxdrivers/", - #endif -Index: sope-xml/SaxObjC/SaxObjectModel.h -=================================================================== ---- sope-xml/SaxObjC/SaxObjectModel.h (révision 1632) -+++ sope-xml/SaxObjC/SaxObjectModel.h (copie de travail) -@@ -34,6 +34,7 @@ - - + (id)modelWithName:(NSString *)_name; - + (id)modelWithContentsOfFile:(NSString *)_path; -++ (NSString *)libraryDriversSubDir; - - - (id)initWithDictionary:(NSDictionary *)_dict; - -Index: sope-xml/SaxObjC/SaxObjectModel.m -=================================================================== ---- sope-xml/SaxObjC/SaxObjectModel.m (révision 1632) -+++ sope-xml/SaxObjC/SaxObjectModel.m (copie de travail) -@@ -67,12 +67,12 @@ - if (searchPathes == nil) { - NSMutableArray *ma; - NSDictionary *env; -- id tmp; - - env = [[NSProcessInfo processInfo] environment]; - ma = [NSMutableArray arrayWithCapacity:6]; - - #if COCOA_Foundation_LIBRARY -+ id tmp; - tmp = NSSearchPathForDirectoriesInDomains(NSAllLibrariesDirectory, - NSAllDomainsMask, - YES); -@@ -86,7 +86,16 @@ - [ma addObject:tmp]; - } - } -+#elif GNUSTEP_BASE_LIBRARY -+ NSEnumerator *libraryPaths; -+ NSString *directory, *suffix; -+ -+ suffix = [self libraryDriversSubDir]; -+ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -+ while ((directory = [libraryPaths nextObject])) -+ [ma addObject: [directory stringByAppendingPathComponent: suffix]]; - #else -+ id tmp; - if ((tmp = [env objectForKey:@"GNUSTEP_PATHPREFIX_LIST"]) == nil) - tmp = [env objectForKey:@"GNUSTEP_PATHLIST"]; - tmp = [tmp componentsSeparatedByString:@":"]; -@@ -122,6 +131,10 @@ - return searchPathes; - } - -++ (NSString *)libraryDriversSubDir { -+ return [NSString stringWithFormat:@"SaxMappings"]; -+} -+ - + (id)modelWithName:(NSString *)_name { - NSFileManager *fileManager; - NSEnumerator *pathes; -Index: sope-xml/SaxObjC/GNUmakefile.preamble -=================================================================== ---- sope-xml/SaxObjC/GNUmakefile.preamble (révision 1632) -+++ sope-xml/SaxObjC/GNUmakefile.preamble (copie de travail) -@@ -1,9 +1,12 @@ - # compilation settings - -+include ./Version -+ - libSaxObjC_DLL_DEF = libSaxObjC.def --libSaxObjC_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libSaxObjC_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libSaxObjC_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libSaxObjC_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) --SaxObjC_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+SaxObjC_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) - SaxObjC_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - libSaxObjC_HEADER_FILES_DIR = . -@@ -48,8 +51,8 @@ - ADDITIONAL_CPPFLAGS += -DFHS_INSTALL_ROOT=\@\"$(FHS_INSTALL_ROOT)\" - endif - --ifeq ($(CONFIGURE_64BIT),yes) --ADDITIONAL_CPPFLAGS += -DCONFIGURE_64BIT=1 -+ifneq ($(CGS_LIBDIR_NAME),) -+ADDITIONAL_CPPFLAGS += -DCGS_LIBDIR_NAME=\@\"$(CGS_LIBDIR_NAME)\" - endif - - # Apple -Index: sope-xml/SaxObjC/GNUmakefile -=================================================================== ---- sope-xml/SaxObjC/GNUmakefile (révision 1632) -+++ sope-xml/SaxObjC/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include ../common.make - - ifneq ($(frameworks),yes) -@@ -56,10 +56,12 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - else - include $(GNUSTEP_MAKEFILES)/framework.make - endif - -include GNUmakefile.postamble ---include fhs.make -Index: sope-xml/common.make -=================================================================== ---- sope-xml/common.make (révision 1632) -+++ sope-xml/common.make (copie de travail) -@@ -1,13 +1,7 @@ - # GNUstep makefile - --SKYROOT=.. -- - include $(GNUSTEP_MAKEFILES)/common.make --include $(SKYROOT)/Version ---include ./Version - --GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -- - ADDITIONAL_CPPFLAGS += -pipe -Wall -Wno-protocol - - ADDITIONAL_INCLUDE_DIRS += -I.. -Index: sope-xml/samples/PlistSaxDriver/GNUmakefile -=================================================================== ---- sope-xml/samples/PlistSaxDriver/GNUmakefile (révision 1632) -+++ sope-xml/samples/PlistSaxDriver/GNUmakefile (copie de travail) -@@ -1,11 +1,11 @@ - # GNUstep Makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - BUNDLE_NAME = PlistSaxDriver - BUNDLE_EXTENSION = .sax --BUNDLE_INSTALL_DIR = $(GNUSTEP_USER_ROOT)/Library/Bundles -+BUNDLE_INSTALL_DIR = $(GNUSTEP_BUNDLES) - - PlistSaxDriver_OBJC_FILES = \ - PlistSaxDriver.m -Index: sope-xml/samples/GNUmakefile -=================================================================== ---- sope-xml/samples/GNUmakefile (révision 1632) -+++ sope-xml/samples/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - TOOL_NAME = \ -@@ -13,14 +13,20 @@ - testqp \ - - rss2plist1_OBJC_FILES = rss2plist1.m -+rss2plist1_INSTALL_DIR = $(SOPE_TOOLS)/ - rss2plist2_OBJC_FILES = rss2plist2.m -+rss2plist2_INSTALL_DIR = $(SOPE_TOOLS)/ - rssparse_OBJC_FILES = rssparse.m -+rssparse_INSTALL_DIR = $(SOPE_TOOLS)/ - saxxml_OBJC_FILES = saxxml.m -+saxxml_INSTALL_DIR = $(SOPE_TOOLS)/ - xmln_OBJC_FILES = xmln.m -+xmln_INSTALL_DIR = $(SOPE_TOOLS)/ - domxml_OBJC_FILES = domxml.m -+domxml_INSTALL_DIR = $(SOPE_TOOLS)/ - testqp_OBJC_FILES = testqp.m -+testqp_INSTALL_DIR = $(SOPE_TOOLS)/ - - -include GNUmakefile.preamble - include $(GNUSTEP_MAKEFILES)/tool.make - -include GNUmakefile.postamble ---include fhs.make -Index: sope-xml/samples/GNUmakefile.preamble -=================================================================== ---- sope-xml/samples/GNUmakefile.preamble (révision 1632) -+++ sope-xml/samples/GNUmakefile.preamble (copie de travail) -@@ -1,5 +1,6 @@ - # compilation settings - -+include ../../config.make - - rss2plist1_PCH_FILE = common.h - rss2plist2_PCH_FILE = common.h -@@ -42,8 +43,8 @@ - $(foreach dir,$(DEP_DIRS),-F$(GNUSTEP_BUILD_DIR)/$(dir)) - endif - --ifeq ($(findstring _64, $(GNUSTEP_TARGET_CPU)), _64) --SYSTEM_LIB_DIR += -L/usr/local/lib64 -L/usr/lib64 -+ifneq ($(CGS_LIBDIR_NAME),) -+SYSTEM_LIB_DIR += -L/usr/local/$(CGS_LIBDIR_NAME) -L/usr/$(CGS_LIBDIR_NAME) - else - SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib - endif -Index: sope-xml/XmlRpc/GNUmakefile.preamble -=================================================================== ---- sope-xml/XmlRpc/GNUmakefile.preamble (révision 1632) -+++ sope-xml/XmlRpc/GNUmakefile.preamble (copie de travail) -@@ -1,10 +1,13 @@ - # compilation settings - -+include ./Version -+ - libXmlRpc_HEADER_FILES_DIR = . - libXmlRpc_HEADER_FILES_INSTALL_DIR = /XmlRpc --libXmlRpc_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libXmlRpc_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libXmlRpc_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libXmlRpc_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) --XmlRpc_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+XmlRpc_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) - XmlRpc_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - -Index: sope-xml/XmlRpc/GNUmakefile -=================================================================== ---- sope-xml/XmlRpc/GNUmakefile (révision 1632) -+++ sope-xml/XmlRpc/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include ../common.make - - ifneq ($(frameworks),yes) -@@ -43,10 +43,12 @@ - - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - else - include $(GNUSTEP_MAKEFILES)/framework.make - endif - -include GNUmakefile.postamble ---include fhs.make -Index: sope-xml/STXSaxDriver/ExtraSTX/GNUmakefile -=================================================================== ---- sope-xml/STXSaxDriver/ExtraSTX/GNUmakefile (révision 1632) -+++ sope-xml/STXSaxDriver/ExtraSTX/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - SUBPROJECT_NAME = ExtraSTX -Index: sope-xml/STXSaxDriver/GNUmakefile -=================================================================== ---- sope-xml/STXSaxDriver/GNUmakefile (révision 1632) -+++ sope-xml/STXSaxDriver/GNUmakefile (copie de travail) -@@ -1,13 +1,13 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - include ./Version - - BUNDLE_NAME = STXSaxDriver - BUNDLE_EXTENSION = .sax --BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/SaxDrivers-$(SOPE_MAJOR_VERSION).$(SOPE_MINOR_VERSION)/ -+BUNDLE_INSTALL_DIR = $(SOPE_SAXDRIVERS) - - STXSaxDriver_PCH_FILE = common.h - -@@ -24,4 +24,3 @@ - -include GNUmakefile.preamble - include $(GNUSTEP_MAKEFILES)/bundle.make - -include GNUmakefile.postamble ---include fhs.make -Index: sope-xml/STXSaxDriver/Model/GNUmakefile -=================================================================== ---- sope-xml/STXSaxDriver/Model/GNUmakefile (révision 1632) -+++ sope-xml/STXSaxDriver/Model/GNUmakefile (copie de travail) -@@ -6,7 +6,7 @@ - # Date: 24 November 2003 - # - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - SUBPROJECT_NAME = Model -Index: sope-xml/pyxSAXDriver/GNUmakefile -=================================================================== ---- sope-xml/pyxSAXDriver/GNUmakefile (révision 1632) -+++ sope-xml/pyxSAXDriver/GNUmakefile (copie de travail) -@@ -1,17 +1,16 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - include ./Version - - BUNDLE_NAME = pyxSAXDriver - BUNDLE_EXTENSION = .sax --BUNDLE_INSTALL_DIR = $(GNUSTEP_USER_ROOT)/Library/SaxDrivers-$(SOPE_MAJOR_VERSION).$(SOPE_MINOR_VERSION)/ -+BUNDLE_INSTALL_DIR = ${SOPE_SAXDRIVERS}/ - - pyxSAXDriver_OBJC_FILES = pyxSAXDriver.m - - -include GNUmakefile.preamble - include $(GNUSTEP_MAKEFILES)/bundle.make - -include GNUmakefile.postamble ---include fhs.make -Index: sope-appserver/GNUmakefile -=================================================================== ---- sope-appserver/GNUmakefile (révision 1632) -+++ sope-appserver/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../config.make -+include ../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - PACKAGE_NAME=sope-appserver -@@ -38,4 +38,4 @@ - # package - - macosx-pkg :: all -- ../maintenance/make-osxpkg.sh sope-appserver -+ ../maintenance/make-osxpkg.sh $(PACKAGE_NAME) -Index: sope-appserver/SoOFS/GNUmakefile.preamble -=================================================================== ---- sope-appserver/SoOFS/GNUmakefile.preamble (révision 1632) -+++ sope-appserver/SoOFS/GNUmakefile.preamble (copie de travail) -@@ -76,17 +76,9 @@ - $(foreach dir,$(DEP_DIRS),-F$(GNUSTEP_BUILD_DIR)/$(dir)) - endif - --ifeq ($(findstring _64, $(GNUSTEP_TARGET_CPU)), _64) --SYSTEM_LIB_DIR += -L/usr/local/lib64 -L/usr/lib64 --else --SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib --endif -- -- -- - # platform specific settings - --ifneq ($(findstring openbsd3, $(GNUSTEP_TARGET_OS)), openbsd3) -+ifneq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd) - # OpenBSD does not require libcrypt - ifneq ($(findstring darwin, $(GNUSTEP_TARGET_OS)), darwin) - # and neither does MacOSX? ... -@@ -94,6 +86,6 @@ - endif - endif - --ifeq ($(findstring openbsd3, $(GNUSTEP_TARGET_OS)), openbsd3) -+ifeq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd) - $(SOPED_NAME)_TOOL_LIBS += -liconv - endif -Index: sope-appserver/SoOFS/GNUmakefile -=================================================================== ---- sope-appserver/SoOFS/GNUmakefile (révision 1632) -+++ sope-appserver/SoOFS/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - include ./Version -@@ -14,7 +14,8 @@ - - - libSoOFS_PCH_FILE = common.h --libSoOFS_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libSoOFS_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libSoOFS_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libSoOFS_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - libSoOFS_HEADER_FILES_DIR = . -@@ -75,7 +76,7 @@ - - BUNDLE_NAME = SoOFS - BUNDLE_EXTENSION = .sxp --BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/SoProducts-$(MAJOR_VERSION).$(MINOR_VERSION)/ -+BUNDLE_INSTALL_DIR = $(SOPE_PRODUCTS)/ - - SoOFS_OBJC_FILES = SoOFSProduct.m - SoOFS_RESOURCE_FILES = product.plist Version -@@ -91,9 +92,13 @@ - TOOL_NAME = $(SOPED_NAME) - - $(SOPED_NAME)_OBJC_FILES = sope.m -+$(SOPED_NAME)_INSTALL_DIR = $(SOPE_ADMIN_TOOLS) - - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - include $(GNUSTEP_MAKEFILES)/bundle.make -@@ -102,4 +107,3 @@ - endif - include $(GNUSTEP_MAKEFILES)/tool.make - -include GNUmakefile.postamble ---include fhs.make -Index: sope-appserver/NGXmlRpc/GNUmakefile -=================================================================== ---- sope-appserver/NGXmlRpc/GNUmakefile (révision 1632) -+++ sope-appserver/NGXmlRpc/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - include ./Version -@@ -12,7 +12,8 @@ - endif - - libNGXmlRpc_PCH_FILE = common.h --libNGXmlRpc_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libNGXmlRpc_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libNGXmlRpc_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libNGXmlRpc_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - libNGXmlRpc_HEADER_FILES_DIR = . -@@ -65,6 +66,9 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - else -@@ -72,4 +76,3 @@ - endif - include $(GNUSTEP_MAKEFILES)/tool.make - -include GNUmakefile.postamble ---include fhs.make -Index: sope-appserver/WEExtensions/GNUmakefile.preamble -=================================================================== ---- sope-appserver/WEExtensions/GNUmakefile.preamble (révision 1632) -+++ sope-appserver/WEExtensions/GNUmakefile.preamble (copie de travail) -@@ -21,7 +21,8 @@ - cp ../bundle-info.plist .) - endif - --libWEExtensions_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libWEExtensions_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libWEExtensions_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libWEExtensions_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - -Index: sope-appserver/WEExtensions/GNUmakefile -=================================================================== ---- sope-appserver/WEExtensions/GNUmakefile (révision 1632) -+++ sope-appserver/WEExtensions/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - include ./Version -@@ -11,7 +11,7 @@ - - BUNDLE_NAME = WEExtensions - BUNDLE_EXTENSION = .wox --BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/WOxElemBuilders-$(MAJOR_VERSION).$(MINOR_VERSION)/ -+BUNDLE_INSTALL_DIR = $(SOPE_WOXBUILDERS)/ - - else - FRAMEWORK_NAME = WEExtensions -@@ -99,6 +99,9 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - include $(GNUSTEP_MAKEFILES)/bundle.make -@@ -106,4 +109,3 @@ - include $(GNUSTEP_MAKEFILES)/framework.make - endif - -include GNUmakefile.postamble ---include fhs.make -Index: sope-appserver/WEExtensions/WEResourceManager.m -=================================================================== ---- sope-appserver/WEExtensions/WEResourceManager.m (révision 1632) -+++ sope-appserver/WEExtensions/WEResourceManager.m (copie de travail) -@@ -53,28 +53,43 @@ - - + (NSString *)gsTemplatesSubpath { - NSString *p; -- - p = [[WOApplication application] gsTemplatesDirectoryName]; -+#if ! GNUSTEP_BASE_LIBRARY -+ // for GNUSTEP_BASE_LIBRARY this is already there in rootPathesInGNUstep - p = [@"Library/" stringByAppendingString:p]; -+#endif - return p; - } - + (NSString *)gsWebSubpath { - NSString *p; - - p = [[WOApplication application] gsWebDirectoryName]; -+#if ! GNUSTEP_BASE_LIBRARY -+ // for GNUSTEP_BASE_LIBRARY this is already there in rootPathesInGNUstep - p = [@"Library/" stringByAppendingString:p]; -+#endif - return p; - } - - /* locate resource directories */ - - + (NSArray *)rootPathesInGNUstep { -+ id tmp; -+#if GNUSTEP_BASE_LIBRARY -+ NSEnumerator *libraryPaths; -+ NSString *directory; -+ -+ tmp = [NSMutableArray array]; -+ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -+ while ((directory = [libraryPaths nextObject])) -+ [tmp addObject: directory]; -+ return tmp; -+#else - NSDictionary *env; -- id tmp; -- - env = [[NSProcessInfo processInfo] environment]; - if ((tmp = [env objectForKey:@"GNUSTEP_PATHPREFIX_LIST"]) == nil) - tmp = [env objectForKey:@"GNUSTEP_PATHLIST"]; -+#endif - - return [tmp componentsSeparatedByString:@":"]; - } -@@ -95,9 +110,17 @@ - NSMutableArray *ma; - BOOL isDir; - id tmp; -- - fm = [NSFileManager defaultManager]; - ma = [NSMutableArray arrayWithCapacity:8]; -+ -+#ifdef GNUSTEP_BASE_LIBRARY -+ NSEnumerator *libraryPaths; -+ NSString *directory; -+ -+ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -+ while ((directory = [libraryPaths nextObject])) -+ [ma addObject: [directory stringByAppendingPathComponent: _name]]; -+#else - - e = [[self rootPathesInGNUstep] objectEnumerator]; - while ((tmp = [e nextObject]) != nil) { -@@ -115,6 +138,7 @@ - - [ma addObject:tmp]; - } -+#endif - - /* hack in FHS pathes */ - -Index: sope-appserver/WEExtensions/WETableView/GNUmakefile -=================================================================== ---- sope-appserver/WEExtensions/WETableView/GNUmakefile (révision 1632) -+++ sope-appserver/WEExtensions/WETableView/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - SUBPROJECT_NAME = WETableView -Index: sope-appserver/NGObjWeb/WOCoreApplication+Bundle.m -=================================================================== ---- sope-appserver/NGObjWeb/WOCoreApplication+Bundle.m (révision 1632) -+++ sope-appserver/NGObjWeb/WOCoreApplication+Bundle.m (copie de travail) -@@ -50,8 +50,6 @@ - } - else { - NSDictionary *env; -- NSEnumerator *e; -- id tmp; - - env = [[NSProcessInfo processInfo] environment]; - -@@ -67,7 +65,20 @@ - bp = @"/System/Library"; - bp = [bp stringByAppendingPathComponent:_domain]; - [chkPathes addObject:bp]; -+#elif GNUSTEP_BASE_LIBRARY -+ NSEnumerator *libraryPaths; -+ NSString *directory; -+ -+ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -+ while ((directory = [libraryPaths nextObject])) { -+ directory = [directory stringByAppendingPathComponent:_domain]; -+ if ([chkPathes containsObject:directory]) continue; -+ [chkPathes addObject:directory]; -+ -+ } - #else -+ NSEnumerator *e; -+ id tmp; - if ((tmp = [env objectForKey:@"GNUSTEP_PATHPREFIX_LIST"]) == nil) - tmp = [env objectForKey:@"GNUSTEP_PATHLIST"]; - tmp = [tmp componentsSeparatedByString:@":"]; -Index: sope-appserver/NGObjWeb/wobundle-gs.make -=================================================================== ---- sope-appserver/NGObjWeb/wobundle-gs.make (révision 1632) -+++ sope-appserver/NGObjWeb/wobundle-gs.make (copie de travail) -@@ -85,7 +85,7 @@ - endif - - ifeq ($(WOBUNDLE_INSTALL_DIR),) --WOBUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Libraries -+WOBUNDLE_INSTALL_DIR = $(GNUSTEP_WEB_APPS) - endif - # The name of the bundle is in the BUNDLE_NAME variable. - # The list of languages the bundle is localized in are in xxx_LANGUAGES -@@ -287,8 +287,10 @@ - @$(MKDIRS) $@ - - internal-wobundle-install_:: $(WOBUNDLE_INSTALL_DIR) shared-instance-headers-install -- rm -rf $(WOBUNDLE_INSTALL_DIR)/$(WOBUNDLE_DIR_NAME); \ -- $(TAR) chf - --exclude=CVS --exclude=.svn --to-stdout $(WOBUNDLE_DIR_NAME) | (cd $(WOBUNDLE_INSTALL_DIR); $(TAR) xf -) -+# rm -rf $(WOBUNDLE_INSTALL_DIR)/$(WOBUNDLE_DIR_NAME); \ -+# $(TAR) chf - --exclude=CVS --exclude=.svn --to-stdout $(WOBUNDLE_DIR_NAME) | (cd $(WOBUNDLE_INSTALL_DIR); $(TAR) xf -) -+ if [ -e $(WOBUNDLE_INSTALL_DIR)/$(WOBUNDLE_DIR_NAME) ]; then rm -rf $(WOBUNDLE_INSTALL_DIR)/$(WOBUNDLE_DIR_NAME); fi; \ -+ cp -LR $(WOBUNDLE_DIR_NAME) $(WOBUNDLE_INSTALL_DIR) - ifneq ($(CHOWN_TO),) - $(CHOWN) -R $(CHOWN_TO) $(WOBUNDLE_INSTALL_DIR)/$(WOBUNDLE_DIR_NAME) - endif -Index: sope-appserver/NGObjWeb/GNUmakefile.preamble -=================================================================== ---- sope-appserver/NGObjWeb/GNUmakefile.preamble (révision 1632) -+++ sope-appserver/NGObjWeb/GNUmakefile.preamble (copie de travail) -@@ -50,9 +50,6 @@ - $(foreach dir,$(DEP_DIRS),-F$(GNUSTEP_BUILD_DIR)/$(dir)) - endif - --SYSTEM_LIB_DIR += $(CONFIGURE_SYSTEM_LIB_DIR) -- -- - # dependencies - - ifneq ($(frameworks),yes) -@@ -85,6 +82,7 @@ - $(sope-mime-libs) \ - $(sope-core-libs) \ - $(sope-xml-libs) -+wod_INSTALL_DIR = $(SOPE_TOOLS) - SoCore_BUNDLE_LIBS += \ - $(sope-ngobjweb-libs) \ - $(sope-mime-libs) \ -@@ -94,7 +92,7 @@ - - # platform specific settings - --ifneq ($(findstring openbsd3, $(GNUSTEP_TARGET_OS)), openbsd3) -+ifneq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd) - # OpenBSD does not require libcrypt - ifneq ($(findstring darwin, $(GNUSTEP_TARGET_OS)), darwin) - # and neither does MacOSX? ... -@@ -116,6 +114,6 @@ - libNGObjWeb_LIBRARIES_DEPEND_UPON += -lFoundationExt - endif - --ifeq ($(findstring openbsd3, $(GNUSTEP_TARGET_OS)), openbsd3) -+ifeq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd) - wod_TOOL_LIBS += -liconv - endif -Index: sope-appserver/NGObjWeb/GNUmakefile -=================================================================== ---- sope-appserver/NGObjWeb/GNUmakefile (révision 1632) -+++ sope-appserver/NGObjWeb/GNUmakefile (copie de travail) -@@ -1,11 +1,9 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include ../common.make - include ./Version - --GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -- - ifneq ($(frameworks),yes) - LIBRARY_NAME = libNGObjWeb - else -@@ -14,15 +12,12 @@ - - - ifneq ($(frameworks),yes) --ifeq ($(FHS_INSTALL_ROOT),) --RESOURCES_DIR = $(GNUSTEP_RESOURCES)/NGObjWeb --else --RESOURCES_DIR = $(FHS_INSTALL_ROOT)/share/sope-$(MAJOR_VERSION).$(MINOR_VERSION)/ngobjweb -+RESOURCES_DIR = $(SOPE_NGOBJWEB)/ - endif --endif - - libNGObjWeb_PCH_FILE = common.h --libNGObjWeb_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libNGObjWeb_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libNGObjWeb_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libNGObjWeb_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - libNGObjWeb_SUBPROJECTS = \ -@@ -40,7 +35,7 @@ - libNGObjWeb_RESOURCES = \ - Defaults.plist \ - Languages.plist \ -- DAVPropMap.plist \ -+ DAVPropMap.plist - - FHS_MANPAGES += \ - sope-ngobjweb-defaults.5 \ -@@ -167,7 +162,7 @@ - - BUNDLE_NAME = SoCore - BUNDLE_EXTENSION = .sxp --BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/SoProducts-$(MAJOR_VERSION).$(MINOR_VERSION)/ -+BUNDLE_INSTALL_DIR = $(SOPE_PRODUCTS)/ - - SoCore_PCH_FILE = common.h - SoCore_OBJC_FILES = SoCoreProduct.m -@@ -190,6 +185,9 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - else -@@ -198,4 +196,3 @@ - include $(GNUSTEP_MAKEFILES)/bundle.make - include $(GNUSTEP_MAKEFILES)/tool.make - -include GNUmakefile.postamble ---include fhs.make -Index: sope-appserver/NGObjWeb/WebDAV/GNUmakefile -=================================================================== ---- sope-appserver/NGObjWeb/WebDAV/GNUmakefile (révision 1632) -+++ sope-appserver/NGObjWeb/WebDAV/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include ../../Version - include ../Version - include $(GNUSTEP_MAKEFILES)/common.make -Index: sope-appserver/NGObjWeb/DynamicElements/GNUmakefile -=================================================================== ---- sope-appserver/NGObjWeb/DynamicElements/GNUmakefile (révision 1632) -+++ sope-appserver/NGObjWeb/DynamicElements/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - SUBPROJECT_NAME = DynamicElements -Index: sope-appserver/NGObjWeb/SoObjects/SoProductLoader.m -=================================================================== ---- sope-appserver/NGObjWeb/SoObjects/SoProductLoader.m (révision 1632) -+++ sope-appserver/NGObjWeb/SoObjects/SoProductLoader.m (copie de travail) -@@ -74,6 +74,14 @@ - } - - - (void)_addGNUstepSearchPathesToArray:(NSMutableArray *)ma { -+#if GNUSTEP_BASE_LIBRARY -+ NSEnumerator *libraryPaths; -+ NSString *directory; -+ -+ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -+ while ((directory = [libraryPaths nextObject])) -+ [ma addObject: [directory stringByAppendingPathComponent: self->productDirectoryName]]; -+#else - NSDictionary *env; - id tmp; - -@@ -97,6 +105,7 @@ - [self logWithFormat:@"%s: empty library search path !", - __PRETTY_FUNCTION__]; - } -+#endif - } - - - (void)_addFHSPathesToArray:(NSMutableArray *)ma { -Index: sope-appserver/NGObjWeb/SoObjects/SoProductRegistry.m -=================================================================== ---- sope-appserver/NGObjWeb/SoObjects/SoProductRegistry.m (révision 1632) -+++ sope-appserver/NGObjWeb/SoObjects/SoProductRegistry.m (copie de travail) -@@ -231,7 +231,7 @@ - - fm = [NSFileManager defaultManager]; - pi = [NSProcessInfo processInfo]; -- -+#if ! GNUSTEP_BASE_LIBRARY - #if COCOA_Foundation_LIBRARY && !COMPILE_FOR_GNUSTEP - /* - TODO: (like COMPILE_FOR_GNUSTEP) -@@ -250,12 +250,9 @@ - pathes = [[pathes stringValue] componentsSeparatedByString:@":"]; - relPath = @"Library/"; - #endif -- -- [self debugWithFormat:@"scanning for products ..."]; -- - relPath = [relPath stringByAppendingFormat:@"SoProducts-%i.%i/", - SOPE_MAJOR_VERSION, SOPE_MINOR_VERSION]; -- -+ [self debugWithFormat:@"scanning for products ..."]; - for (i = 0; i < [pathes count]; i++) { - NSString *lPath; - BOOL isDir; -@@ -271,7 +268,38 @@ - [self debugWithFormat:@" directory %@", lPath]; - [self scanForProductsInDirectory:lPath]; - } -+#else -+ NSEnumerator *libraryPaths; -+ NSString *directory; -+ NSMutableArray *tmppath; - -+ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -+ tmppath = [[NSMutableArray alloc] init]; -+ while ((directory = [libraryPaths nextObject])) -+ [tmppath addObject: [directory stringByAppendingPathComponent: -+ [NSString stringWithFormat:@"SoProducts-%i.%i/", -+ SOPE_MAJOR_VERSION, SOPE_MINOR_VERSION]]]; -+ pathes = [tmppath mutableCopy]; -+ [self debugWithFormat:@"scanning for products ..."]; -+ for (i = 0; i < [pathes count]; i++) { -+ NSString *lPath; -+ BOOL isDir; -+ -+ lPath = [pathes objectAtIndex:i]; -+ [self debugWithFormat:@" scan: %@", lPath]; -+ -+ if (![fm fileExistsAtPath:lPath isDirectory:&isDir]) -+ continue; -+ if (!isDir) -+ continue; -+ -+ [self debugWithFormat:@" directory %@", lPath]; -+ [self scanForProductsInDirectory:lPath]; -+ } -+ [tmppath release]; -+#endif -+ -+ - #if COCOA_Foundation_LIBRARY - /* look in wrapper places */ - bundle = [NSBundle bundleForClass:[self class]]; -@@ -282,8 +310,8 @@ - /* look into FHS pathes */ - - relPath = [NSString stringWithFormat: --#if CONFIGURE_64BIT -- @"lib64/sope-%i.%i/products/", -+#ifdef CGS_LIBDIR_NAME -+ [CGS_LIBDIR_NAME stringByAppendingString:@"/sope-%i.%i/products/"], - #else - @"lib/sope-%i.%i/products/", - #endif -Index: sope-appserver/NGObjWeb/SoObjects/GNUmakefile.preamble -=================================================================== ---- sope-appserver/NGObjWeb/SoObjects/GNUmakefile.preamble (révision 1632) -+++ sope-appserver/NGObjWeb/SoObjects/GNUmakefile.preamble (copie de travail) -@@ -1,5 +1,7 @@ - # compilation settings - -+include ../../../config.make -+ - ADDITIONAL_INCLUDE_DIRS += -I../WebDAV/ - - ADDITIONAL_CPPFLAGS += -DCOMPILING_NGOBJWEB=1 -DCOMPILE_FOR_GNUSTEP=1 -@@ -10,6 +12,6 @@ - ADDITIONAL_CPPFLAGS += -DFHS_INSTALL_ROOT=\@\"$(FHS_INSTALL_ROOT)\" - endif - --ifeq ($(CONFIGURE_64BIT),yes) --ADDITIONAL_CPPFLAGS += -DCONFIGURE_64BIT=1 -+ifneq ($(CGS_LIBDIR_NAME),) -+ADDITIONAL_CPPFLAGS += -DCGS_LIBDIR_NAME=\@\"$(CGS_LIBDIR_NAME)\" - endif -Index: sope-appserver/NGObjWeb/SoObjects/GNUmakefile -=================================================================== ---- sope-appserver/NGObjWeb/SoObjects/GNUmakefile (révision 1632) -+++ sope-appserver/NGObjWeb/SoObjects/GNUmakefile (copie de travail) -@@ -1,7 +1,7 @@ - # GNUstep makefile - ---include ../../../config.make - include ../subdirs.make -+include ../../../config.make - - SUBPROJECT_NAME = SoObjects - -Index: sope-appserver/NGObjWeb/Templates/GNUmakefile -=================================================================== ---- sope-appserver/NGObjWeb/Templates/GNUmakefile (révision 1632) -+++ sope-appserver/NGObjWeb/Templates/GNUmakefile (copie de travail) -@@ -1,7 +1,7 @@ - # GNUmakefile makefile - ---include ../../../config.make - include ../subdirs.make -+include ../../../config.make - - SUBPROJECT_NAME = Templates - -Index: sope-appserver/NGObjWeb/Templates/WOApplication+Builders.m -=================================================================== ---- sope-appserver/NGObjWeb/Templates/WOApplication+Builders.m (révision 1632) -+++ sope-appserver/NGObjWeb/Templates/WOApplication+Builders.m (copie de travail) -@@ -76,7 +76,7 @@ - - fm = [NSFileManager defaultManager]; - pi = [NSProcessInfo processInfo]; -- -+#if ! GNUSTEP_BASE_LIBRARY - #if COCOA_Foundation_LIBRARY - /* - TODO: (like COMPILE_FOR_GNUSTEP) -@@ -121,16 +121,43 @@ - [self debugWithFormat:@" directory %@", lPath]; - [self scanForBuilderBundlesInDirectory:lPath]; - } -+#else -+ NSEnumerator *libraryPaths; -+ NSString *directory; -+ NSMutableArray *tmppathes; -+ -+ libraryPaths = [NSStandardLibraryPaths() objectEnumerator]; -+ tmppathes = [[NSMutableArray alloc] init]; -+ while ((directory = [libraryPaths nextObject])) -+ [tmppathes addObject: [directory stringByAppendingPathComponent: -+ [NSString stringWithFormat:@"WOxElemBuilders-%i.%i/", -+ SOPE_MAJOR_VERSION, SOPE_MINOR_VERSION]]]; -+ pathes = [tmppathes mutableCopy]; -+ for (i = 0; i < [pathes count]; i++) { -+ NSString *lPath; -+ BOOL isDir; -+ -+ lPath = [pathes objectAtIndex:i]; -+ if (![fm fileExistsAtPath:lPath isDirectory:&isDir]) -+ continue; -+ if (!isDir) -+ continue; -+ -+ [self debugWithFormat:@" directory %@", lPath]; -+ [self scanForBuilderBundlesInDirectory:lPath]; -+ } -+ [tmppathes release]; -+#endif - - /* look into FHS pathes */ - - relPath = [NSString stringWithFormat: --#if CONFIGURE_64BIT -- @"lib/sope-%i.%i/wox-builders/", -+#ifdef CGS_LIBDIR_NAME -+ [CGS_LIBDIR_NAME stringByAppendingString:@"/sope-%i.%i/wox-builders/"], - #else -- @"lib64/sope-%i.%i/wox-builders/", -+ @"lib/sope-%i.%i/wox-builders/", - #endif -- SOPE_MAJOR_VERSION, SOPE_MINOR_VERSION]; -+ SOPE_MAJOR_VERSION, SOPE_MINOR_VERSION]; - pathes = [NSArray arrayWithObjects: - #ifdef FHS_INSTALL_ROOT - [FHS_INSTALL_ROOT stringByAppendingString:relPath], -Index: sope-appserver/NGObjWeb/Templates/GNUmakefile.preamble -=================================================================== ---- sope-appserver/NGObjWeb/Templates/GNUmakefile.preamble (révision 1632) -+++ sope-appserver/NGObjWeb/Templates/GNUmakefile.preamble (copie de travail) -@@ -6,6 +6,6 @@ - ADDITIONAL_CPPFLAGS += -DFHS_INSTALL_ROOT=\@\"$(FHS_INSTALL_ROOT)\" - endif - --ifeq ($(CONFIGURE_64BIT),yes) --ADDITIONAL_CPPFLAGS += -DCONFIGURE_64BIT=1 -+ifneq ($(CGS_LIBDIR_NAME),) -+ADDITIONAL_CPPFLAGS += -DCGS_LIBDIR_NAME=\@\"$(CGS_LIBDIR_NAME)\" - endif -Index: sope-appserver/NGObjWeb/Associations/GNUmakefile -=================================================================== ---- sope-appserver/NGObjWeb/Associations/GNUmakefile (révision 1632) -+++ sope-appserver/NGObjWeb/Associations/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - SUBPROJECT_NAME = Associations -Index: sope-appserver/NGObjWeb/WOHttpAdaptor/GNUmakefile -=================================================================== ---- sope-appserver/NGObjWeb/WOHttpAdaptor/GNUmakefile (révision 1632) -+++ sope-appserver/NGObjWeb/WOHttpAdaptor/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - SUBPROJECT_NAME = WOHttpAdaptor -Index: sope-appserver/NGObjWeb/woapp-gs.make -=================================================================== ---- sope-appserver/NGObjWeb/woapp-gs.make (révision 1632) -+++ sope-appserver/NGObjWeb/woapp-gs.make (copie de travail) -@@ -103,7 +103,7 @@ - # Determine the application directory extension - WOAPP_EXTENSION = woa - --GNUSTEP_WOAPPS = $(GNUSTEP_INSTALLATION_DIR)/WOApps -+GNUSTEP_WOAPPS = $(GNUSTEP_WEB_APPS) - - .PHONY: internal-woapp-all_ \ - internal-woapp-install_ \ -@@ -372,8 +372,9 @@ - - internal-woapp-install_:: - @($(MKINSTALLDIRS) $(GNUSTEP_WOAPPS); \ -- rm -rf $(GNUSTEP_WOAPPS)/$(WOAPP_DIR_NAME); \ -- $(TAR) chf - --exclude=CVS --exclude=.svn --to-stdout $(WOAPP_DIR_NAME) | (cd $(GNUSTEP_WOAPPS); $(TAR) xf -)) -+ if [ -e $(GNUSTEP_WOAPPS)/$(WOAPP_DIR_NAME) ]; then rm -rf $(GNUSTEP_WOAPPS)/$(WOAPP_DIR_NAME); fi; \ -+# $(TAR) chf - --exclude=CVS --exclude=.svn --to-stdout $(WOAPP_DIR_NAME) | (cd $(GNUSTEP_WOAPPS); $(TAR) xf -)) -+ cp -LR $(WOAPP_DIR_NAME) $(GNUSTEP_WOAPPS) - ifneq ($(CHOWN_TO),) - $(CHOWN) -R $(CHOWN_TO) $(GNUSTEP_WOAPPS)/$(WOAPP_DIR_NAME) - endif -Index: sope-appserver/NGObjWeb/WOCoreApplication.m -=================================================================== ---- sope-appserver/NGObjWeb/WOCoreApplication.m (révision 1632) -+++ sope-appserver/NGObjWeb/WOCoreApplication.m (copie de travail) -@@ -730,9 +730,15 @@ - [self sopeMajorVersion], [self sopeMinorVersion]]; - } - + (NGResourceLocator *)ngobjwebResourceLocator { -+#if GNUSTEP_BASE_LIBRARY - return [NGResourceLocator resourceLocatorForGNUstepPath: -+ @"Libraries/Resources/NGObjWeb" -+ fhsPath:[self ngobjwebShareDirectorySubPath]]; -+#else -+ return [NGResourceLocator resourceLocatorForGNUstepPath: - @"Library/Libraries/Resources/NGObjWeb" - fhsPath:[self ngobjwebShareDirectorySubPath]]; -+#endif - } - - + (NSArray *)resourcesSearchPathes { -Index: sope-appserver/NGObjWeb/NGHttp/GNUmakefile -=================================================================== ---- sope-appserver/NGObjWeb/NGHttp/GNUmakefile (révision 1632) -+++ sope-appserver/NGObjWeb/NGHttp/GNUmakefile (copie de travail) -@@ -1,10 +1,8 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - --GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -- - SUBPROJECT_NAME = NGHttp - - NGHttp_PCH_FILE = common.h -@@ -37,5 +35,8 @@ - NGUrlFormCoder.m \ - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - include $(GNUSTEP_MAKEFILES)/subproject.make - -include GNUmakefile.postamble -Index: sope-appserver/WEPrototype/GNUmakefile -=================================================================== ---- sope-appserver/WEPrototype/GNUmakefile (révision 1632) -+++ sope-appserver/WEPrototype/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - include ./Version -@@ -10,7 +10,7 @@ - - BUNDLE_NAME = WEPrototype - BUNDLE_EXTENSION = .wox --BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/WOxElemBuilders-$(MAJOR_VERSION).$(MINOR_VERSION)/ -+BUNDLE_INSTALL_DIR = $(SOPE_WOXBUILDERS)/ - else - FRAMEWORK_NAME = WEPrototype - endif -@@ -46,6 +46,9 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - include $(GNUSTEP_MAKEFILES)/bundle.make -@@ -53,4 +56,3 @@ - include $(GNUSTEP_MAKEFILES)/framework.make - endif - -include GNUmakefile.postamble ---include fhs.make -Index: sope-appserver/WEPrototype/doc/GNUmakefile -=================================================================== ---- sope-appserver/WEPrototype/doc/GNUmakefile (révision 1632) -+++ sope-appserver/WEPrototype/doc/GNUmakefile (copie de travail) -@@ -2,7 +2,7 @@ - - SOPE_ROOT=../../.. - ---include $(SOPE_ROOT)/config.make -+include $(SOPE_ROOT)/config.make - include $(SOPE_ROOT)/Version - include ../Version - -Index: sope-appserver/WEPrototype/GNUmakefile.preamble -=================================================================== ---- sope-appserver/WEPrototype/GNUmakefile.preamble (révision 1632) -+++ sope-appserver/WEPrototype/GNUmakefile.preamble (copie de travail) -@@ -1,4 +1,4 @@ --# compiler flags -+# GNUstep makefile - - SOPE_ROOT=../.. - -@@ -21,7 +21,8 @@ - -I$(SOPE_ROOT)/sope-xml - - --libWEPrototype_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libWEPrototype_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libWEPrototype_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libWEPrototype_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - libWEPrototype_LIBRARIES_DEPEND_UPON += \ -Index: sope-appserver/common.make -=================================================================== ---- sope-appserver/common.make (révision 1632) -+++ sope-appserver/common.make (copie de travail) -@@ -4,8 +4,6 @@ - include ../Version - -include ./Version - --GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) -- - ADDITIONAL_CPPFLAGS += -pipe -Wall -Wno-protocol - - ADDITIONAL_INCLUDE_DIRS += \ -Index: sope-appserver/samples/CoreDataBlog/GNUmakefile -=================================================================== ---- sope-appserver/samples/CoreDataBlog/GNUmakefile (révision 1632) -+++ sope-appserver/samples/CoreDataBlog/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - WOAPP_NAME = CoreDataBlog -Index: sope-appserver/samples/HelloForm/GNUmakefile -=================================================================== ---- sope-appserver/samples/HelloForm/GNUmakefile (révision 1632) -+++ sope-appserver/samples/HelloForm/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - WOAPP_NAME = HelloForm -Index: sope-appserver/samples/GNUmakefile -=================================================================== ---- sope-appserver/samples/GNUmakefile (révision 1632) -+++ sope-appserver/samples/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - SUBPROJECTS += \ -Index: sope-appserver/samples/iCalPortal/GNUmakefile.preamble -=================================================================== ---- sope-appserver/samples/iCalPortal/GNUmakefile.preamble (révision 1632) -+++ sope-appserver/samples/iCalPortal/GNUmakefile.preamble (copie de travail) -@@ -7,7 +7,9 @@ - -lEOControl \ - -lXmlRpc -lDOM -lSaxObjC - else -+ifneq ($(findstring openbsd, $(GNUSTEP_TARGET_OS)), openbsd) - ADDITIONAL_TOOL_LIBS += -lcrypt - endif -+endif - - SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib -Index: sope-appserver/samples/iCalPortal/GNUmakefile -=================================================================== ---- sope-appserver/samples/iCalPortal/GNUmakefile (révision 1632) -+++ sope-appserver/samples/iCalPortal/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - WOAPP_NAME = iCalPortal -Index: sope-appserver/samples/iCalPortal/Pages/GNUmakefile -=================================================================== ---- sope-appserver/samples/iCalPortal/Pages/GNUmakefile (révision 1632) -+++ sope-appserver/samples/iCalPortal/Pages/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../../config.make -+include ../../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - SUBPROJECT_NAME = Pages -Index: sope-appserver/samples/iCalPortal/WebDAV/GNUmakefile -=================================================================== ---- sope-appserver/samples/iCalPortal/WebDAV/GNUmakefile (révision 1632) -+++ sope-appserver/samples/iCalPortal/WebDAV/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../../config.make -+include ../../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - SUBPROJECT_NAME = DAV -Index: sope-appserver/samples/SoCookieAuth/GNUmakefile -=================================================================== ---- sope-appserver/samples/SoCookieAuth/GNUmakefile (révision 1632) -+++ sope-appserver/samples/SoCookieAuth/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - WOAPP_NAME = SoCookieAuth -Index: sope-appserver/samples/WOxExtTest/GNUmakefile -=================================================================== ---- sope-appserver/samples/WOxExtTest/GNUmakefile (révision 1632) -+++ sope-appserver/samples/WOxExtTest/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - WOAPP_NAME = WOxExtTest -Index: sope-appserver/samples/TestPages/GNUmakefile -=================================================================== ---- sope-appserver/samples/TestPages/GNUmakefile (révision 1632) -+++ sope-appserver/samples/TestPages/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - WOAPP_NAME = TestPages -Index: sope-appserver/samples/parsedav/GNUmakefile -=================================================================== ---- sope-appserver/samples/parsedav/GNUmakefile (révision 1632) -+++ sope-appserver/samples/parsedav/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - TOOL_NAME = parsedav -Index: sope-appserver/samples/xmlrpc/GNUmakefile -=================================================================== ---- sope-appserver/samples/xmlrpc/GNUmakefile (révision 1632) -+++ sope-appserver/samples/xmlrpc/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - TOOL_NAME = \ -Index: sope-appserver/samples/TestPrototype/GNUmakefile -=================================================================== ---- sope-appserver/samples/TestPrototype/GNUmakefile (révision 1632) -+++ sope-appserver/samples/TestPrototype/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - WOAPP_NAME = TestPrototype -Index: sope-appserver/samples/HelloWorld/GNUmakefile -=================================================================== ---- sope-appserver/samples/HelloWorld/GNUmakefile (révision 1632) -+++ sope-appserver/samples/HelloWorld/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - WOAPP_NAME = HelloWorld -Index: sope-appserver/samples/davpropget/GNUmakefile -=================================================================== ---- sope-appserver/samples/davpropget/GNUmakefile (révision 1632) -+++ sope-appserver/samples/davpropget/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../../config.make -+include ../../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - TOOL_NAME = davpropget -Index: sope-appserver/WOExtensions/GNUmakefile.preamble -=================================================================== ---- sope-appserver/WOExtensions/GNUmakefile.preamble (révision 1632) -+++ sope-appserver/WOExtensions/GNUmakefile.preamble (copie de travail) -@@ -12,7 +12,8 @@ - -I$(SOPE_ROOT)/sope-xml - - --libWOExtensions_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libWOExtensions_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libWOExtensions_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libWOExtensions_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - -Index: sope-appserver/WOExtensions/GNUmakefile -=================================================================== ---- sope-appserver/WOExtensions/GNUmakefile (révision 1632) -+++ sope-appserver/WOExtensions/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ../Version - include ./Version -@@ -9,7 +9,7 @@ - LIBRARY_NAME = libWOExtensions - BUNDLE_NAME = WOExtensions - BUNDLE_EXTENSION = .wox --BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/WOxElemBuilders-$(MAJOR_VERSION).$(MINOR_VERSION)/ -+BUNDLE_INSTALL_DIR = $(SOPE_WOXBUILDERS)/ - - else - FRAMEWORK_NAME = WOExtensions -@@ -71,6 +71,9 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - include $(GNUSTEP_MAKEFILES)/bundle.make -@@ -78,4 +81,3 @@ - include $(GNUSTEP_MAKEFILES)/framework.make - endif - -include GNUmakefile.postamble ---include fhs.make -Index: sope-appserver/WOXML/GNUmakefile -=================================================================== ---- sope-appserver/WOXML/GNUmakefile (révision 1632) -+++ sope-appserver/WOXML/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include ../common.make - include ../Version - include ./Version -@@ -15,6 +15,7 @@ - libWOXML_PCH_FILE = common.h - libWOXML_HEADER_FILES_DIR = . - libWOXML_HEADER_FILES_INSTALL_DIR = /WOXML -+libWOXML_INSTALL_DIR=$(SOPE_SYSLIBDIR) - - - libWOXML_HEADER_FILES += \ -@@ -42,10 +43,12 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - else - include $(GNUSTEP_MAKEFILES)/framework.make - endif - -include GNUmakefile.postamble ---include fhs.make -Index: sope-appserver/WOXML/GNUmakefile.preamble -=================================================================== ---- sope-appserver/WOXML/GNUmakefile.preamble (révision 1632) -+++ sope-appserver/WOXML/GNUmakefile.preamble (copie de travail) -@@ -2,7 +2,7 @@ - - SOPE_ROOT=../.. - --libWOXML_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libWOXML_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) - libWOXML_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - libWOXML_INCLUDE_DIRS += -I. -I.. -Index: sope-ical/samples/GNUmakefile -=================================================================== ---- sope-ical/samples/GNUmakefile (révision 1632) -+++ sope-ical/samples/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - TOOL_NAME = icalparsetest icalds vcf2xml vcfparsetest ievalrrule -@@ -14,4 +14,3 @@ - -include GNUmakefile.preamble - include $(GNUSTEP_MAKEFILES)/tool.make - -include GNUmakefile.postamble ---include fhs.make -Index: sope-ical/versitSaxDriver/GNUmakefile -=================================================================== ---- sope-ical/versitSaxDriver/GNUmakefile (révision 1632) -+++ sope-ical/versitSaxDriver/GNUmakefile (copie de travail) -@@ -1,13 +1,13 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - -include ../../Version - -include ./Version - - BUNDLE_NAME = versitSaxDriver - BUNDLE_EXTENSION = .sax --BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/SaxDrivers-$(MAJOR_VERSION).$(MINOR_VERSION)/ -+BUNDLE_INSTALL_DIR = $(SOPE_SAXDRIVERS)/ - - versitSaxDriver_PRINCIPAL_CLASS = VSSaxDriver - -@@ -24,4 +24,3 @@ - -include GNUmakefile.preamble - include $(GNUSTEP_MAKEFILES)/bundle.make - -include GNUmakefile.postamble ---include fhs.make -Index: sope-ical/GNUmakefile -=================================================================== ---- sope-ical/GNUmakefile (révision 1632) -+++ sope-ical/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../config.make -+include ../config.make - include $(GNUSTEP_MAKEFILES)/common.make - - PACKAGE_NAME=sope-ical -Index: sope-ical/NGiCal/GNUmakefile.postamble -=================================================================== ---- sope-ical/NGiCal/GNUmakefile.postamble (révision 1632) -+++ sope-ical/NGiCal/GNUmakefile.postamble (copie de travail) -@@ -1,10 +1,6 @@ - # compilation settings - --ifeq ($(FHS_INSTALL_ROOT),) --MAPDIR="$(GNUSTEP_INSTALLATION_DIR)/Library/SaxMappings/" --else --MAPDIR="$(FHS_INSTALL_ROOT)/share/sope-$(MAJOR_VERSION).$(MINOR_VERSION)/saxmappings/" --endif -+MAPDIR="$(SOPE_SAXMAPPINGS)/" - - mappings-dir :: - $(MKDIRS) $(MAPDIR) -Index: sope-ical/NGiCal/GNUmakefile -=================================================================== ---- sope-ical/NGiCal/GNUmakefile (révision 1632) -+++ sope-ical/NGiCal/GNUmakefile (copie de travail) -@@ -1,6 +1,6 @@ - # GNUstep makefile - ---include ../../config.make -+include ../../config.make - include $(GNUSTEP_MAKEFILES)/common.make - include ./Version - -@@ -14,7 +14,8 @@ - libNGiCal_PCH_FILE = common.h - libNGiCal_HEADER_FILES_DIR = . - libNGiCal_HEADER_FILES_INSTALL_DIR = /NGiCal --libNGiCal_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libNGiCal_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) -+libNGiCal_INSTALL_DIR=$(SOPE_SYSLIBDIR) - libNGiCal_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) - - libNGiCal_HEADER_FILES = \ -@@ -107,10 +108,12 @@ - # building - - -include GNUmakefile.preamble -+ifneq ($(FHS_INSTALL_ROOT),) -+GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include -+endif - ifneq ($(frameworks),yes) - include $(GNUSTEP_MAKEFILES)/library.make - else - include $(GNUSTEP_MAKEFILES)/framework.make - endif - -include GNUmakefile.postamble ---include fhs.make diff --git a/SOPE/sope-ngobjweb-fix.diff b/SOPE/sope-ngobjweb-fix.diff deleted file mode 100644 index 75cc9c274..000000000 --- a/SOPE/sope-ngobjweb-fix.diff +++ /dev/null @@ -1,12 +0,0 @@ ---- sope-appserver/GNUmakefile.withngobjweb 2008-02-27 12:25:22.000000000 -0500 -+++ sope-appserver/GNUmakefile 2008-02-27 12:25:29.000000000 -0500 -@@ -13,8 +13,7 @@ - WOXML \ - SoOFS \ - NGXmlRpc \ -- WEPrototype \ -- mod_ngobjweb -+ WEPrototype - - - ifeq ($(frameworks),yes) diff --git a/SOPE/sope-patchset-r1664.diff b/SOPE/sope-patchset-r1664.diff deleted file mode 100644 index ab76f055a..000000000 --- a/SOPE/sope-patchset-r1664.diff +++ /dev/null @@ -1,9408 +0,0 @@ -Index: sope-ldap/NGLdap/NGLdapConnection.m -=================================================================== ---- sope-ldap/NGLdap/NGLdapConnection.m (revision 1664) -+++ sope-ldap/NGLdap/NGLdapConnection.m (working copy) -@@ -26,7 +26,6 @@ - #include "NGLdapModification.h" - #include "EOQualifier+LDAP.h" - #include "common.h" --#include - - static BOOL LDAPDebugEnabled = NO; - static BOOL LDAPInitialBindSpecific = NO; -@@ -310,6 +309,295 @@ - return NO; - } - -+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST -+- (BOOL) bindWithMethod: (NSString *) _method -+ binddn: (NSString *) _login -+ credentials: (NSString *) _cred -+ perr: (LDAPPasswordPolicyError *) _perr -+ expire: (int *) _expire -+ grace: (int *) _grace -+{ -+ LDAPControl **sctrlsp = NULL; -+ LDAPControl *sctrls[2]; -+ LDAPControl sctrl[2]; -+ LDAPControl **ctrls; -+ LDAPControl c, *ctrl; -+ LDAPMessage *result = NULL; -+ -+ -+ int err, msgid, rc; -+ const char *l, *p; -+ char *matched = NULL; -+ char *info = NULL; -+ char **refs = NULL; -+ struct berval passwd = { 0, NULL }; -+ -+ l = (char *)[_login UTF8String]; -+ p = LDAPUseLatin1Creds -+ ? (char *)[_cred cString] -+ : (char *)[_cred UTF8String]; -+ -+ *_perr = -1; -+ passwd.bv_val = p; -+ passwd.bv_len = strlen(p); -+ -+ -+ c.ldctl_oid = LDAP_CONTROL_PASSWORDPOLICYREQUEST; -+ c.ldctl_value.bv_val = NULL; -+ c.ldctl_value.bv_len = 0; -+ c.ldctl_iscritical = 0; -+ sctrl[0] = c; -+ sctrls[0] = &sctrl[0]; -+ sctrls[1] = NULL; -+ -+ sctrlsp = sctrls; -+ -+ rc = ldap_sasl_bind(self->handle, l, LDAP_SASL_SIMPLE, &passwd, sctrlsp, NULL, &msgid); -+ -+ if (msgid == -1 || rc != LDAP_SUCCESS) -+ { -+ [self logWithFormat: @"bind - ldap_sasl_bind call failed"]; -+ return NO; -+ } -+ -+ rc = ldap_result(self->handle, msgid, LDAP_MSG_ALL, NULL, &result); -+ -+ if (rc == -1) -+ { -+ [self logWithFormat: @"bind - ldap_result call failed"]; -+ if (result) ldap_msgfree(result); -+ return NO; -+ } -+ -+ [self logWithFormat: @"bind - ldap_result call result: %d", rc]; -+ -+ rc = ldap_parse_result(self->handle, result, &err, &matched, &info, &refs, &ctrls, 1); -+ -+ if (rc != LDAP_SUCCESS) -+ { -+ [self logWithFormat: @"bind - ldap_parse_result call failed"]; -+ //if (result) ldap_msgfree(result); => causes a crash!? -+ if (matched) ber_memfree(matched); -+ if (info) ber_memfree(info); -+ if (refs) ber_memvfree((void **)refs); -+ return NO; -+ } -+ -+ if (err == LDAP_SUCCESS) -+ self->flags.isBound = YES; -+ else -+ self->flags.isBound = NO; -+ -+ // Even if we aren't bound to the server, we continue and we go get the -+ // policy control -+ if (ctrls) -+ { -+ ctrl = ldap_find_control(LDAP_CONTROL_PASSWORDPOLICYRESPONSE, ctrls); -+ if (ctrl) -+ { -+ rc = ldap_parse_passwordpolicy_control(self->handle, ctrl, _expire, _grace, _perr); -+ -+ if (rc == LDAP_SUCCESS) -+ { -+ [self logWithFormat: @"bind - policy values: %d %d %d - bound: %d", *_expire, *_grace, *_perr, self->flags.isBound]; -+ } -+ else -+ [self logWithFormat: @"bind - ldap_parse_passwordpolicy call failed"]; -+ } -+ else -+ [self logWithFormat: @"bind - ldap_find_control call failed"]; -+ -+ ldap_controls_free(ctrls); -+ } -+ else -+ { -+ [self logWithFormat: @"bind - ldap_parse_result - ctrls is NULL"]; -+ } -+ -+ return self->flags.isBound; -+} -+ -+// -+// No need to bind prior to calling this method. In fact, -+// if a bind() was issued prior calling this method, it -+// will fail. -+// -+- (BOOL) changePasswordAtDn: (NSString *) _dn -+ oldPassword: (NSString *) _oldPassword -+ newPassword: (NSString *) _newPassword -+ perr: (LDAPPasswordPolicyError *) _perr -+ -+{ -+ const char *user, *p; -+ int rc; -+ -+ *_perr = -1; -+ -+ user = (char *)[_dn UTF8String]; -+ p = LDAPUseLatin1Creds ? (char *)[_oldPassword cString] : (char *)[_oldPassword UTF8String]; -+ -+ if (!self->flags.isBound) -+ { -+ rc = ldap_simple_bind_s(self->handle, user, p); -+ -+ if (rc == LDAP_SUCCESS) -+ { -+ struct berval newpw = { 0, NULL }; -+ struct berval oldpw = { 0, NULL }; -+ struct berval bv = {0, NULL}; -+ struct berval *retdata = NULL; -+ -+ LDAPControl *sctrls[2]; -+ LDAPControl **ctrls; -+ LDAPControl sctrl[2]; -+ LDAPControl c, *ctrl; -+ LDAPMessage *result; -+ -+ BerElement *ber = NULL; -+ -+ char *matcheddn = NULL, *retoid = NULL, *text = NULL, **refs = NULL; -+ int idd, grace, expire, code; -+ -+ self->flags.isBound = YES; -+ code = LDAP_OTHER; -+ -+ newpw.bv_val = LDAPUseLatin1Creds ? (char *)[_newPassword cString] : (char *)[_newPassword UTF8String]; -+ newpw.bv_len = strlen(newpw.bv_val); -+ -+ oldpw.bv_val = p; -+ oldpw.bv_len = strlen(p); -+ -+ ber = ber_alloc_t(LBER_USE_DER); -+ -+ if (ber == NULL) -+ return NO; -+ -+ ber_printf(ber, "{" /*}*/ ); -+ ber_printf(ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, user); -+ ber_printf(ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, &oldpw); -+ ber_printf(ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, &newpw); -+ ber_printf(ber, /*{*/ "N}" ); -+ -+ rc = ber_flatten2(ber, &bv, 0 ); -+ -+ if (rc < 0) -+ { -+ [self logWithFormat: @"change password - ber_flatten2 call failed"]; -+ ber_free(ber, 1); -+ return NO; -+ } -+ -+ // Everything is alright... -+ *_perr = -1; -+ -+ c.ldctl_oid = LDAP_CONTROL_PASSWORDPOLICYREQUEST; -+ c.ldctl_value.bv_val = NULL; -+ c.ldctl_value.bv_len = 0; -+ c.ldctl_iscritical = 0; -+ sctrl[0] = c; -+ sctrls[0] = &sctrl[0]; -+ sctrls[1] = NULL; -+ -+ rc = ldap_set_option(self->handle, LDAP_OPT_SERVER_CONTROLS, sctrls); -+ -+ if (rc != LDAP_OPT_SUCCESS) -+ { -+ [self logWithFormat: @"change password - ldap_set_option call failed"]; -+ ber_free(ber, 1); -+ return NO; -+ } -+ -+ rc = ldap_extended_operation(self->handle, -+ LDAP_EXOP_MODIFY_PASSWD, &bv, -+ NULL, NULL, &idd); -+ -+ ber_free(ber, 1); -+ -+ if (rc != LDAP_SUCCESS ) -+ { -+ [self logWithFormat: @"change password - ldap_extended_operation call failed"]; -+ return NO; -+ } -+ -+ rc = ldap_result(self->handle, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &result); -+ -+ if (rc < 0) -+ { -+ [self logWithFormat: @"change password - ldap_result call failed"]; -+ return NO; -+ } -+ -+ rc = ldap_parse_result(self->handle, result, &code, &matcheddn, &text, &refs, &ctrls, 0 ); -+ -+ if (rc != LDAP_SUCCESS) -+ { -+ [self logWithFormat: @"change password - ldap_parse_result call failed, rc = %d, code = %d, matcheddn = %s, text = %s", rc, code, matcheddn, text]; -+ ber_memfree(text); -+ ber_memfree(matcheddn); -+ ber_memvfree((void **) refs); -+ free(ctrls); -+ return NO; -+ } -+ -+ rc = ldap_parse_extended_result(self->handle, result, &retoid, &retdata, 1); -+ if (rc != LDAP_SUCCESS) -+ { -+ [self logWithFormat: @"change password - ldap_parse_extended result call failed"]; -+ ber_memfree(text); -+ ber_memfree(matcheddn); -+ ber_memvfree((void **) refs); -+ ber_memfree(retoid); -+ ber_bvfree(retdata); -+ free(ctrls); -+ return NO; -+ } -+ -+ ctrl = ldap_find_control(LDAP_CONTROL_PASSWORDPOLICYRESPONSE, ctrls); -+ -+ if (ctrl) -+ { -+ rc = ldap_parse_passwordpolicy_control(self->handle, ctrl, &expire, &grace, _perr); -+ -+ if (rc == LDAP_SUCCESS && *_perr == PP_noError) -+ { -+ [self logWithFormat: @"change password - policy values: %d %d %d", expire, grace, *_perr]; -+ } -+ else -+ { -+ [self logWithFormat: @"change password - ldap_parse_passwordpolicy call failed or error during password change: %d", *_perr]; -+ ber_memfree(text); -+ ber_memfree(matcheddn); -+ ber_memvfree((void **) refs); -+ ber_memfree(retoid); -+ ber_bvfree(retdata); -+ free(ctrls); -+ return NO; -+ } -+ } -+ else -+ { -+ // Ending up here doesn't mean that things failed. It could simply be caused by the -+ // fact that the password change was a success but no policy control object -+ // could be found. -+ [self logWithFormat: @"change password - ldap_find_control call failed"]; -+ } -+ -+ ber_memfree(text); -+ ber_memfree(matcheddn); -+ ber_memvfree((void **) refs); -+ ber_memfree(retoid); -+ ber_bvfree(retdata); -+ free(ctrls); -+ -+ return YES; -+ } -+ } -+ -+ return NO; -+} -+ -+#endif -+ - /* running queries */ - - - (void)setQueryTimeLimit:(NSTimeInterval)_timeLimit { -@@ -731,7 +1019,7 @@ - attrName = [attr attributeName]; - /* TODO: use UTF-8, UNICODE */ - -- modBuf[i].mod_type = strdup(modBuf[i].mod_type); -+ modBuf[i].mod_type = strdup([attrName UTF8String]); - - valCount = [attr count]; - values = calloc(valCount + 1, sizeof(struct berval *)); -Index: sope-ldap/NGLdap/NGLdapEntry.m -=================================================================== ---- sope-ldap/NGLdap/NGLdapEntry.m (revision 1664) -+++ sope-ldap/NGLdap/NGLdapEntry.m (working copy) -@@ -105,14 +105,16 @@ - - (NGLdapAttribute *)attributeWithName:(NSString *)_name { - NSEnumerator *e; - NGLdapAttribute *a; -- -+ NSString *upperName; -+ - if (_name == nil) - return nil; - -+ upperName = [_name uppercaseString]; - e = [self->attributes objectEnumerator]; - - while ((a = [e nextObject])) { -- if ([[a attributeName] isEqualToString:_name]) -+ if ([[[a attributeName] uppercaseString] isEqualToString:upperName]) - return a; - } - return nil; -Index: sope-ldap/NGLdap/ChangeLog -=================================================================== ---- sope-ldap/NGLdap/ChangeLog (revision 1664) -+++ sope-ldap/NGLdap/ChangeLog (working copy) -@@ -1,3 +1,13 @@ -+2010-03-08 Ludovic Marcotte -+ -+ * Added password policy support when binding to the -+ LDAP server or when changing passwords. -+ -+2009-08-13 Wolfgang Sourdeau -+ -+ * NGLdapEntry.m (-attributeWithName:): attribute names are now -+ accessed in a case-insensitive way. -+ - 2009-04-02 Wolfgang Sourdeau - - * NGLdapConnection.m (useSSL,startTLS): new method enabling -Index: sope-ldap/NGLdap/NGLdapConnection.h -=================================================================== ---- sope-ldap/NGLdap/NGLdapConnection.h (revision 1664) -+++ sope-ldap/NGLdap/NGLdapConnection.h (working copy) -@@ -25,6 +25,9 @@ - #import - #import - -+#define LDAP_DEPRECATED 1 -+#include -+ - @class NSString, NSArray, NSEnumerator; - @class EOQualifier; - @class NGLdapEntry; -@@ -65,6 +68,20 @@ - - (BOOL)bindWithMethod:(NSString *)_method - binddn:(NSString *)_login credentials:(NSString *)_cred; - -+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST -+- (BOOL) bindWithMethod: (NSString *) _method -+ binddn: (NSString *) _login -+ credentials: (NSString *) _cred -+ perr: (LDAPPasswordPolicyError *) _perr -+ expire: (int *) _expire -+ grace: (int *) _grace; -+ -+- (BOOL) changePasswordAtDn: (NSString *) _dn -+ oldPassword: (NSString *) _oldPassword -+ newPassword: (NSString *) _newPassword -+ perr: (LDAPPasswordPolicyError *) _perr; -+#endif -+ - /* query parameters */ - - - (void)setQueryTimeLimit:(NSTimeInterval)_timeLimit; -Index: sope-gdl1/MySQL/MySQL4Channel.m -=================================================================== ---- sope-gdl1/MySQL/MySQL4Channel.m (revision 1664) -+++ sope-gdl1/MySQL/MySQL4Channel.m (working copy) -@@ -635,10 +635,10 @@ - if ((merrno = mysql_errno(self->_connection)) != 0) { - const char *error; - -+ error = mysql_error(self->_connection); - if (isDebuggingEnabled) - NSLog(@"%@ cannot use result: '%s'", self, error); - -- error = mysql_error(self->_connection); - return [MySQL4Exception exceptionWithName:@"FetchFailed" - reason:[NSString stringWithUTF8String:error] - userInfo:nil]; -Index: sope-gdl1/Oracle8/ChangeLog -=================================================================== ---- sope-gdl1/Oracle8/ChangeLog (revision 1664) -+++ sope-gdl1/Oracle8/ChangeLog (working copy) -@@ -1,3 +1,13 @@ -+2010-03-31 Wolfgang Sourdeau -+ -+ * OracleAdaptorChannel.m (+initialize): set the prefetch memory -+ size from a new "OracleAdaptorPrefetchMemorySize" userdefault. Use -+ "16 * 1024" by default. -+ (-evaluateExpression:): make use of the new prefetchMemorySize -+ variable to configure the OCI_ATTR_PREFETCH_MEMORY on the -+ statement. We also set OCI_ATTR_PREFETCH_ROWS to an unreasonably -+ high number to ensure the memory size always has precedence. -+ - 2007-11-15 Ludovic Marcotte - - * fixes -Index: sope-gdl1/Oracle8/OracleAdaptorChannel.m -=================================================================== ---- sope-gdl1/Oracle8/OracleAdaptorChannel.m (revision 1664) -+++ sope-gdl1/Oracle8/OracleAdaptorChannel.m (working copy) -@@ -1,7 +1,7 @@ - /* - ** OracleAdaptorChannel.m - ** --** Copyright (c) 2007 Inverse groupe conseil inc. and Ludovic Marcotte -+** Copyright (c) 2007-2009 Inverse inc. and Ludovic Marcotte - ** - ** Author: Ludovic Marcotte - ** -@@ -30,6 +30,12 @@ - - #import - -+#include -+ -+static BOOL debugOn = NO; -+static int prefetchMemorySize; -+static int maxTry = 3; -+static int maxSleep = 500; - // - // - // -@@ -41,10 +47,11 @@ - - @implementation OracleAdaptorChannel (Private) - --- (void) _cleanup -+- (void) _cleanup - { - column_info *info; - int c; -+ sword result; - - [_resultSetProperties removeAllObjects]; - -@@ -58,11 +65,29 @@ - // so we just free the value instead. - if (info->value) - { -- if (OCIDescriptorFree((dvoid *)info->value, (ub4)OCI_DTYPE_LOB) != OCI_SUCCESS) -+ if (info->type == SQLT_CLOB -+ || info->type == SQLT_BLOB -+ || info->type == SQLT_BFILEE -+ || info->type == SQLT_CFILEE) -+ { -+ result = OCIDescriptorFree((dvoid *)info->value, (ub4) OCI_DTYPE_LOB); -+ if (result != OCI_SUCCESS) -+ { -+ NSLog (@"value was not a LOB descriptor"); -+ abort(); -+ } -+ } -+ else - free(info->value); - info->value = NULL; - } -- free(info); -+ else -+ { -+ NSLog (@"trying to free an already freed value!"); -+ abort(); -+ } -+ free(info); -+ - [_row_buffer removeObjectAtIndex: c]; - } - -@@ -78,8 +103,7 @@ - // - @implementation OracleAdaptorChannel - --static void --DBTerminate() -+static void DBTerminate() - { - if (OCITerminate(OCI_DEFAULT)) - NSLog(@"FAILED: OCITerminate()"); -@@ -89,6 +113,15 @@ - - + (void) initialize - { -+ NSUserDefaults *ud; -+ -+ ud = [NSUserDefaults standardUserDefaults]; -+ debugOn = [ud boolForKey: @"OracleAdaptorDebug"]; -+ -+ prefetchMemorySize = [ud integerForKey: @"OracleAdaptorPrefetchMemorySize"]; -+ if (!prefetchMemorySize) -+ prefetchMemorySize = 16 * 1024; /* 16Kb */ -+ - // We Initialize the OCI process environment. - if (OCIInitialize((ub4)OCI_DEFAULT, (dvoid *)0, - (dvoid * (*)(dvoid *, size_t)) 0, -@@ -156,14 +189,17 @@ - [super closeChannel]; - - // We logoff from the database. -- if (OCILogoff(_oci_ctx, _oci_err)) -+ if (!_oci_ctx || !_oci_err || OCILogoff(_oci_ctx, _oci_err)) - { - NSLog(@"FAILED: OCILogoff()"); - } - -+ if (_oci_ctx) -+ OCIHandleFree(_oci_ctx, OCI_HTYPE_SVCCTX); - -- OCIHandleFree(_oci_ctx, OCI_HTYPE_SVCCTX); -- OCIHandleFree(_oci_err, OCI_HTYPE_ERROR); -+ if (_oci_err) -+ OCIHandleFree(_oci_err, OCI_HTYPE_ERROR); -+ - // OCIHandleFree(_oci_env, OCI_HTYPE_ENV); - - _oci_ctx = (OCISvcCtx *)0; -@@ -177,7 +213,8 @@ - // - - (void) dealloc - { -- //NSLog(@"OracleAdaptorChannel: -dealloc"); -+ if (debugOn) -+ NSLog(@"OracleAdaptorChannel: -dealloc"); - - [self _cleanup]; - -@@ -222,21 +259,25 @@ - { - EOAttribute *attribute; - OCIParam *param; -- -+ int rCount; - column_info *info; - ub4 i, clen, count; - text *sql, *cname; - sword status; - ub2 type; -+ ub4 memory, prefetchrows; - - [self _cleanup]; - -+ if (debugOn) -+ [self logWithFormat: @"expression: %@", theExpression]; -+ - if (!theExpression || ![theExpression length]) - { - [NSException raise: @"OracleInvalidExpressionException" - format: @"Passed an invalid (nil or length == 0) SQL expression"]; - } -- -+ - if (![self isOpen]) - { - [NSException raise: @"OracleChannelNotOpenException" -@@ -244,7 +285,9 @@ - } - - sql = (text *)[theExpression UTF8String]; -- -+ -+ rCount = 0; -+ retry: - // We alloc our statement handle - if ((status = OCIHandleAlloc((dvoid *)_oci_env, (dvoid **)&_current_stm, (ub4)OCI_HTYPE_STMT, (CONST size_t) 0, (dvoid **) 0))) - { -@@ -253,6 +296,22 @@ - return NO; - } - -+ prefetchrows = 100000; /* huge numbers here force a fallback on the memory limit below, which is what we really are interested in */ -+ if ((status = OCIAttrSet(_current_stm, (ub4)OCI_HTYPE_STMT, (dvoid *)&prefetchrows, (ub4) sizeof(ub4), (ub4)OCI_ATTR_PREFETCH_ROWS, _oci_err))) -+ { -+ checkerr(_oci_err, status); -+ NSLog(@"Can't set prefetch rows (%d).", prefetchrows); -+ return NO; -+ } -+ -+ memory = prefetchMemorySize; -+ if ((status = OCIAttrSet(_current_stm, (ub4)OCI_HTYPE_STMT, (dvoid *)&memory, (ub4) sizeof(ub4), (ub4)OCI_ATTR_PREFETCH_MEMORY, _oci_err))) -+ { -+ checkerr(_oci_err, status); -+ NSLog(@"Can't set prefetch memory (%d).", memory); -+ return NO; -+ } -+ - // We prepare our statement - if ((status = OCIStmtPrepare(_current_stm, _oci_err, sql, strlen((const char *)sql), OCI_NTV_SYNTAX, OCI_DEFAULT))) - { -@@ -264,13 +323,39 @@ - // We check if we're doing a SELECT and if so, we're fetching data! - OCIAttrGet(_current_stm, OCI_HTYPE_STMT, &type, 0, OCI_ATTR_STMT_TYPE, _oci_err); - self->isFetchInProgress = (type == OCI_STMT_SELECT ? YES : NO); -- -+ - // We execute our statement. Not that we _MUST_ set iter to 0 for non-SELECT statements. - if ((status = OCIStmtExecute(_oci_ctx, _current_stm, _oci_err, (self->isFetchInProgress ? (ub4)0 : (ub4)1), (ub4)0, (CONST OCISnapshot *)NULL, (OCISnapshot *)NULL, - ([(OracleAdaptorContext *)[self adaptorContext] autoCommit] ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT)))) - { -+ ub4 serverStatus; -+ - checkerr(_oci_err, status); - NSLog(@"Statement execute failed (OCI_ERROR): %@", theExpression); -+ -+ // We check to see if we lost connection and need to reconnect. -+ serverStatus = 0; -+ OCIAttrGet((dvoid *)_oci_env, OCI_HTYPE_SERVER, (dvoid *)&serverStatus, (ub4 *)0, OCI_ATTR_SERVER_STATUS, _oci_err); -+ -+ if (serverStatus == OCI_SERVER_NOT_CONNECTED) -+ { -+ // We cleanup our previous handles -+ [self cancelFetch]; -+ [self closeChannel]; -+ -+ // We try to reconnect a couple of times before giving up... -+ while (rCount < maxTry) -+ { -+ usleep(maxSleep); -+ rCount++; -+ -+ if ([self openChannel]) -+ { -+ NSLog(@"Connection re-established to Oracle - retrying to process the statement."); -+ goto retry; -+ } -+ } -+ } - return NO; - } - -@@ -302,7 +387,9 @@ - // We read the maximum width of a column - info->max_width = 0; - status = OCIAttrGet((dvoid*)param, (ub4)OCI_DTYPE_PARAM, (dvoid*)&(info->max_width), (ub4 *)0, (ub4)OCI_ATTR_DATA_SIZE, (OCIError *)_oci_err); -- -+ -+ if (debugOn) -+ NSLog(@"name: %s, type: %d", cname, info->type); - attribute = [EOAttribute attributeWithOracleType: info->type name: cname length: clen width: info->max_width]; - [_resultSetProperties addObject: attribute]; - -@@ -394,16 +481,17 @@ - return NO; - } - -- - if (OCIEnvInit((OCIEnv **)&_oci_env, (ub4)OCI_DEFAULT, (size_t)0, (dvoid **)0)) - { - NSLog(@"FAILED: OCIEnvInit()"); -+ [self closeChannel]; - return NO; - } - - if (OCIHandleAlloc((dvoid *)_oci_env, (dvoid *)&_oci_err, (ub4)OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0)) - { - NSLog(@"FAILED: OCIHandleAlloc() on errhp"); -+ [self closeChannel]; - return NO; - } - -@@ -414,7 +502,10 @@ - // Under Oracle 10g, the third parameter of OCILogon() has the form: [//]host[:port][/service_name] - // See http://download-west.oracle.com/docs/cd/B12037_01/network.101/b10775/naming.htm#i498306 for - // all juicy details. -- database = [[NSString stringWithFormat:@"%@:%@", [o serverName], [o port]] UTF8String]; -+ if ([o serverName] && [o port]) -+ database = [[NSString stringWithFormat:@"%@:%@/%@", [o serverName], [o port], [o databaseName]] UTF8String]; -+ else -+ database = [[o databaseName] UTF8String]; - - // We logon to the database. - if (OCILogon(_oci_env, _oci_err, &_oci_ctx, (const OraText*)username, strlen(username), -@@ -422,6 +513,7 @@ - { - NSLog(@"FAILED: OCILogon(). username = %s password = %s" - @" database = %s", username, password, database); -+ [self closeChannel]; - return NO; - } - -@@ -438,6 +530,11 @@ - { - sword status; - -+ // We check if our connection is open prior to trying to fetch any data. OCIStmtFetch2() returns -+ // NO error code if the OCI environment is set up but the OCILogon() has failed. -+ if (![self isOpen]) -+ return nil; -+ - status = OCIStmtFetch2(_current_stm, _oci_err, (ub4)1, (ub4)OCI_FETCH_NEXT, (sb4)0, (ub4)OCI_DEFAULT); - - if (status == OCI_NO_DATA) -@@ -607,37 +704,4 @@ - return _oci_ctx; - } - --/* GCSEOAdaptorChannel protocol */ --static NSString *sqlFolderFormat = (@"CREATE TABLE %@ (\n" \ -- @" c_name VARCHAR2 (256) NOT NULL,\n" -- @" c_content CLOB NOT NULL,\n" -- @" c_creationdate INTEGER NOT NULL,\n" -- @" c_lastmodified INTEGER NOT NULL,\n" -- @" c_version INTEGER NOT NULL,\n" -- @" c_deleted INTEGER DEFAULT 0 NOT NULL\n" -- @")"); --static NSString *sqlFolderACLFormat = (@"CREATE TABLE %@ (\n" \ -- @" c_uid VARCHAR (256) NOT NULL,\n" -- @" c_object VARCHAR (256) NOT NULL,\n" -- @" c_role VARCHAR (80) NOT NULL\n" -- @")"); -- --- (NSException *) createGCSFolderTableWithName: (NSString *) tableName --{ -- NSString *sql; -- -- sql = [NSString stringWithFormat: sqlFolderFormat, tableName]; -- -- return [self evaluateExpressionX: sql]; --} -- --- (NSException *) createGCSFolderACLTableWithName: (NSString *) tableName --{ -- NSString *sql; -- -- sql = [NSString stringWithFormat: sqlFolderACLFormat, tableName]; -- -- return [self evaluateExpressionX: sql]; --} -- - @end -Index: sope-gdl1/Oracle8/OracleAdaptorChannelController.m -=================================================================== ---- sope-gdl1/Oracle8/OracleAdaptorChannelController.m (revision 1664) -+++ sope-gdl1/Oracle8/OracleAdaptorChannelController.m (working copy) -@@ -31,6 +31,8 @@ - #import - #import - -+static BOOL debugOn = NO; -+ - // - // - // -@@ -48,6 +50,14 @@ - // - @implementation OracleAdaptorChannelController - -++ (void) initialize -+{ -+ NSUserDefaults *ud; -+ -+ ud = [NSUserDefaults standardUserDefaults]; -+ debugOn = [ud boolForKey: @"OracleAdaptorDebug"]; -+} -+ - - (EODelegateResponse) adaptorChannel: (id) theChannel - willInsertRow: (NSMutableDictionary *) theRow - forEntity: (EOEntity *) theEntity -@@ -56,7 +66,8 @@ - NSArray *keys; - int i, c; - -- NSLog(@"willInsertRow: %@ %@", [theRow description], [theEntity description]); -+ if (debugOn) -+ NSLog(@"willInsertRow: %@ %@", [theRow description], [theEntity description]); - - s = AUTORELEASE([[NSMutableString alloc] init]); - -@@ -101,7 +112,8 @@ - NSArray *keys; - int i, c; - -- NSLog(@"willUpdatetRow: %@ %@", [theRow description], [theQualifier description]); -+ if (debugOn) -+ NSLog(@"willUpdateRow: %@ %@", [theRow description], [theQualifier description]); - - s = AUTORELEASE([[NSMutableString alloc] init]); - -Index: sope-mime/NGImap4/NGImap4Functions.m -=================================================================== ---- sope-mime/NGImap4/NGImap4Functions.m (revision 1664) -+++ sope-mime/NGImap4/NGImap4Functions.m (working copy) -@@ -367,3 +367,16 @@ - } - - @end /* NGImap4FolderHandler */ -+ -+NSString * -+SaneFolderName(NSString *folderName) -+{ -+ NSString *saneFName; -+ -+ saneFName = [[folderName stringByReplacingString: @"\\" -+ withString: @"\\\\"] -+ stringByReplacingString: @"\"" -+ withString: @"\\\""]; -+ -+ return saneFName; -+} -Index: sope-mime/NGImap4/NGImap4Client.h -=================================================================== ---- sope-mime/NGImap4/NGImap4Client.h (revision 1664) -+++ sope-mime/NGImap4/NGImap4Client.h (working copy) -@@ -62,6 +62,8 @@ - NGImap4ResponseNormalizer *normer; - NSMutableArray *responseReceiver; - -+ BOOL loggedIn; -+ - BOOL isLogin; - unsigned tagId; - -@@ -117,9 +119,11 @@ - - (NSDictionary *)noop; - - - (NSDictionary *)capability; -+- (NSDictionary *)namespace; - - (NSDictionary *)list:(NSString *)_folder pattern:(NSString *)_pattern; - - (NSDictionary *)lsub:(NSString *)_folder pattern:(NSString *)_pattern; - - (NSDictionary *)select:(NSString *)_folder; -+- (NSDictionary *)unselect; - - (NSDictionary *)status:(NSString *)_folder flags:(NSArray *)_flags; - - (NSDictionary *)rename:(NSString *)_folder to:(NSString *)_newName; - - (NSDictionary *)delete:(NSString *)_folder; -@@ -138,7 +142,7 @@ - flags:(NSArray *)_flags; - - (NSDictionary *)storeFrom:(unsigned)_from to:(unsigned)_to - add:(NSNumber *)_add flags:(NSArray *)_flags; --- (NSDictionary *)storeFlags:(NSArray *)_flags forMSNs:(id)_msns -+- (NSDictionary *)storeFlags:(NSArray *)_flags forUIDs:(id)_uids - addOrRemove:(BOOL)_flag; - - - (NSDictionary *)copyUid:(unsigned)_uid toFolder:(NSString *)_folder; -Index: sope-mime/NGImap4/NGImap4Client.m -=================================================================== ---- sope-mime/NGImap4/NGImap4Client.m (revision 1664) -+++ sope-mime/NGImap4/NGImap4Client.m (working copy) -@@ -24,6 +24,8 @@ - #include "NGImap4Client.h" - #include "NGImap4Context.h" - #include "NGImap4Support.h" -+#include "NGImap4Envelope.h" -+#include "NGImap4EnvelopeAddress.h" - #include "NGImap4Functions.h" - #include "NGImap4ResponseParser.h" - #include "NGImap4ResponseNormalizer.h" -@@ -53,17 +55,17 @@ - - @end /* NGImap4Client(ConnectionRegistration); */ - --#if GNUSTEP_BASE_LIBRARY --/* FIXME: TODO: move someplace better (hh: NGExtensions...) */ --@implementation NSException(setUserInfo) -+// #if GNUSTEP_BASE_LIBRARY -+// /* FIXME: TODO: move someplace better (hh: NGExtensions...) */ -+// @implementation NSException(setUserInfo) - --- (id)setUserInfo:(NSDictionary *)_userInfo { -- ASSIGN(self->_e_info, _userInfo); -- return self; --} -+// - (id)setUserInfo:(NSDictionary *)_userInfo { -+// ASSIGN(self->_e_info, _userInfo); -+// return self; -+// } - --@end /* NSException(setUserInfo) */ --#endif -+// @end /* NSException(setUserInfo) */ -+// #endif - - @interface NGImap4Client(Private) - -@@ -84,6 +86,8 @@ - - - (NSDictionary *)login; - -+- (NSDictionary *) _sopeSORT: (id)_sortSpec qualifier:(EOQualifier *)_qual encoding:(NSString *)_encoding; -+ - @end - - /* -@@ -110,6 +114,9 @@ - static BOOL ImapDebugEnabled = NO; - static NSArray *Imap4SystemFlags = nil; - -+static NSMutableDictionary *capabilities; -+static NSMutableDictionary *namespaces; -+ - - (BOOL)useSSL { - return self->useSSL; - } -@@ -140,6 +147,9 @@ - - Imap4SystemFlags = [[NSArray alloc] initWithObjects: @"seen", @"answered", - @"deleted", @"draft", nil]; -+ -+ capabilities = [[NSMutableDictionary alloc] init]; -+ namespaces = [[NSMutableDictionary alloc] init]; - } - - /* constructors */ -@@ -195,11 +205,14 @@ - self->debug = ImapDebugEnabled; - self->responseReceiver = [[NSMutableArray alloc] initWithCapacity:128]; - self->normer = [[NGImap4ResponseNormalizer alloc] initWithClient:self]; -+ self->loggedIn = NO; -+ self->context = nil; - } - return self; - } - - - (void)dealloc { -+ if (self->loggedIn) [self logout]; - [self removeFromConnectionRegister]; - [self->normer release]; - [self->text release]; -@@ -457,8 +470,8 @@ - - (void)reconnect { - if ([self->context lastException] != nil) - return; -- -- [self closeConnection]; -+ -+ [self closeConnection]; - self->tagId = 0; - [self openConnection]; - -@@ -481,6 +494,7 @@ - */ - NGHashMap *map; - NSString *s, *log; -+ NSDictionary *response; - - if (self->isLogin ) - return nil; -@@ -499,7 +513,11 @@ - - self->isLogin = NO; - -- return [self->normer normalizeResponse:map]; -+ response = [self->normer normalizeResponse:map]; -+ -+ self->loggedIn = [[response valueForKey:@"result"] boolValue]; -+ -+ return response; - } - - - (NSDictionary *)logout { -@@ -508,6 +526,8 @@ - - map = [self processCommand:@"logout"]; - [self closeConnection]; -+ [self->selectedFolder release]; self->selectedFolder = nil; -+ self->loggedIn = NO; - - return [self->normer normalizeResponse:map]; - } -@@ -530,7 +550,7 @@ - NSAutoreleasePool *pool; - NGHashMap *map; - NSDictionary *result; -- NSString *s; -+ NSString *s, *prefix; - - pool = [[NSAutoreleasePool alloc] init]; - -@@ -547,7 +567,12 @@ - if (!(_pattern = [self _folder2ImapFolder:_pattern])) - return nil; - -- s = [NSString stringWithFormat:@"list \"%@\" \"%@\"", _folder, _pattern]; -+ if ([_folder length] > 0) -+ prefix = [NSString stringWithFormat: @"%@%@", -+ SaneFolderName(_folder), self->delimiter]; -+ else -+ prefix = @""; -+ s = [NSString stringWithFormat:@"LIST \"\" \"%@%@\"", prefix, _pattern]; - map = [self processCommand:s]; - - if (self->delimiter == nil) { -@@ -563,18 +588,49 @@ - } - - - (NSDictionary *)capability { -+ NSDictionary *result; - id capres; -- capres = [self processCommand:@"capability"]; -- return [self->normer normalizeCapabilityRespone:capres]; -+ -+ result = [capabilities objectForKey: [self->address description]]; -+ -+ if (!result) -+ { -+ capres = [self processCommand:@"capability"]; -+ result = [self->normer normalizeCapabilityResponse:capres]; -+ -+ if (result) -+ [capabilities setObject: result forKey: [self->address description]]; -+ } -+ return result; - } - -+- (NSDictionary *)namespace { -+ NSArray *capabilities; -+ NGHashMap *namesres; -+ id namespace; -+ -+ namespace = [namespaces objectForKey: [self->address description]]; -+ if (!namespace) { -+ capabilities = [[self capability] objectForKey: @"capability"]; -+ if ([capabilities containsObject: @"namespace"]) { -+ namesres = [self processCommand: @"namespace"]; -+ namespace = [self->normer normalizeNamespaceResponse:namesres]; -+ } -+ else -+ namespace = [NSNull null]; -+ [namespaces setObject: namespace forKey: [self->address description]]; -+ } -+ -+ return ([namespace isKindOfClass: [NSNull class]] ? nil : namespace); -+} -+ - - (NSDictionary *)lsub:(NSString *)_folder pattern:(NSString *)_pattern { - /* - The method build statements like 'LSUB "_folder" "_pattern"'. - The returnvalue is the same like the list:pattern: method - */ - NGHashMap *map; -- NSString *s; -+ NSString *s, *prefix; - - if (_folder == nil) - _folder = @""; -@@ -591,7 +647,11 @@ - return nil; - } - -- s = [NSString stringWithFormat:@"lsub \"%@\" \"%@\"", _folder, _pattern]; -+ if ([_folder length] > 0) -+ prefix = [NSString stringWithFormat: @"%@%@", SaneFolderName(_folder), self->delimiter]; -+ else -+ prefix = @""; -+ s = [NSString stringWithFormat:@"LSUB \"\" \"%@%@\"", prefix, _pattern]; - map = [self processCommand:s]; - - if (self->delimiter == nil) { -@@ -617,24 +677,25 @@ - 'flags' - array of strings (eg (answered,flagged,draft,seen); - 'RawResponse' - the raw IMAP4 response - */ -- NSString *s; -- id tmp; -- -- tmp = self->selectedFolder; // remember ptr to old folder name -- -+ NSString *s, *newFolder; -+ - if (![_folder isNotEmpty]) - return nil; - if ((_folder = [self _folder2ImapFolder:_folder]) == nil) - return nil; - -- self->selectedFolder = [_folder copy]; -- -- [tmp release]; tmp = nil; // release old folder name -+ newFolder = [NSString stringWithString: _folder]; -+ ASSIGN (self->selectedFolder, newFolder); - -- s = [NSString stringWithFormat:@"select \"%@\"", self->selectedFolder]; -+ s = [NSString stringWithFormat:@"select \"%@\"", SaneFolderName(self->selectedFolder)]; - return [self->normer normalizeSelectResponse:[self processCommand:s]]; - } - -+- (NSDictionary *)unselect { -+ [self->selectedFolder release]; self->selectedFolder = nil; -+ return [self->normer normalizeResponse:[self processCommand:@"unselect"]]; -+} -+ - - (NSDictionary *)status:(NSString *)_folder flags:(NSArray *)_flags { - NSString *cmd; - -@@ -646,7 +707,7 @@ - return nil; - - cmd = [NSString stringWithFormat:@"status \"%@\" (%@)", -- _folder, [_flags componentsJoinedByString:@" "]]; -+ SaneFolderName(_folder), [_flags componentsJoinedByString:@" "]]; - return [self->normer normalizeStatusResponse:[self processCommand:cmd]]; - } - -@@ -663,24 +724,28 @@ - if ((_newName = [self _folder2ImapFolder:_newName]) == nil) - return nil; - -- cmd = [NSString stringWithFormat:@"rename \"%@\" \"%@\"", _folder, _newName]; -+ cmd = [NSString stringWithFormat:@"rename \"%@\" \"%@\"", -+ SaneFolderName(_folder), SaneFolderName(_newName)]; - - return [self->normer normalizeResponse:[self processCommand:cmd]]; - } - - - (NSDictionary *)_performCommand:(NSString *)_op onFolder:(NSString *)_fname { - NSString *command; -- -+ - if ((_fname = [self _folder2ImapFolder:_fname]) == nil) - return nil; -- -+ - // eg: 'delete "blah"' -- command = [NSString stringWithFormat:@"%@ \"%@\"", _op, _fname]; -- -+ command = [NSString stringWithFormat:@"%@ \"%@\"", _op, SaneFolderName(_fname)]; -+ - return [self->normer normalizeResponse:[self processCommand:command]]; - } - - - (NSDictionary *)delete:(NSString *)_name { -+ if ([self->selectedFolder isEqualToString:_name]) { -+ [self unselect]; -+ } - return [self _performCommand:@"delete" onFolder:_name]; - } - - (NSDictionary *)create:(NSString *)_name { -@@ -820,23 +885,23 @@ - return [self->normer normalizeResponse:[self processCommand:cmd]]; - } - --- (NSDictionary *)storeFlags:(NSArray *)_flags forMSNs:(id)_msns -+- (NSDictionary *)storeFlags:(NSArray *)_flags forUIDs:(id)_uids - addOrRemove:(BOOL)_flag - { - NSString *cmd; - NSString *flagstr; - NSString *seqstr; - -- if ([_msns isKindOfClass:[NSArray class]]) { -+ if ([_uids isKindOfClass:[NSArray class]]) { - // TODO: improve by using ranges, eg 1:5 instead of 1,2,3,4,5 -- _msns = [_msns valueForKey:@"stringValue"]; -- seqstr = [_msns componentsJoinedByString:@","]; -+ _uids = [_uids valueForKey:@"stringValue"]; -+ seqstr = [_uids componentsJoinedByString:@","]; - } - else -- seqstr = [_msns stringValue]; -+ seqstr = [_uids stringValue]; - - flagstr = [_flags2ImapFlags(self, _flags) componentsJoinedByString:@" "]; -- cmd = [NSString stringWithFormat:@"store %@ %cFLAGS (%@)", -+ cmd = [NSString stringWithFormat:@"UID STORE %@ %cFLAGS (%@)", - seqstr, _flag ? '+' : '-', flagstr]; - - return [self->normer normalizeResponse:[self processCommand:cmd]]; -@@ -896,35 +961,23 @@ - NSArray *flags; - NGHashMap *result; - NSString *message, *icmd; -+ char *new; -+ const char *old; -+ int cntOld = 0; -+ int cntNew = 0; -+ int len = 0; - - flags = _flags2ImapFlags(self, _flags); - if ((_folder = [self _folder2ImapFolder:_folder]) == nil) - return nil; - -+ /* Remove bare newlines */ -+ old = [_message bytes]; -+ len = [_message length]; - -- /* Remove bare newlines */ -- { -- char *new; -- const char *old; -- int cntOld = 0; -- int cntNew = 0; -- int len = 0; -- -- old = [_message bytes]; -- len = [_message length]; -- -- new = calloc(len * 2 + 4, sizeof(char)); -- -- while (cntOld < (len - 1)) { -- if (old[cntOld] == '\n') { -- new[cntNew] = '\r'; cntNew++; -- new[cntNew] = '\n'; cntNew++; -- } -- else if (old[cntOld] != '\r') { -- new[cntNew] = old[cntOld]; cntNew++; -- } -- cntOld++; -- } -+ new = calloc(len * 2 + 4, sizeof(char)); -+ -+ while (cntOld < (len - 1)) { - if (old[cntOld] == '\n') { - new[cntNew] = '\r'; cntNew++; - new[cntNew] = '\n'; cntNew++; -@@ -932,16 +985,24 @@ - else if (old[cntOld] != '\r') { - new[cntNew] = old[cntOld]; cntNew++; - } -- -- // TODO: fix this junk, do not treat the message as a string, its NSData -- message = [(NSString *)[NSString alloc] initWithCString:new length:cntNew]; -- if (new != NULL) free(new); new = NULL; -+ cntOld++; - } -- -+ if (old[cntOld] == '\n') { -+ new[cntNew] = '\r'; cntNew++; -+ new[cntNew] = '\n'; cntNew++; -+ } -+ else if (old[cntOld] != '\r') { -+ new[cntNew] = old[cntOld]; cntNew++; -+ } -+ -+ // TODO: fix this junk, do not treat the message as a string, its NSData -+ message = [(NSString *)[NSString alloc] initWithUTF8String:new]; -+ if (new != NULL) free(new); new = NULL; -+ - icmd = [NSString stringWithFormat:@"append \"%@\" (%@) {%d}", - _folder, - [flags componentsJoinedByString:@" "], -- [message cStringLength]]; -+ cntNew]; - result = [self processCommand:icmd - withTag:YES withNotification:NO]; - -@@ -967,11 +1028,12 @@ - descr = @"Could not process qualifier for imap search "; - descr = [descr stringByAppendingString:reason]; - -- exception = [[NGImap4SearchException alloc] initWithFormat:@"%@", descr]; - ui = [NSDictionary dictionaryWithObject:_q forKey:@"qualifier"]; -- [exception setUserInfo:ui]; -+ exception -+ = [NGImap4SearchException exceptionWithName: @"NGImap4SearchException" -+ reason: descr -+ userInfo: ui]; - [self->context setLastException:exception]; -- [exception release]; - } - - - (NSString *)_searchExprForQual:(EOQualifier *)_qualifier { -@@ -1093,7 +1155,18 @@ - Eg: UID SORT ( DATE REVERSE SUBJECT ) UTF-8 TODO - */ - NSString *tmp; -+ NSArray *capa; - -+ // We first check to see if our server supports IMAP SORT. If not -+ // we'll sort ourself the results. -+ capa = [[self capability] objectForKey: @"capability"]; -+ -+ if ([capa indexOfObject: @"sort"] == NSNotFound) -+ { -+ return [self _sopeSORT: _sortSpec qualifier: _qual encoding: _encoding]; -+ } -+ -+ - if ([_sortSpec isKindOfClass:[NSArray class]]) - tmp = [self _generateIMAP4SortOrderings:_sortSpec]; - else if ([_sortSpec isKindOfClass:[EOSortOrdering class]]) -@@ -1107,9 +1180,10 @@ - tmp = @"DATE"; - } - -+ - return [self primarySort:tmp -- qualifierString:[self _searchExprForQual:_qual] -- encoding:_encoding]; -+ qualifierString:[self _searchExprForQual:_qual] -+ encoding:_encoding]; - } - - (NSDictionary *)sort:(NSArray *)_sortOrderings - qualifier:(EOQualifier *)_qual -@@ -1130,7 +1204,7 @@ - return nil; - } - -- s = [@"search" stringByAppendingString:s]; -+ s = [@"UID SEARCH" stringByAppendingString:s]; - return [self->normer normalizeSearchResponse:[self processCommand:s]]; - } - -@@ -1142,7 +1216,7 @@ - if ((_folder = [self _folder2ImapFolder:_folder]) == nil) - return nil; - -- cmd = [NSString stringWithFormat:@"getacl \"%@\"", _folder]; -+ cmd = [NSString stringWithFormat:@"getacl \"%@\"", SaneFolderName(_folder)]; - return [self->normer normalizeGetACLResponse:[self processCommand:cmd]]; - } - -@@ -1155,7 +1229,7 @@ - return nil; - - cmd = [NSString stringWithFormat:@"setacl \"%@\" \"%@\" \"%@\"", -- _folder, _uid, _r]; -+ SaneFolderName(_folder), _uid, _r]; - return [self->normer normalizeResponse:[self processCommand:cmd]]; - } - -@@ -1166,7 +1240,7 @@ - return nil; - - cmd = [NSString stringWithFormat:@"deleteacl \"%@\" \"%@\"", -- _folder, _uid]; -+ SaneFolderName(_folder), _uid]; - return [self->normer normalizeResponse:[self processCommand:cmd]]; - } - -@@ -1177,7 +1251,7 @@ - return nil; - - cmd = [NSString stringWithFormat:@"listrights \"%@\" \"%@\"", -- _folder, _uid]; -+ SaneFolderName(_folder), _uid]; - return [self->normer normalizeListRightsResponse:[self processCommand:cmd]]; - } - -@@ -1187,12 +1261,94 @@ - if ((_folder = [self _folder2ImapFolder:_folder]) == nil) - return nil; - -- cmd = [NSString stringWithFormat:@"myrights \"%@\"", _folder]; -+ cmd = [NSString stringWithFormat:@"myrights \"%@\"", SaneFolderName(_folder)]; - return [self->normer normalizeMyRightsResponse:[self processCommand:cmd]]; - } - - /* Private Methods */ - -+- (NSDictionary *) _sopeSORT: (id)_sortSpec qualifier:(EOQualifier *)_qual encoding:(NSString *)_encoding { -+ NSMutableDictionary *result; -+ NSDictionary *d; -+ NSCalendarDate *envDate; -+ -+ result = [NSMutableDictionary dictionary]; -+ [result setObject: [NSNumber numberWithBool: NO] forKey: @"result"]; -+ -+ // _sortSpec: [REVERSE] {DATE,FROM,SUBJECT} -+ d = [self searchWithQualifier: _qual]; -+ -+ if ((d = [d objectForKey: @"RawResponse"])) { -+ NSMutableDictionary *dict; -+ NSArray *a, *s_a; -+ BOOL b; -+ int i; -+ -+ a = [d objectForKey: @"search"]; -+ if ([a isNotEmpty]) { -+ d = [self fetchUids: a -+ parts: [NSArray arrayWithObjects: @"ENVELOPE", -+ @"RFC822.SIZE", nil]]; -+ a = [d objectForKey: @"fetch"]; -+ -+ dict = [NSMutableDictionary dictionary]; -+ b = YES; -+ -+ for (i = 0; i < [a count]; i++) { -+ NGImap4Envelope *env; -+ id o, uid, s; -+ -+ o = [a objectAtIndex: i]; -+ env = [o objectForKey: @"envelope"]; -+ uid = [o objectForKey: @"uid"]; -+ -+ if ([_sortSpec rangeOfString: @"SUBJECT"].length) { -+ s = [env subject]; -+ if ([s isKindOfClass: [NSData class]]) -+ s = [[[NSString alloc] initWithData: s encoding: NSUTF8StringEncoding] autorelease]; -+ -+ [dict setObject: (s != nil ? s : (id)@"") forKey: uid]; -+ } -+ else if ([_sortSpec rangeOfString: @"FROM"].length) { -+ s = [[[env from] lastObject] email]; -+ [dict setObject: (s != nil ? s : (id)@"") forKey: uid]; -+ } -+ else if ([_sortSpec rangeOfString: @"SIZE"].length) { -+ s = [o objectForKey: @"size"]; -+ [dict setObject: (s != nil ? s : [NSNumber numberWithInt: 0]) -+ forKey: uid]; -+ b = NO; -+ } -+ else { -+ envDate = [env date]; -+ if (!envDate) -+ envDate = [NSCalendarDate date]; -+ [dict setObject: envDate forKey: uid]; -+ b = NO; -+ } -+ } -+ -+ if (b) -+ s_a = [dict keysSortedByValueUsingSelector: @selector(caseInsensitiveCompare:)]; -+ else -+ s_a = [dict keysSortedByValueUsingSelector: @selector(compare:)]; -+ -+ if ([_sortSpec rangeOfString: @"REVERSE"].length) { -+ s_a = [[s_a reverseObjectEnumerator] allObjects]; -+ } -+ -+ } -+ else { -+ s_a = [NSArray array]; -+ } -+ [result setObject: [NSNumber numberWithBool: YES] forKey: @"result"]; -+ [result setObject: s_a forKey: @"sort"]; -+ } -+ -+ return result; -+} -+ -+ - - (NSException *)_processCommandParserException:(NSException *)_exception { - [self logWithFormat:@"ERROR(%s): catched IMAP4 parser exception %@: %@", - __PRETTY_FUNCTION__, [_exception name], [_exception reason]]; -@@ -1280,7 +1436,9 @@ - if (tryReconnect) { - [self reconnect]; - } -- else if ([map objectForKey:@"bye"] && ![_command hasPrefix:@"logout"]) { -+ else if ([map objectForKey:@"bye"] -+ && ![_command hasPrefix:@"logout"] -+ && ![self _isLoginCommand:_command]) { - if (reconnectCnt == 0) { - reconnectCnt++; - tryReconnect = YES; -@@ -1412,21 +1570,24 @@ - return nil; - } - -- array = [_folder pathComponents]; -+// array = [_folder pathComponents]; -+ array = [_folder componentsSeparatedByString:@"/"]; - -- if ([array isNotEmpty]) { -+ if ([array count]) { - NSString *o; - - o = [array objectAtIndex:0]; -- if (([o isEqualToString:@"/"]) || ([o length] == 0)) -+ if ([o length] == 0) - array = [array subarrayWithRange:NSMakeRange(1, [array count] - 1)]; -- -- o = [array lastObject]; -- if (([o length] == 0) || ([o isEqualToString:@"/"])) -- array = [array subarrayWithRange:NSMakeRange(0, [array count] - 1)]; -+ -+ if ([array count]) { -+ o = [array lastObject]; -+ if ([o length] == 0) -+ array = [array subarrayWithRange:NSMakeRange(0, [array count] - 1)]; -+ } - } - return [[array componentsJoinedByString:self->delimiter] -- stringByEncodingImap4FolderName]; -+ stringByEncodingImap4FolderName]; - } - - - (NSString *)_imapFolder2Folder:(NSString *)_folder { -@@ -1442,10 +1603,16 @@ - return nil; - } - -+ if ([_folder hasPrefix: self->delimiter]) -+ _folder = [_folder substringFromIndex: 1]; -+ if ([_folder hasSuffix: self->delimiter]) -+ _folder = [_folder substringToIndex: [_folder length] - 1]; -+ - array = [array arrayByAddingObjectsFromArray: - [_folder componentsSeparatedByString:[self delimiter]]]; -- -- return [[NSString pathWithComponents:array] stringByDecodingImap4FolderName]; -+ -+ return [[array componentsJoinedByString: @"/"] -+ stringByDecodingImap4FolderName]; - } - - - (void)setContext:(NGImap4Context *)_ctx { -Index: sope-mime/NGImap4/NGSieveClient.m -=================================================================== ---- sope-mime/NGImap4/NGSieveClient.m (revision 1664) -+++ sope-mime/NGImap4/NGSieveClient.m (working copy) -@@ -294,8 +294,8 @@ - return con; - } - -- logLen = [self->login cStringLength]; -- bufLen = (logLen * 2) + [self->password cStringLength] +2; -+ logLen = [self->login lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; -+ bufLen = (logLen * 2) + [self->password lengthOfBytesUsingEncoding: NSUTF8StringEncoding] +2; - - buf = calloc(bufLen + 2, sizeof(char)); - -@@ -306,8 +306,9 @@ - password - */ - sprintf(buf, "%s %s %s", -- [self->login cString], [self->login cString], -- [self->password cString]); -+ [self->login cStringUsingEncoding:NSUTF8StringEncoding], -+ [self->login cStringUsingEncoding:NSUTF8StringEncoding], -+ [self->password cStringUsingEncoding:NSUTF8StringEncoding]); - - buf[logLen] = '\0'; - buf[logLen * 2 + 1] = '\0'; -@@ -422,8 +423,9 @@ - s = @"PUTSCRIPT \""; - s = [s stringByAppendingString:_name]; - s = [s stringByAppendingString:@"\" "]; -- s = [s stringByAppendingFormat:@"{%d+}\r\n%@", [_script length], _script]; -- s = [s stringByAppendingString:@"\r\n"]; -+ s = [s stringByAppendingFormat:@"{%d+}\r\n%@", -+ [_script lengthOfBytesUsingEncoding: NSUTF8StringEncoding], -+ _script]; - map = [self processCommand:s]; - return [self normalizeResponse:map]; - } -@@ -431,12 +433,12 @@ - - (NSDictionary *)setActiveScript:(NSString *)_name { - NGHashMap *map; - -- if (![self isValidScriptName:_name]) { -+ if (!_name) { - NSLog(@"%s: missing script-name", __PRETTY_FUNCTION__); - return nil; - } - map = [self processCommand: -- [NSString stringWithFormat:@"SETACTIVE \"%@\"\r\n", _name]]; -+ [NSString stringWithFormat:@"SETACTIVE \"%@\"", _name]]; - return [self normalizeResponse:map]; - } - -@@ -449,7 +451,7 @@ - return nil; - } - -- s = [NSString stringWithFormat:@"DELETESCRIPT \"%@\"\r\n", _name]; -+ s = [NSString stringWithFormat:@"DELETESCRIPT \"%@\"", _name]; - map = [self processCommand:s]; - return [self normalizeResponse:map]; - } -@@ -656,7 +658,7 @@ - fputc('\n', stderr); - } - else -- fprintf(stderr, "C: %s\n", [_txt cString]); -+ fprintf(stderr, "C: %s\n", [_txt cStringUsingEncoding:NSUTF8StringEncoding]); - } - - /* write */ -Index: sope-mime/NGImap4/NGImap4Connection.h -=================================================================== ---- sope-mime/NGImap4/NGImap4Connection.h (revision 1664) -+++ sope-mime/NGImap4/NGImap4Connection.h (working copy) -@@ -52,7 +52,7 @@ - NSString *separator; - - /* hierarchy cache */ -- NSDictionary *subfolders; -+ NSMutableDictionary *subfolders; - - /* permission cache */ - NSMutableDictionary *urlToRights; -@@ -72,8 +72,9 @@ - - - (NSDate *)creationTime; - --- (void)cacheHierarchyResults:(NSDictionary *)_hierarchy; --- (NSDictionary *)cachedHierarchyResults; -+- (void)cacheHierarchyResults:(NSDictionary *)_hierarchy -+ forURL:(NSURL *)_url; -+- (NSDictionary *)cachedHierarchyResultsForURL:(NSURL *)_url; - - (void)flushFolderHierarchyCache; - - - (id)cachedUIDsForURL:(NSURL *)_url qualifier:(id)_q sortOrdering:(id)_so; -@@ -88,7 +89,12 @@ - /* folder operations */ - - - (NSArray *)subfoldersForURL:(NSURL *)_url; -+- (NSArray *)subfoldersForURL:(NSURL *)_url -+ onlySubscribedFolders: (BOOL) subscribedFoldersOnly; - - (NSArray *)allFoldersForURL:(NSURL *)_url; -+- (NSArray *)allFoldersForURL:(NSURL *)_url -+ onlySubscribedFolders: (BOOL) subscribedFoldersOnly; -+- (BOOL)selectFolder:(id)_url; - - /* message operations */ - -Index: sope-mime/NGImap4/NGImap4ResponseNormalizer.h -=================================================================== ---- sope-mime/NGImap4/NGImap4ResponseNormalizer.h (revision 1664) -+++ sope-mime/NGImap4/NGImap4ResponseNormalizer.h (working copy) -@@ -49,7 +49,8 @@ - - (NSDictionary *)normalizeSearchResponse:(NGHashMap *)_map; - - (NSDictionary *)normalizeSortResponse:(NGHashMap *)_map; - - (NSDictionary *)normalizeThreadResponse:(NGHashMap *)_map; --- (NSDictionary *)normalizeCapabilityRespone:(NGHashMap *)_map; -+- (NSDictionary *)normalizeCapabilityResponse:(NGHashMap *)_map; -+- (NSDictionary *)normalizeNamespaceResponse:(NGHashMap *)_map; - - (NSDictionary *)normalizeQuotaResponse:(NGHashMap *)_map; - - /* ACL */ -Index: sope-mime/NGImap4/NGImap4Connection.m -=================================================================== ---- sope-mime/NGImap4/NGImap4Connection.m (revision 1664) -+++ sope-mime/NGImap4/NGImap4Connection.m (working copy) -@@ -22,6 +22,7 @@ - #include "NGImap4Connection.h" - #include "NGImap4MailboxInfo.h" - #include "NGImap4Client.h" -+#include "NGImap4Functions.h" - #include "imCommon.h" - - @implementation NGImap4Connection -@@ -66,7 +67,8 @@ - self->creationTime = [[NSDate alloc] init]; - - // TODO: retrieve from IMAP4 instead of using a default -- self->separator = imap4Separator; -+ self->separator = [imap4Separator copy]; -+ self->subfolders = [NSMutableDictionary new]; - } - return self; - } -@@ -100,14 +102,16 @@ - return self->creationTime; - } - --- (void)cacheHierarchyResults:(NSDictionary *)_hierarchy { -- ASSIGNCOPY(self->subfolders, _hierarchy); -+- (void)cacheHierarchyResults:(NSDictionary *)_hierarchy -+ forURL:(NSURL *)_url -+{ -+ [self->subfolders setObject:_hierarchy forKey:[_url absoluteString]]; - } --- (NSDictionary *)cachedHierarchyResults { -- return self->subfolders; -+- (NSDictionary *)cachedHierarchyResultsForURL:(NSURL *)_url { -+ return [self->subfolders objectForKey:[_url absoluteString]]; - } - - (void)flushFolderHierarchyCache { -- [self->subfolders release]; self->subfolders = nil; -+ [self->subfolders release]; self->subfolders = [NSMutableDictionary new]; - [self->urlToRights release]; self->urlToRights = nil; - } - -@@ -152,7 +156,6 @@ - ASSIGN(self->cachedUIDs, nil); - } - -- - /* errors */ - - - (NSException *)errorCouldNotSelectURL:(NSURL *)_url { -@@ -215,18 +218,13 @@ - NSMutableArray *ma; - unsigned i, count, prefixlen; - -- if ((count = [_array count]) < 2) { -- /* one entry is the folder itself, so we need at least two */ -- return [NSArray array]; -- } -+ count = [_array count]; - - // TODO: somehow results are different on OSX - // we should investigate and test all Foundation libraries and document the - // differences - #if __APPLE__ - prefixlen = [_fn isEqualToString:@""] ? 0 : [_fn length] + 1; --#elif GNUSTEP_BASE_LIBRARY -- prefixlen = [_fn isEqualToString:@"/"] ? 1 : [_fn length]; - #else - prefixlen = [_fn isEqualToString:@"/"] ? 1 : [_fn length] + 1; - #endif -@@ -321,13 +319,15 @@ - return nil; - if ([folderName characterAtIndex:0] == '/') - folderName = [folderName substringFromIndex:1]; -+ if ([folderName hasSuffix: @"/"]) -+ folderName = [folderName substringToIndex:[folderName length] - 1]; - - if (_delfn) folderName = [folderName stringByDeletingLastPathComponent]; - - if ([[self imap4Separator] isEqualToString:@"/"]) - return folderName; - -- names = [folderName pathComponents]; -+ names = [folderName componentsSeparatedByString: @"/"]; - return [names componentsJoinedByString:[self imap4Separator]]; - } - - (NSString *)imap4FolderNameForURL:(NSURL *)_url { -@@ -373,16 +373,26 @@ - - /* folder operations */ - --- (NSDictionary *)primaryFetchMailboxHierarchyForURL:(NSURL *)_url { -+- (NSDictionary *)primaryFetchMailboxHierarchyForURL:(NSURL *)_url -+ onlySubscribedFolders:(BOOL) subscribedFoldersOnly -+{ - NSDictionary *result; -+ NSString *prefix; - -- if ((result = [self cachedHierarchyResults]) != nil) -+ if ((result = [self cachedHierarchyResultsForURL:_url]) != nil) - return [result isNotNull] ? result : (NSDictionary *)nil; - - if (debugCache) [self logWithFormat:@" no folders cached yet .."]; -- -- result = [[self client] list:(onlyFetchInbox ? @"INBOX" : @"*") -- pattern:@"*"]; -+ -+ prefix = [_url path]; -+ if ([prefix hasPrefix: @"/"]) -+ prefix = [prefix substringFromIndex:1]; -+ if (subscribedFoldersOnly) -+ result = [[self client] lsub:(onlyFetchInbox ? @"INBOX" : prefix) -+ pattern:@"*"]; -+ else -+ result = [[self client] list:(onlyFetchInbox ? @"INBOX" : prefix) -+ pattern:@"*"]; - if (![[result valueForKey:@"result"] boolValue]) { - [self errorWithFormat:@"Could not list mailbox hierarchy!"]; - return nil; -@@ -391,7 +401,7 @@ - /* cache results */ - - if ([result isNotNull]) { -- [self cacheHierarchyResults:result]; -+ [self cacheHierarchyResults:result forURL:_url]; - if (debugCache) { - [self logWithFormat:@"cached results: 0x%p(%d)", - result, [result count]]; -@@ -400,32 +410,55 @@ - return result; - } - --- (NSArray *)subfoldersForURL:(NSURL *)_url { -+- (NSDictionary *)primaryFetchMailboxHierarchyForURL:(NSURL *)_url -+{ -+ return [self primaryFetchMailboxHierarchyForURL: _url onlySubscribedFolders: NO]; -+} -+ -+- (NSArray *)allFoldersForURL:(NSURL *)_url -+ onlySubscribedFolders:(BOOL)_subscribedFoldersOnly -+{ - NSDictionary *result; - -- if ((result = [self primaryFetchMailboxHierarchyForURL:_url]) == nil) -+ if ((result = [self primaryFetchMailboxHierarchyForURL:_url -+ onlySubscribedFolders:_subscribedFoldersOnly]) == nil) - return nil; - if ([result isKindOfClass:[NSException class]]) { - [self errorWithFormat:@"failed to retrieve hierarchy: %@", result]; - return nil; - } - -- return [self extractSubfoldersForURL:_url fromResultSet:result]; -+ return [self extractFoldersFromResultSet:result]; - } - --- (NSArray *)allFoldersForURL:(NSURL *)_url { -+- (NSArray *)allFoldersForURL:(NSURL *)_url -+{ -+ return [self allFoldersForURL: _url onlySubscribedFolders: NO]; -+} -+ -+- (NSArray *)subfoldersForURL:(NSURL *)_url -+ onlySubscribedFolders:(BOOL)_subscribedFoldersOnly -+{ - NSDictionary *result; -+ NSString *baseFolder; - -- if ((result = [self primaryFetchMailboxHierarchyForURL:_url]) == nil) -+ baseFolder = [self imap4FolderNameForURL:_url removeFileName:NO]; -+ if (_subscribedFoldersOnly) -+ result = [[self client] lsub:baseFolder pattern:@"%"]; -+ else -+ result = [[self client] list:baseFolder pattern:@"%"]; -+ if (![[result valueForKey:@"result"] boolValue]) { -+ [self errorWithFormat:@"Could not list mailbox hierarchy!"]; - return nil; -- if ([result isKindOfClass:[NSException class]]) { -- [self errorWithFormat:@"failed to retrieve hierarchy: %@", result]; -- return nil; - } -- -- return [self extractFoldersFromResultSet:result]; -+ -+ return [self extractSubfoldersForURL:_url fromResultSet: result]; - } - -+- (NSArray *)subfoldersForURL:(NSURL *)_url { -+ return [self subfoldersForURL:_url onlySubscribedFolders: NO]; -+} -+ - /* message operations */ - - - (NSArray *)fetchUIDsInURL:(NSURL *)_url qualifier:(id)_qualifier -@@ -646,7 +679,7 @@ - - /* store flags */ - -- result = [[self client] storeFlags:_f forMSNs:result addOrRemove:YES]; -+ result = [[self client] storeFlags:_f forUIDs:result addOrRemove:YES]; - if (![[result valueForKey:@"result"] boolValue]) { - return [self errorForResult:result - text:@"Failed to change flags of IMAP4 message"]; -@@ -737,34 +770,42 @@ - - - (BOOL)doesMailboxExistAtURL:(NSURL *)_url { - NSString *folderName; -+ NSArray *caches; - id result; -+ int count, max; -+ BOOL found; - -+ found = NO; -+ - /* check in hierarchy cache */ -- -- if ((result = [self cachedHierarchyResults]) != nil) { -+ caches = [self->subfolders allValues]; -+ max = [caches count]; -+ for (count = 0; !found && count < max; count++) { - NSString *p; -- -- result = [(NSDictionary *)result objectForKey:@"list"]; -+ -+ result = [[caches objectAtIndex: count] objectForKey:@"list"]; - p = [_url path]; --#if __APPLE__ - /* normalized results already have the / in front on libFoundation?! */ - if ([p hasPrefix:@"/"]) - p = [p substringFromIndex:1]; --#endif - if ([p hasSuffix:@"/"]) - p = [p substringToIndex:[p length]-1]; -- return ([(NSDictionary *)result objectForKey:p] != nil) ? YES : NO; -+ found = ([(NSDictionary *)result objectForKey:p] != nil); - } -+ -+ if (!found) { -+ /* check using IMAP4 select */ -+ // TODO: we should probably just fetch the whole hierarchy? - -- /* check using IMAP4 select */ -- // TODO: we should probably just fetch the whole hierarchy? -- -- folderName = [self imap4FolderNameForURL:_url]; -- result = [[self client] select:folderName]; -- if (![[result valueForKey:@"result"] boolValue]) -- return NO; -- -- return YES; -+ folderName = [self imap4FolderNameForURL:_url]; -+ -+ result = [self->client status: folderName -+ flags: [NSArray arrayWithObject: @"UIDVALIDITY"]]; -+ -+ found =([[result valueForKey: @"result"] boolValue]); -+ } -+ -+ return found; - } - - - (id)infoForMailboxAtURL:(NSURL *)_url { -@@ -789,7 +830,8 @@ - /* construct path */ - - newPath = [self imap4FolderNameForURL:_url]; -- newPath = [newPath stringByAppendingString:[self imap4Separator]]; -+ if ([newPath length]) -+ newPath = [newPath stringByAppendingString:[self imap4Separator]]; - newPath = [newPath stringByAppendingString:_mailbox]; - - /* create */ -Index: sope-mime/NGImap4/NGImap4ResponseNormalizer.m -=================================================================== ---- sope-mime/NGImap4/NGImap4ResponseNormalizer.m (revision 1664) -+++ sope-mime/NGImap4/NGImap4ResponseNormalizer.m (working copy) -@@ -76,22 +76,6 @@ - return self; - } - --/* client callbacks */ -- --- (void)closeConnection { -- [(id)self->client closeConnection]; --} -- --- (NSString *)delimiter { -- return [self->client delimiter]; --} -- --/* folder handling */ -- --- (NSString *)_imapFolder2Folder:(NSString *)_folder { -- return [self->client _imapFolder2Folder:_folder]; --} -- - /* primary */ - - - (NSMutableDictionary *)normalizeResponse:(NGHashMap *)_map { -@@ -117,7 +101,7 @@ - if ((obj = [_map objectForKey:@"bye"])) { - [result setObject:NoNumber forKey:@"result"]; - [result setObject:obj forKey:@"reason"]; -- [self closeConnection]; -+ [self->client closeConnection]; - return result; - } - -@@ -157,7 +141,7 @@ - return result; - } - --- (NSDictionary *)normalizeCapabilityRespone:(NGHashMap *)_map { -+- (NSDictionary *)normalizeCapabilityResponse:(NGHashMap *)_map { - /* filter for capability response: capability : NSArray */ - id obj; - NSMutableDictionary *result; -@@ -170,6 +154,51 @@ - return result; - } - -+- (NSArray *)_normalizeNamespace:(NSArray *)_namespace { -+ NSMutableArray *result; -+ NSDictionary *currentNS; -+ NSMutableDictionary *newNS; -+ NSString *newPrefix; -+ int count, max; -+ -+ max = [_namespace count]; -+ result = [NSMutableArray arrayWithCapacity: max]; -+ for (count = 0; count < max; count++) { -+ currentNS = [_namespace objectAtIndex: count]; -+ newNS = [currentNS mutableCopy]; -+ newPrefix = [self->client -+ _imapFolder2Folder: [currentNS objectForKey: @"prefix"]]; -+ [newNS setObject: newPrefix forKey: @"prefix"]; -+ [result addObject: newNS]; -+ [newNS release]; -+ } -+ -+ return result; -+} -+ -+- (NSDictionary *)normalizeNamespaceResponse:(NGHashMap *)_map { -+ NSMutableDictionary *result; -+ NSDictionary *rawResponse; -+ NSArray *namespace; -+ -+ result = [self normalizeResponse:_map]; -+ rawResponse = [result objectForKey: @"RawResponse"]; -+ namespace = [rawResponse objectForKey: @"personal"]; -+ if (namespace) -+ [result setObject: [self _normalizeNamespace: namespace] -+ forKey: @"personal"]; -+ namespace = [rawResponse objectForKey: @"other users"]; -+ if (namespace) -+ [result setObject: [self _normalizeNamespace: namespace] -+ forKey: @"other users"]; -+ namespace = [rawResponse objectForKey: @"shared"]; -+ if (namespace) -+ [result setObject: [self _normalizeNamespace: namespace] -+ forKey: @"shared"]; -+ -+ return result; -+} -+ - - (NSDictionary *)normalizeThreadResponse:(NGHashMap *)_map { - /* filter for thread response: thread : NSArray (msn) */ - id obj; -@@ -292,7 +321,7 @@ - /* - filter for fetch response - fetch : NSArray (fetch responses) -- 'header' - RFC822.HEADER -+ 'header' - RFC822.HEADER and BODY[HEADER.FIELDS (...)] - 'text' - RFC822.TEXT - 'size' - SIZE - 'flags' - FLAGS -@@ -336,7 +365,12 @@ - switch (c) { - case 'b': - /* Note: we check for _prefix_! eg body[1] is valid too */ -- if (klen > 3 && [key hasPrefix:@"body"]) { -+ if (klen > 17 && [key hasPrefix:@"body[header.fields"]) { -+ keys[count] = @"header"; -+ values[count] = objForKey(obj, @selector(objectForKey:), key); -+ count++; -+ } -+ else if (klen > 3 && [key hasPrefix:@"body"]) { - keys[count] = @"body"; - values[count] = objForKey(obj, @selector(objectForKey:), key); - count++; -@@ -516,7 +550,7 @@ - } - continue; - } -- [tmp setObject:qDesc forKey:[self _imapFolder2Folder:obj]]; -+ [tmp setObject:qDesc forKey:[self->client _imapFolder2Folder:obj]]; - } - [result setObject:tmp forKey:@"quotas"]; - return [[result copy] autorelease]; -@@ -615,7 +649,7 @@ - - while ((o = [enumerator nextObject])) { - [folder setObject:_imapFlags2Flags(self, [o objectForKey:@"flags"]) -- forKey:[self _imapFolder2Folder:[o objectForKey:@"folderName"]]]; -+ forKey:[self->client _imapFolder2Folder:[o objectForKey:@"folderName"]]]; - } - - { -@@ -648,14 +682,13 @@ - enumerator = [_flags objectEnumerator]; - cnt = 0; - while ((obj = [enumerator nextObject])) { -- if (![obj isNotEmpty]) -- continue; -- -- if (![[obj substringToIndex:1] isEqualToString:@"\\"]) -- continue; -- -- objs[cnt] = [obj substringFromIndex:1]; -- cnt++; -+ if ([obj isNotEmpty]) { -+ if ([obj hasPrefix:@"\\"]) -+ objs[cnt] = [obj substringFromIndex:1]; -+ else -+ objs[cnt] = obj; -+ cnt++; -+ } - } - result = [NSArray arrayWithObjects:objs count:cnt]; - if (objs) free(objs); -Index: sope-mime/NGImap4/EOQualifier+IMAPAdditions.m -=================================================================== ---- sope-mime/NGImap4/EOQualifier+IMAPAdditions.m (revision 1664) -+++ sope-mime/NGImap4/EOQualifier+IMAPAdditions.m (working copy) -@@ -53,13 +53,13 @@ - if (FlagKeyWords) return; - - ud = [NSUserDefaults standardUserDefaults]; -- FlagKeyWords = [[NSArray alloc] initWithObjects: @"answered", @"deleted", -- @"draft", @"flagged", @"new", @"old", @"recent", -- @"seen", @"unanswered", @"undeleted", @"undraft", -- @"unflagged", @"unseen", nil]; -- OtherKeyWords = [[NSArray alloc] initWithObjects: -- @"bcc", @"body", @"cc", @"from", @"subject", -- @"text", @"to", @"keyword", @"unkeyword", nil]; -+ FlagKeyWords = [[NSArray alloc] initWithObjects: @"ANSWERED", @"DELETED", -+ @"DRAFT", @"FLAGGED", @"NEW", @"OLD", @"RECENT", -+ @"SEEN", @"UNANSWERED", @"UNDELETED", @"UNDRAFT", -+ @"UNFLAGGED", @"UNSEEN", nil]; -+ OtherKeyWords = [[NSArray alloc] initWithObjects: @"ALL", @"BCC", @"BODY", -+ @"CC", @"FROM", @"SUBJECT", @"TEXT", @"TO", -+ @"KEYWORD", @"UID", @"UNKEYWORD", nil]; - - debugOn = [ud boolForKey:@"ImapDebugQualifierGeneration"]; - } -@@ -266,10 +266,10 @@ - - enumerator = [lvalue objectEnumerator]; - while ((lvalue = [enumerator nextObject]) != nil) { -- lvalue = [lvalue lowercaseString]; -+ lvalue = [lvalue uppercaseString]; - - if ([FlagKeyWords containsObject:lvalue]) { -- if (insertNot) [search appendString:@"not "]; -+ if (insertNot) [search appendString:@"NOT "]; - [search appendString:lvalue]; - } - else { -@@ -280,15 +280,31 @@ - return nil; - } - --- (NSString *)imap4OperatorForDateComparisonSelector:(SEL)lselector { -+- (NSString *)imap4OperatorForDateKeyword:(NSString *)dkey -+andComparisonSelector:(SEL)lselector { -+ NSString *operatorPrefix, *dateOperator, *imap4Operator; -+ - if (sel_eq(lselector, EOQualifierOperatorEqual)) -- return @" senton "; -- if (sel_eq(lselector, EOQualifierOperatorGreaterThan)) -- return @" sentsince "; -- if (sel_eq(lselector, EOQualifierOperatorLessThan)) -- return @" sentbefore "; -- -- return nil; -+ dateOperator = @"ON"; -+ else if (sel_eq(lselector, EOQualifierOperatorGreaterThan)) -+ dateOperator = @"SINCE"; -+ else if (sel_eq(lselector, EOQualifierOperatorLessThan)) -+ dateOperator = @"BEFORE"; -+ else -+ dateOperator = nil; -+ -+ if (dateOperator) { -+ if ([dkey isEqualToString: @"DATE"]) -+ operatorPrefix = @"SENT"; -+ else -+ operatorPrefix = @""; -+ imap4Operator = [NSString stringWithFormat: @"%@%@ ", -+ operatorPrefix, dateOperator]; -+ } -+ else -+ imap4Operator = nil; -+ -+ return imap4Operator; - } - - - (NSException *)appendToImap4SearchString:(NSMutableString *)search -@@ -300,11 +316,11 @@ - id lvalue; - SEL lselector; - -- lkey = [[self key] lowercaseString]; -+ lkey = [[self key] uppercaseString]; - lvalue = [self value]; - lselector = [self selector]; - -- if ([lkey isEqualToString:@"flags"]) { -+ if ([lkey isEqualToString:@"FLAGS"]) { - /* NOTE: special "not" processing! */ - return [self appendFlagsCheckToImap4SearchString:search - insertNot:insertNot]; -@@ -312,9 +328,9 @@ - - /* not a flag */ - if (insertNot) -- [search appendString:@"not "]; -+ [search appendString:@"NOT "]; - -- if ([lkey isEqualToString:@"date"]) { -+ if ([lkey isEqualToString:@"DATE"] || [lkey isEqualToString:@"RECEIVE-DATE"]) { - NSString *s; - - if (![lvalue isKindOfClass:[NSCalendarDate class]]) { -@@ -322,35 +338,38 @@ - @"expected a NSDate as value"]; - } - -- if ((s = [self imap4OperatorForDateComparisonSelector:lselector]) == nil) -+ if ((s = [self imap4OperatorForDateKeyword:lkey -+ andComparisonSelector:lselector]) == nil) - return [self invalidImap4SearchQualifier:@"unexpected selector"]; - -- // TODO: operator created but NOT added? -+ [search appendString:s]; - - // TODO: much faster without descriptionWithCalendarFormat:?! -- s = [lvalue descriptionWithCalendarFormat:@"%d-%b-%Y"]; -+ s = [lvalue descriptionWithCalendarFormat:@"\"%d-%b-%Y\""]; - [search appendString:s]; - return nil; - } - -- if ([lkey isEqualToString:@"uid"]) { -- if (!sel_eq(lselector, EOQualifierOperatorEqual)) -+ if ([lkey isEqualToString:@"UID"]) { -+ if (!sel_eq(lselector, EOQualifierOperatorEqual)) { - return [self invalidImap4SearchQualifier:@"unexpected qualifier 2"]; -+ } - -- [search appendString:@"uid "]; -+ [search appendString:@"UID "]; - [search appendString:[lvalue stringValue]]; - return nil; - } - -- if ([lkey isEqualToString:@"size"]) { -+ if ([lkey isEqualToString:@"SIZE"]) { - if (sel_eq(lselector, EOQualifierOperatorGreaterThan)) -- [search appendString:@"larger "]; -+ [search appendString:@"LARGER "]; - else if (sel_eq(lselector, EOQualifierOperatorLessThan)) -- [search appendString:@"smaller "]; -+ [search appendString:@"SMALLER "]; - else - return [self invalidImap4SearchQualifier:@"unexpected qualifier 3"]; - - [search appendString:[lvalue stringValue]]; -+ - return nil; - } - -@@ -386,7 +405,7 @@ - if (!sel_eq(lselector, EOQualifierOperatorEqual)) - return [self invalidImap4SearchQualifier:@"unexpected qualifier 5"]; - -- [search appendString:@"header "]; -+ [search appendString:@"HEADER "]; - [search appendString:lkey]; - [search appendString:@" \""]; - [search appendString:[lvalue stringValue]]; -Index: sope-mime/NGImap4/NGImap4ResponseParser.m -=================================================================== ---- sope-mime/NGImap4/NGImap4ResponseParser.m (revision 1664) -+++ sope-mime/NGImap4/NGImap4ResponseParser.m (working copy) -@@ -31,6 +31,7 @@ - @interface NGImap4ResponseParser(ParsingPrivates) - - (BOOL)_parseNumberUntaggedResponse:(NGMutableHashMap *)result_; - - (NSDictionary *)_parseBodyContent; -+- (NSData *) _parseBodyHeaderFields; - - - (NSData *)_parseData; - -@@ -38,6 +39,7 @@ - - (void)_parseContinuationResponseIntoHashMap:(NGMutableHashMap *)result_; - - (BOOL)_parseListOrLSubResponseIntoHashMap:(NGMutableHashMap *)result_; - - (BOOL)_parseCapabilityResponseIntoHashMap:(NGMutableHashMap *)result_; -+- (BOOL)_parseNamespaceResponseIntoHashMap:(NGMutableHashMap *)result_; - - (BOOL)_parseSearchResponseIntoHashMap:(NGMutableHashMap *)result_; - - (BOOL)_parseSortResponseIntoHashMap:(NGMutableHashMap *)result_; - - (BOOL)_parseQuotaRootResponseIntoHashMap:(NGMutableHashMap *)result_; -@@ -84,6 +86,8 @@ - static NSDictionary *_parseMultipartBody(NGImap4ResponseParser *self, - BOOL isBodyStructure); - -+static NSArray *_parseLanguages(); -+ - static NSString *_parseBodyString(NGImap4ResponseParser *self, - BOOL _convertString); - static NSString *_parseBodyDecodeString(NGImap4ResponseParser *self, -@@ -111,6 +115,7 @@ - static NSNumber *_parseUnsigned(NGImap4ResponseParser *self); - static NSString *_parseUntil(NGImap4ResponseParser *self, char _c); - static NSString *_parseUntil2(NGImap4ResponseParser *self, char _c1, char _c2); -+static BOOL _endsWithCQuote(NSString *_string); - - static __inline__ NSException *_consumeIfMatch - (NGImap4ResponseParser *self, unsigned char _m); -@@ -261,20 +266,6 @@ - } - - result = [NGMutableHashMap hashMapWithCapacity:64]; -- -- if (_la(self, 0) == -1) { -- [self logWithFormat:@"%s: catched: %@", __PRETTY_FUNCTION__, -- [self->buffer lastException]]; -- -- if (ex_) { -- *ex_ = [self->buffer lastException]; -- return nil; -- } -- else { -- [self setLastException:[self->buffer lastException]]; -- return nil; -- } -- } - for (endOfCommand = NO; !endOfCommand; ) { - unsigned char l0; - -@@ -300,6 +291,21 @@ - /* those starting with a number '24 ', eg '24 OK Completed' */ - endOfCommand = (_parseTaggedResponse(self, result) == _tag); - } -+ else if (l0 == (unsigned char) -1) { -+ if (ex_) { -+ *ex_ = [self->buffer lastException]; -+ if (!*ex_) -+ *ex_ -+ = [NSException exceptionWithName:@"UnexpectedEndOfStream" -+ reason:(@"the parsed stream ended" -+ @" unexpectedly") -+ userInfo:nil]; -+ } else { -+ [self setLastException: [self->buffer lastException]]; -+ } -+ endOfCommand = YES; -+ result = nil; -+ } - } - return result; - } -@@ -488,6 +494,50 @@ - return [self _parseDataIntoRAM:size]; - } - -+/* -+ Similair to _parseData but used to parse something like this : -+ -+ BODY[HEADER.FIELDS (X-PRIORITY)] {17} -+ X-Priority: 1 -+ -+ ) -+ -+ Headers are returned as data, as is. -+*/ -+- (NSData *) _parseBodyHeaderFields -+{ -+ NSData *result; -+ unsigned size; -+ NSNumber *sizeNum; -+ -+ /* we skip until we're ready to parse {length} */ -+ _parseUntil(self, '{'); -+ -+ result = nil; -+ -+ if ((sizeNum = _parseUnsigned(self)) == nil) { -+ NSException *e; -+ -+ e = [[NGImap4ParserException alloc] -+ initWithFormat:@"expect a number between {}"]; -+ [self setLastException:[e autorelease]]; -+ return nil; -+ } -+ _consumeIfMatch(self, '}'); -+ _consumeIfMatch(self, '\n'); -+ -+ if ((size = [sizeNum intValue]) == 0) { -+ [self logWithFormat:@"ERROR(%s): got content size '0'!", -+ __PRETTY_FUNCTION__]; -+ return nil; -+ } -+ -+ if (UseMemoryMappedData && (size > Imap4MMDataBoundary)) -+ return [self _parseDataToFile:size]; -+ -+ return [self _parseDataIntoRAM:size]; -+} -+ - static int _parseTaggedResponse(NGImap4ResponseParser *self, - NGMutableHashMap *result_) - { -@@ -584,6 +634,10 @@ - break; - - case 'N': -+ if (_matchesString(self, "NAMESPACE")) { -+ if ([self _parseNamespaceResponseIntoHashMap:result_]) -+ return; -+ } - if (_parseNoUntaggedResponse(self, result_)) // la: 2 - return; - break; -@@ -648,14 +702,171 @@ - [result_ addObject:_parseUntil(self, '\n') forKey:@"description"]; - } - -+static inline void -+_purifyQuotedString(NSMutableString *quotedString) { -+ unichar *currentChar, *qString, *maxC, *startC; -+ unsigned int max, questionMarks; -+ BOOL possiblyQuoted, skipSpaces; -+ NSMutableString *newString; -+ -+ newString = [NSMutableString string]; -+ -+ max = [quotedString length]; -+ qString = malloc (sizeof (unichar) * max); -+ [quotedString getCharacters: qString]; -+ currentChar = qString; -+ startC = qString; -+ maxC = qString + max; -+ -+ possiblyQuoted = NO; -+ skipSpaces = NO; -+ -+ questionMarks = 0; -+ -+ while (currentChar < maxC) { -+ if (possiblyQuoted) { -+ if (questionMarks == 2) { -+ if ((*currentChar == 'Q' || *currentChar == 'q' -+ || *currentChar == 'B' || *currentChar == 'b') -+ && ((currentChar + 1) < maxC -+ && (*(currentChar + 1) == '?'))) { -+ currentChar++; -+ questionMarks = 3; -+ } -+ else { -+ possiblyQuoted = NO; -+ } -+ } -+ else if (questionMarks == 4) { -+ if (*currentChar == '=') { -+ skipSpaces = YES; -+ possiblyQuoted = NO; -+ currentChar++; -+ [newString appendString: [NSString stringWithCharacters: startC -+ length: (currentChar - startC)]]; -+ startC = currentChar; -+ } -+ else { -+ possiblyQuoted = NO; -+ } -+ } -+ else { -+ if (*currentChar == '?') { -+ questionMarks++; -+ } -+ else if (*currentChar == ' ' && questionMarks != 3) { -+ possiblyQuoted = NO; -+ } -+ } -+ } -+ else if (*currentChar == '=' -+ && ((currentChar + 1) < maxC -+ && (*(currentChar + 1) == '?'))) { -+ [newString appendString: [NSString stringWithCharacters: startC -+ length: (currentChar - startC)]]; -+ startC = currentChar; -+ possiblyQuoted = YES; -+ skipSpaces = NO; -+ currentChar++; -+ questionMarks = 1; -+ } -+ -+ currentChar++; -+ -+ if (skipSpaces) { -+ while (currentChar < maxC -+ && (*currentChar == ' ' -+ || *currentChar == '\t')) -+ currentChar++; -+ skipSpaces = NO; -+ startC = currentChar; -+ } -+ } -+ -+ if (startC < maxC) -+ [newString appendString: [NSString stringWithCharacters: startC -+ length: (currentChar - startC)]]; -+ -+ [quotedString setString: newString]; -+ free (qString); -+} -+ - - (NSString *)_parseQuotedString { -+ NSMutableString *quotedString; -+ NSString *tmpString; -+ BOOL stop; -+ - /* parse a quoted string, eg '"' */ - if (_la(self, 0) == '"') { - _consume(self, 1); -- return _parseUntil(self, '"'); -+ quotedString = [NSMutableString string]; -+ stop = NO; -+ while (!stop) { -+ tmpString = _parseUntil(self, '"'); -+ [quotedString appendString: tmpString]; -+ if(_endsWithCQuote(tmpString)) { -+ [quotedString deleteSuffix: @"\\"]; -+ [quotedString appendString: @"\""]; -+ } -+ else { -+ stop = YES; -+ } -+ } - } -+ else { -+ quotedString = nil; -+ } -+ -+ _purifyQuotedString(quotedString); -+ -+ return quotedString; -+} -+- (NSString *)_parseQuotedStringOrNIL { -+ unsigned char c0; -+ -+ if ((c0 = _la(self, 0)) == '"') -+ return [self _parseQuotedString]; -+ -+ if (c0 == '{') { -+ /* a size indicator, eg '{112}\nkasdjfkja sdj fhj hasdfj hjasdf' */ -+ NSData *data; -+ NSString *s; -+ -+ if ((data = [self _parseData]) == nil) -+ return nil; -+ if (![data isNotEmpty]) -+ return @""; -+ -+ s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; -+ if (s == nil) -+ s = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding]; -+ if (s == nil) { -+ [self logWithFormat: -+ @"ERROR(%s): could not convert data (%d bytes) into string.", -+ __PRETTY_FUNCTION__, [data length]]; -+ return @"[ERROR: NGImap4 could not parse IMAP4 data string]"; -+ } -+ return [s autorelease]; -+ } -+ -+ if (c0 == 'N' && _matchesString(self, "NIL")) { -+ _consume(self, 3); -+ return (id)null; -+ } - return nil; - } -+- (id)_parseQuotedStringOrDataOrNIL { -+ if (_la(self, 0) == '"') -+ return [self _parseQuotedString]; -+ if (_la(self, 0) == '{') -+ return [self _parseData]; -+ -+ if (_matchesString(self, "NIL")) { -+ _consume(self, 3); -+ return null; -+ } -+ return nil; -+} - - (void)_consumeOptionalSpace { - if (_la(self, 0) == ' ') _consume(self, 1); - } -@@ -685,6 +896,10 @@ - name = [self _parseQuotedString]; - _parseUntil(self, '\n'); - } -+ else if (_la(self, 0) == '{') { -+ name = [self _parseQuotedStringOrNIL]; -+ _parseUntil(self, '\n'); -+ } - else - name = _parseUntil(self, '\n'); - -@@ -723,6 +938,85 @@ - return YES; - } - -+/* support for NAMESPACE extension - RFC2342 */ -+ -+- (NSDictionary *)_parseNamespacePart { -+ NSDictionary *namespacePart; -+ NSString *prefix, *key, *delimiter; -+ NSMutableDictionary *parameters; -+ NSMutableArray *values; -+ -+ _consume(self, 1); /* ( */ -+ prefix = [self _parseQuotedStringOrNIL]; /* "prefix" */ -+ _consume(self, 1); /* */ -+ delimiter = [self _parseQuotedStringOrNIL]; /* "delimiter" */ -+ parameters = [NSMutableDictionary dictionary]; -+ while (_la(self, 0) == ' ') { -+ _consume(self, 1); /* */ -+ key = [self _parseQuotedString]; -+ _consume(self, 1); /* */ -+ values = [NSMutableArray new]; -+ while (_la(self, 0) != ')') { -+ _consume(self, 1); /* ( or */ -+ [values addObject: [self _parseQuotedString]]; -+ } -+ _consume(self, 1); /* ) */ -+ [parameters setObject: values forKey: key]; -+ [values release]; -+ } -+ _consume(self, 1); /* ) */ -+ -+ namespacePart = [NSDictionary dictionaryWithObjectsAndKeys: -+ prefix, @"prefix", -+ delimiter, @"delimiter", -+ parameters, @"parameters", -+ nil]; -+ -+ return namespacePart; -+} -+ -+- (NSArray *)_parseNamespace { -+ NSMutableArray *namespace; -+ -+ namespace = [[NSMutableArray alloc] initWithCapacity: 3]; -+ if (_la(self, 0) == 'N') { -+ namespace = nil; -+ _consume(self, 3); -+ } else { -+ _consume(self, 1); /* ( */ -+ while (_la(self, 0) == '(') { -+ [namespace addObject: [self _parseNamespacePart]]; -+ } -+ _consume(self, 1); /* ) */ -+ } -+ -+ return namespace; -+} -+ -+- (BOOL)_parseNamespaceResponseIntoHashMap:(NGMutableHashMap *)result_ { -+ NSArray *namespace; -+ -+ if (!_matchesString(self, "NAMESPACE ")) -+ return NO; -+ -+ _parseUntil(self, ' '); -+ -+ namespace = [self _parseNamespace]; -+ if (namespace) -+ [result_ addObject:namespace forKey:@"personal"]; -+ _consume(self, 1); -+ namespace = [self _parseNamespace]; -+ if (namespace) -+ [result_ addObject:namespace forKey:@"other users"]; -+ _consume(self, 1); -+ namespace = [self _parseNamespace]; -+ if (namespace) -+ [result_ addObject:namespace forKey:@"shared"]; -+ _consume(self, 1); /* \n */ -+ -+ return YES; -+} -+ - - (BOOL)_parseACLResponseIntoHashMap:(NGMutableHashMap *)result_ { - /* - 21 GETACL INBOX -@@ -734,6 +1028,7 @@ - NSMutableArray *uids; - NSMutableArray *rights; - NSDictionary *result; -+ int length; - - if (!_matchesString(self, "ACL ")) - return NO; -@@ -750,6 +1045,12 @@ - - enumerator = [[acls componentsSeparatedByString:@" "] objectEnumerator]; - while ((obj = [enumerator nextObject]) != nil) { -+ if ([obj characterAtIndex: 0] == '"') { -+ length = [obj length]; -+ if ([obj characterAtIndex: length - 1] == '"') { -+ obj = [obj substringFromRange: NSMakeRange (1, length - 2)]; -+ } -+ } - [uids addObject:obj]; - obj = [enumerator nextObject]; - [rights addObject:(obj != nil ? obj : (id)@"")]; -@@ -1030,10 +1331,15 @@ - _consume(self, 7); - - if (_la(self, 0) == '"') { -- _consume(self, 1); -- name = _parseUntil(self, '"'); -+ name = [self _parseQuotedString]; -+// _consume(self, 1); -+// name = _parseUntil(self, '"'); - _consumeIfMatch(self, ' '); - } -+ else if (_la(self, 0) == '{') { -+ name = [self _parseQuotedStringOrNIL]; -+ _consumeIfMatch(self, ' '); -+ } - else { - name = _parseUntil(self, ' '); - } -@@ -1073,51 +1379,6 @@ - return YES; - } - --- (NSString *)_parseQuotedStringOrNIL { -- unsigned char c0; -- -- if ((c0 = _la(self, 0)) == '"') -- return [self _parseQuotedString]; -- -- if (c0 == '{') { -- /* a size indicator, eg '{112}\nkasdjfkja sdj fhj hasdfj hjasdf' */ -- NSData *data; -- NSString *s; -- -- if ((data = [self _parseData]) == nil) -- return nil; -- if (![data isNotEmpty]) -- return @""; -- -- s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; -- if (s == nil) { -- [self logWithFormat: -- @"ERROR(%s): could not convert data (%d bytes) into string.", -- __PRETTY_FUNCTION__, [data length]]; -- return @"[ERROR: NGImap4 could not parse IMAP4 data string]"; -- } -- return [s autorelease]; -- } -- -- if (c0 == 'N' && _matchesString(self, "NIL")) { -- _consume(self, 3); -- return (id)null; -- } -- return nil; --} --- (id)_parseQuotedStringOrDataOrNIL { -- if (_la(self, 0) == '"') -- return [self _parseQuotedString]; -- if (_la(self, 0) == '{') -- return [self _parseData]; -- -- if (_matchesString(self, "NIL")) { -- _consume(self, 3); -- return null; -- } -- return nil; --} -- - - (id)_decodeQP:(id)_string headerField:(NSString *)_field { - if (![_string isNotNull]) - return _string; -@@ -1185,7 +1446,7 @@ - route = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; - mailbox = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; - host = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; -- -+ - if (_la(self, 0) != ')') { - [self logWithFormat:@"WARNING: IMAP4 envelope " - @"address not properly closed (c0=%c,c1=%c): %@", -@@ -1197,6 +1458,7 @@ - address = [[NGImap4EnvelopeAddress alloc] initWithPersonalName:pname - sourceRoute:route mailbox:mailbox - host:host]; -+ - return address; - } - -@@ -1382,7 +1644,15 @@ - #if 0 - [self logWithFormat:@"PARSE KEY: %@", key]; - #endif -- if ([key hasPrefix:@"body["]) { -+ if ([key hasPrefix:@"body[header.fields"]) { -+ NSData *content; -+ -+ if ((content = [self _parseBodyHeaderFields]) != nil) -+ [fetch setObject:content forKey:key]; -+ else -+ [self logWithFormat:@"ERROR: got no body content for key: '%@'",key]; -+ } -+ else if ([key hasPrefix:@"body["]) { - NSDictionary *content; - - if ((content = [self _parseBodyContent]) != nil) -@@ -1497,6 +1767,7 @@ - _parseUntil(self, '\n'); - [result_ addObject:value forKey:[key lowercaseString]]; - } -+ - return isOK; - } - -@@ -1509,9 +1780,12 @@ - if ((data = [self _parseData]) == nil) - return NO; - -- str = [[StrClass alloc] initWithData:data encoding:defCStringEncoding]; -+ str = [[StrClass alloc] initWithData:data encoding:NSUTF8StringEncoding]; - [result_ setObject:str forKey:@"data"]; - [str release]; str = nil; -+ -+ _parseUntil(self, '\n'); -+ - return YES; - } - -@@ -1542,13 +1816,16 @@ - - if (!((_la(self, 0)=='N') && (_la(self, 1)=='O') && (_la(self, 2)==' '))) - return NO; -- -+ - _consume(self, 3); - - data = _parseContentSieveResponse(self); -- -+ - [result_ addObject:NoNum forKey:@"ok"]; - if (data) [result_ addObject:data forKey:@"reason"]; -+ -+ _parseUntil(self, '\n'); -+ - return YES; - } - -@@ -1562,7 +1839,7 @@ - if ((data = [self _parseData]) == nil) - return nil; - -- return [[[StrClass alloc] initWithData:data encoding:defCStringEncoding] -+ return [[[StrClass alloc] initWithData:data encoding:NSUTF8StringEncoding] - autorelease]; - } - -@@ -1594,8 +1871,11 @@ - if (_decode) - data = [data decodeQuotedPrintableValueOfMIMEHeaderField:nil]; - -- return [[[StrClass alloc] initWithData:data encoding:encoding] -- autorelease]; -+ if ([data isKindOfClass: [NSString class]]) -+ return (NSString *) data; -+ else -+ return [[[StrClass alloc] initWithData:data encoding:encoding] -+ autorelease]; - } - else { - str = _parseUntil2(self, ' ', ')'); -@@ -1620,13 +1900,35 @@ - return str; - } - -- - static NSString *_parseBodyString(NGImap4ResponseParser *self, - BOOL _convertString) - { - return _parseBodyDecodeString(self, _convertString, NO /* no decode */); - } - -+static NSArray *_parseLanguages(NGImap4ResponseParser *self) { -+ NSMutableArray *languages; -+ NSString *language; -+ -+ languages = [NSMutableArray array]; -+ if (_la(self, 0) == '(') { -+ while (_la(self, 0) != ')') { -+ _consume(self,1); -+ language = _parseBodyString(self, YES); -+ if ([language length]) -+ [languages addObject: language]; -+ } -+ _consume(self,1); -+ } -+ else { -+ language = _parseBodyString(self, YES); -+ if ([language length]) -+ [languages addObject: language]; -+ } -+ -+ return languages; -+} -+ - static NSDictionary *_parseBodyParameterList(NGImap4ResponseParser *self) - { - NSMutableDictionary *list; -@@ -1646,7 +1948,7 @@ - _consumeIfMatch(self, ' '); - value = _parseBodyDecodeString(self, YES, YES); - -- [list setObject:value forKey:[key lowercaseString]]; -+ if (value) [list setObject:value forKey:[key lowercaseString]]; - } - _consumeIfMatch(self, ')'); - } -@@ -1731,13 +2033,14 @@ - static NSDictionary *_parseSingleBody(NGImap4ResponseParser *self, - BOOL isBodyStructure) { - NSString *type, *subtype, *bodyId, *description, -- *encoding, *bodysize; -+ *result, *encoding, *bodysize; - NSDictionary *parameterList; - NSMutableDictionary *dict; -+ NSArray *languages; - - type = [_parseBodyString(self, YES) lowercaseString]; - _consumeIfMatch(self, ' '); -- subtype = _parseBodyString(self, YES); -+ subtype = [_parseBodyString(self, YES) lowercaseString]; - _consumeIfMatch(self, ' '); - parameterList = _parseBodyParameterList(self); - _consumeIfMatch(self, ' '); -@@ -1762,13 +2065,18 @@ - _consumeIfMatch(self, ' '); - [dict setObject:_parseBodyString(self, YES) forKey:@"lines"]; - } -- else if ([type isEqualToString:@"message"]) { -+ else if ([type isEqualToString:@"message"] -+ && [subtype isEqualToString:@"rfc822"]) { - if (_la(self, 0) != ')') { - _consumeIfMatch(self, ' '); - _consumeIfMatch(self, '('); -- [dict setObject:_parseBodyString(self, YES) forKey:@"date"]; -+ result = _parseBodyString(self, YES); -+ if (result == nil) result = @""; -+ [dict setObject:result forKey:@"date"]; - _consumeIfMatch(self, ' '); -- [dict setObject:_parseBodyString(self, YES) forKey:@"subject"]; -+ result = _parseBodyString(self, YES); -+ if (result == nil) result = @""; -+ [dict setObject:result forKey:@"subject"]; - _consumeIfMatch(self, ' '); - [dict setObject:_parseParenthesizedAddressList(self) forKey:@"from"]; - _consumeIfMatch(self, ' '); -@@ -1783,14 +2091,20 @@ - _consumeIfMatch(self, ' '); - [dict setObject:_parseParenthesizedAddressList(self) forKey:@"bcc"]; - _consumeIfMatch(self, ' '); -- [dict setObject:_parseBodyString(self, YES) forKey:@"in-reply-to"]; -+ result = _parseBodyString(self, YES); -+ if (result == nil) result = @""; -+ [dict setObject:result forKey:@"in-reply-to"]; - _consumeIfMatch(self, ' '); -- [dict setObject:_parseBodyString(self, YES) forKey:@"messageId"]; -+ result = _parseBodyString(self, YES); -+ if (result == nil) result = @""; -+ [dict setObject:result forKey:@"messageId"]; - _consumeIfMatch(self, ')'); - _consumeIfMatch(self, ' '); - [dict setObject:_parseBody(self, isBodyStructure) forKey:@"body"]; - _consumeIfMatch(self, ' '); -- [dict setObject:_parseBodyString(self, YES) forKey:@"bodyLines"]; -+ result = _parseBodyString(self, YES); -+ if (result == nil) result = @""; -+ [dict setObject:result forKey:@"bodyLines"]; - } - } - -@@ -1805,14 +2119,9 @@ - forKey: @"disposition"]; - if (_la(self, 0) != ')') { - _consume(self,1); -- if (_la(self, 0) == '(') { -- [dict setObject: _parseBodyParameterList(self) -- forKey: @"language"]; -- } -- else { -- [dict setObject: _parseBodyString(self, YES) -- forKey: @"language"]; -- } -+ languages = _parseLanguages(self); -+ if ([languages count]) -+ [dict setObject: languages forKey: @"languages"]; - if (_la(self, 0) != ')') { - _consume(self,1); - [dict setObject: _parseBodyString(self, YES) -@@ -1829,6 +2138,7 @@ - static NSDictionary *_parseMultipartBody(NGImap4ResponseParser *self, - BOOL isBodyStructure) { - NSMutableArray *parts; -+ NSArray *languages; - NSString *kind; - NSMutableDictionary *dict; - -@@ -1854,14 +2164,9 @@ - forKey: @"disposition"]; - if (_la(self, 0) != ')') { - _consume(self,1); -- if (_la(self, 0) == '(') { -- [dict setObject: _parseBodyParameterList(self) -- forKey: @"language"]; -- } -- else { -- [dict setObject: _parseBodyString(self, YES) -- forKey: @"language"]; -- } -+ languages = _parseLanguages(self); -+ if ([languages count]) -+ [dict setObject: languages forKey: @"languages"]; - if (_la(self, 0) != ')') { - _consume(self,1); - [dict setObject: _parseBodyString(self, YES) -@@ -2090,6 +2395,10 @@ - cnt = 0; - str = nil; - while ((c = _la(self, 0)) != _c) { -+ if (c == '\\') { -+ _consume(self, 1); -+ c = _la(self, 0); -+ } - buf[cnt] = c; - _consume(self, 1); - cnt++; -@@ -2170,6 +2479,21 @@ - } - } - -+static BOOL _endsWithCQuote(NSString *_string){ -+ unsigned int quoteSlashes; -+ int pos; -+ -+ quoteSlashes = 0; -+ pos = [_string length] - 1; -+ while (pos > -1 -+ && [_string characterAtIndex: pos] == '\\') { -+ quoteSlashes++; -+ pos--; -+ } -+ -+ return ((quoteSlashes % 2) == 1); -+} -+ - - (NSException *)exceptionForFailedMatch:(unsigned char)_match - got:(unsigned char)_avail - { -@@ -2225,9 +2549,9 @@ - [s release]; - - if (c == '\n') { -- if ([self->serverResponseDebug cStringLength] > 2) { -+ if ([self->serverResponseDebug lengthOfBytesUsingEncoding:NSISOLatin1StringEncoding] > 2) { - fprintf(stderr, "S[%p]: %s", self, -- [self->serverResponseDebug cString]); -+ [self->serverResponseDebug cStringUsingEncoding:NSISOLatin1StringEncoding]); - } - [self->serverResponseDebug release]; - self->serverResponseDebug = -Index: sope-mime/NGImap4/ChangeLog -=================================================================== ---- sope-mime/NGImap4/ChangeLog (revision 1664) -+++ sope-mime/NGImap4/ChangeLog (working copy) -@@ -1,3 +1,165 @@ -+2010-04-07 Wolfgang Sourdeau -+ -+ * NGImap4Client.m (-list:pattern:, -lsub:pattern:): use an empty -+ prefix and put the used prefix in the "pattern" component of the -+ LIST or LSUB command, as this work around bugs in bad server -+ implementations. -+ -+2010-04-02 Wolfgang Sourdeau -+ -+ * NGSieveClient.m (-putScript:script:): -+ (-setActiveScript:, -deleteScript:): do not append an ending "\r\n" -+ since sendCommand:logText: does it for us. -+ (-setActiveScript:): we accept an empty non-nil script name as -+ argument in order to deactivate the currently active script. -+ -+2010-03-11 Wolfgang Sourdeau -+ -+ * NGImap4ResponseParser.m (_parseContentSieveResponse): we now use -+ NSUTF8StringEncoding as explicit NSString encoding for sieve -+ responses. -+ (_parseDataSieveResponse): same as above. -+ (_parseOkSieveResponse): added a _parseUntil(.."\n") clause to -+ ensure that the current line has been completely parsed before -+ going on with the rest. -+ (_parseNoSieveResponse): same as above. -+ -+2010-03-03 Wolfgang Sourdeau -+ -+ * NGSieveClient.m (-putScript:script:): the byte count passed as -+ parameter to the server must correspond to an UTF-8 encoded -+ string. -+ -+2010-02-19 Wolfgang Sourdeau -+ -+ * NGImap4ResponseParser.m (_parseACLResponseIntoHashMap:): user -+ ids enclosed in quotes are extracted from them, for servers not -+ following the standards properly. -+ -+2010-02-18 Wolfgang Sourdeau -+ -+ * NGImap4ResponseParser.m (-parseResponseForTagId:exception:): the -+ unsigned "l0" was never compared with "-1". Therefore we cast "-1" -+ as an unsigned char to let the error check happen. -+ -+2010-01-28 Wolfgang Sourdeau -+ -+ * NGImap4Client.m (-processCommand:withTag:withNotification:): -+ don't retry the command if it was a login command. -+ -+2010-01-25 Wolfgang Sourdeau -+ -+ * NGImap4Client.m (-append:toFolder:withFlags:): we use the count -+ found in cntNew to avoid a crash with GNUstep's cStringLength. -+ -+ * NGImap4ResponseParser.m (-parseResponseForTagId:exception:): -+ detect "-1" return code from _la and leave the loop with a proper -+ execption when it occurs. -+ -+2010-01-15 Wolfgang Sourdeau -+ -+ * NGImap4Connection.m (-doesMailboxExistAtURL:): sometimes an -+ entry is present in the subfolders cache. When it is the case, the -+ method was returning at the end of the first iteration even though -+ the mailbox was never found. We need to continue and then proceed -+ to the "status" check whether the cache is populated or not. -+ -+2010-01-14 Wolfgang Sourdeau -+ -+ * NGImap4Connection.m (-doesMailboxExistAtURL:): mailbox paths can -+ start with '/' on non-Apple platforms. -+ (-flushFolderHierarchyCache): reassign a new dictionary to -+ self->subfolders to avoid disappearing folders. -+ -+2010-01-05 Wolfgang Sourdeau -+ -+ * NGImap4ResponseParser.m (_parseUntaggedResponse): now accepts -+ the "NAMESPACE" response and parse accordingly by making use of -+ the appropriate new method. -+ -+ * NGImap4ResponseNormalizer.m (-normalizeNamespaceResponse): -+ self-explicit new method. -+ -+ * NGImap4Connection.m (-subfolderForURL:, -allFoldersForURL:): -+ differenciate both methods by having "subfolder..." use the "%" -+ wild card and "allFolders" the "*" wildcard. -+ (-cachedHierarchyResultsForURL): now accepts a url parameter so -+ in order to maintain multiple caches depending on the queried -+ namespace. -+ (SOGoMailGetDirectChildren): if the array count is < 2, we must -+ not return since certain implementations may not return the -+ current folder. -+ -+ * NGImap4Client.m (-namespace): new method implementing the -+ "NAMESPACE" command. -+ (-lsub:pattern:): we now sanitize the "prefix" particle of the -+ LSUB command. -+ -+2009-11-25 Wolfgang Sourdeau -+ -+ * NSString+Imap4.m (_encodeToModifiedUTF7): handle the case where -+ the leftOver is 0 by "chance" after the first 2 cycles. This -+ can happen when coding characters having a bitmask with 6 zeroes -+ in a row. -+ -+2009-10-06 Wolfgang Sourdeau -+ -+ * NGImap4Client.m (-delete:): if the folder we want to delete is -+ the same as self->selectedFolder, we unselect it first to ensure a -+ "SELECT" happens if a new folder with the same name is created. -+ -+ * EOQualifier+IMAPAdditions.m -+ (-imap4OperatorForDateKeyword:andComparisonSelector:): modified -+ operator handler to handle "receive-date" search key as well as -+ "date", prefixing the real filter with "sent" or not. -+ -+2009-09-22 Wolfgang Sourdeau -+ -+ * NGImap4Client.m (_sopeSORT:qualifier:encoding:): added support -+ for sorting by message size. -+ -+2009-07-01 Wolfgang Sourdeau -+ -+ * NGImap4Connection.m (-initWithClient:password:): we need to copy -+ the imap4Separator, otherwise it will be released when the connection -+ is deallocated. -+ -+2009-06-15 Wolfgang Sourdeau -+ -+ * NSString+Imap4.m (-stringByEncodingImap4FolderName, -+ -stringByDecodingImap4FolderName): reimplemented the original -+ methods in a unicode-safe way, thereby simplifying the code at the -+ same time. -+ -+ * NGImap4Functions.m (SaneFolderName): new function designed to -+ sanitize folder names prior to using them in IMAP commands. -+ -+2008-10-23 Wolfgang Sourdeau -+ -+ * NGImap4Client.m ([NGImap -sort:qualifier:encoding:]): message -+ without date that are sorted on servers which do not have the SORT -+ capability are now given the current date as a work-around. -+ -+2008-09-22 Wolfgang Sourdeau -+ -+ * NGImap4Connection.m ([NGImap -doesMailboxExistAtURL:]): restore -+ the previously selected folder state. -+ -+2008-09-19 Wolfgang Sourdeau -+ -+ * NGImap4Client.m ([NGImap -select:]): simplified method by -+ removing the need for storing the previous folder before releasing -+ it. This strangely seems to fix a crash with gnustep 1.14. -+ -+2008-09-01 Ludovic Marcotte -+ -+ * NGImap4ConnectionManager.m: implemented _garbageCollect. -+ -+2008-08-28 Wolfgang Sourdeau -+ -+ * NGImap4Client.m ([NGImap -unselect]): new method to send -+ "UNSELECT" to the imap server. -+ - 2007-08-24 Wolfgang Sourdeau - - * NGImap4Connection.m: some fix for folders ending with a slash (OGo -Index: sope-mime/NGImap4/NGImap4ConnectionManager.m -=================================================================== ---- sope-mime/NGImap4/NGImap4ConnectionManager.m (revision 1664) -+++ sope-mime/NGImap4/NGImap4ConnectionManager.m (working copy) -@@ -38,6 +38,9 @@ - debugCache = [ud boolForKey:@"NGImap4EnableIMAP4CacheDebug"]; - poolingOff = [ud boolForKey:@"NGImap4DisableIMAP4Pooling"]; - -+ if ([ud objectForKey:@"NGImap4PoolingCleanupInterval"]) -+ PoolScanInterval = [[ud objectForKey:@"NGImap4PoolingCleanupInterval"] doubleValue]; -+ - if (debugOn) NSLog(@"Note: NGImap4EnableIMAP4Debug is enabled!"); - if (poolingOff) NSLog(@"WARNING: IMAP4 connection pooling is disabled!"); - } -@@ -53,18 +56,17 @@ - if ((self = [super init])) { - if (!poolingOff) { - self->urlToEntry = [[NSMutableDictionary alloc] initWithCapacity:256]; -+ self->gcTimer = [[NSTimer scheduledTimerWithTimeInterval: -+ PoolScanInterval -+ target:self selector:@selector(_garbageCollect:) -+ userInfo:nil repeats:YES] retain]; - } -- -- self->gcTimer = [[NSTimer scheduledTimerWithTimeInterval: -- PoolScanInterval -- target:self selector:@selector(_garbageCollect:) -- userInfo:nil repeats:YES] retain]; - } - return self; - } - - - (void)dealloc { -- if (self->gcTimer) [self->gcTimer invalidate]; -+ [self->gcTimer invalidate]; - [self->urlToEntry release]; - [self->gcTimer release]; - [super dealloc]; -@@ -91,6 +93,25 @@ - - - (void)_garbageCollect:(NSTimer *)_timer { - // TODO: scan for old IMAP4 channels -+ NGImap4Connection *entry; -+ NSDate *now; -+ NSArray *a; -+ int i; -+ -+ a = [self->urlToEntry allKeys]; -+ now = [NSDate date]; -+ -+ for (i = 0; i < [a count]; i++) -+ { -+ entry = [self->urlToEntry objectForKey: [a objectAtIndex: i]]; -+ -+ if ([now timeIntervalSinceDate: [entry creationTime]] > PoolScanInterval) -+ { -+ [[entry client] logout]; -+ [self->urlToEntry removeObjectForKey: [a objectAtIndex: i]]; -+ } -+ } -+ - [self debugWithFormat:@"should collect IMAP4 channels (%d active)", - [self->urlToEntry count]]; - } -@@ -105,34 +126,42 @@ - NGImap4Connection *entry; - NGImap4Client *client; - -+ if (poolingOff) { -+ client = [self imap4ClientForURL:_url password:_p]; -+ entry = [[NGImap4Connection alloc] initWithClient:client -+ password:_p]; -+ return [entry autorelease]; -+ } -+ else { - /* check cache */ - -- if ((entry = [self entryForURL:_url]) != nil) { -- if ([entry isValidPassword:_p]) { -+ if ((entry = [self entryForURL:_url]) != nil) { -+ if ([entry isValidPassword:_p]) { -+ if (debugCache) -+ [self logWithFormat:@"valid password, reusing cache entry ..."]; -+ return entry; -+ } -+ -+ /* different password, password could have changed! */ - if (debugCache) -- [self logWithFormat:@"valid password, reusing cache entry ..."]; -- return entry; -+ [self logWithFormat:@"different password than cached entry: %@", _url]; -+ entry = nil; - } -- -- /* different password, password could have changed! */ -- if (debugCache) -- [self logWithFormat:@"different password than cached entry: %@", _url]; -- entry = nil; -- } -- else -- [self debugWithFormat:@"no connection cached yet for url: %@", _url]; -+ else -+ [self debugWithFormat:@"no connection cached yet for url: %@", _url]; - -- /* try to login */ -+ /* try to login */ - -- client = [entry isValidPassword:_p] -- ? [entry client] -- : [self imap4ClientForURL:_url password:_p]; -+ client = [entry isValidPassword:_p] -+ ? [entry client] -+ : [self imap4ClientForURL:_url password:_p]; -+ -+ if (client == nil) -+ return nil; - -- if (client == nil) -- return nil; -- - /* sideeffect of -imap4ClientForURL:password: is to create a cache entry */ -- return [self entryForURL:_url]; -+ return [self entryForURL:_url]; -+ } - } - - /* client object */ -Index: sope-mime/NGImap4/NSString+Imap4.m -=================================================================== ---- sope-mime/NGImap4/NSString+Imap4.m (revision 1664) -+++ sope-mime/NGImap4/NSString+Imap4.m (working copy) -@@ -20,117 +20,86 @@ - 02111-1307, USA. - */ - -+#import -+ - #include - #include "imCommon.h" - --/* TODO: NOT UNICODE SAFE (uses cString) */ -- --static void _encodeToModifiedUTF7(unsigned char *_buf, int encLen, -- unsigned char **result_, -- unsigned int *cntRes_); --static int _decodeOfModifiedUTF7(unsigned char *_target, unsigned _targetLen, -- unsigned *usedBytes_ , -- unsigned char **buffer_, -- int *bufLen_, int maxBuf); -- - @implementation NSString(Imap4) - -+static unsigned int _encodeToModifiedUTF7(unichar *_char, unsigned char *result_, -+ unsigned int *cntRes_); -+static unsigned int _decodeOfModifiedUTF7(unsigned char *_source, unichar *result_, -+ unsigned int *cntRes_ ); -+ - - (NSString *)stringByEncodingImap4FolderName { -- // TBD: this is restricted to Latin1, should be fixed to UTF-8 -- /* dude.d& --> dude.d&- */ -- unsigned char *buf = NULL; -+ unichar *buf = NULL; - unsigned char *res = NULL; - unsigned int len = 0; - unsigned int cnt = 0; - unsigned int cntRes = 0; - NSString *result = nil; -- NSData *data; - -- len = [self cStringLength]; -- buf = calloc(len + 3, sizeof(char)); -- res = calloc((len * 6) + 3, sizeof(char)); -- buf[len] = '\0'; -- res[len * 6] = '\0'; -- [self getCString:(char *)buf]; -+ len = [self length]; -+ buf = NSZoneMalloc(NULL, (len + 1) * sizeof(unichar)); -+ [self getCharacters: buf]; -+ buf[len] = 0; - -+ /* 1 * '&', 3 for the max bytes / char, 1 * '-' */ -+ res = NSZoneMalloc(NULL, ((len * 5) + 1) * sizeof(char)); -+ - while (cnt < len) { -- int c = buf[cnt]; -+ unichar c = buf[cnt]; - if (((c > 31) && (c < 38)) || - ((c > 38) && (c < 127))) { - res[cntRes++] = c; -- cnt++; - } - else { - if (c == '&') { - res[cntRes++] = '&'; - res[cntRes++] = '-'; -- cnt++; - } - else { -- int start; -- -- start = cnt; -- -- while (cnt < (len - 1)) { -- int c = buf[cnt + 1]; -- if (((c > 31) && (c < 38)) || -- ((c > 38) && (c < 127)) || -- (c == '&')) { -- break; -- } -- else { -- cnt++; -- } -- } -- { -- unsigned length; -- -- res[cntRes++] = '&'; -- -- length = cnt - start + 1; -- -- _encodeToModifiedUTF7(buf + start, length, &res, &cntRes); -- -- res[cntRes] = '-'; -- cntRes++; -- cnt++; -- } -+ res[cntRes++] = '&'; -+ cnt += _encodeToModifiedUTF7(buf + cnt, res + cntRes, &cntRes); -+ res[cntRes++] = '-'; - } - } -+ cnt++; - } -- if (buf != NULL) free(buf); buf = NULL; -+ if (buf != NULL) NSZoneFree(NULL, buf); - -- data = [[NSData alloc] initWithBytesNoCopy:res length:cntRes -- freeWhenDone:YES]; -- result = [[NSString alloc] initWithData:data -- encoding:NSISOLatin1StringEncoding]; -- [data release]; data = nil; -- -- return [result autorelease]; -+ res[cntRes] = 0; -+ result = [NSString stringWithCString: (char *) res -+ encoding: NSISOLatin1StringEncoding]; -+ -+ return result; - } - - - (NSString *)stringByDecodingImap4FolderName { -- // TBD: this is restricted to Latin1, should be fixed to UTF-8 -- /* dude/d&- --> dude/d& */ - unsigned char *buf; -- unsigned char *res; -+ unichar *res; - unsigned int len; - unsigned int cnt = 0; - unsigned int cntRes = 0; - NSString *result = nil; -- NSData *data; -+// NSData *data; - -- if ((len = [self cStringLength]) == 0) -+ if ((len = [self lengthOfBytesUsingEncoding: NSISOLatin1StringEncoding]) == 0) - return @""; -- -- buf = calloc(len + 3, sizeof(unsigned char)); -- res = calloc(len + 3, sizeof(unsigned char)); -+ -+ buf = NSZoneMalloc(NULL, (len + 1) * sizeof(unsigned char)); -+ -+ if ([self getCString:(char *)buf maxLength: len + 1 -+ encoding: NSISOLatin1StringEncoding] == NO) { -+ NSZoneFree(NULL, buf); -+ return @""; -+ } - buf[len] = '\0'; -- res[len] = '\0'; -- -- [self getCString:(char *)buf]; -- -- while (cnt < (len - 1)) { /* &- */ -+ -+ res = NSZoneMalloc(NULL, (len + 1) * sizeof(unichar)); -+ -+ while (cnt < len) { /* &- */ - unsigned char c; - - c = buf[cnt]; -@@ -141,29 +110,7 @@ - cnt += 2; - } - else { -- unsigned usedBytes = 0; -- unsigned char *buffer; -- int maxBuf, bufLen; -- -- cnt++; -- maxBuf = 511; -- bufLen = 0; -- buffer = calloc(maxBuf + 3, sizeof(char)); -- -- if (_decodeOfModifiedUTF7(buf + cnt, len - cnt, &usedBytes , &buffer, -- &bufLen, maxBuf) == 0) { -- int cnt1; -- -- cnt1 = 0; -- while (cnt1 < bufLen) { -- res[cntRes++] = buffer[cnt1++]; -- } -- cnt += usedBytes; -- } -- else { -- NSCAssert(NO, @"couldn't decode UTF-7 .."); -- } -- free(buffer); buffer = NULL; -+ cnt += _decodeOfModifiedUTF7(buf + cnt + 1, res + cntRes, &cntRes) + 1; - } - } - else { -@@ -171,20 +118,133 @@ - cnt++; - } - } -- if (cnt < len) -- res[cntRes++] = buf[cnt++]; -- -- if (buf != NULL) free(buf); buf = NULL; - -- data = [[NSData alloc] initWithBytesNoCopy:res length:cntRes -- freeWhenDone:YES]; -- result = [[NSString alloc] initWithData:data -- encoding:NSISOLatin1StringEncoding]; -- [data release]; data = nil; -- -- return [result autorelease]; -+ if (buf != NULL) NSZoneFree(NULL, buf); -+ -+ res[cntRes] = 0; -+ result = [NSString stringWithCharacters: res length: cntRes]; -+ -+ return result; - } - -+/* check metamail output for correctness */ -+ -+static unsigned char basis_64[] = -+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -+ -+static char index_64[128] = { -+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, -+ 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, -+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, -+ 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, -+ -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, -+ 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 -+}; -+ -+#define char64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) -+ -+static unsigned int _encodeToModifiedUTF7(unichar *_char, unsigned char *result_, -+ unsigned int *cntRes_) -+{ -+ unsigned int processedSrc, processedDest, cycle; -+ unichar c; -+ char leftover; -+ BOOL hasLeftOver; -+ -+ processedSrc = 0; -+ processedDest = 0; -+ cycle = 0; -+ leftover = 0; -+ -+ c = *_char; -+ while (c > 126 || (c > 0 && c < 32)) { -+ if (cycle == 0) { -+ *(result_ + processedDest) = basis_64[(c >> 10) & 0x3f]; -+ *(result_ + processedDest + 1) = basis_64[(c >> 4) & 0x3f]; -+ leftover = (c << 2); -+ hasLeftOver = YES; -+ processedDest += 2; -+ cycle = 1; -+ } -+ else if (cycle == 1) { -+ *(result_ + processedDest) = basis_64[(leftover | (c >> 14)) & 0x3f]; -+ *(result_ + processedDest + 1) = basis_64[(c >> 8) & 0x3f]; -+ *(result_ + processedDest + 2) = basis_64[(c >> 2) & 0x3f]; -+ leftover = (c << 4); -+ hasLeftOver = YES; -+ processedDest += 3; -+ cycle = 2; -+ } -+ else if (cycle == 2) { -+ *(result_ + processedDest) = basis_64[(leftover | (c >> 12)) & 0x3f]; -+ *(result_ + processedDest + 1) = basis_64[(c >> 6) & 0x3f]; -+ *(result_ + processedDest + 2) = basis_64[c & 0x3f]; -+ leftover = 0; -+ hasLeftOver = NO; -+ processedDest += 3; -+ cycle = 0; -+ } -+ processedSrc++; -+ c = *(_char + processedSrc); -+ } -+ if (hasLeftOver) { -+ *(result_ + processedDest) = basis_64[leftover & 0x3f]; -+ processedDest++; -+ } -+ processedSrc--; -+ *cntRes_ += processedDest; -+ -+ return processedSrc; -+} -+ -+static unsigned int _decodeOfModifiedUTF7(unsigned char *_source, unichar *result_, -+ unsigned int *cntRes_) -+{ -+ unsigned int processedSrc, processedDest; -+ unsigned char c, decoded; -+ unichar currentRes; -+ int shift; -+ -+ processedSrc = 0; -+ processedDest = 0; -+ shift = 10; -+ currentRes = 0; -+ -+ c = *_source; -+ while (c != 0 && c != '-') { -+ decoded = index_64[c]; -+ if (shift < 0) { -+ currentRes |= (decoded >> (shift * -1)); -+ *(result_ + processedDest) = currentRes; -+ processedDest++; -+ shift += 16; -+ currentRes = (decoded << shift); -+ } else { -+ currentRes |= (decoded << shift); -+ if (shift == 0) { -+ *(result_ + processedDest) = currentRes; -+ processedDest++; -+ currentRes = 0; -+ shift = 16; -+ } -+ } -+ shift -= 6; -+ processedSrc++; -+ c = *(_source + processedSrc); -+ } -+ if (shift != 10) { -+ *(result_ + processedDest) = currentRes; -+ } -+ if (c == '-') -+ processedSrc++; -+ -+ *cntRes_ += processedDest; -+ -+ return processedSrc; -+} -+ - - (NSString *)stringByEscapingImap4Password { - // TODO: perf - unichar *buffer; -@@ -193,12 +253,12 @@ - NSString *s; - - len = [self length]; -- chars = calloc(len + 2, sizeof(unichar)); -+ chars = NSZoneCalloc(NULL, len + 2, sizeof(unichar)); - [self getCharacters:chars]; -- -- buffer = calloc(len * 2 + 2, sizeof(unichar)); -+ -+ buffer = NSZoneCalloc(NULL, len * 2 + 2, sizeof(unichar)); - buffer[len * 2] = '\0'; -- -+ - for (i = 0, j = 0; i < len; i++, j++) { - BOOL conv = NO; - -@@ -224,209 +284,11 @@ - } - buffer[j] = chars[i]; - } -- if (chars != NULL) free(chars); chars = NULL; -+ if (chars != NULL) NSZoneFree(NULL, chars); - - s = [NSString stringWithCharacters:buffer length:j]; -- if (buffer != NULL) free(buffer); buffer = NULL; -+ - return s; - } - - @end /* NSString(Imap4) */ -- --static void writeChunk(int _c1, int _c2, int _c3, int _pads, -- unsigned char **result_, -- unsigned int *cntRes_); -- --static int getChar(int _cnt, int *cnt_, unsigned char *_buf) { -- int result; -- -- if ((_cnt % 2)) { -- result = _buf[*cnt_]; -- (*cnt_)++; -- } -- else { -- result = 0; -- } -- return result; --} --static void _encodeToModifiedUTF7(unsigned char *_buf, int encLen, -- unsigned char **result_, unsigned int *cntRes_) --{ -- int c1, c2, c3; -- int cnt, cntAll; -- -- cnt = 0; -- cntAll = 0; -- -- while (cnt < encLen) { -- c1 = getChar(cntAll++, &cnt, _buf); -- if (cnt == encLen) { -- writeChunk(c1, 0, 0, 2, result_, cntRes_); -- } -- else { -- c2 = getChar(cntAll++, &cnt, _buf); -- if (cnt == encLen) { -- writeChunk(c1, c2, 0, 1, result_, cntRes_); -- } -- else { -- c3 = getChar(cntAll++, &cnt, _buf); -- writeChunk(c1, c2, c3, 0, result_, cntRes_); -- } -- } -- } --} -- --/* check metamail output for correctness */ -- --static unsigned char basis_64[] = -- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -- --static void writeChunk(int c1, int c2, int c3, int pads, unsigned char **result_, -- unsigned int *cntRes_) { -- unsigned char c; -- -- c = basis_64[c1>>2]; -- (*result_)[*cntRes_] = c; -- (*cntRes_)++; -- -- c = basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)]; -- -- (*result_)[*cntRes_] = c; -- (*cntRes_)++; -- -- -- if (pads == 2) { -- ; -- } -- else if (pads) { -- c = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)]; -- (*result_)[*cntRes_] = c; -- (*cntRes_)++; -- } -- else { -- c = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)]; -- -- (*result_)[*cntRes_] = c; -- (*cntRes_)++; -- -- c = basis_64[c3 & 0x3F]; -- (*result_)[*cntRes_] = c; -- (*cntRes_)++; -- } --} -- --static char index_64[128] = { -- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, -- 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, -- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, -- 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, -- -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, -- 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 --}; -- --#define char64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) -- --static int _decodeOfModifiedUTF7(unsigned char *_target, unsigned _targetLen, -- unsigned *usedBytes_ , unsigned char **buffer_, -- int *bufLen_, int maxBuf) --{ -- int c1, c2, c3, c4; -- unsigned int cnt; -- -- for (cnt = 0; cnt < _targetLen; ) { -- c1 = '='; -- c2 = '='; -- c3 = '='; -- c4 = '='; -- -- c1 = _target[cnt++]; -- -- if (c1 == '-') { -- (*usedBytes_)++; -- return 0; -- } -- if (cnt < _targetLen) -- c2 = _target[cnt++]; -- -- if (c2 == '-') { -- (*usedBytes_)+=2; -- return 0; -- } -- -- (*usedBytes_) += 2; -- -- if (cnt < _targetLen) { -- c3 = _target[cnt++]; -- (*usedBytes_)++; -- } -- -- if (cnt < _targetLen) { -- c4 = _target[cnt++]; -- if (c3 != '-') -- (*usedBytes_)++; -- } -- -- if (c2 == -1 || c3 == -1 || c4 == -1) { -- fprintf(stderr, "Warning: base64 decoder saw premature EOF!\n"); -- return 0; -- } -- -- if (c1 == '=' || c2 == '=') { -- continue; -- } -- -- c1 = char64(c1); -- c2 = char64(c2); -- -- if (*bufLen_ < maxBuf) { -- unsigned char c; -- -- c = ((c1<<2) | ((c2&0x30)>>4)); -- -- if (c) { -- (*buffer_)[*bufLen_] = c; -- *bufLen_ = *bufLen_ + 1; -- } -- } -- if (c3 == '-') { -- return 0; -- } -- else if (c3 == '=') { -- continue; -- } else { -- -- c3 = char64(c3); -- -- if (*bufLen_ < maxBuf) { -- unsigned char c; -- c = (((c2&0XF) << 4) | ((c3&0x3C) >> 2)); -- if (c) { -- (*buffer_)[*bufLen_] = c; -- *bufLen_ = *bufLen_ + 1; -- } -- } -- -- if (c4 == '-') { -- return 0; -- } -- else if (c4 == '=') { -- continue; -- } else { -- c4 = char64(c4); -- -- if (*bufLen_ < maxBuf) { -- unsigned char c; -- -- c = (((c3&0x03) <<6) | c4); -- if (c) { -- (*buffer_)[*bufLen_] = c; -- (*bufLen_) = (*bufLen_) + 1; -- } -- } -- } -- } -- } -- return 0; --} -Index: sope-mime/NGImap4/NGImap4Functions.h -=================================================================== ---- sope-mime/NGImap4/NGImap4Functions.h (revision 1664) -+++ sope-mime/NGImap4/NGImap4Functions.h (working copy) -@@ -58,4 +58,6 @@ - id_folder); - BOOL _createSubFolderWithName(id self, NSString *_name, BOOL _app); - -+NSString *SaneFolderName(NSString *folderName); -+ - #endif /* __NGMime_NGImap4_NGImap4Functions_H__ */ -Index: sope-mime/NGMail/NSData+MimeQP.m -=================================================================== ---- sope-mime/NGMail/NSData+MimeQP.m (revision 1664) -+++ sope-mime/NGMail/NSData+MimeQP.m (working copy) -@@ -81,7 +81,7 @@ - BOOL appendLC; - int cnt, tmp; - unsigned char encoding; -- -+ - buffer = calloc(length + 13, sizeof(unichar)); - - maxBufLen = length + 3; -@@ -175,7 +175,7 @@ - autorelease]; - } - tmpLen = [tmpStr length]; -- -+ - if ((tmpLen + bufLen) < maxBufLen) { - [tmpStr getCharacters:(buffer + bufLen)]; - bufLen += tmpLen; -@@ -198,14 +198,23 @@ - } - } - buffer[bufLen] = '\0'; -+ while(bufLen > 1 && buffer[bufLen-1] == '\0') -+ bufLen--; - { - id data; - - data = nil; - - if (buffer && foundQP) { -+ static NSCharacterSet *illegalCS = nil; -+ -+ if (illegalCS == nil) { -+ illegalCS = [NSCharacterSet illegalCharacterSet]; -+ [illegalCS retain]; -+ } - data = [[[NSStringClass alloc] initWithCharacters:buffer length:bufLen] - autorelease]; -+ data = [data stringByTrimmingCharactersInSet: illegalCS]; - if (data == nil) { - [self warnWithFormat: - @"%s: got no string for buffer '%s', length '%i' !", -Index: sope-mime/NGMail/NGSmtpClient.m -=================================================================== ---- sope-mime/NGMail/NGSmtpClient.m (revision 1664) -+++ sope-mime/NGMail/NGSmtpClient.m (working copy) -@@ -467,13 +467,27 @@ - - // transaction commands - -+- (NSString *) _sanitizeAddress: (NSString *) address -+{ -+ NSString *saneAddress; -+ -+ if ([address hasPrefix: @"<"]) -+ saneAddress = address; -+ else -+ saneAddress = [NSString stringWithFormat: @"<%@>", address]; -+ -+ return saneAddress; -+} -+ - - (BOOL)mailFrom:(id)_sender { -- NGSmtpResponse *reply = nil; -- NSString *sender = nil; -+ NGSmtpResponse *reply; -+ NSString *sender; -+ - [self requireState:NGSmtpState_connected]; - -- sender = [@"FROM:" stringByAppendingString:[_sender stringValue]]; -- reply = [self sendCommand:@"MAIL" argument:sender]; -+ sender = [self _sanitizeAddress: [_sender stringValue]]; -+ reply = [self sendCommand: @"MAIL" -+ argument: [@"FROM:" stringByAppendingString: sender]]; - if ([reply isPositive]) { - if ([reply code] != NGSmtpActionCompleted) { - NSLog(@"SMTP(MAIL FROM): expected reply code %i, got code %i ..", -@@ -490,9 +504,10 @@ - NSString *rcpt = nil; - - [self requireState:NGSmtpState_TRANSACTION]; -- -- rcpt = [@"TO:" stringByAppendingString:[_receiver stringValue]]; -- reply = [self sendCommand:@"RCPT" argument:rcpt]; -+ -+ rcpt = [self _sanitizeAddress: [_receiver stringValue]]; -+ reply = [self sendCommand: @"RCPT" -+ argument: [@"TO:" stringByAppendingString: rcpt]]; - if ([reply isPositive]) { - if ([reply code] != NGSmtpActionCompleted) { - NSLog(@"SMTP(RCPT TO): expected reply code %i, got code %i ..", -@@ -507,6 +522,10 @@ - NGSmtpResponse *reply = nil; - NSMutableData *cleaned_data; - NSRange r1, r2; -+ -+ const char *bytes; -+ char *mbytes; -+ int len, mlen; - - [self requireState:NGSmtpState_TRANSACTION]; - -@@ -519,8 +538,38 @@ - } - [self->text flush]; - -- cleaned_data = [NSMutableData dataWithData: _data]; -+ // -+ // SOPE sucks in many ways and that is one of them. The headers are actually -+ // correctly encoded (trailing \r\n is inserted) but not the base64 encoded -+ // data since it uses GNUstep's dataByEncodingBase64 function which says: -+ // -+ // NGBase64Coding.h:- (NSData *)dataByEncodingBase64; /* Note: inserts '\n' every 72 chars */ -+ // -+ len = [_data length]; -+ mlen = 0; - -+ cleaned_data = [NSMutableData dataWithLength: len*2]; -+ -+ bytes = [_data bytes]; -+ mbytes = [cleaned_data mutableBytes]; -+ -+ while (len > 0) -+ { -+ if (*bytes == '\n' && *(bytes-1) != '\r' && mlen > 0) -+ { -+ *mbytes = '\r'; -+ mbytes++; -+ mlen++; -+ } -+ -+ *mbytes = *bytes; -+ mbytes++; bytes++; -+ len--; -+ mlen++; -+ } -+ -+ [cleaned_data setLength: mlen]; -+ - // - // According to RFC 2821 section 4.5.2, we must check for the character - // sequence "."; any occurrence have its period duplicated -Index: sope-mime/NGMail/NGMailAddressParser.h -=================================================================== ---- sope-mime/NGMail/NGMailAddressParser.h (revision 1664) -+++ sope-mime/NGMail/NGMailAddressParser.h (working copy) -@@ -24,7 +24,9 @@ - - #import - --@class NSData, NSString, NSArray; -+#import -+ -+@class NSData, NSArray; - @class NGMailAddressList; - - /* -@@ -34,16 +36,16 @@ - @interface NGMailAddressParser : NSObject - { - @private -- unsigned char *data; -- int dataPos; -- int errorPos; -- int maxLength; -+ unichar *data; -+ int dataPos; -+ int errorPos; -+ int maxLength; - } - - + (id)mailAddressParserWithString:(NSString *)_string; - + (id)mailAddressParserWithData:(NSData *)_data; --+ (id)mailAddressParserWithCString:(char *)_cString; --- (id)initWithCString:(const unsigned char *)_cstr length:(int unsigned)_len; -++ (id)mailAddressParserWithCString:(const char *)_cString; -+- (id)initWithString:(NSString *)_str; - - /* parsing */ - -Index: sope-mime/NGMail/NGMimeMessageGenerator.m -=================================================================== ---- sope-mime/NGMail/NGMimeMessageGenerator.m (revision 1664) -+++ sope-mime/NGMail/NGMimeMessageGenerator.m (working copy) -@@ -86,37 +86,40 @@ - char *des = NULL; - unsigned int cnt; - BOOL doEnc; -- NSString *str; -+// NSString *str; - - // TODO: this s***s big time! -+// NSLog (@"class: '%@'", NSStringFromClass ([_data class])); -+// #if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY -+// str = [[NSString alloc] initWithData:_data -+// encoding:NSISOLatin1StringEncoding]; -+// str = [str autorelease]; -+ -+// #else -+// str = [[NSString alloc] initWithData:_data -+// encoding:NSISOLatin9StringEncoding]; -+// #endif -+// bytes = [str cString]; -+// length = [str cStringLength]; - --#if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY -- str = [[NSString alloc] initWithData:_data -- encoding:NSISOLatin1StringEncoding]; --#else -- str = [[NSString alloc] initWithData:_data -- encoding:NSISOLatin9StringEncoding]; --#endif -- str = [str autorelease]; -- -- bytes = [str cString]; -- length = [str cStringLength]; -- -+ bytes = [_data bytes]; -+ length = [_data length]; -+ - /* check whether we need to encode */ -- -- for (cnt = 0, doEnc = NO; cnt < length; cnt++) { -- if ((unsigned char)bytes[cnt] > 127) { -+ cnt = 0; -+ doEnc = NO; -+ while (!doEnc && cnt < length) -+ if ((unsigned char)bytes[cnt] > 127) - doEnc = YES; -- break; -- } -- } -- -+ else -+ cnt++; -+ - if (!doEnc) - return _data; - - /* encode quoted printable */ - { -- char iso[] = "=?iso-8859-15?q?"; -+ char iso[] = "=?utf-8?q?"; - unsigned isoLen = 16; - char isoEnd[] = "?="; - unsigned isoEndLen = 2; -Index: sope-mime/NGMail/NGMailAddressParser.m -=================================================================== ---- sope-mime/NGMail/NGMailAddressParser.m (revision 1664) -+++ sope-mime/NGMail/NGMailAddressParser.m (working copy) -@@ -52,9 +52,9 @@ - StrClass = [NSString class]; - } - --static inline NSString *mkStrObj(const unsigned char *s, unsigned int l) { -+static inline NSString *mkStrObj(const unichar *s, unsigned int l) { - // TODO: unicode -- return [(NSString *)[StrClass alloc] initWithCString:(char *)s length:l]; -+ return [(NSString *)[StrClass alloc] initWithCharacters:s length:l]; - } - - static inline id parseWhiteSpaces(NGMailAddressParser *self, BOOL _guessMode) { -@@ -79,12 +79,29 @@ - return returnValue; - } - -+static void dumpBadString(unichar *text, int length) { -+ char *bytes; -+ NSMutableString *logString; -+ int count, max; - -+ max = length * sizeof (unichar); -+ logString = [NSMutableString stringWithCapacity: max]; -+ [logString appendString: @"dumping buggy atom string: "]; -+ bytes = (char *) text; -+ for (count = 0; count < max; count++) { -+ [logString appendFormat: @"0x%X", bytes[count]]; -+ if (count < (max - 1)) -+ [logString appendString: @", "]; -+ } -+ -+ NSLog (@"%@", logString); -+} -+ - static inline id parseAtom(NGMailAddressParser *self, BOOL _guessMode) { - int keepPos = self->dataPos; // keep reference for backtracking - id returnValue = nil; - BOOL isAtom = YES; -- unsigned char text[self->maxLength + 2]; // token text -+ unichar text[self->maxLength + 2]; // token text - int length = 0; // token text length - BOOL done = NO; - -@@ -94,7 +111,7 @@ - done = YES; - } - else { -- register unsigned char c = self->data[self->dataPos]; -+ register unichar c = self->data[self->dataPos]; - - switch (c) { - case '(' : case ')': case '<': case '>': -@@ -128,6 +145,9 @@ - else { - NSCAssert(length > 0, @"no atom with length=0"); - returnValue = [mkStrObj(text, length) autorelease]; -+ if (!returnValue) { -+ dumpBadString(text, length); -+ } - NSCAssert([returnValue isKindOfClass:StrClass], @"got no string .."); - } - } -@@ -162,7 +182,7 @@ - int keepPos = self->dataPos; // keep reference for backtracking - id returnValue = nil; - BOOL isQText = YES; -- unsigned char text[self->maxLength + 4]; // token text -+ unichar text[self->maxLength + 4]; // token text - int length = 0; // token text length - BOOL done = YES; - -@@ -172,9 +192,9 @@ - done = YES; - } - else { -- register char c = self->data[self->dataPos]; -+ register unichar c = self->data[self->dataPos]; - -- switch ((int)c) { -+ switch (c) { - case '"' : - case '\\': - case 13 : -@@ -215,7 +235,7 @@ - int keepPos = self->dataPos; // keep reference for backtracking - id returnValue = nil; - BOOL isDText = YES; -- unsigned char text[self->maxLength]; // token text -+ unichar text[self->maxLength]; // token text - int length = 0; // token text length - BOOL done = YES; - -@@ -225,9 +245,9 @@ - done = YES; - } - else { -- register char c = self->data[self->dataPos]; -+ register unichar c = self->data[self->dataPos]; - -- switch ((int)c) { -+ switch (c) { - case '[': case ']': - case '\\': case 13: - isDText = (length > 0); -@@ -320,42 +340,47 @@ - /* constructors */ - - + (id)mailAddressParserWithData:(NSData *)_data { -- return [[(NGMailAddressParser *)[self alloc] -- initWithCString:[_data bytes] -- length:[_data length]] autorelease]; -+ NSString *uniString; -+ -+ uniString = [NSString stringWithCharacters:(unichar *)[_data bytes] -+ length:([_data length] / sizeof(unichar))]; -+ -+ return [(NGMailAddressParser *)self mailAddressParserWithString:uniString]; - } -+ - + (id)mailAddressParserWithCString:(char *)_cString { -- return [[(NGMailAddressParser *)[self alloc] -- initWithCString:(unsigned char *)_cString -- length:strlen(_cString)] autorelease]; -+ NSString *nsCString; -+ -+ nsCString = [NSString stringWithCString:_cString]; -+ -+ return [(NGMailAddressParser *)self mailAddressParserWithString:nsCString]; - } --- (id)initWithCString:(const unsigned char *)_cstr length:(int unsigned)_len { -+ -++ (id)mailAddressParserWithString:(NSString *)_string { -+ return [[(NGMailAddressParser *)[self alloc] initWithString:_string] -+ autorelease]; -+} -+ -+- (id)initWithString:(NSString *)_str { - if ((self = [super init])) { - // TODO: remember some string encoding? -- self->data = (unsigned char *)_cstr; -- self->maxLength = _len; -+ self->maxLength = [_str length]; -+ self->data = malloc(self->maxLength*sizeof(unichar)); -+ [_str getCharacters:self->data]; - self->dataPos = 0; - self->errorPos = -1; - } - return self; - } - --- (id)initWithString:(NSString *)_str { -- // TODO: unicode -- return [self initWithCString:(unsigned char *)[_str cString] -- length:[_str cStringLength]]; --} -- - - (id)init { -- return [self initWithCString:NULL length:0]; -+ return [self initWithString:nil]; - } - --+ (id)mailAddressParserWithString:(NSString *)_string { -- return [[(NGMailAddressParser *)[self alloc] initWithString:_string] -- autorelease]; --} -- - - (void)dealloc { -+ if (self->data != NULL) { -+ free(self->data); -+ } - self->data = NULL; - self->maxLength = 0; - self->dataPos = 0; -Index: sope-mime/NGMail/ChangeLog -=================================================================== ---- sope-mime/NGMail/ChangeLog (revision 1664) -+++ sope-mime/NGMail/ChangeLog (working copy) -@@ -1,3 +1,13 @@ -+2010-04-30 Wolfgang Sourdeau -+ -+ * NSData+MimeQP.m (-decodeQuotedPrintableValueOfMIMEHeaderField:): -+ we now strip invalid characters from the resulting string. -+ -+2010-04-13 Wolfgang Sourdeau -+ -+ * NGSmtpClient.m (-mailFrom, -recipientTo): we ensure that the -+ provided email address is enclosed within brackets. -+ - 2008-09-01 Ludovic Marcotte - - * NGSmtpClient.m: improved implementation -@@ -31,9 +41,9 @@ - fields to fix #1324 - - 2005-03-24 Helge Hess -- -+ - * NGMimeMessageGenerator.m: minor code cleanups -- -+ - 2005-01-30 Helge Hess - - * NGMimeMessageGenerator.m: fixed a format bug in an error log which -Index: sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m -=================================================================== ---- sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m (revision 1664) -+++ sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m (working copy) -@@ -19,88 +19,45 @@ - 02111-1307, USA. - */ - -+#ifdef HAVE_STRNDUP -+#define _GNU_SOURCE 1 -+#endif -+ -+#include -+ - #include "NGMimeHeaderFieldParser.h" - #include "NGMimeHeaderFields.h" - #include "NGMimeUtilities.h" - #include "common.h" --#include - -+#ifndef HAVE_STRNDUP -+char *strndup(const char *str, size_t len) -+{ -+ char *dup = (char *)malloc(len+1); -+ if (dup) { -+ strncpy(dup,str,len); -+ dup[len]= '\0'; -+ } -+ return dup; -+} -+#endif -+ - @implementation NGMimeRFC822DateHeaderFieldParser - --static Class CalDateClass = Nil; --static NSTimeZone *gmt = nil; --static NSTimeZone *gmt01 = nil; --static NSTimeZone *gmt02 = nil; --static NSTimeZone *gmt03 = nil; --static NSTimeZone *gmt04 = nil; --static NSTimeZone *gmt05 = nil; --static NSTimeZone *gmt06 = nil; --static NSTimeZone *gmt07 = nil; --static NSTimeZone *gmt08 = nil; --static NSTimeZone *gmt09 = nil; --static NSTimeZone *gmt10 = nil; --static NSTimeZone *gmt11 = nil; --static NSTimeZone *gmt12 = nil; --static NSTimeZone *gmt0530 = nil; --static NSTimeZone *gmtM01 = nil; --static NSTimeZone *gmtM02 = nil; --static NSTimeZone *gmtM03 = nil; --static NSTimeZone *gmtM04 = nil; --static NSTimeZone *gmtM05 = nil; --static NSTimeZone *gmtM06 = nil; --static NSTimeZone *gmtM07 = nil; --static NSTimeZone *gmtM08 = nil; --static NSTimeZone *gmtM09 = nil; --static NSTimeZone *gmtM10 = nil; --static NSTimeZone *gmtM11 = nil; --static NSTimeZone *gmtM12 = nil; --static NSTimeZone *gmtM13 = nil; --static NSTimeZone *gmtM14 = nil; --static NSTimeZone *met = nil; -+static NSTimeZone *gmt = nil; -+static NSTimeZone *met = nil; - - + (int)version { - return 2; - } -+ - + (void)initialize { - static BOOL didInit = NO; -- Class TzClass; - if (didInit) return; - didInit = YES; - -- CalDateClass = [NSCalendarDate class]; -- -- /* timezones which were actually used in a maillist mailbox */ -- TzClass = [NSTimeZone class]; -- gmt = [[TzClass timeZoneWithName:@"GMT"] retain]; -- met = [[TzClass timeZoneWithName:@"MET"] retain]; -- gmt01 = [[TzClass timeZoneForSecondsFromGMT: 1 * (60 * 60)] retain]; -- gmt02 = [[TzClass timeZoneForSecondsFromGMT: 2 * (60 * 60)] retain]; -- gmt03 = [[TzClass timeZoneForSecondsFromGMT: 3 * (60 * 60)] retain]; -- gmt04 = [[TzClass timeZoneForSecondsFromGMT: 4 * (60 * 60)] retain]; -- gmt05 = [[TzClass timeZoneForSecondsFromGMT: 5 * (60 * 60)] retain]; -- gmt06 = [[TzClass timeZoneForSecondsFromGMT: 6 * (60 * 60)] retain]; -- gmt07 = [[TzClass timeZoneForSecondsFromGMT: 7 * (60 * 60)] retain]; -- gmt08 = [[TzClass timeZoneForSecondsFromGMT: 8 * (60 * 60)] retain]; -- gmt09 = [[TzClass timeZoneForSecondsFromGMT: 9 * (60 * 60)] retain]; -- gmt10 = [[TzClass timeZoneForSecondsFromGMT: 10 * (60 * 60)] retain]; -- gmt11 = [[TzClass timeZoneForSecondsFromGMT: 11 * (60 * 60)] retain]; -- gmt12 = [[TzClass timeZoneForSecondsFromGMT: 12 * (60 * 60)] retain]; -- gmtM01 = [[TzClass timeZoneForSecondsFromGMT: -1 * (60 * 60)] retain]; -- gmtM02 = [[TzClass timeZoneForSecondsFromGMT: -2 * (60 * 60)] retain]; -- gmtM03 = [[TzClass timeZoneForSecondsFromGMT: -3 * (60 * 60)] retain]; -- gmtM04 = [[TzClass timeZoneForSecondsFromGMT: -4 * (60 * 60)] retain]; -- gmtM05 = [[TzClass timeZoneForSecondsFromGMT: -5 * (60 * 60)] retain]; -- gmtM06 = [[TzClass timeZoneForSecondsFromGMT: -6 * (60 * 60)] retain]; -- gmtM07 = [[TzClass timeZoneForSecondsFromGMT: -7 * (60 * 60)] retain]; -- gmtM08 = [[TzClass timeZoneForSecondsFromGMT: -8 * (60 * 60)] retain]; -- gmtM09 = [[TzClass timeZoneForSecondsFromGMT: -9 * (60 * 60)] retain]; -- gmtM10 = [[TzClass timeZoneForSecondsFromGMT:-10 * (60 * 60)] retain]; -- gmtM11 = [[TzClass timeZoneForSecondsFromGMT:-11 * (60 * 60)] retain]; -- gmtM12 = [[TzClass timeZoneForSecondsFromGMT:-12 * (60 * 60)] retain]; -- gmtM13 = [[TzClass timeZoneForSecondsFromGMT:-13 * (60 * 60)] retain]; -- gmtM14 = [[TzClass timeZoneForSecondsFromGMT:-14 * (60 * 60)] retain]; -- -- gmt0530 = [[TzClass timeZoneForSecondsFromGMT:5 * (60*60) + (30*60)] retain]; -+ gmt = [[NSTimeZone timeZoneWithName:@"GMT"] retain]; -+ met = [[NSTimeZone timeZoneWithName:@"MET"] retain]; - } - - /* -@@ -111,7 +68,7 @@ - TODO: use an own parser for that. - */ - --static int parseMonthOfYear(unsigned char *s, unsigned int len) { -+static int parseMonthOfYear(char *s, unsigned int len) { - /* - This one is *extremely* forgiving, it only checks what is - necessary for the set below. This should work for both, English -@@ -147,162 +104,110 @@ - } - } - --static NSTimeZone *parseTimeZone(unsigned char *s, unsigned int len) { -+static int offsetFromTZAbbreviation(const char **p) { -+ NSString *abbreviation; -+ NSTimeZone *offsetTZ; -+ unsigned int length; -+ -+ length = 0; -+ while (isalpha(*(*p+length))) -+ length++; -+ abbreviation = [[NSString alloc] initWithBytes: *p -+ length: length - 1 -+ encoding: NSISOLatin1StringEncoding]; -+ offsetTZ = [NSTimeZone timeZoneWithAbbreviation: abbreviation]; -+ [abbreviation release]; -+ *p += length; -+ -+ return [offsetTZ secondsFromGMT]; -+} -+ -+static inline char *digitsString(const char *string) { -+ const char *p; -+ unsigned int len; -+ -+ p = string; -+ while (!isdigit(*p)) -+ p++; -+ len = 0; -+ while (isdigit(*(p + len))) -+ len++; -+ -+ return strndup(p, len); -+} -+ -+static NSTimeZone *parseTimeZone(const char *s, unsigned int len) { - /* - WARNING: failed to parse RFC822 timezone: '+0530' \ - (value='Tue, 13 Jul 2004 21:39:28 +0530') - TODO: this is because libFoundation doesn't accept 'GMT+0530' as input. - */ -- char *p = (char *)s; -+ char *newString, *digits; -+ const char *p; - NSTimeZone *tz; -- NSString *ts; -- -- if (len == 0) -- return nil; -- -- if (*s == '+' || *s == '-') { -- if (len == 3) { -- if (p[1] == '0' && p[2] == '0') // '+00' or '-00' -- return gmt; -- if (*s == '+') { -- if (p[1] == '0' && p[2] == '1') // '+01' -- return gmt01; -- if (p[1] == '0' && p[2] == '2') // '+02' -- return gmt02; -- } -- } -- else if (len == 5) { -- if (p[3] == '0' && p[4] == '0' && p[1] == '0') { // '?0x00' -- if (p[2] == '0') // '+0000' -- return gmt; -- -- if (*s == '+') { -- if (p[2] == '1') return gmt01; // '+0100' -- if (p[2] == '2') return gmt02; // '+0200' -- if (p[2] == '3') return gmt03; // '+0300' -- if (p[2] == '4') return gmt04; // '+0400' -- if (p[2] == '5') return gmt05; // '+0500' -- if (p[2] == '6') return gmt06; // '+0600' -- if (p[2] == '7') return gmt07; // '+0700' -- if (p[2] == '8') return gmt08; // '+0800' -- if (p[2] == '9') return gmt09; // '+0900' -- } -- else if (*s == '-') { -- if (p[2] == '1') return gmtM01; // '-0100' -- if (p[2] == '2') return gmtM02; // '-0200' -- if (p[2] == '3') return gmtM03; // '-0300' -- if (p[2] == '4') return gmtM04; // '-0400' -- if (p[2] == '5') return gmtM05; // '-0500' -- if (p[2] == '6') return gmtM06; // '-0600' -- if (p[2] == '7') return gmtM07; // '-0700' -- if (p[2] == '8') return gmtM08; // '-0800' -- if (p[2] == '9') return gmtM09; // '-0900' -- } -- } -- else if (p[3] == '0' && p[4] == '0' && p[1] == '1') { // "?1x00" -- if (*s == '+') { -- if (p[2] == '0') return gmt10; // '+1000' -- if (p[2] == '1') return gmt11; // '+1100' -- if (p[2] == '2') return gmt12; // '+1200' -- } -- else if (*s == '-') { -- if (p[2] == '0') return gmtM10; // '-1000' -- if (p[2] == '1') return gmtM11; // '-1100' -- if (p[2] == '2') return gmtM12; // '-1200' -- if (p[2] == '3') return gmtM13; // '-1300' -- if (p[2] == '4') return gmtM14; // '-1400' -- } -- } -- -- /* special case for GMT+0530 */ -- if (strncmp((char *)s, "+0530", 5) == 0) -- return gmt0530; -- } -- else if (len == 7) { -- /* -- "MultiMail" submits timezones like this: -- "Tue, 9 Mar 2004 9:43:00 -05-500", -- don't know what the "-500" trailer is supposed to mean? Apparently -- Thunderbird just uses the "-05", so do we. -- */ -- -- if (isdigit(p[1]) && isdigit(p[2]) && (p[3] == '-'||p[3] == '+')) { -- unsigned char tmp[8]; -- -- strncpy((char *)tmp, p, 3); -- tmp[3] = '0'; -- tmp[4] = '0'; -- tmp[5] = '\0'; -- return parseTimeZone(tmp, 5); -- } -- } -+ unsigned int hours, minutes, seconds, remaining; -+ int sign; -+ -+ sign = 1; -+ hours = 0; -+ minutes = 0; -+ seconds = 0; -+ -+ newString = strndup(s, len); -+ p = newString; -+ -+ if (isalpha(*p)) -+ seconds = offsetFromTZAbbreviation(&p); -+ while (isspace(*p)) -+ p++; -+ while (*p == '+' || *p == '-') { -+ if (*p == '-') -+ sign = -sign; -+ p++; - } -- else if (*s == '0') { -- if (len == 2) { // '00' -- if (p[1] == '0') return gmt; -- if (p[1] == '1') return gmt01; -- if (p[1] == '2') return gmt02; -- } -- else if (len == 4) { -- if (p[2] == '0' && p[3] == '0') { // '0x00' -- if (p[1] == '0') return gmt; -- if (p[1] == '1') return gmt01; -- if (p[1] == '2') return gmt02; -- } -- } -+ digits = digitsString(p); -+ p = digits; -+ remaining = strlen(p); -+ switch(remaining) { -+ case 6: /* hhmmss */ -+ seconds += (10 * (*(p + remaining - 2) - 48) -+ + *(p + remaining - 1) - 48); -+ case 4: /* hhmm */ -+ hours += 10 * (*p - 48); -+ p++; -+ case 3: /* hmm */ -+ hours += (*p - 48); -+ p++; -+ minutes += 10 * (*p - 48) + *(p + 1) - 48; -+ break; -+ case 2: /* hh */ -+ hours += 10 * (*p - 48) + *(p + 1) - 48; -+ break; -+ default: -+ NSLog (@"parseTimeZone: cannot parse time notation '%s'", newString); - } -- else if (len == 3) { -- if (strcasecmp((char *)s, "GMT") == 0) return gmt; -- if (strcasecmp((char *)s, "UTC") == 0) return gmt; -- if (strcasecmp((char *)s, "MET") == 0) return met; -- if (strcasecmp((char *)s, "CET") == 0) return met; -- } -- -- if (isalpha(*s)) { -- ts = [[NSString alloc] initWithCString:(char *)s length:len]; -- } -- else { -- char buf[len + 5]; -- -- buf[0] = 'G'; buf[1] = 'M'; buf[2] = 'T'; -- if (*s == '+' || *s == '-') { -- strcpy(&(buf[3]), (char *)s); -- } -- else { -- buf[3] = '+'; -- strcpy(&(buf[4]), (char *)s); -- } -- ts = [[NSString alloc] initWithCString:buf]; -- } --#if 1 -- NSLog(@"%s: RFC822 TZ Parser: expensive: '%@'", __PRETTY_FUNCTION__, ts); --#endif -- tz = [NSTimeZone timeZoneWithAbbreviation:ts]; -- [ts release]; -+ free(digits); -+ -+ seconds += sign * (3600 * hours + 60 * minutes); -+ tz = [NSTimeZone timeZoneForSecondsFromGMT: seconds]; -+ free(newString); -+ - return tz; - } - - - (id)parseValue:(id)_data ofHeaderField:(NSString *)_field { - // TODO: use UNICODE - NSCalendarDate *date = nil; -- unsigned char buf[256]; -- unsigned char *bytes = buf, *pe; -+ char *bytes, *pe; - unsigned length = 0; - NSTimeZone *tz = nil; - char dayOfMonth, monthOfYear, hour, minute, second; - short year; - BOOL flag; -- -- if ((length = [_data cStringLength]) > 254) { -- [self logWithFormat: -- @"header field value to large for date parsing: '%@'(%i)", -- _data, length]; -- length = 254; -- } -- -- [_data getCString:(char *)buf maxLength:length]; -- buf[length] = '\0'; -- -+ -+ length = [_data lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; -+ bytes = [_data cStringUsingEncoding: NSUTF8StringEncoding]; -+ - /* remove leading chars (skip to first digit, the day of the month) */ - while (length > 0 && (!isdigit(*bytes))) { - bytes++; -@@ -312,7 +217,7 @@ - if (length == 0) { - NSLog(@"WARNING(%s): empty value for header field %@ ..", - __PRETTY_FUNCTION__, _field); -- return [CalDateClass date]; -+ return [NSCalendarDate date]; - } - - // TODO: should be a category on NSCalendarDate -@@ -435,7 +340,8 @@ - for (pe = bytes; isalnum(*pe) || *pe == '-' || *pe == '+'; pe++) - ; - *pe = '\0'; -- if ((tz = parseTimeZone(bytes, (pe - bytes))) == nil) { -+ if (pe == bytes -+ || (tz = parseTimeZone((const char *) bytes, (pe - bytes))) == nil) { - [self logWithFormat: - @"WARNING: failed to parse RFC822 timezone: '%s' (value='%@')", - bytes, _data]; -@@ -444,9 +350,9 @@ - - /* construct and return */ - finished: -- date = [CalDateClass dateWithYear:year month:monthOfYear day:dayOfMonth -- hour:hour minute:minute second:second -- timeZone:tz]; -+ date = [NSCalendarDate dateWithYear:year month:monthOfYear day:dayOfMonth -+ hour:hour minute:minute second:second -+ timeZone:tz]; - if (date == nil) goto failed; - - #if 0 -Index: sope-mime/NGMime/NGMimeMultipartBodyParser.m -=================================================================== ---- sope-mime/NGMime/NGMimeMultipartBodyParser.m (revision 1664) -+++ sope-mime/NGMime/NGMimeMultipartBodyParser.m (working copy) -@@ -428,6 +428,7 @@ - NSString *boundary = nil; - NSArray *rawBodyParts = nil; - BOOL foundError = NO; -+ NSData *boundaryBytes; - - contentType = [_part contentType]; - boundary = [contentType valueOfParameter:@"boundary"]; -@@ -437,9 +438,10 @@ - - *(&foundError) = NO; - -+ boundaryBytes = [boundary dataUsingEncoding:NSISOLatin1StringEncoding]; - *(&rawBodyParts) = [self _parseBody:_body part:_part data:_data -- boundary:[boundary cString] -- length:[boundary cStringLength] -+ boundary:[boundaryBytes bytes] -+ length:[boundary length] - delegate:_d]; - - if (rawBodyParts) { -Index: sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m -=================================================================== ---- sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m (revision 1664) -+++ sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m (working copy) -@@ -77,6 +77,7 @@ - [rfc822Set setGenerator:gen forField:@"bcc"]; - [rfc822Set setGenerator:gen forField:Fields->from]; - [rfc822Set setGenerator:gen forField:@"reply-to"]; -+ [rfc822Set setGenerator:gen forField:@"in-reply-to"]; - [rfc822Set setGenerator:gen forField:@"Disposition-Notification-To"]; - } - -Index: sope-mime/NGMime/NGMimeType.m -=================================================================== ---- sope-mime/NGMime/NGMimeType.m (revision 1664) -+++ sope-mime/NGMime/NGMimeType.m (working copy) -@@ -120,30 +120,30 @@ - - /* some unsupported, but known encoding */ - else if ([charset isEqualToString:@"ks_c_5601-1987"]) { -- encoding = [NSString defaultCStringEncoding]; -+ encoding = NSISOLatin1StringEncoding; - foundUnsupported = YES; - } - else if ([charset isEqualToString:@"euc-kr"]) { -- encoding = [NSString defaultCStringEncoding]; -- foundUnsupported = YES; -+ encoding = NSKoreanEUCStringEncoding; - } - else if ([charset isEqualToString:@"big5"]) { -- encoding = [NSString defaultCStringEncoding]; -- foundUnsupported = YES; -+ encoding = NSBIG5StringEncoding; - } - else if ([charset isEqualToString:@"iso-2022-jp"]) { -- encoding = [NSString defaultCStringEncoding]; -- foundUnsupported = YES; -+ encoding = NSISO2022JPStringEncoding; - } - else if ([charset isEqualToString:@"gb2312"]) { -- encoding = [NSString defaultCStringEncoding]; -- foundUnsupported = YES; -+ encoding = NSGB2312StringEncoding; - } - else if ([charset isEqualToString:@"koi8-r"]) { -- encoding = [NSString defaultCStringEncoding]; -- foundUnsupported = YES; -+ encoding = NSKOI8RStringEncoding; - } -- -+ else if ([charset isEqualToString:@"windows-1250"]) { -+ encoding = NSWindowsCP1250StringEncoding; -+ } -+ else if ([charset isEqualToString:@"windows-1251"]) { -+ encoding = NSWindowsCP1251StringEncoding; -+ } - else if ([charset isEqualToString:@"windows-1252"]) { - encoding = NSWindowsCP1252StringEncoding; - } -@@ -152,7 +152,7 @@ - } - else if ([charset isEqualToString:@"x-unknown"] || - [charset isEqualToString:@"unknown"]) { -- encoding = NSASCIIStringEncoding; -+ encoding = NSISOLatin1StringEncoding; - } - /* ISO Latin 9 */ - #if !(NeXT_Foundation_LIBRARY || APPLE_Foundation_LIBRARY) -@@ -166,7 +166,7 @@ - else { - [self logWithFormat:@"%s: unknown charset '%@'", - __PRETTY_FUNCTION__, _s]; -- encoding = [NSString defaultCStringEncoding]; -+ encoding = NSISOLatin1StringEncoding; - } - return encoding; - } -@@ -385,23 +385,26 @@ - } - - - (BOOL)valueNeedsQuotes:(NSString *)_parameterValue { -- unsigned len = [_parameterValue cStringLength]; -- char buf[len + 15]; -- char *cstr; -+ NSData *stringData; -+ const char *cstr; -+ unsigned int count, max; -+ BOOL needsQuote; - -- cstr = &(buf[0]); -+ needsQuote = NO; - -- [_parameterValue getCString:cstr]; cstr[len] = '\0'; -- while (*cstr) { -- if (isMime_SpecialByte(*cstr)) -- return YES; -+ stringData = [_parameterValue dataUsingEncoding:NSUTF8StringEncoding]; -+ cstr = [stringData bytes]; -+ max = [stringData length]; -+ count = 0; -+ while (!needsQuote && count < max) { -+ if (isMime_SpecialByte(*(cstr + count)) -+ || *(cstr + count) == 32) -+ needsQuote = YES; -+ else -+ count++; -+ } - -- if (*cstr == 32) -- return YES; -- -- cstr++; -- } -- return NO; -+ return needsQuote; - } - - - (NSString *)stringValue { -Index: sope-mime/NGMime/NGMimeBodyPart.m -=================================================================== ---- sope-mime/NGMime/NGMimeBodyPart.m (revision 1664) -+++ sope-mime/NGMime/NGMimeBodyPart.m (working copy) -@@ -31,18 +31,6 @@ - return 2; - } - --static NGMimeType *defaultType = nil; -- --+ (void)initialize { -- static BOOL isInitialized = NO; -- if (!isInitialized) { -- isInitialized = YES; -- -- defaultType = -- [[NGMimeType mimeType:@"text/plain; charset=us-ascii"] retain]; -- } --} -- - + (id)bodyPartWithHeader:(NGHashMap *)_header { - return [[[self alloc] initWithHeader:_header] autorelease]; - } -@@ -156,13 +144,12 @@ - if (!Fields) - Fields = (NGMimeHeaderNames *)[NGMimePartParser headerFieldNames]; - -- - type = [self->header objectForKey:Fields->contentType]; - - if (![type isKindOfClass:[NGMimeType class]]) - type = [NGMimeType mimeType:[type stringValue]]; - -- return (type != nil ? type : (id)defaultType); -+ return type; - } - - - (NSString *)contentId { -Index: sope-mime/NGMime/ChangeLog -=================================================================== ---- sope-mime/NGMime/ChangeLog (revision 1664) -+++ sope-mime/NGMime/ChangeLog (working copy) -@@ -1,3 +1,25 @@ -+2008-09-08 Wolfgang Sourdeau -+ -+ * NGMimeRFC822DateHeaderFieldParser.m ([NGMimeRFC -+ -parseValue:ofHeaderField:]): don't parse timezone with a length -+ of 0. -+ -+2008-09-01 Wolfgang Sourdeau -+ -+ * NGMimeRFC822DateHeaderFieldParser.m ([NGMimeRFC -+ -parseValue:ofHeaderField:]): use an 8-bit safe encoding when -+ parsing dates. Since we only consider 7-bits characters, we ensure -+ that bad user-agents can be handled more properly. -+ -+ * NGMimeType.m ([NGMimeType +stringEncodingForCharset:]): -+ x-unknown encoding is now translated to an 8-bit safe encoding -+ (NSISOLatin1StringEncoding). -+ -+ * NGMimeAddressHeaderFieldGenerator.m -+ ([NGMimeAddressHeaderFieldGenerator -+ -generateDataForHeaderFieldNamed:value:]): encode resulting string -+ in an 8-bit safe encoding (NSISOLatin1StringEncoding). -+ - 2008-01-29 Albrecht Dress - - * fixes for OGo bug #789 (reply-to QP encoding) -Index: sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m -=================================================================== ---- sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m (revision 1664) -+++ sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m (working copy) -@@ -36,8 +36,7 @@ - NGMimeType *type = nil; // only one content-type field - NSString *tmp = nil; - NSMutableData *data = nil; -- unsigned char *ctmp = NULL; -- unsigned len = 0; -+ NSData *valueData; - - type = _value; - -@@ -59,21 +58,15 @@ - - tmp = [type type]; - NSAssert(tmp, @"type should not be nil"); -- len = [tmp length]; -- ctmp = malloc(len + 4); -- [tmp getCString:(char *)ctmp]; ctmp[len] = '\0'; -- [data appendBytes:ctmp length:len]; -- free(ctmp); -+ valueData = [tmp dataUsingEncoding: NSISOLatin1StringEncoding]; -+ [data appendData: valueData]; -+ -+ [data appendBytes:"/" length:1]; - -- [data appendBytes:"//" length:1]; -- - tmp = [type subType]; - if (tmp != nil) { -- len = [tmp length]; -- ctmp = malloc(len + 4); -- [tmp getCString:(char *)ctmp]; ctmp[len] = '\0'; -- [data appendBytes:ctmp length:len]; -- free(ctmp); -+ valueData = [tmp dataUsingEncoding: NSISOLatin1StringEncoding]; -+ [data appendData:valueData]; - } - else - [data appendBytes:"*" length:1]; -@@ -91,12 +84,9 @@ - continue; - } - [data appendBytes:"; " length:2]; -- -- len = [name cStringLength]; -- ctmp = malloc(len + 1); -- [name getCString:(char *)ctmp]; ctmp[len] = '\0'; -- [data appendBytes:ctmp length:len]; -- free(ctmp); -+ -+ valueData = [name dataUsingEncoding: NSUTF8StringEncoding]; -+ [data appendData: valueData]; - - /* - this confuses GroupWise: "= \"" (a space) -@@ -105,66 +95,30 @@ - - /* check for encoding */ - { -- unsigned cnt; -+ unsigned cnt, max; -+ const char *dataBytes; - BOOL doEnc; - -- len = [value cStringLength]; -- ctmp = malloc(len + 4); -- [value getCString:(char *)ctmp]; ctmp[len] = '\0'; -- cnt = 0; -+ valueData = [value dataUsingEncoding:NSUTF8StringEncoding]; -+ dataBytes = [valueData bytes]; -+ max = [valueData length]; -+ - doEnc = NO; -- while (cnt < len) { -- if ((unsigned char)ctmp[cnt] > 127) { -+ cnt = 0; -+ while (!doEnc && cnt < max) { -+ if ((unsigned char)dataBytes[cnt] > 127) - doEnc = YES; -- break; -- } -- cnt++; -+ else -+ cnt++; - } - if (doEnc) { -- unsigned char iso[] = "=?iso-8859-15?q?"; -- unsigned isoLen = 16; -- unsigned char isoEnd[] = "?="; -- unsigned isoEndLen = 2; -- unsigned desLen; -- unsigned char *des; -- -- if (ctmp) free(ctmp); -- { -- NSData *data; -- --#if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY -- data = [value dataUsingEncoding:NSISOLatin1StringEncoding]; --#else -- data = [value dataUsingEncoding:NSISOLatin9StringEncoding]; --#endif -- -- len = [data length]; -- ctmp = malloc(len + 10); -- [data getBytes:ctmp]; ctmp[len] = '\0'; -- } -- -- desLen = len * 3 + 20; -- des = calloc(desLen + 10, sizeof(char)); -- -- memcpy(des, ctmp, cnt); -- memcpy(des + cnt, iso, isoLen); -- desLen = -- NGEncodeQuotedPrintableMime(ctmp + cnt, len - cnt, -- des + cnt + isoLen, -- desLen - cnt - isoLen); -- if ((int)desLen != -1) { -- memcpy(des + cnt + isoLen + desLen, isoEnd, isoEndLen); -- [data appendBytes:des length:(cnt + isoLen + desLen + isoEndLen)]; -- } -- else { -- NSLog(@"WARNING: An error occour during quoted-printable decoding"); -- } -- if (des) free(des); -+ [data appendBytes:"=?utf-8?q?" length:10]; -+ [data appendData: [valueData dataByEncodingQuotedPrintable]]; -+ [data appendBytes:"?=" length:2]; - } - else { -- [data appendBytes:ctmp length:len]; -+ [data appendData: valueData]; - } -- free(ctmp); - } - [data appendBytes:"\"" length:1]; - } -Index: sope-mime/NGMime/NGMimePartGenerator.m -=================================================================== ---- sope-mime/NGMime/NGMimePartGenerator.m (revision 1664) -+++ sope-mime/NGMime/NGMimePartGenerator.m (working copy) -@@ -155,8 +155,9 @@ - BOOL isMultiValue, isFirst; - - /* get field name and strip leading spaces */ -- fcname = (const unsigned char *)[_field cString]; -- for (len = [_field cStringLength]; len > 0; fcname++, len--) { -+ fcname = (const unsigned char *)[_field cStringUsingEncoding:NSISOLatin1StringEncoding]; -+ for (len = [_field lengthOfBytesUsingEncoding:NSISOLatin1StringEncoding]; -+ len > 0; fcname++, len--) { - if (*fcname != ' ') - break; - } -@@ -328,7 +329,7 @@ - if ([body isKindOfClass:[NSData class]]) - data = body; - else if ([body isKindOfClass:[NSString class]]) -- data = [body dataUsingEncoding:[NSString defaultCStringEncoding]]; -+ data = [body dataUsingEncoding: NSISOLatin1StringEncoding]; - else - data = nil; - -Index: sope-mime/NGMime/NGMimeBodyParser.m -=================================================================== ---- sope-mime/NGMime/NGMimeBodyParser.m (revision 1664) -+++ sope-mime/NGMime/NGMimeBodyParser.m (working copy) -@@ -67,7 +67,10 @@ - if (_data == nil) return nil; - - ctype = [_part contentType]; -- -+ if (!ctype -+ && [_d respondsToSelector: @selector(parser:contentTypeOfPart:)]) -+ ctype = [_d parser: self contentTypeOfPart: _part]; -+ - if (![ctype isKindOfClass:[NGMimeType class]]) - ctype = [NGMimeType mimeType:[ctype stringValue]]; - -@@ -88,10 +91,20 @@ - NSStringEncoding encoding; - - encoding = [NGMimeType stringEncodingForCharset:charset]; -- -+ -+ // If we nave no encoding here, let's not simply return nil. -+ // We SHOULD try at least UTF-8 and after, Latin1. -+ if (!encoding) -+ encoding = NSUTF8StringEncoding; -+ - body = [[[NSString alloc] -- initWithData:_data -+ initWithData:_data - encoding:encoding] autorelease]; -+ -+ if (!body) -+ body = [[[NSString alloc] initWithData:_data -+ encoding:NSISOLatin1StringEncoding] -+ autorelease]; - } - return body; - } -Index: sope-mime/NGMime/NGMimePartParser.h -=================================================================== ---- sope-mime/NGMime/NGMimePartParser.h (revision 1664) -+++ sope-mime/NGMime/NGMimePartParser.h (working copy) -@@ -117,6 +117,7 @@ - BOOL parserParseRawBodyDataOfPart:1; - BOOL parserBodyParserForPart:1; - BOOL parserDecodeBodyOfPart:1; -+ BOOL parserContentTypeOfPart:1; - } delegateRespondsTo; - - -@@ -275,6 +276,9 @@ - - (id)parser:(NGMimePartParser *)_parser - bodyParserForPart:(id)_part; - -+- (NGMimeType *)parser:(id)_parser -+ contentTypeOfPart:(id)_part; -+ - @end /* NSObject(NGMimePartParserDelegate) */ - - @interface NSObject(NGMimePartParser) -Index: sope-mime/NGMime/NGMimePartParser.m -=================================================================== ---- sope-mime/NGMime/NGMimePartParser.m (revision 1664) -+++ sope-mime/NGMime/NGMimePartParser.m (working copy) -@@ -227,7 +227,7 @@ - } - - + (NSStringEncoding)defaultHeaderFieldEncoding { -- return NSISOLatin1StringEncoding; -+ return NSUTF8StringEncoding; - } - - - (id)valueOfHeaderField:(NSString *)_name data:(id)_data { -@@ -1091,7 +1091,10 @@ - id bodyParser = nil; - - ctype = [_p contentType]; -- -+ if (!ctype -+ && self->delegateRespondsTo.parserContentTypeOfPart) -+ ctype = [self->delegate parser: self contentTypeOfPart: _p]; -+ - contentType = ([ctype isKindOfClass:[NGMimeType class]]) - ? ctype - : [NGMimeType mimeType:[ctype stringValue]]; -Index: sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m -=================================================================== ---- sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m (revision 1664) -+++ sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m (working copy) -@@ -105,10 +105,10 @@ - } - - tmp = [obj displayName]; -- bufLen = [tmp cStringLength]; -+ bufLen = [tmp lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; - -- buffer = calloc(bufLen + 10, sizeof(char)); -- [tmp getCString:buffer]; -+ buffer = calloc(bufLen, sizeof(char)); -+ [tmp getCString: buffer maxLength: bufLen encoding: NSUTF8StringEncoding]; - - cnt = 0; - doEnc = NO; -@@ -117,11 +117,11 @@ - /* must encode chars outside ASCII 33..60, 62..126 ranges [RFC 2045, Sect. 6.7] - * RFC 2047, Sect. 4.2 also requires chars 63 and 95 to be encoded - * For spaces, quotation is fine */ -- if ((unsigned char)buffer[cnt] < 32 || -- (unsigned char)buffer[cnt] == 61 || -- (unsigned char)buffer[cnt] == 63 || -- (unsigned char)buffer[cnt] == 95 || -- (unsigned char)buffer[cnt] > 126) { -+ if ((unichar)buffer[cnt] < 32 || -+ (unichar)buffer[cnt] == 61 || -+ (unichar)buffer[cnt] == 63 || -+ (unichar)buffer[cnt] == 95 || -+ (unichar)buffer[cnt] > 126) { - doEnc = YES; - break; - } -@@ -130,8 +130,13 @@ - - if (doEnc) { - /* FIXME - better use UTF8 encoding! */ -+#if NeXT_Foundation_LIBRARY - unsigned char iso[] = "=?iso-8859-15?q?"; - unsigned isoLen = 16; -+#else -+ unsigned char iso[] = "=?utf-8?q?"; -+ unsigned isoLen = 10; -+#endif - unsigned char isoEnd[] = "?="; - unsigned isoEndLen = 2; - unsigned desLen; -@@ -141,10 +146,10 @@ - { - NSData *data; - --#if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY -+#if NeXT_Foundation_LIBRARY - data = [tmp dataUsingEncoding:NSISOLatin1StringEncoding]; - #else -- data = [tmp dataUsingEncoding:NSISOLatin9StringEncoding]; -+ data = [tmp dataUsingEncoding:NSUTF8StringEncoding]; - #endif - - bufLen = [data length]; -@@ -162,8 +167,9 @@ - des + isoLen, desLen - isoLen); - if ((int)desLen != -1) { - memcpy(des + isoLen + desLen, isoEnd, isoEndLen); -- tmp = [NSString stringWithCString:(char *)des -- length:(isoLen + desLen + isoEndLen)]; -+ tmp = [[NSString alloc] initWithData: [NSData dataWithBytes:(char *)des length:(isoLen + desLen + isoEndLen)] -+ encoding: NSISOLatin1StringEncoding]; -+ [tmp autorelease]; - } - else { - [self warnWithFormat: -@@ -190,11 +196,7 @@ - } - } - --#if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY - data = [result dataUsingEncoding:NSISOLatin1StringEncoding]; --#else -- data = [result dataUsingEncoding:NSISOLatin9StringEncoding]; --#endif - [result release]; - - return data; -Index: sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m -=================================================================== ---- sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m (revision 1664) -+++ sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m (working copy) -@@ -49,80 +49,70 @@ - - // TODO: move the stuff below to some NSString or NSData category? - -- data = [NSMutableData dataWithCapacity:64]; -+ data = [NSMutableData dataWithCapacity: 64]; - tmp = [field type]; - [data appendBytes:[tmp cString] length:[tmp length]]; - tmp = [field filename]; - if (tmp != nil) { - [data appendBytes:"; " length:2]; - [data appendBytes:"filename=\"" length:10]; -- { -- unsigned char *ctmp; -- int cnt, len; -- BOOL doEnc; -- -- // TODO: unicode? -- len = [tmp cStringLength]; -- ctmp = malloc(len + 3); -- [tmp getCString:(char *)ctmp]; ctmp[len] = '\0'; -- cnt = 0; -- doEnc = NO; -- while (cnt < len) { -- if ((unsigned char)ctmp[cnt] > 127) { -- doEnc = YES; -- break; -- } -- cnt++; -+ -+ NSData *d; -+ unsigned char* bytes; -+ unsigned length; -+ int cnt; -+ BOOL doEnc; -+ -+ //d = [tmp dataUsingEncoding: NSUTF8StringEncoding]; -+ //bytes = [d bytes]; -+ //length = [d length]; -+ bytes = [tmp cStringUsingEncoding: NSUTF8StringEncoding]; -+ length = strlen(bytes); -+ -+ cnt = 0; -+ doEnc = NO; -+ while (cnt < length) { -+ if ((unsigned char)bytes[cnt] > 127) { -+ doEnc = YES; -+ break; - } -- if (doEnc) { -- char iso[] = "=?iso-8859-15?q?"; -- unsigned isoLen = 16; -- char isoEnd[] = "?="; -- unsigned isoEndLen = 2; -- unsigned desLen; -- char *des; -- -- if (ctmp) free(ctmp); -- { -- NSData *data; -+ cnt++; -+ } - --#if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY -- data = [tmp dataUsingEncoding:NSISOLatin1StringEncoding]; --#else -- data = [tmp dataUsingEncoding:NSISOLatin9StringEncoding]; --#endif -- -- len = [data length]; -- ctmp = malloc(len+1); -- [data getBytes:ctmp]; ctmp[len] = '\0'; -- } -- -- desLen = len * 3 + 20; -- des = calloc(desLen + 10, sizeof(char)); -- -- memcpy(des, ctmp, cnt); -- memcpy(des + cnt, iso, isoLen); -- desLen = -- NGEncodeQuotedPrintableMime((unsigned char *)ctmp + cnt, len - cnt, -- (unsigned char *)des + cnt + isoLen, -- desLen - cnt - isoLen); -- if ((int)desLen != -1) { -- memcpy(des + cnt + isoLen + desLen, isoEnd, isoEndLen); -- [data appendBytes:des length:(cnt + isoLen + desLen + isoEndLen)]; -- } -- else { -+ if (doEnc) -+ { -+ char iso[] = "=?utf-8?q?"; -+ unsigned isoLen = 10; -+ char isoEnd[] = "?="; -+ unsigned isoEndLen = 2; -+ int desLen; -+ char *des; -+ -+ desLen = length * 3 + 20; -+ -+ des = calloc(desLen + 2, sizeof(char)); -+ -+ memcpy(des, iso, isoLen); -+ desLen = NGEncodeQuotedPrintableMime((unsigned char *)bytes, length, -+ (unsigned char *)(des + isoLen), -+ desLen - isoLen); -+ if (desLen != -1) { -+ memcpy(des + isoLen + desLen, isoEnd, isoEndLen); -+ [data appendBytes:des length:(isoLen + desLen + isoEndLen)]; -+ } -+ else { - [self logWithFormat:@"WARNING(%s:%i): An error occour during " - @"quoted-printable decoding", - __PRETTY_FUNCTION__, __LINE__]; -- } -- if (des) free(des); -+ if (des != NULL) free(des); -+ } - } -- else { -- [data appendBytes:ctmp length:len]; -+ else -+ { -+ [data appendBytes:[tmp cString] length:[tmp length]]; - } -- } -- // [data appendBytes:[tmp cString] length:[tmp length]]; -- [data appendBytes:"\"" length:1]; -+ -+ [data appendBytes:"\"" length:1]; - } - return data; - } -Index: sope-core/NGExtensions/NGExtensions/NSString+Ext.h -=================================================================== ---- sope-core/NGExtensions/NGExtensions/NSString+Ext.h (revision 1664) -+++ sope-core/NGExtensions/NGExtensions/NSString+Ext.h (working copy) -@@ -30,6 +30,7 @@ - - @interface NSString(GSAdditions) - -+#if !GNUSTEP - - (NSString *)stringWithoutPrefix:(NSString *)_prefix; - - (NSString *)stringWithoutSuffix:(NSString *)_suffix; - -@@ -39,6 +40,7 @@ - - (NSString *)stringByTrimmingLeadSpaces; - - (NSString *)stringByTrimmingTailSpaces; - - (NSString *)stringByTrimmingSpaces; -+#endif /* !GNUSTEP */ - - /* the following are not available in gstep-base 1.6 ? */ - - (NSString *)stringByTrimmingLeadWhiteSpaces; -@@ -47,6 +49,8 @@ - - @end /* NSString(GSAdditions) */ - -+#if !GNUSTEP -+ - @interface NSMutableString(GNUstepCompatibility) - - - (void)trimLeadSpaces; -@@ -55,6 +59,8 @@ - - @end /* NSMutableString(GNUstepCompatibility) */ - -+#endif /* !GNUSTEP */ -+ - #endif - - /* specific to libFoundation */ -Index: sope-core/NGExtensions/FdExt.subproj/NSString+Ext.m -=================================================================== ---- sope-core/NGExtensions/FdExt.subproj/NSString+Ext.m (revision 1664) -+++ sope-core/NGExtensions/FdExt.subproj/NSString+Ext.m (working copy) -@@ -39,18 +39,6 @@ - : (NSString *)[[self copy] autorelease]; - } - --- (NSString *)stringByReplacingString:(NSString *)_orignal -- withString:(NSString *)_replacement --{ -- /* very slow solution .. */ -- -- if ([self rangeOfString:_orignal].length == 0) -- return [[self copy] autorelease]; -- -- return [[self componentsSeparatedByString:_orignal] -- componentsJoinedByString:_replacement]; --} -- - - (NSString *)stringByTrimmingLeadWhiteSpaces - { - // should check 'whitespaceAndNewlineCharacterSet' .. -@@ -96,6 +84,25 @@ - return [[self copy] autorelease]; - } - -+- (NSString *)stringByTrimmingWhiteSpaces -+{ -+ return [[self stringByTrimmingTailWhiteSpaces] -+ stringByTrimmingLeadWhiteSpaces]; -+} -+ -+#ifndef GNUSTEP -+- (NSString *)stringByReplacingString:(NSString *)_orignal -+ withString:(NSString *)_replacement -+{ -+ /* very slow solution .. */ -+ -+ if ([self rangeOfString:_orignal].length == 0) -+ return [[self copy] autorelease]; -+ -+ return [[self componentsSeparatedByString:_orignal] -+ componentsJoinedByString:_replacement]; -+} -+ - - (NSString *)stringByTrimmingLeadSpaces - { - unsigned len; -@@ -117,6 +124,7 @@ - else - return [[self copy] autorelease]; - } -+ - - (NSString *)stringByTrimmingTailSpaces - { - unsigned len; -@@ -139,19 +147,17 @@ - return [[self copy] autorelease]; - } - --- (NSString *)stringByTrimmingWhiteSpaces --{ -- return [[self stringByTrimmingTailWhiteSpaces] -- stringByTrimmingLeadWhiteSpaces]; --} - - (NSString *)stringByTrimmingSpaces - { - return [[self stringByTrimmingTailSpaces] - stringByTrimmingLeadSpaces]; - } -+#endif - - @end /* NSString(GSAdditions) */ - -+#if !GNUSTEP -+ - @implementation NSMutableString(GNUstepCompatibility) - - - (void)trimLeadSpaces -@@ -169,6 +175,8 @@ - - @end /* NSMutableString(GNUstepCompatibility) */ - -+#endif /* !GNUSTEP */ -+ - @implementation NSString(lfNSURLUtilities) - - - (BOOL)isAbsoluteURL -Index: sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m -=================================================================== ---- sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m (revision 1664) -+++ sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m (working copy) -@@ -140,8 +140,12 @@ - - - #ifdef __linux__ -+#if __BYTE_ORDER == __LITTLE_ENDIAN - static NSString *unicharEncoding = @"UCS-2LE"; - #else -+static NSString *unicharEncoding = @"UCS-2BE"; -+#endif /* __BYTE_ORDER */ -+#else - static NSString *unicharEncoding = @"UCS-2-INTERNAL"; - #endif - static int IconvLogEnabled = -1; -@@ -149,21 +153,12 @@ - static void checkDefaults(void) { - NSUserDefaults *ud; - -- if (IconvLogEnabled != -1) -- return; -- ud = [NSUserDefaults standardUserDefaults]; -- IconvLogEnabled = [ud boolForKey:@"IconvLogEnabled"]?1:0; -+ if (IconvLogEnabled == -1) { -+ ud = [NSUserDefaults standardUserDefaults]; -+ IconvLogEnabled = [ud boolForKey:@"IconvLogEnabled"]?1:0; - --#ifdef __linux__ -- if (NSHostByteOrder() == NS_BigEndian) { -- NSLog(@"Note: using UCS-2 big endian on Linux."); -- unicharEncoding = @"UCS-2BE"; -+ NSLog(@"Note: using '%@' on Linux.", unicharEncoding); - } -- else { -- NSLog(@"Note: using UCS-2 little endian on Linux."); -- unicharEncoding = @"UCS-2LE"; -- } --#endif - } - - static char *iconv_wrapper(id self, char *_src, unsigned _srcLen, -Index: sope-core/NGExtensions/EOExt.subproj/EOGlobalID+Ext.m -=================================================================== ---- sope-core/NGExtensions/EOExt.subproj/EOGlobalID+Ext.m (revision 1664) -+++ sope-core/NGExtensions/EOExt.subproj/EOGlobalID+Ext.m (working copy) -@@ -19,6 +19,7 @@ - 02111-1307, USA. - */ - -+#import - #import - #import - -Index: sope-core/NGExtensions/ChangeLog -=================================================================== ---- sope-core/NGExtensions/ChangeLog (revision 1664) -+++ sope-core/NGExtensions/ChangeLog (working copy) -@@ -1,3 +1,16 @@ -+2010-07-16 Wolfgang Sourdeau -+ -+ * NGBase64Coding.m (-dataByDecodingBase64) -+ (-stringByDecodingBase64, -stringByEncodingBase64): make use of -+ -[NSString lengthOfBytesUsingEncoding: NSISOLatin1StringEncoding] -+ rather than -[... cStringLength] to avoid a crash within GNUstep. -+ The latter is deprecated anyway... -+ -+2010-01-30 Wolfgang Sourdeau -+ -+ * NGRuleEngine.subproj/NGRuleModel.m (-candidateRulesForKey:): -+ return an autoreleased array to avoid leaks. -+ - 2009-03-24 Wolfgang Sourdeau - - * NGQuotedPrintableCoding.m: encode '_' as '=5F', so that it is not -Index: sope-core/NGExtensions/NGBase64Coding.m -=================================================================== ---- sope-core/NGExtensions/NGBase64Coding.m (revision 1664) -+++ sope-core/NGExtensions/NGBase64Coding.m (working copy) -@@ -53,7 +53,7 @@ - size_t destLength = -1; - char *dest, *src; - -- if ((len = [self cStringLength]) == 0) -+ if ((len = [self lengthOfBytesUsingEncoding: NSISOLatin1StringEncoding]) == 0) - return @""; - - destSize = (len + 2) / 3 * 4; // 3:4 conversion ratio -@@ -91,7 +91,7 @@ - - if (StringClass == Nil) StringClass = [NSString class]; - -- if ((len = [self cStringLength]) == 0) -+ if ((len = [self lengthOfBytesUsingEncoding: NSISOLatin1StringEncoding]) == 0) - return @""; - - destSize = (len / 4 + 1) * 3 + 1; -@@ -135,9 +135,9 @@ - - if (StringClass == Nil) StringClass = [NSString class]; - -- if ((len = [self cStringLength]) == 0) -+ if ((len = [self lengthOfBytesUsingEncoding: NSISOLatin1StringEncoding]) == 0) - return [NSData data]; -- -+ - destSize = (len / 4 + 1) * 3 + 1; - dest = malloc(destSize + 1); - -Index: sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleModel.m -=================================================================== ---- sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleModel.m (revision 1664) -+++ sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleModel.m (working copy) -@@ -180,6 +180,7 @@ - - /* sort candidates */ - [candidates sortUsingFunction:(void *)candidateSort context:self]; -+ [candidates autorelease]; - - return candidates; - } -Index: sope-core/NGStreams/NGStream+serialization.m -=================================================================== ---- sope-core/NGStreams/NGStream+serialization.m (revision 1664) -+++ sope-core/NGStreams/NGStream+serialization.m (working copy) -@@ -282,10 +282,10 @@ - else { - char *result = NULL; - --#if NeXT_Foundation_LIBRARY -+#if LIB_FOUNDATION_LIBRARY -+ result = NSZoneMallocAtomic(NULL, len + 1); -+#else - result = NSZoneMalloc(NULL, len + 1); --#else -- result = NSZoneMallocAtomic(NULL, len + 1); - #endif - result[len] = '\0'; - -Index: sope-core/NGStreams/NGStreams/NGDatagramSocket.h -=================================================================== ---- sope-core/NGStreams/NGStreams/NGDatagramSocket.h (revision 1664) -+++ sope-core/NGStreams/NGStreams/NGDatagramSocket.h (working copy) -@@ -69,7 +69,7 @@ - + (id)socketBoundToAddress:(id)_address; - - #if !defined(WIN32) --+ (BOOL)socketPair:(id[2])_pair inDomain:(id)_domain; -++ (BOOL)socketPair:(id[2])_pair; - #endif - - // accessors -Index: sope-core/NGStreams/NGStreams/NGActiveSocket.h -=================================================================== ---- sope-core/NGStreams/NGStreams/NGActiveSocket.h (revision 1664) -+++ sope-core/NGStreams/NGStreams/NGActiveSocket.h (working copy) -@@ -60,7 +60,7 @@ - - (id)initWithDomain:(id)_domain; // designated initializer - - #if !defined(WIN32) --+ (BOOL)socketPair:(id[2])_pair inDomain:(id)_domain; -++ (BOOL)socketPair:(id[2])_pair; - #endif - - // ******************** operations ******************** -Index: sope-core/NGStreams/NGGZipStream.m -=================================================================== ---- sope-core/NGStreams/NGGZipStream.m (revision 1664) -+++ sope-core/NGStreams/NGGZipStream.m (working copy) -@@ -52,7 +52,7 @@ - @"invalid compression level %i (0-9)", _level); - - self->outBufLen = 2048; --#if GNU_RUNTIME -+#if LIB_FOUNDATION_LIBRARY - self->outBuf = NSZoneMallocAtomic([self zone], self->outBufLen); - self->outp = NSZoneMallocAtomic([self zone], sizeof(z_stream)); - #else -Index: sope-core/NGStreams/NGDatagramSocket.m -=================================================================== ---- sope-core/NGStreams/NGDatagramSocket.m (revision 1664) -+++ sope-core/NGStreams/NGDatagramSocket.m (working copy) -@@ -25,6 +25,8 @@ - #endif - - #include -+#include -+#include - #include "NGDatagramSocket.h" - #include "NGDatagramPacket.h" - #include "NGSocketExceptions.h" -@@ -55,19 +57,21 @@ - - #if !defined(WIN32) || defined(__CYGWIN32__) - --+ (BOOL)socketPair:(id[2])_pair inDomain:(id)_domain { -++ (BOOL)socketPair:(id[2])_pair { - int fds[2]; -+ NGLocalSocketDomain *domain; - - _pair[0] = nil; - _pair[1] = nil; - -- if (socketpair([_domain socketDomain], SOCK_DGRAM, [_domain protocol], -+ domain = [NGLocalSocketDomain domain]; -+ if (socketpair([domain socketDomain], SOCK_DGRAM, [domain protocol], - fds) == 0) { - NGDatagramSocket *s1 = nil; - NGDatagramSocket *s2 = nil; - -- s1 = [[self alloc] _initWithDomain:_domain descriptor:fds[0]]; -- s2 = [[self alloc] _initWithDomain:_domain descriptor:fds[1]]; -+ s1 = [[self alloc] _initWithDomain:domain descriptor:fds[0]]; -+ s2 = [[self alloc] _initWithDomain:domain descriptor:fds[1]]; - s1 = AUTORELEASE(s1); - s2 = AUTORELEASE(s2); - -@@ -112,7 +116,7 @@ - break; - } - [[[NGCouldNotCreateSocketException alloc] -- initWithReason:reason domain:_domain] raise]; -+ initWithReason:reason domain:domain] raise]; - return NO; - } - } -Index: sope-core/NGStreams/GNUmakefile.preamble -=================================================================== ---- sope-core/NGStreams/GNUmakefile.preamble (revision 1664) -+++ sope-core/NGStreams/GNUmakefile.preamble (working copy) -@@ -1,6 +1,7 @@ - # compilation settings - --MACHCPU = $(shell echo $$MACHTYPE | cut -f 1 -d '-') -+# MACHCPU = $(shell echo $$MACHTYPE | cut -f 1 -d '-') -+MACHCPU = $(shell uname -m) - - libNGStreams_INCLUDE_DIRS += \ - -I$(GNUSTEP_TARGET_CPU)/$(GNUSTEP_TARGET_OS) \ -Index: sope-core/NGStreams/NGCTextStream.m -=================================================================== ---- sope-core/NGStreams/NGCTextStream.m (revision 1664) -+++ sope-core/NGStreams/NGCTextStream.m (working copy) -@@ -296,7 +296,7 @@ - unsigned char *str, *buf; - unsigned toGo; - --#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 -+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 || (GNUSTEP && OS_API_VERSION(100400,GS_API_LATEST)) - if ((toGo = [_string maximumLengthOfBytesUsingEncoding:self->encoding]) == 0) - return YES; - -Index: sope-core/NGStreams/ChangeLog -=================================================================== ---- sope-core/NGStreams/ChangeLog (revision 1664) -+++ sope-core/NGStreams/ChangeLog (working copy) -@@ -1,3 +1,27 @@ -+2010-01-28 Wolfgang Sourdeau -+ -+ * NGActiveSocket.m (-safeReadBytes:count:): explicitly make use of -+ [NGEndOfStreamException alloc] when allocating localException, -+ since the init method is only present in that class and this may -+ cause a crash on rare occasions. -+ -+2010-01-25 Wolfgang Sourdeau -+ -+ * NGCTextStream.m (-writeString:): use -+ getCString:maxLength:encoding: on GNUstep too to avoid a possible -+ segfault in GNUstep's handling of cStringLength. -+ -+2009-11-11 Wolfgang Sourdeau -+ -+ * NGActiveSocket.m (+socketPair): removed the domain: parameter as -+ only AF_LOCAL is permitted. Assign a default instance of -+ NGLocalSocketAddress to the sockets to "declare" the sockets as -+ connected. -+ -+ * NGActiveSocket.m (-setSendTimeout, -setReceiveTimeout): make use -+ of those methods to actually configure the timeouts on the socket -+ objects (via setsockopt and SO_RCVTIMEO and SO_SNDTIMEO). -+ - 2009-03-24 Wolfgang Sourdeau - - * GNUmakefile.preamble: add machine-type to include path (eg i386) (v4.7.57) -Index: sope-core/NGStreams/NGCharBuffer.m -=================================================================== ---- sope-core/NGStreams/NGCharBuffer.m (revision 1664) -+++ sope-core/NGStreams/NGCharBuffer.m (working copy) -@@ -46,11 +46,11 @@ - // Find first power of 2 >= to requested size - for (size = 2; size < _la; size *=2); - --#if NeXT_Foundation_LIBRARY -- self->la = NSZoneMalloc([self zone], sizeof(LA_NGCharBuffer) * size); --#else -+#if LIB_FOUNDATION_LIBRARY - self->la = NSZoneMallocAtomic([self zone], - sizeof(LA_NGCharBuffer) * size); -+#else -+ self->la = NSZoneMalloc([self zone], sizeof(LA_NGCharBuffer) * size); - #endif - memset(self->la, 0, sizeof(LA_NGCharBuffer) * size); - -Index: sope-core/NGStreams/NGActiveSocket.m -=================================================================== ---- sope-core/NGStreams/NGActiveSocket.m (revision 1664) -+++ sope-core/NGStreams/NGActiveSocket.m (working copy) -@@ -62,6 +62,8 @@ - #include "common.h" - - #include -+#include -+#include - #include "NGActiveSocket.h" - #include "NGSocketExceptions.h" - #include "NGSocket+private.h" -@@ -83,29 +85,35 @@ - - #if !defined(WIN32) || defined(__CYGWIN32__) - --+ (BOOL)socketPair:(id[2])_pair inDomain:(id)_domain { -++ (BOOL)socketPair:(id[2])_pair { - int fds[2]; -+ NGLocalSocketDomain *domain; - - _pair[0] = nil; - _pair[1] = nil; - -- if (socketpair([_domain socketDomain], SOCK_STREAM, [_domain protocol], -+ domain = [NGLocalSocketDomain domain]; -+ if (socketpair([domain socketDomain], SOCK_STREAM, [domain protocol], - fds) == 0) { - NGActiveSocket *s1 = nil; - NGActiveSocket *s2 = nil; -+ NGLocalSocketAddress *address; - -- s1 = [[self alloc] _initWithDomain:_domain descriptor:fds[0]]; -- s2 = [[self alloc] _initWithDomain:_domain descriptor:fds[1]]; -+ s1 = [[self alloc] _initWithDomain:domain descriptor:fds[0]]; -+ s2 = [[self alloc] _initWithDomain:domain descriptor:fds[1]]; - s1 = [s1 autorelease]; - s2 = [s2 autorelease]; - -+ address = [NGLocalSocketAddress address]; - if ((s1 != nil) && (s2 != nil)) { - s1->mode = NGStreamMode_readWrite; - s1->receiveTimeout = 0.0; - s1->sendTimeout = 0.0; -+ ASSIGN(s1->remoteAddress, address); - s2->mode = NGStreamMode_readWrite; - s2->receiveTimeout = 0.0; - s2->sendTimeout = 0.0; -+ ASSIGN(s2->remoteAddress, address); - - _pair[0] = s1; - _pair[1] = s2; -@@ -152,7 +160,7 @@ - break; - } - [[[NGCouldNotCreateSocketException alloc] -- initWithReason:reason domain:_domain] raise]; -+ initWithReason:reason domain:domain] raise]; - return NO; - } - } -@@ -507,6 +515,13 @@ - } - - - (void)setSendTimeout:(NSTimeInterval)_timeout { -+ struct timeval tv; -+ -+ if ([self isConnected]) { -+ tv.tv_sec = (int) _timeout; -+ tv.tv_usec = 0; -+ setsockopt(self->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof (struct timeval)); -+ } - self->sendTimeout = _timeout; - } - - (NSTimeInterval)sendTimeout { -@@ -514,6 +529,13 @@ - } - - - (void)setReceiveTimeout:(NSTimeInterval)_timeout { -+ struct timeval tv; -+ -+ if ([self isConnected]) { -+ tv.tv_sec = (int) _timeout; -+ tv.tv_usec = 0; -+ setsockopt(self->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof (struct timeval)); -+ } - self->receiveTimeout = _timeout; - } - - (NSTimeInterval)receiveTimeout { -@@ -965,12 +987,12 @@ - readBytes(self, @selector(readBytes:count:), pos, toBeRead); - - if (readResult == NGStreamError) { -- NSException *localException = [self lastException]; -+ NSException *localException; - NSData *data; - - data = [NSData dataWithBytes:_buf length:(_len - toBeRead)]; - -- localException = [[[localException class] alloc] -+ localException = [[NGEndOfStreamException alloc] - initWithStream:self - readCount:(_len - toBeRead) - safeCount:_len -Index: sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.h -=================================================================== ---- sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.h (revision 1664) -+++ sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.h (working copy) -@@ -19,6 +19,8 @@ - 02111-1307, USA. - */ - -+#include -+ - #include - #include - #include -@@ -34,7 +36,7 @@ - - @interface libxmlHTMLSAXDriver : NSObject < SaxXMLReader > - { -- id contentHandler; -+ NSObject *contentHandler; - id dtdHandler; - id errorHandler; - id entityResolver; -Index: sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.m -=================================================================== ---- sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.m (revision 1664) -+++ sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.m (working copy) -@@ -200,10 +200,10 @@ - return self->entityResolver; - } - --- (void)setContentHandler:(id)_handler { -+- (void)setContentHandler:(NSObject *)_handler { - ASSIGN(self->contentHandler, _handler); - } --- (id)contentHandler { -+- (NSObject *)contentHandler { - return self->contentHandler; - } - -Index: sope-xml/SaxObjC/XMLNamespaces.h -=================================================================== ---- sope-xml/SaxObjC/XMLNamespaces.h (revision 1664) -+++ sope-xml/SaxObjC/XMLNamespaces.h (working copy) -@@ -292,6 +292,9 @@ - #ifndef XMLNS_AppleCalServer - # define XMLNS_AppleCalServer @"http://apple.com/ns/calendarserver/" - #endif -+#ifndef XMLNS_CalendarServerOrg -+# define XMLNS_CalendarServerOrg @"http://calendarserver.org/ns/" -+#endif - #ifndef XMLNS_AppleCalApp - # define XMLNS_AppleCalApp @"com.apple.ical:" - #endif -Index: sope-appserver/WEExtensions/ChangeLog -=================================================================== ---- sope-appserver/WEExtensions/ChangeLog (revision 1664) -+++ sope-appserver/WEExtensions/ChangeLog (working copy) -@@ -1,3 +1,11 @@ -+2010-01-29 Wolfgang Sourdeau -+ -+ * WEResourceManager.m -+ (_urlForResourceNamed:inFramework:language:applicationName:): -+ append the language with stringByAppendingPathComponent: rather -+ than ...ByAppendingString. Also, we want to return an autoreleased -+ value to avoid leaks. -+ - 2008-02-21 Helge Hess - - * WEMonthOverview.m: fixed bug, last day of appointments got lost ... -Index: sope-appserver/WEExtensions/WEResourceManager.m -=================================================================== ---- sope-appserver/WEExtensions/WEResourceManager.m (revision 1664) -+++ sope-appserver/WEExtensions/WEResourceManager.m (working copy) -@@ -525,7 +525,7 @@ - - /* check language */ - if (_lang) { -- path = [path stringByAppendingString:_lang]; -+ path = [path stringByAppendingPathComponent:_lang]; - path = [path stringByAppendingPathExtension:@"lproj"]; - } - -@@ -568,7 +568,7 @@ - - /* check language */ - if (_lang) { -- basepath = [path stringByAppendingString:_lang]; -+ basepath = [path stringByAppendingPathComponent:_lang]; - basepath = [basepath stringByAppendingPathExtension:@"lproj"]; - } - else -@@ -613,6 +613,8 @@ - - done: - [self cacheValue:url inCache:self->keyToURL]; -+ [url autorelease]; -+ - return url; - } - -Index: sope-appserver/mod_ngobjweb/GNUmakefile -=================================================================== ---- sope-appserver/mod_ngobjweb/GNUmakefile (revision 1664) -+++ sope-appserver/mod_ngobjweb/GNUmakefile (working copy) -@@ -82,7 +82,7 @@ - - CFLAGS = -Wall -I. -fPIC \ - $(APXS_CFLAGS) $(APR_CFLAGS) \ -- $(APXS_INCLUDE_DIRS) $(APR_INCLUDE_DIRS) -+ $(APXS_INCLUDE_DIRS) $(APR_INCLUDE_DIRS) -O0 -ggdb - - LDFLAGS = $(APXS_LDFLAGS) $(APR_LDFLAGS) -shared -fPIC - LDLIBS = $(APXS_LIBS) $(APR_LIBS) -@@ -111,8 +111,7 @@ - apache-dir : - $(MKDIRS) $(GNUSTEP_INSTALLATION_DIR) - --install :: apache-dir all -- $(INSTALL_PROGRAM) $(product) $(GNUSTEP_INSTALLATION_DIR) -+install :: - - install-usr-libexec :: all - $(INSTALL_PROGRAM) $(product) /usr/libexec/httpd/ -Index: sope-appserver/NGObjWeb/WOWatchDogApplicationMain.m -=================================================================== ---- sope-appserver/NGObjWeb/WOWatchDogApplicationMain.m (revision 1664) -+++ sope-appserver/NGObjWeb/WOWatchDogApplicationMain.m (working copy) -@@ -1,5 +1,6 @@ - /* - Copyright (C) 2000-2005 SKYRIX Software AG -+ Copyright (C) 2009 Inverse inc. - - This file is part of SOPE. - -@@ -19,9 +20,29 @@ - 02111-1307, USA. - */ - --#import --#include -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import - -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+ -+#import "UnixSignalHandler.h" -+ - #if defined(__CYGWIN32__) || defined(__MINGW32__) - - int WOWatchDogApplicationMain -@@ -39,201 +60,876 @@ - #include - #include - --static pid_t child = -1; --static NSString *pidFile = nil; --static time_t lastFailExit = 0; --static unsigned failExitCount = 0; --static BOOL killedChild = NO; -+static NSTimeInterval respawnDelay; /* seconds */ -+static const char *pidFile = NULL; - --static void killChild(void) { -- if (child > 0) { -- int status; -- -- fprintf(stderr, "watchdog[%i]: terminating child %i ..\n", getpid(), child); -- -- if (kill(child, SIGTERM) == 0) { -- waitpid(child, &status, 0); -- killedChild = YES; -- -- fprintf(stderr, " terminated child %i", child); -- -- if (WIFEXITED(status)) -- fprintf(stderr, " exit=%i", WEXITSTATUS(status)); -- if (WIFSIGNALED(status)) -- fprintf(stderr, " signal=%i", WTERMSIG(status)); -- -- fprintf(stderr, ".\n"); -- fflush(stderr); -- -- child = -1; -- return; -+typedef enum { -+ WOChildStatusDown = 0, -+ WOChildStatusSpawning, -+ WOChildStatusReady, -+ WOChildStatusBusy, -+ WOChildStatusExcessive, -+ WOChildStatusTerminating, -+ WOChildStatusMax -+} WOChildStatus; -+ -+@class WOWatchDog; -+ -+@interface WOWatchDogChild : NSObject -+{ -+ int pid; -+ int counter; -+ NGActiveSocket *controlSocket; -+ WOChildStatus status; -+ NSTimer *killTimer; -+ WOWatchDog *watchDog; -+ NSCalendarDate *lastSpawn; -+ BOOL loggedNotRespawn; -+} -+ -+- (void) setWatchDog: (WOWatchDog *) newWatchDog; -+ -+- (void) setPid: (int) newPid; -+- (int) pid; -+ -+- (void) handleProcessStatus: (int) status; -+ -+- (void) setControlSocket: (NGActiveSocket *) newSocket; -+- (NGActiveSocket *) controlSocket; -+ -+- (void) setStatus: (WOChildStatus) newStatus; -+- (WOChildStatus) status; -+ -+- (void) setLastSpawn: (NSCalendarDate *) newLastSpawn; -+- (NSCalendarDate *) lastSpawn; -+- (NSCalendarDate *) nextSpawn; -+- (void) logNotRespawn; -+ -+- (BOOL) readMessage; -+ -+- (void) notify; -+- (void) terminate; -+ -+@end -+ -+@interface WOWatchDog : NSObject -+{ -+ NSString *appName; -+ int argc; -+ const char **argv; -+ -+ NSTimer *loopTimer; -+ BOOL terminate; -+ BOOL willTerminate; -+ NSNumber *terminationSignal; -+ int pendingSIGHUP; -+ -+ NGPassiveSocket *listeningSocket; -+ -+ int numberOfChildren; -+ NSMutableArray *children; -+ NSMutableArray *readyChildren; -+ NSMutableArray *downChildren; -+} -+ -++ (id) sharedWatchDog; -+ -+- (void) declareChildReady: (WOWatchDogChild *) readyChild; -+- (void) declareChildDown: (WOWatchDogChild *) readyChild; -+ -+- (int) run: (NSString *) appName -+ argc: (int) argc -+ argv: (const char **) argv; -+ -+@end -+ -+@implementation WOWatchDogChild -+ -++ (WOWatchDogChild *) watchDogChild -+{ -+ WOWatchDogChild *newChild; -+ -+ newChild = [self new]; -+ [newChild autorelease]; -+ -+ return newChild; -+} -+ -+- (id) init -+{ -+ if ((self = [super init])) -+ { -+ pid = -1; -+ controlSocket = nil; -+ status = WOChildStatusDown; -+ killTimer = nil; -+ counter = 0; -+ lastSpawn = nil; -+ loggedNotRespawn = NO; - } -- else if (kill(child, SIGKILL)) { -- waitpid(child, &status, 0); -- killedChild = YES; -- -- fprintf(stderr, " killed child %i", child); -- -- if (WIFEXITED(status)) -- fprintf(stderr, " exit=%i", WEXITSTATUS(status)); -- if (WIFSIGNALED(status)) -- fprintf(stderr, " signal=%i", WTERMSIG(status)); -- -- fprintf(stderr, ".\n"); -- fflush(stderr); -- -- child = -1; -- return; -+ -+ return self; -+} -+ -+- (void) dealloc -+{ -+ [killTimer invalidate]; -+ [self setControlSocket: nil]; -+ [lastSpawn release]; -+ [super dealloc]; -+} -+ -+- (void) setWatchDog: (WOWatchDog *) newWatchDog -+{ -+ watchDog = newWatchDog; -+} -+ -+- (void) setPid: (int) newPid -+{ -+ pid = newPid; -+} -+ -+- (int) pid -+{ -+ return pid; -+} -+ -+- (void) handleProcessStatus: (int) processStatus -+{ -+ int code; -+ -+ code = WEXITSTATUS (processStatus); -+ if (code == 0) -+ [self logWithFormat: @"child %d exited", pid]; -+ else -+ [self logWithFormat: @"child %d exited with code %i", pid, code]; -+ if (WIFSIGNALED (processStatus)) -+ [self logWithFormat: @" (terminated due to signal %i%@)", -+ WTERMSIG (processStatus), -+ WCOREDUMP (processStatus) ? @", coredump" : @""]; -+ if (WIFSTOPPED (processStatus)) -+ [self logWithFormat: @" (stopped due to signal %i)", -+ WSTOPSIG (processStatus)]; -+ [self setStatus: WOChildStatusDown]; -+ [self setControlSocket: nil]; -+} -+ -+- (void) setControlSocket: (NGActiveSocket *) newSocket -+{ -+ NSRunLoop *runLoop; -+ -+ runLoop = [NSRunLoop currentRunLoop]; -+ if (controlSocket) -+ [runLoop removeEvent: (void *) [controlSocket fileDescriptor] -+ type: ET_RDESC -+ forMode: NSDefaultRunLoopMode -+ all: YES]; -+ [controlSocket close]; -+ ASSIGN (controlSocket, newSocket); -+ if (controlSocket) -+ [runLoop addEvent: (void *) [controlSocket fileDescriptor] -+ type: ET_RDESC -+ watcher: self -+ forMode: NSDefaultRunLoopMode]; -+} -+ -+- (NGActiveSocket *) controlSocket -+{ -+ return controlSocket; -+} -+ -+- (void) setStatus: (WOChildStatus) newStatus -+{ -+ status = newStatus; -+} -+ -+- (WOChildStatus) status -+{ -+ return status; -+} -+ -+- (void) setLastSpawn: (NSCalendarDate *) newLastSpawn -+{ -+ ASSIGN (lastSpawn, newLastSpawn); -+ loggedNotRespawn = NO; -+} -+ -+- (NSCalendarDate *) lastSpawn -+{ -+ return lastSpawn; -+} -+ -+- (NSCalendarDate *) nextSpawn -+{ -+ return [lastSpawn addYear: 0 month: 0 day: 0 -+ hour: 0 minute: 0 -+ second: respawnDelay]; -+} -+ -+- (void) logNotRespawn -+{ -+ if (!loggedNotRespawn) -+ { -+ [self logWithFormat: -+ @"avoiding to respawn child before %@", [self nextSpawn]]; -+ loggedNotRespawn = YES; - } -+} -+ -+- (void) _killKill -+{ -+ if (status != WOChildStatusDown) { -+ [self warnWithFormat: @"safety belt -- sending KILL signal to pid %d", -+ pid]; -+ kill (pid, SIGKILL); -+ killTimer = nil; - } - } - --static void _writePid(NSString *pidFile) { -- if ([pidFile length] > 0) { -- FILE *pf; -- -- if ((pf = fopen([pidFile cString], "w"))) { -- fprintf(pf, "%i\n", getpid()); -- fflush(pf); -- fclose(pf); -+- (void) _kill -+{ -+ if (status != WOChildStatusDown) { -+ [self logWithFormat: @"sending terminate signal to pid %d", pid]; -+ status = WOChildStatusTerminating; -+ kill (pid, SIGTERM); -+ } -+} -+ -+- (BOOL) readMessage -+{ -+ WOChildMessage message; -+ BOOL rc; -+ -+ if ([controlSocket readBytes: &message -+ count: sizeof (WOChildMessage)] == NGStreamError) { -+ rc = NO; -+ [self errorWithFormat: @"FAILURE receiving status for child %d", pid]; -+ [self errorWithFormat: @" socket: %@", controlSocket]; -+ [self _kill]; -+ } -+ else { -+ rc = YES; -+ if (message == WOChildMessageAccept) { -+ status = WOChildStatusBusy; -+ /* We schedule a 10 minutes grace period while the child is processing -+ the request. This enables long requests to complete while providing a -+ safety belt for children gone rogue. */ -+ killTimer -+ = [NSTimer scheduledTimerWithTimeInterval: 10.0 * 60 -+ target: self -+ selector: @selector (_killKill) -+ userInfo: nil -+ repeats: NO]; - } -+ else if (message == WOChildMessageReady) { -+ status = WOChildStatusReady; -+ [killTimer invalidate]; -+ killTimer = nil; -+ [watchDog declareChildReady: self]; -+ } - } -+ -+ return rc; - } --static void _delPid(void) { -- if ([pidFile length] > 0) { -- if (unlink([pidFile cString]) == 0) -- pidFile = nil; -+ -+- (BOOL) _sendMessage: (WOChildMessage) message -+{ -+ return ([controlSocket writeBytes: &message -+ count: sizeof (WOChildMessage)] != NGStreamError -+ && [self readMessage]); -+} -+ -+- (void) notify -+{ -+ WOChildMessage message; -+ -+ counter++; -+ message = WOChildMessageAccept; -+ if (![self _sendMessage: message]) { -+ [self errorWithFormat: @"FAILURE notifying child %d", pid]; -+ [self _kill]; - } - } - --static void exitWatchdog(void) { -- killChild(); -- _delPid(); -+- (void) terminate -+{ -+ if (status == WOChildStatusDown) { -+ [self logWithFormat: @"child is already down"]; -+ } else { -+ [self setControlSocket: nil]; -+ [self _kill]; -+ } - } - --static void wsignalHandler(int _signal) { -- switch (_signal) { -- case SIGINT: -- /* Control-C */ -- fprintf(stderr, "[%i]: watchdog handling signal ctrl-c ..\n", getpid()); -- killChild(); -- exit(0); -- /* shouldn't get here */ -- abort(); -+- (void) receivedEvent: (void*)data -+ type: (RunLoopEventType)type -+ extra: (void*)extra -+ forMode: (NSString*)mode -+{ -+ if ([controlSocket isAlive]) -+ [self readMessage]; -+ else { -+ /* This happens when a socket has been closed by the child but the child -+ has not terminated yet. */ -+ [[NSRunLoop currentRunLoop] removeEvent: data -+ type: ET_RDESC -+ forMode: NSDefaultRunLoopMode -+ all: YES]; -+ [self setControlSocket: nil]; -+ } -+} - -- case SIGSEGV: -- /* Coredump ! */ -- fprintf(stderr, -- "[%i]: watchdog handling segmentation fault " -- "(SERIOUS PROBLEM) ..\n", -- getpid()); -- killChild(); -- exit(123); -- /* shouldn't get here */ -- abort(); -+@end - -- case SIGTERM: -- /* TERM signal (kill 'pid') */ -- fprintf(stderr, "[%i]: watchdog handling SIGTERM ..\n", getpid()); -- killChild(); -- exit(0); -- /* shouldn't get here */ -- abort(); -- -- case SIGHUP: -- /* HUP signal (restart children) */ -- fprintf(stderr, "[%i]: watchdog handling SIGHUP ..\n", getpid()); -- killChild(); -- killedChild = YES; -- signal(_signal, wsignalHandler); -- return; -- -- case SIGCHLD: -- break; -- -- default: -- fprintf(stderr, "[%i]: watchdog handling signal %i ..\n", -- getpid(), _signal); -- break; -+@implementation WOWatchDog -+ -++ (id) sharedWatchDog -+{ -+ static WOWatchDog *sharedWatchDog = nil; -+ -+ if (!sharedWatchDog) -+ sharedWatchDog = [self new]; -+ -+ return sharedWatchDog; -+} -+ -+- (id) init -+{ -+ if ((self = [super init])) -+ { -+ listeningSocket = nil; -+ terminate = NO; -+ willTerminate = NO; -+ terminationSignal = nil; -+ pendingSIGHUP = 0; -+ -+ numberOfChildren = 0; -+ children = [[NSMutableArray alloc] initWithCapacity: 10]; -+ readyChildren = [[NSMutableArray alloc] initWithCapacity: 10]; -+ downChildren = [[NSMutableArray alloc] initWithCapacity: 10]; -+ } -+ -+ return self; -+} -+ -+- (void) _releaseListeningSocket -+{ -+ if (listeningSocket) { -+ [[NSRunLoop currentRunLoop] removeEvent: (void *) [listeningSocket fileDescriptor] -+ type: ET_RDESC -+ forMode: NSDefaultRunLoopMode -+ all: YES]; -+ [listeningSocket close]; -+ [listeningSocket release]; -+ listeningSocket = nil; - } -- fflush(stderr); -- -- switch (_signal) { -- case SIGTERM: -- case SIGINT: -- case SIGKILL: -- case SIGILL: -- killChild(); -- exit(0); -- break; -- -- case SIGHUP: -- killChild(); -- break; -- -- case SIGCHLD: { -- int returnStatus; -- pid_t result; -- -- // NSLog(@"SIGNAL: SIGCHLD"); -- // fetch return state -- -- do { -- result = waitpid(-1, &returnStatus, WNOHANG); -- if (result > 0) { -- fprintf(stderr, "[%i]: process %i exited with code %i", -- getpid(), (int)result, WEXITSTATUS(returnStatus)); -+} - -- if (WIFSIGNALED(returnStatus)) { -- fprintf(stderr, " (terminated due to signal %i%s)", -- WTERMSIG(returnStatus), -- WCOREDUMP(returnStatus) ? ", coredump" : ""); -- } -- if (WIFSTOPPED(returnStatus)) { -- fprintf(stderr, " (stopped due to signal %i)", -- WSTOPSIG(returnStatus)); -- } -- -- fprintf(stderr, "\n"); -- fflush(stderr); -+- (void) dealloc -+{ -+ [self _releaseListeningSocket]; -+ [terminationSignal release]; -+ [appName release]; -+ [children release]; -+ [super dealloc]; -+} -+ -+- (void) _runChildWithControlSocket: (NGActiveSocket *) controlSocket -+{ -+ WOApplication *app; -+ extern char **environ; -+ -+ [NSProcessInfo initializeWithArguments: (char **) argv -+ count: argc -+ environment: environ]; -+ NGInitTextStdio(); -+ app = [NSClassFromString(appName) new]; -+ [app autorelease]; -+ [app setListeningSocket: listeningSocket]; -+ [app setControlSocket: controlSocket]; -+ [app run]; -+} -+ -+- (void) receivedEvent: (void*)data -+ type: (RunLoopEventType)type -+ extra: (void*)extra -+ forMode: (NSString*)mode -+{ -+ int nextId; -+ WOWatchDogChild *child; -+ -+ nextId = [readyChildren count] - 1; -+ if (nextId > -1) { -+ child = [readyChildren objectAtIndex: nextId]; -+ [readyChildren removeObjectAtIndex: nextId]; -+ [child notify]; -+ } -+} -+ -+- (void) _cleanupSignalAndEventHandlers -+{ -+ int count; -+ NSRunLoop *runLoop; -+ -+ [[UnixSignalHandler sharedHandler] removeObserver: self]; -+ [loopTimer invalidate]; -+ loopTimer = nil; -+ runLoop = [NSRunLoop currentRunLoop]; -+ [runLoop removeEvent: (void *) [listeningSocket fileDescriptor] -+ type: ET_RDESC -+ forMode: NSDefaultRunLoopMode -+ all: YES]; -+ -+ for (count = 0; count < numberOfChildren; count++) -+ [[children objectAtIndex: count] setControlSocket: nil]; -+} -+ -+- (BOOL) _spawnChild: (WOWatchDogChild *) child -+{ -+ NGActiveSocket *pair[2]; -+ BOOL isChild; -+ int childPid; -+ extern char **environ; -+ -+ isChild = NO; -+ -+ if ([NGActiveSocket socketPair: pair]) { -+ childPid = fork (); -+ if (childPid == 0) { -+ setsid (); -+ isChild = YES; -+ [self _cleanupSignalAndEventHandlers]; -+ [self _runChildWithControlSocket: pair[0]]; -+ } else if (childPid > 0) { -+ [self logWithFormat: @"child spawned with pid %d", childPid]; -+ [child setPid: childPid]; -+ [child setStatus: WOChildStatusSpawning]; -+ [pair[1] setReceiveTimeout: 1.0]; -+ [child setControlSocket: pair[1]]; -+ [child setLastSpawn: [NSCalendarDate date]]; -+ } else { -+ perror ("fork"); -+ } -+ } -+ -+ return isChild; -+} -+ -+- (void) _ensureNumberOfChildren -+{ -+ int currentNumber, delta, count, min, max; -+ WOWatchDogChild *child; -+ -+ currentNumber = [children count]; -+ if (currentNumber < numberOfChildren) { -+ delta = numberOfChildren - currentNumber; -+ for (count = 0; count < delta; count++) { -+ child = [WOWatchDogChild watchDogChild]; -+ [child setWatchDog: self]; -+ [children addObject: child]; -+ [downChildren addObject: child]; -+ } -+ [self logWithFormat: @"preparing %d children", delta]; -+ } -+ else if (currentNumber > numberOfChildren) { -+ delta = currentNumber - numberOfChildren; -+ max = [downChildren count]; -+ if (max > delta) -+ min = max - delta; -+ else -+ min = 0; -+ for (count = max - 1; count >= min; count--) { -+ child = [downChildren objectAtIndex: count]; -+ [downChildren removeObjectAtIndex: count]; -+ [children removeObject: child]; -+ delta--; -+ [self logWithFormat: @"%d processes purged from pool", delta]; -+ } -+ -+ max = [readyChildren count]; -+ if (max > delta) -+ max -= delta; -+ for (count = max - 1; count > -1; count--) { -+ child = [readyChildren objectAtIndex: count]; -+ [readyChildren removeObjectAtIndex: count]; -+ [child terminate]; -+ [child setStatus: WOChildStatusExcessive]; -+ delta--; -+ } -+ [self logWithFormat: @"%d processes left to terminate", delta]; -+ } -+} -+ -+- (void) _noop -+{ -+} -+ -+- (BOOL) _ensureChildren -+{ -+ int count, max; -+ WOWatchDogChild *child; -+ BOOL isChild, delayed; -+ NSCalendarDate *now, *nextSpawn; -+ -+ isChild = NO; -+ -+ if (!willTerminate) { -+ [self _ensureNumberOfChildren]; -+ max = [downChildren count]; -+ for (count = max - 1; !isChild && count > -1; count--) { -+ delayed = NO; -+ child = [downChildren objectAtIndex: count]; -+ -+ if ([child status] == WOChildStatusExcessive) -+ [children removeObject: child]; -+ else { -+ now = [NSCalendarDate date]; -+ nextSpawn = [child nextSpawn]; -+ if ([nextSpawn earlierDate: now] == nextSpawn) -+ isChild = [self _spawnChild: child]; -+ else { -+ delayed = YES; -+ [child logNotRespawn]; - } - } -- while (result > 0); -- -- break; -+ if (!delayed) -+ [downChildren removeObjectAtIndex: count]; - } -- -- default: -- fprintf(stderr, "watchdog[%i]: caught signal %i\n", getpid(), _signal); -- break; - } -- signal(_signal, wsignalHandler); -+ -+ return isChild; - } - --static void signalHandler(int _signal) { -- fprintf(stderr, "[%i]: handling signal %i ..\n", -- getpid(), _signal); -- fflush(stderr); -- -- switch (_signal) { -- case SIGPIPE: -- fprintf(stderr, "[%i]: caught signal SIGPIPE\n", getpid()); -- break; -- -- default: -- fprintf(stderr, "[%i]: caught signal %i\n", getpid(), _signal); -- break; -+/* SOPE on GNUstep does not need to parse the argument line, since the -+ arguments will be put in the NSArgumentDomain. I don't know about -+ libFoundation but OSX is supposed to act the same way. */ -+- (NGInternetSocketAddress *) _listeningAddress -+{ -+ NGInternetSocketAddress *listeningAddress; -+ NSUserDefaults *ud; -+ id port, allow; -+ static BOOL warnedAboutAllow = NO; -+ -+ listeningAddress = nil; -+ -+ ud = [NSUserDefaults standardUserDefaults]; -+ port = [ud objectForKey:@"p"]; -+ if (!port) { -+ port = [ud objectForKey:@"WOPort"]; -+ if (!port) -+ port = @"auto"; - } -- signal(_signal, signalHandler); -+ allow = [ud objectForKey:@"WOHttpAllowHost"]; -+ if (allow && !warnedAboutAllow) { -+ [self warnWithFormat: @"'WOHttpAllowHost' is ignored in watchdog mode," -+ @" use a real firewall instead"]; -+ warnedAboutAllow = YES; -+ } -+ -+ if ([port isKindOfClass: [NSString class]]) { -+ if ([port isEqualToString: @"auto"]) { -+ listeningAddress -+ = [[NGInternetSocketAddress alloc] initWithPort:0 onHost:@"127.0.0.1"]; -+ [listeningAddress autorelease]; -+ } else if ([port rangeOfString: @":"].location == NSNotFound) { -+ if (allow) -+ listeningAddress = -+ [NGInternetSocketAddress wildcardAddressWithPort:[port intValue]]; -+ else -+ port = [NSString stringWithFormat: @"127.0.0.1:%d", [port intValue]]; -+ } -+ } -+ else { -+ if (allow) -+ listeningAddress = -+ [NGInternetSocketAddress wildcardAddressWithPort:[port intValue]]; -+ else { -+ port = [NSString stringWithFormat: @"127.0.0.1:%@", port]; -+ } -+ } -+ -+ if (!listeningAddress) -+ listeningAddress = (NGInternetSocketAddress *) NGSocketAddressFromString(port); -+ -+ return listeningAddress; - } - -+- (BOOL) _prepareListeningSocket -+{ -+ NGInternetSocketAddress *addr; -+ NSString *address; -+ BOOL rc; -+ int backlog; -+ -+ addr = [self _listeningAddress]; -+ NS_DURING { -+ [listeningSocket release]; -+ listeningSocket = [[NGPassiveSocket alloc] initWithDomain: [addr domain]]; -+ [listeningSocket bindToAddress: addr]; -+ backlog = [[NSUserDefaults standardUserDefaults] -+ integerForKey: @"WOListenQueueSize"]; -+ if (!backlog) -+ backlog = 5; -+ [listeningSocket listenWithBacklog: backlog]; -+ address = [addr address]; -+ if (!address) -+ address = @"*"; -+ [self logWithFormat: @"listening on %@:%d", address, [addr port]]; -+ [[NSRunLoop currentRunLoop] addEvent: (void *) [listeningSocket fileDescriptor] -+ type: ET_RDESC -+ watcher: self -+ forMode: NSDefaultRunLoopMode]; -+ rc = YES; -+ } -+ NS_HANDLER { -+ rc = NO; -+ } -+ NS_ENDHANDLER; -+ -+ return rc; -+} -+ -+- (WOWatchDogChild *) _childWithPID: (pid_t) childPid -+{ -+ WOWatchDogChild *currentChild, *child; -+ int count; -+ -+ child = nil; -+ for (count = 0; !child && count < numberOfChildren; count++) { -+ currentChild = [children objectAtIndex: count]; -+ if ([currentChild pid] == childPid) -+ child = currentChild; -+ } -+ -+ return child; -+} -+ -+- (void) _handleSIGPIPE:(NSNumber *)_signal { -+ [self logWithFormat: @"received SIGPIPE (ignored)"]; -+} -+ -+- (void) _handleTermination:(NSNumber *)_signal { -+ if (!terminationSignal) { -+ ASSIGN (terminationSignal, _signal); -+ if (pidFile) -+ unlink (pidFile); -+ } -+} -+ -+- (void) _handleSIGHUP:(NSNumber *)_signal { -+ pendingSIGHUP++; -+} -+ -+- (void) _setupSignals -+{ -+#if !defined(__MINGW32__) && !defined(NeXT_Foundation_LIBRARY) -+ UnixSignalHandler *us; -+ -+ us = [UnixSignalHandler sharedHandler]; -+ [us addObserver:self selector:@selector(_handleSIGPIPE:) -+ forSignal:SIGPIPE immediatelyNotifyOnSignal:YES]; -+ [us addObserver:self selector:@selector(_handleTermination:) -+ forSignal:SIGINT immediatelyNotifyOnSignal:YES]; -+ [us addObserver:self selector:@selector(_handleTermination:) -+ forSignal:SIGTERM immediatelyNotifyOnSignal:YES]; -+ [us addObserver:self selector:@selector(_handleSIGHUP:) -+ forSignal:SIGHUP immediatelyNotifyOnSignal:YES]; -+#endif -+} -+ -+- (void) declareChildReady: (WOWatchDogChild *) readyChild -+{ -+ [readyChildren addObject: readyChild]; -+} -+ -+- (void) declareChildDown: (WOWatchDogChild *) downChild -+{ -+ if (![downChildren containsObject: downChild]) -+ [downChildren addObject: downChild]; -+} -+ -+- (void) _ensureWorkersCount -+{ -+ int newNumberOfChildren; -+ NSUserDefaults *ud; -+ -+ ud = [NSUserDefaults standardUserDefaults]; -+ [ud synchronize]; -+ newNumberOfChildren = [ud integerForKey: @"WOHttpAdaptorForkCount"]; -+ if (newNumberOfChildren) -+ [self logWithFormat: @"user default 'WOHttpAdaptorForkCount' has been" -+ " replaced with 'WOWorkersCount'"]; -+ else -+ newNumberOfChildren = [ud integerForKey: @"WOWorkersCount"]; -+ if (newNumberOfChildren < 1) -+ newNumberOfChildren = 1; -+ numberOfChildren = newNumberOfChildren; -+} -+ -+- (void) _handlePostTerminationSignal -+{ -+ WOWatchDogChild *child; -+ int count; -+ -+ [self logWithFormat: @"Terminating with signal %@", terminationSignal]; -+ [self _releaseListeningSocket]; -+ for (count = 0; count < numberOfChildren; count++) { -+ child = [children objectAtIndex: count]; -+ if ([child status] != WOChildStatusDown -+ && [child status] != WOChildStatusTerminating) -+ [child terminate]; -+ } -+ [terminationSignal release]; -+ terminationSignal = nil; -+ if ([downChildren count] == numberOfChildren) { -+ [self logWithFormat: @"all children exited. We now terminate."]; -+ terminate = YES; -+ } -+ else -+ willTerminate = YES; -+} -+ -+- (void) _checkProcessesStatus -+{ -+ int status; -+ pid_t childPid; -+ WOWatchDogChild *child; -+ -+ while ((childPid = waitpid (-1, &status, WNOHANG)) > 0) { -+ child = [self _childWithPID: childPid]; -+ [child handleProcessStatus: status]; -+ [self declareChildDown: child]; -+ if (willTerminate && [downChildren count] == numberOfChildren) { -+ [self logWithFormat: @"all children exited. We now terminate."]; -+ terminate = YES; -+ } -+ } -+} -+ -+- (void) _setupProcessName -+{ -+ NSProcessInfo *processInfo; -+ NSString *name; -+ -+ /* this does not seem to work */ -+ processInfo = [NSProcessInfo processInfo]; -+ name = [processInfo processName]; -+ if (!name) -+ name = @""; -+ [processInfo setProcessName: [NSString stringWithFormat: @"%@: %@ watchdog", -+ name, appName]]; -+} -+ -+- (int) run: (NSString *) newAppName -+ argc: (int) newArgC argv: (const char **) newArgV -+{ -+ NSAutoreleasePool *pool; -+ NSRunLoop *runLoop; -+ NSDate *limitDate; -+ BOOL listening; -+ int retries; -+ -+ willTerminate = NO; -+ -+ ASSIGN (appName, newAppName); -+ [self _setupProcessName]; -+ -+ argc = newArgC; -+ argv = newArgV; -+ -+ listening = NO; -+ retries = 0; -+ while (!listening && retries < 5) { -+ listening = [self _prepareListeningSocket]; -+ retries++; -+ if (!listening) { -+ [self warnWithFormat: @"listening socket: attempt %d failed", retries]; -+ [NSThread sleepForTimeInterval: 1.0]; -+ } -+ } -+ if (listening) { -+ [self logWithFormat: @"watchdog process pid: %d", getpid ()]; -+ [self _setupSignals]; -+ [self _ensureWorkersCount]; -+ -+ // NSLog (@"ready to process requests"); -+ runLoop = [NSRunLoop currentRunLoop]; -+ -+ /* This timer ensures the looping of the runloop at reasonable intervals -+ for correct processing of signal handlers. */ -+ loopTimer = [NSTimer scheduledTimerWithTimeInterval: 0.5 -+ target: self -+ selector: @selector (_noop) -+ userInfo: nil -+ repeats: YES]; -+ terminate = NO; -+ while (!terminate) { -+ pool = [NSAutoreleasePool new]; -+ -+ while (pendingSIGHUP) { -+ [self logWithFormat: @"received SIGHUP"]; -+ [self _ensureWorkersCount]; -+ pendingSIGHUP--; -+ } -+ -+ // [self logWithFormat: @"watchdog loop"]; -+ NS_DURING { -+ terminate = [self _ensureChildren]; -+ if (!terminate) { -+ limitDate = [runLoop limitDateForMode:NSDefaultRunLoopMode]; -+ [runLoop runMode: NSDefaultRunLoopMode beforeDate: limitDate]; -+ } -+ } -+ NS_HANDLER { -+ terminate = YES; -+ [self errorWithFormat: -+ @"an exception occured in runloop %@", localException]; -+ } -+ NS_ENDHANDLER; -+ -+ if (!terminate) { -+ if (terminationSignal) -+ [self _handlePostTerminationSignal]; -+ [self _checkProcessesStatus]; -+ } -+ -+ [pool release]; -+ } -+ -+ [loopTimer invalidate]; -+ [[UnixSignalHandler sharedHandler] removeObserver: self]; -+ } -+ else -+ [self errorWithFormat: @"unable to listen on specified port," -+ @" check that no other process is already using it"]; -+ -+ return 0; -+} -+ -+@end -+ -+static BOOL _writePid(NSString *nsPidFile) { -+ NSString *pid; -+ BOOL rc; -+ -+ pid = [NSString stringWithFormat: @"%d", getpid()]; -+ rc = [pid writeToFile: nsPidFile atomically: NO]; -+ -+ return rc; -+} -+ - int WOWatchDogApplicationMain - (NSString *appName, int argc, const char *argv[]) - { - NSAutoreleasePool *pool; - NSUserDefaults *ud; -+ NSString *logFile, *nsPidFile; -+ int rc; -+ pid_t childPid; -+ NSProcessInfo *processInfo; - - pool = [[NSAutoreleasePool alloc] init]; -+ - #if LIB_FOUNDATION_LIBRARY || defined(GS_PASS_ARGUMENTS) - { - extern char **environ; -@@ -241,179 +937,59 @@ - environment:(void*)environ]; - } - #endif -- -+ -+ /* This invocation forces the class initialization of WOCoreApplication, -+ which causes the NSUserDefaults to be initialized as well with -+ Defaults.plist. */ -+ [NSClassFromString (appName) class]; -+ - ud = [NSUserDefaults standardUserDefaults]; -- -- /* default is to use the watch dog! */ -- /* Note: the Defaults.plist is not yet loaded at this stage! */ -- if ([ud objectForKey:@"WOUseWatchDog"] != nil) { -- if (![ud boolForKey:@"WOUseWatchDog"]) -- return WOApplicationMain(appName, argc, argv); -+ processInfo = [NSProcessInfo processInfo]; -+ -+ logFile = [ud objectForKey: @"WOLogFile"]; -+ if (!logFile) -+ logFile = [NSString stringWithFormat: @"/var/log/%@/%@.log", -+ [processInfo processName], -+ [processInfo processName]]; -+ if (![logFile isEqualToString: @"-"]) { -+ freopen([logFile cString], "a", stdout); -+ freopen([logFile cString], "a", stderr); - } -- -- /* watch dog */ -- { -- int failCount = 0; -- int forkCount = 0; -- BOOL repeat = YES; -- BOOL isVerbose = NO; -- -- isVerbose = [[ud objectForKey:@"watchdog_verbose"] boolValue]; -- pidFile = [[[ud objectForKey:@"watchdog_pidfile"] stringValue] copy]; -- -- /* write current pid to pidfile */ -- _writePid(pidFile); -- -- /* register exit handler */ -- atexit(exitWatchdog); -- -- /* register signal handlers of watch dog */ -- signal(SIGPIPE, wsignalHandler); -- signal(SIGCHLD, wsignalHandler); -- signal(SIGINT, wsignalHandler); -- signal(SIGTERM, wsignalHandler); -- signal(SIGKILL, wsignalHandler); -- signal(SIGHUP, wsignalHandler); -- -- /* loop */ -- -- while (repeat) { -- time_t clientStartTime; -- -- clientStartTime = time(NULL); -- killedChild = NO; -- -- if ((child = fork()) == -1) { -- fprintf(stderr, "[%i]: fork failed: %s\n", getpid(), strerror(errno)); -- failCount++; -- -- if (failCount > 5) { -- fprintf(stderr, " fork failed %i times, sleeping 60 seconds ..\n", -- failCount); -- sleep(60); -- } -- else { -- sleep(1); -- } -- } -- else { -- if (child == 0) { -- /* child process */ -- signal(SIGPIPE, SIG_DFL); -- signal(SIGCHLD, SIG_DFL); -- signal(SIGINT, SIG_DFL); -- signal(SIGTERM, SIG_DFL); -- signal(SIGKILL, SIG_DFL); -- -- if (isVerbose) -- fprintf(stderr, "starting child %i ..\n", getpid()); -+ if ([ud boolForKey: @"WONoDetach"]) -+ childPid = 0; -+ else -+ childPid = fork(); - -- pidFile = [pidFile stringByAppendingPathExtension:@"child"]; -- _writePid(pidFile); -- -- atexit(_delPid); -- -- exit(WOApplicationMain(appName, argc, argv)); -- -- /* shouldn't even get here ! */ -- fprintf(stderr, "internal server error !\n"); -- abort(); -- } -- else { -- /* parent (watch dog) */ -- int status = 0; -- pid_t result = 0; -- time_t clientStopTime; -- unsigned uptime; -- -- forkCount++; -- -- if (isVerbose) { -- fprintf(stderr, "forked child process %i (#%i) ..\n", -- child, forkCount); -- } -- -- failCount = 0; -- status = 0; -- -- if ((result = waitpid(child, &status, 0)) == -1) { -- if (killedChild) { -- killedChild = NO; -- continue; -- } -- -- fprintf(stderr, -- "### waiting for child %i (#%i) failed: %s\n", -- child, forkCount, strerror(errno)); -- continue; -- } -+ if (childPid) { -+ rc = 0; -+ } -+ else { -+ nsPidFile = [ud objectForKey: @"WOPidFile"]; -+ if (!nsPidFile) -+ nsPidFile = [NSString stringWithFormat: @"/var/run/%@/%@.pid", -+ [processInfo processName], -+ [processInfo processName]]; -+ pidFile = [nsPidFile UTF8String]; -+ if (_writePid(nsPidFile)) { -+ respawnDelay = [ud integerForKey: @"WORespawnDelay"]; -+ if (!respawnDelay) -+ respawnDelay = 5; -+ /* default is to use the watch dog! */ -+ if ([ud objectForKey:@"WOUseWatchDog"] != nil -+ && ![ud boolForKey:@"WOUseWatchDog"]) -+ rc = WOApplicationMain(appName, argc, argv); -+ else -+ rc = [[WOWatchDog sharedWatchDog] run: appName argc: argc argv: argv]; -+ } -+ else { -+ [ud errorWithFormat: @"unable to open pid file: %@", pidFile]; -+ rc = -1; -+ } -+ } - -- clientStopTime = time(NULL); -- uptime = clientStopTime - clientStartTime; -- -- if (WIFSIGNALED(status)) { -- fprintf(stderr, -- "### child %i (#%i) was terminated by signal %i " -- "(uptime=%ds).\n", -- child, forkCount, WTERMSIG(status), uptime); -- -- lastFailExit = time(NULL); -- failExitCount++; -- } -- else if (WIFEXITED(status)) { -- unsigned exitCode; -- -- if ((exitCode = WEXITSTATUS(status)) != 0) { -- time_t now; -- -- now = time(NULL); -+ [pool release]; - -- if (uptime < 3) { -- if (failExitCount > 0) { -- unsigned secsSinceLastFail; -- -- secsSinceLastFail = (now - lastFailExit); -- -- if (secsSinceLastFail > 120) { -- /* reset fail count */ -- failExitCount = 0; -- } -- else if (failExitCount > 20) { -- printf("### child %i (#%i) already failed %i times " -- "in the last %i seconds, stopping watchdog !\n", -- child, forkCount, failExitCount, secsSinceLastFail); -- repeat = NO; -- } -- } -- } -- failExitCount++; -- lastFailExit = now; -- -- fprintf(stderr, -- "### child %i (#%i) exited with status %i " -- "(#fails=%i, uptime=%ds).\n", -- child, forkCount, exitCode, failExitCount, uptime); -- } -- else { -- fprintf(stderr, -- "### child %i (#%i) exited successfully (uptime=%ds).\n", -- child, forkCount, uptime); -- } -- -- if (exitCode == 123) // ??? -- repeat = NO; -- } -- else { -- fprintf(stderr, -- "### abnormal termination of child %i (#%i) status=%i" -- "(was not signaled nor exited).", -- child, forkCount, status); -- } -- } -- } -- } -- return 0; -- } -+ return rc; - } - #endif - -@@ -421,8 +997,8 @@ - - @interface NSUserDefaults(ServerDefaults) - + (id)hackInServerDefaults:(NSUserDefaults *)_ud -- withAppDomainPath:(NSString *)_appDomainPath -- globalDomainPath:(NSString *)_globalDomainPath; -+ withAppDomainPath:(NSString *)_appDomainPath -+ globalDomainPath:(NSString *)_globalDomainPath; - @end - - int WOWatchDogApplicationMainWithServerDefaults -@@ -437,7 +1013,7 @@ - { - extern char **environ; - [NSProcessInfo initializeWithArguments:(void*)argv count:argc -- environment:(void*)environ]; -+ environment:(void*)environ]; - } - #endif - -@@ -446,8 +1022,8 @@ - - ud = [NSUserDefaults standardUserDefaults]; - sd = [defClass hackInServerDefaults:ud -- withAppDomainPath:appDomainPath -- globalDomainPath:globalDomainPath]; -+ withAppDomainPath:appDomainPath -+ globalDomainPath:globalDomainPath]; - - #if 0 - if (((sd == nil) || (sd == ud)) && (appDomainPath != nil)) { -Index: sope-appserver/NGObjWeb/WODynamicElement.m -=================================================================== ---- sope-appserver/NGObjWeb/WODynamicElement.m (revision 1664) -+++ sope-appserver/NGObjWeb/WODynamicElement.m (working copy) -@@ -98,6 +98,7 @@ - template = [[WOCompoundElement allocForCount:[_contents count] - zone:[self zone]] - initWithContentElements:_contents]; -+ [template autorelease]; - } - - return [self initWithName:_name -@@ -362,6 +363,7 @@ - - children = [_builder buildNodes:[_element childNodes] - templateBuilder:_builder]; -+ [children autorelease]; - } - else - children = nil; -Index: sope-appserver/NGObjWeb/WOHTTPConnection.m -=================================================================== ---- sope-appserver/NGObjWeb/WOHTTPConnection.m (revision 1664) -+++ sope-appserver/NGObjWeb/WOHTTPConnection.m (working copy) -@@ -38,7 +38,6 @@ - @interface WOHTTPConnection(Privates) - - (BOOL)_connect; - - (void)_disconnect; --- (void)_unregisterNotification; - @end - - @interface WOCookie(Privates) -@@ -153,7 +152,6 @@ - } - - - (void)dealloc { -- [self _unregisterNotification]; - [self->lastException release]; - [self->log release]; - [self->io release]; -@@ -288,57 +286,6 @@ - [self->socket release]; self->socket = nil; - } - --/* runloop based IO */ -- --- (NSNotificationCenter *)notificationCenter { -- return [NSNotificationCenter defaultCenter]; --} --- (NSRunLoop *)runLoop { -- return [NSRunLoop currentRunLoop]; --} --- (NSString *)runLoopMode { -- return NSDefaultRunLoopMode; --} -- --- (void)_socketActivated:(NSNotification *)_n { -- if ([_n object] != self->socket) -- return; -- --#if DEBUG && 0 -- [self debugWithFormat:@"socket activated ..."]; --#endif -- -- [[self notificationCenter] -- postNotificationName:WOHTTPConnectionCanReadResponse -- object:self]; --} -- --- (void)_registerForNotification { -- NSRunLoop *rl; -- -- if (self->didRegisterForNotification) -- return; -- -- [[self notificationCenter] -- addObserver:self selector:@selector(_socketActivated:) -- name:NSFileObjectBecameActiveNotificationName -- object:self->socket]; -- -- rl = [self runLoop]; -- [rl addFileObject:self->socket -- activities:(NSPosixReadableActivity|NSPosixExceptionalActivity) -- forMode:[self runLoopMode]]; --} --- (void)_unregisterNotification { -- if (!self->didRegisterForNotification) -- return; -- -- [[self notificationCenter] removeObserver:self]; -- -- [[self runLoop] removeFileObject:self->socket -- forMode:[self runLoopMode]]; --} -- - /* logging IO */ - - - (void)logRequest:(WORequest *)_response data:(NSData *)_data { -@@ -543,8 +490,6 @@ - if (![self->socket isConnected]) - return NO; - -- [self _registerForNotification]; -- - return YES; - } - -@@ -560,7 +505,6 @@ - WOResponse *response; - - *(&response) = nil; -- [self _unregisterNotification]; - - if (self->socket == nil) { - [self debugWithFormat:@"no socket available for reading response ..."]; -Index: sope-appserver/NGObjWeb/WOCookie.m -=================================================================== ---- sope-appserver/NGObjWeb/WOCookie.m (revision 1664) -+++ sope-appserver/NGObjWeb/WOCookie.m (working copy) -@@ -160,7 +160,7 @@ - - - (NSString *)stringValue { - NSMutableString *str; -- -+ - str = [NSMutableString stringWithCapacity:512]; - [str appendString:[self->name stringByEscapingURL]]; - [str appendString:@"="]; -@@ -168,14 +168,29 @@ - - if (self->expireDate) { - static NSTimeZone *gmt = nil; -+ static NSMutableDictionary *localeDict = nil; - NSString *s; - if (gmt == nil) - gmt = [[NSTimeZone timeZoneWithAbbreviation:@"GMT"] retain]; -- -+ if (localeDict == nil) -+ { -+ localeDict = [NSMutableDictionary new]; -+ -+ [localeDict setObject: [NSArray arrayWithObjects: @"Jan", @"Feb", -+ @"Mar", @"Apr", @"May", @"Jun", -+ @"Jul", @"Aug", @"Sep", @"Oct", -+ @"Nov", @"Dec", nil] -+ forKey: @"NSShortMonthNameArray"]; -+ [localeDict setObject: [NSArray arrayWithObjects: @"Sun", @"Mon", -+ @"Tue", @"Wed", @"Thu", @"Fri", -+ @"Sat", nil] -+ forKey: @"NSShortWeekDayNameArray"]; -+ } -+ - // TODO: replace, -descriptionWithCalendarFormat is *slow* - s = [self->expireDate descriptionWithCalendarFormat:cookieDateFormat - timeZone:gmt -- locale:nil]; -+ locale:localeDict]; - - [str appendString:@"; expires="]; - [str appendString:s]; -Index: sope-appserver/NGObjWeb/GNUmakefile.postamble -=================================================================== ---- sope-appserver/NGObjWeb/GNUmakefile.postamble (revision 1664) -+++ sope-appserver/NGObjWeb/GNUmakefile.postamble (working copy) -@@ -23,14 +23,20 @@ - - # install makefiles - --after-install :: -- $(MKDIRS) $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/Additional/ -- $(INSTALL_DATA) ngobjweb.make $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/Additional/ngobjweb.make -+after-install :: $(DESTDIR)/$(GNUSTEP_MAKEFILES)/Additional/ngobjweb.make - - ifneq ($(GNUSTEP_MAKE_VERSION),1.3.0) --after-install :: -+after-install :: $(DESTDIR)/$(GNUSTEP_MAKEFILES)/woapp.make $(DESTDIR)/$(GNUSTEP_MAKEFILES)/wobundle.make -+endif -+ -+$(DESTDIR)/$(GNUSTEP_MAKEFILES)/Additional/ngobjweb.make: ngobjweb.make -+ $(MKDIRS) $(DESTDIR)/$(GNUSTEP_MAKEFILES)/Additional/ -+ $(INSTALL_DATA) ngobjweb.make $(DESTDIR)/$(GNUSTEP_MAKEFILES)/Additional/ngobjweb.make -+ -+$(DESTDIR)/$(GNUSTEP_MAKEFILES)/woapp.make: woapp-gs.make - $(INSTALL_DATA) woapp-gs.make \ -- $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/woapp.make -+ $(DESTDIR)/$(GNUSTEP_MAKEFILES)/woapp.make -+ -+$(DESTDIR)/$(GNUSTEP_MAKEFILES)/wobundle.make: wobundle-gs.make - $(INSTALL_DATA) wobundle-gs.make \ -- $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/wobundle.make --endif -+ $(DESTDIR)/$(GNUSTEP_MAKEFILES)/wobundle.make -Index: sope-appserver/NGObjWeb/WOComponentDefinition.m -=================================================================== ---- sope-appserver/NGObjWeb/WOComponentDefinition.m (revision 1664) -+++ sope-appserver/NGObjWeb/WOComponentDefinition.m (working copy) -@@ -540,7 +540,7 @@ - builder = [self templateBuilderForURL:url]; - if (debugOn) [self debugWithFormat:@"builder: %@", builder]; - -- self->template = [[builder buildTemplateAtURL:url] retain]; -+ self->template = [builder buildTemplateAtURL:url]; - if (debugOn) [self debugWithFormat:@"template: %@", self->template]; - - return self->template ? YES : NO; -Index: sope-appserver/NGObjWeb/WOMessage+XML.m -=================================================================== ---- sope-appserver/NGObjWeb/WOMessage+XML.m (revision 1664) -+++ sope-appserver/NGObjWeb/WOMessage+XML.m (working copy) -@@ -84,7 +84,7 @@ - id builder; - - builder = [[[NSClassFromString(@"DOMSaxBuilder") alloc] init] autorelease]; -- dom = [[builder buildFromData:data] retain]; -+ dom = [builder buildFromData:data]; - } - - /* cache DOM structure */ -Index: sope-appserver/NGObjWeb/ChangeLog -=================================================================== ---- sope-appserver/NGObjWeb/ChangeLog (revision 1664) -+++ sope-appserver/NGObjWeb/ChangeLog (working copy) -@@ -1,3 +1,184 @@ -+2010-02-24 Wolfgang Sourdeau -+ -+ * WOWatchDogApplicationMain.m (_spawnChild:): we set a timeout of -+ 1 second to the parent-side child control socket to avoid hang on -+ status reads when the child dies before the message reaches the -+ parent. -+ -+2010-02-18 Wolfgang Sourdeau -+ -+ * WOWatchDogApplicationMain.m (-run:argc:argv:): we assign the -+ loop timer to an ivar so that it can be invalidated when a child -+ process is spawned. Child processes are check at each loop, since -+ receiving SIGCHILD is not guaranteed and we deadlock -+ when all remaining processes are zombies. -+ (-_setupSignals): SIGCHILD is no longer trapped. -+ (-readMessage): we now setup a 10 minutes timer when the child -+ accepts the request up to the moment its done with it. This -+ provides a supplemental safety for deadlocked children. -+ (WOWatchDogApplicationMain): we no longer care about the return -+ values for fdreopen since this is useless and is not portable. -+ -+2010-02-03 Wolfgang Sourdeau -+ -+ * WOCookie.m (-stringValue): pass an minimal english locale -+ dictionary when producing expiration date representation to avoid -+ using the system locale. -+ -+2010-01-29 Wolfgang Sourdeau -+ -+ * Templates/WOxComponentElemBuilder.m -+ (-buildElement:tempateBuilder:): "children" (local) is the result -+ of a "buildXXX" method that we won't return, so we autorelease it -+ to avoid leaks. -+ -+ * Templates/WOxTemplateBuilder.m (-buildTemplateAtURL): same as -+ below for "root". -+ -+ * Templates/WOWrapperTemplateBuilder.m (-buildTemplateAtURL): -+ avoid a leak by releasing "rootElement" (local) when used. -+ -+ * Templates/WOxElemBuilder.m (-buildNodes:templateBuilder:): the -+ "buildXXX" methods return retained objects all through NGObjWeb, -+ here too now. -+ -+ * DynamicElements/_WOTemporaryHyperlink.m -+ (-initWithName:associations:contentElements:): same as below for -+ "template". -+ -+ * DynamicElements/WOString.m -+ (-initWithName:associations:template:): "avalue" and "aescape" are -+ local variables and OWGetProperty always returns a retained -+ object. Therefore we want to release them after their use. -+ -+ * DynamicElements/WOxHTMLElemBuilder.m -+ (-buildContainer:templateBuilder:): same as below. -+ -+ * DynamicElements/WOConditional.m -+ (-initWithNegateElement:templateBuilder:): same as below. -+ -+ * DynamicElements/WOGenericElement.m -+ (-initWithElement:templateBuilder:): "children" is retained when -+ returned from "buildNodesXX" but is not an ivar so we want to -+ autorelease that result to avoid leaks. -+ -+ * WOComponentDefinition.m (-load): the "buildXX" methods already -+ return retained objects. We don't want to retain them once more. -+ -+2010-01-28 Wolfgang Sourdeau -+ -+ * WOHttpAdaptor/WOHttpAdaptor.m (-registerForEvents): the -+ controlSocket is now a retained ivar, that we further use for -+ validation in -acceptControlMessage:. -+ -+ * WOHTTPConnection.m: got rid of "runloop based IO" code, which -+ was useless and error prone. -+ -+2010-01-14 Wolfgang Sourdeau -+ -+ * SoObjects/SoObject.m (-isFolderish): now a real category method, -+ defaulting to NO. -+ -+ * WebDAV/SoWebDAVRenderer.m (-renderSearchResultEntry:...): take -+ the potential ending slash of the request to keep or remove the -+ ending slash of the hrefs to the returned objects, in order to -+ avoid confusing iCal with otherwise standard urls to DAV -+ collections. -+ -+2009-12-22 Wolfgang Sourdeau -+ -+ * WOWatchDogApplicationMain.m (_listeningAddress): read "WOPort" -+ from the user defaults rather than by invoking [WOApplication -+ port], which returns an NSNumber. -+ -+2009-12-14 Wolfgang Sourdeau -+ -+ * WOWatchDogApplicationMain.m (-run:argc:argv:): added a -+ repeatable timer, triggered every 0.5 seconds, that ensures the -+ proper looping of the runloop when a signal was received. -+ -+2009-12-09 Wolfgang Sourdeau -+ -+ * WOWatchDogApplicationMain.m (_handleSIGCHLD:) -+ (_handleTermination:, _handleSIGHUP:): the actual handling is now -+ done elsewhere, in order to avoid messing with memory allocation -+ and risking a dead lock. -+ (-_handlePostTerminationSignal): we set "terminate" to YES if all -+ children are already down, in order to avoid another deadlock -+ where the process termination would stall waiting for SIGCHLD. -+ (-receivedEvent:type:extra:forMode:): check that the control -+ socket is still "alive" before reading from it. If not, we -+ unregister the filedescriptor passed as "data" from the runloop -+ listener. -+ -+2009-12-07 Wolfgang Sourdeau -+ -+ * WOCoreApplication.m (+initialize): we invoke -+ "registerUserDefaults" from here now. This enables Defaults.plist -+ to be registered as soon as the watchdog is active. -+ -+ * WOWatchDogApplicationMain.m (-terminate): we use a SIGTERM to -+ terminate the children instead of passing a message. We also setup -+ a timer that will send a SIGKILL after 5 minutes. -+ (-_releaseListeningSocket): we close the socket here so that other -+ processes can start listening. -+ (WOWatchDogApplicationMain): we accept "-" as argument to -+ "WOLogFile" so that we avoid redirecting the output and the error -+ channels. -+ -+2009-11-11 Wolfgang Sourdeau -+ -+ * WOCoreApplication.m (-setControlSocket, -controlSocket) -+ (-setListeningSocket, -listeningSocke): new helper accessors for -+ the new watchdog mechanism. -+ -+ * WOHttpAdaptor/WOHttpAdaptor.m: slightly refactored to use the -+ control socket provided by the watchdog. -+ -+ * WOWatchDogApplicationMain.m: rewritten the watchdog mechanism: -+ - added WOWatchDog and WOWatchDogChild classes -+ - make use of UnixSignalHandler -+ - added support for preforked preocesses (WOWorkersCount) -+ - detach watchdog processes from terminal by default (WONoDetach) -+ - redirect stderr and stdout to file -+ (WOLogFile = /var/log/[name]/[name].log) -+ - write pid file -+ (WOPidFile = /var/run/[name]/[name].pid) -+ - use "127.0.0.1:port" as default bind address, unless -+ WOHTTPAllowHost is specified -+ - added support for delaying process respawning -+ (WORespawnDelay = 5 seconds) -+ -+2009-10-26 Wolfgang Sourdeau -+ -+ * WOMessage+XML.m (-contentAsDOMDocument): do not retain "dom" as -+ it will be assigned to self->domCache, to avoid a leak. -+ -+2009-10-21 Wolfgang Sourdeau -+ -+ * WebDAV/SoObjectResultEntry.m (-valueForKey:): we now take -+ WOUseRelativeURLs into account when the "href" key is requested, -+ to work around a bug in iCal 4. -+ -+2009-07-02 Wolfgang Sourdeau -+ -+ * WOMessage.m (-setHeaders:, -setHeader:forKey:, headerForKey:, -+ -appendHeader:forKey:, -appendHeaders:forKey:, setHeaders:forKey:, -+ -headersForKey:): convert the specified header key to lowercase, -+ to ensure they are managed case-insensitively. -+ * WOHttpAdaptor/WOHttpTransaction.m -+ (-deliverResponse:toRequest:onStream:): if the content-type is -+ specified and already has "text/plain" as prefix, we don't -+ override it. -+ -+2009-07-01 Wolfgang Sourdeau -+ -+ * WOHttpAdaptor/WOHttpTransaction.m -+ (-deliverResponse:toRequest:onStream:): we test the content-length -+ and impose a content-type of text/plain when 0. This work-arounds -+ a bug in Mozilla clients where empty responses with a content-type -+ set to X/xml will trigger an exception. -+ - 2009-06-10 Helge Hess - - * DAVPropMap.plist: mapped {DAV:}current-user-principal (v4.9.37) -Index: sope-appserver/NGObjWeb/DAVPropMap.plist -=================================================================== ---- sope-appserver/NGObjWeb/DAVPropMap.plist (revision 1664) -+++ sope-appserver/NGObjWeb/DAVPropMap.plist (working copy) -@@ -157,6 +157,9 @@ - "{urn:ietf:params:xml:ns:caldav}supported-calendar-data" = - davSupportedCalendarDataTypes; - "{urn:ietf:params:xml:ns:caldav}calendar-description" = davDescription; -+ "{urn:ietf:params:xml:ns:caldav}calendar-timezone" = davCalendarTimeZone; -+ "{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL" = davScheduleDefaultCalendarURL; -+ "{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp" = davScheduleCalendarTransparency; - - /* CardDAV */ - "{urn:ietf:params:xml:ns:carddav}addressbook-home-set" = davAddressbookHomeSet; -@@ -168,6 +171,8 @@ - "{http://calendarserver.org/ns/}dropbox-home-URL" = davDropboxHomeURL; - "{http://calendarserver.org/ns/}notifications-URL" = davNotificationsURL; - "{http://calendarserver.org/ns/}getctag" = davCollectionTag; -+ "{http://calendarserver.org/ns/}calendar-proxy-read-for" = davCalendarProxyReadFor; -+ "{http://calendarserver.org/ns/}calendar-proxy-write-for" = davCalendarProxyWriteFor; - - /* Apple extensions */ - "{http://apple.com/ns/ical/}calendar-color" = davCalendarColor; -Index: sope-appserver/NGObjWeb/WebDAV/SoObjectResultEntry.m -=================================================================== ---- sope-appserver/NGObjWeb/WebDAV/SoObjectResultEntry.m (revision 1664) -+++ sope-appserver/NGObjWeb/WebDAV/SoObjectResultEntry.m (working copy) -@@ -25,7 +25,14 @@ - @implementation SoObjectResultEntry - - static BOOL debugOn = NO; -+static BOOL useRelativeURLs = NO; - -++ (void) initialize -+{ -+ useRelativeURLs = [[NSUserDefaults standardUserDefaults] -+ boolForKey: @"WOUseRelativeURLs"]; -+} -+ - - (id)initWithURI:(NSString *)_href object:(id)_o values:(NSDictionary *)_d { - if ((self = [super init])) { - if (debugOn) { -@@ -85,10 +92,36 @@ - return YES; - } - -+- (NSString *)_relativeHREF { -+ NSString *newHREF; -+ NSRange hostRange; -+ -+ if ([self->href hasPrefix: @"/"]) -+ return self->href; -+ else { -+ hostRange = [self->href rangeOfString: @"://"]; -+ if (hostRange.length > 0) { -+ newHREF = [self->href substringFromIndex: NSMaxRange (hostRange)]; -+ hostRange = [newHREF rangeOfString: @"/"]; -+ if (hostRange.length > 0) { -+ newHREF = [newHREF substringFromIndex: hostRange.location]; -+ } -+ } else { -+ newHREF = self->href; -+ } -+ -+ return newHREF; -+ } -+} -+ - - (id)valueForKey:(NSString *)_key { -- if ([_key isEqualToString:@"{DAV:}href"]) -- return self->href; -- -+ if ([_key isEqualToString:@"{DAV:}href"]) { -+ if (useRelativeURLs) -+ return [self _relativeHREF]; -+ else -+ return self->href; -+ } -+ - if ([_key isEqualToString:@"{DAV:}status"]) - return nil; - -@@ -102,6 +135,12 @@ - } - } - -+/* SoObject */ -+- (BOOL)isFolderish -+{ -+ return [self->object isFolderish]; -+} -+ - /* description */ - - - (NSString *)description { -Index: sope-appserver/NGObjWeb/WebDAV/SoWebDAVRenderer.m -=================================================================== ---- sope-appserver/NGObjWeb/WebDAV/SoWebDAVRenderer.m (revision 1664) -+++ sope-appserver/NGObjWeb/WebDAV/SoWebDAVRenderer.m (working copy) -@@ -25,6 +25,7 @@ - #include "SoObject+SoDAV.h" - #include "EOFetchSpecification+SoDAV.h" - #include "NSException+HTTP.h" -+#include - #include - #include - #include -@@ -49,6 +50,8 @@ - #define XMLNS_INTTASK \ - @"{http://schemas.microsoft.com/mapi/id/{00062003-0000-0000-C000-000000000046}/}" - -+static Class NSURLKlass = Nil; -+ - @interface SoWebDAVRenderer(Privates) - - (BOOL)renderStatusResult:(id)_object withDefaultStatus:(int)_defStatus - inContext:(WOContext *)_ctx; -@@ -79,6 +82,8 @@ - - if ((debugOn = [ud boolForKey:@"SoRendererDebugEnabled"])) - NSLog(@"enabled debugging in SoWebDAVRenderer (SoRendererDebugEnabled)"); -+ -+ NSURLKlass = [NSURL class]; - } - - + (id)sharedRenderer { -@@ -616,16 +621,19 @@ - [r appendContentString:s]; - } - else { -+ s = [self stringForValue:value ofProperty:_key prefixes:nsToPrefix]; - [r appendContentCharacter:'<']; - [r appendContentString:extName]; -- [r appendContentCharacter:'>']; -- -- s = [self stringForValue:value ofProperty:_key prefixes:nsToPrefix]; -- [r appendContentString:s]; -- -- [r appendContentString:@""]; -+ if ([s length] > 0) { -+ [r appendContentCharacter:'>']; -+ [r appendContentString:s]; -+ [r appendContentString:@""]; -+ } -+ else { -+ [r appendContentString:@"/>"]; -+ } - if (formatOutput) [r appendContentCharacter:'\n']; - } - } -@@ -646,8 +654,9 @@ - NSString *key; - id href = nil; - id stat = nil; -- BOOL isBrief; -- -+ BOOL isBrief, hasSlash; -+ -+ hasSlash = [[[_ctx request] uri] hasSuffix: @"/"]; - r = [_ctx response]; - isBrief = [[[_ctx request] headerForKey:@"brief"] hasPrefix:@"t"] ? YES : NO; - -@@ -694,8 +703,13 @@ - } - - /* tidy href */ -- href = [self tidyHref:href baseURL:baseURL]; -- -+ if (useRelativeURLs) { -+ if ([href isKindOfClass: NSURLKlass]) -+ href = [href path]; -+ } -+ else -+ href = [self tidyHref:href baseURL:baseURL]; -+ - /* tidy status */ - stat = [self tidyStatus:stat]; - } -@@ -703,7 +717,22 @@ - href = [baseURL stringValue]; - stat = @"HTTP/1.1 200 OK"; - } -- -+ -+ /* make the presence of the href slash correspond to the request slash */ -+ if (hasSlash) { -+ /* megahack: we consider entry to be the base entry if it's an -+ NSDictionary */ -+ if (![href hasSuffix: @"/"] -+ && ([entry isFolderish] -+ || [entry isKindOfClass: [NSDictionary class]])) { -+ href = [href stringByAppendingString: @"/"]; -+ } -+ } -+ else { -+ if ([href hasSuffix: @"/"]) -+ href = [href substringToIndex: [href length] - 2]; -+ } -+ - if (debugOn) { - [self debugWithFormat:@" status: %@", stat]; - [self debugWithFormat:@" href: %@", href]; -Index: sope-appserver/NGObjWeb/WODirectAction.m -=================================================================== ---- sope-appserver/NGObjWeb/WODirectAction.m (revision 1664) -+++ sope-appserver/NGObjWeb/WODirectAction.m (working copy) -@@ -46,7 +46,7 @@ - } - - (id)initWithContext:(WOContext *)_ctx { - if ((self = [self initWithRequest:[_ctx request]])) { -- self->context = [_ctx retain]; -+ self->context = _ctx; - } - return self; - } -@@ -54,16 +54,16 @@ - return [self initWithRequest:nil]; - } - --- (void)dealloc { -- [self->context release]; -- [super dealloc]; --} -+// - (void)dealloc { -+// [self->context release]; -+// [super dealloc]; -+// } - - /* accessors */ - - - (WOContext *)context { - if (self->context == nil) -- self->context = [[[WOApplication application] context] retain]; -+ self->context = [[WOApplication application] context]; - return self->context; - } - -Index: sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m -=================================================================== ---- sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m (revision 1664) -+++ sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m (working copy) -@@ -216,6 +216,12 @@ - assocCount++; - } - } -+ if (count > 0) { -+ if ((self->isAbsolute = OWGetProperty(_config, @"absolute"))) { -+ count--; -+ assocCount++; -+ } -+ } - - self->rest = _config; - -Index: sope-appserver/NGObjWeb/DynamicElements/WOGenericElement.m -=================================================================== ---- sope-appserver/NGObjWeb/DynamicElements/WOGenericElement.m (revision 1664) -+++ sope-appserver/NGObjWeb/DynamicElements/WOGenericElement.m (working copy) -@@ -74,6 +74,7 @@ - children = [_element hasChildNodes] - ? [_builder buildNodes:[_element childNodes] templateBuilder:_builder] - : (NSArray *)nil; -+ [children autorelease]; - - /* construct self ... */ - self = [(WODynamicElement *)self initWithName:name -Index: sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m -=================================================================== ---- sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m (revision 1664) -+++ sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m (working copy) -@@ -41,6 +41,7 @@ - WOAssociation *string; - WOAssociation *target; - WOAssociation *disabled; -+ WOAssociation *isAbsolute; - WOElement *template; - - /* new in WO4: */ -@@ -360,6 +361,7 @@ - { - if ((self = [super initWithName:_name hyperlinkInfo:_info template:_t])) { - self->href = _info->href; -+ self->isAbsolute = _info->isAbsolute; - } - return self; - } -@@ -375,8 +377,11 @@ - // TODO: we need a binding to disable rewriting! - NSRange r; - -+ if ([[self->isAbsolute valueInContext:_ctx] boolValue] == YES) -+ return NO; -+ - r.length = [_s length]; -- -+ - /* do not rewrite pure fragment URLs */ - if (r.length > 0 && [_s characterAtIndex:0] == '#') - return NO; -Index: sope-appserver/NGObjWeb/DynamicElements/WOConditional.m -=================================================================== ---- sope-appserver/NGObjWeb/DynamicElements/WOConditional.m (revision 1664) -+++ sope-appserver/NGObjWeb/DynamicElements/WOConditional.m (working copy) -@@ -121,6 +121,7 @@ - - children = [_builder buildNodes:[_element childNodes] - templateBuilder:_builder]; -+ [children autorelease]; - } - else - children = nil; -Index: sope-appserver/NGObjWeb/DynamicElements/WOString.m -=================================================================== ---- sope-appserver/NGObjWeb/DynamicElements/WOString.m (revision 1664) -+++ sope-appserver/NGObjWeb/DynamicElements/WOString.m (working copy) -@@ -235,6 +235,8 @@ - - doEscape = (aescape != nil) ? [aescape boolValueInComponent:nil] : YES; - self = [self initWithValue:avalue escapeHTML:doEscape]; -+ [avalue release]; -+ [aescape release]; - } - return self; - } -@@ -357,6 +359,8 @@ - - doEscape = (aescape != nil) ? [aescape boolValueInComponent:nil] : YES; - self = [self initWithValue:avalue escapeHTML:doEscape]; -+ [avalue release]; -+ [aescape release]; - } - return self; - } -Index: sope-appserver/NGObjWeb/DynamicElements/WORepetition.m -=================================================================== ---- sope-appserver/NGObjWeb/DynamicElements/WORepetition.m (revision 1664) -+++ sope-appserver/NGObjWeb/DynamicElements/WORepetition.m (working copy) -@@ -823,6 +823,7 @@ - [self->template appendToResponse:_response inContext:_ctx]; - - /* cleanup */ -+ [self->item setValue:nil inComponent:sComponent]; - - [_ctx incrementLastElementIDComponent]; - -Index: sope-appserver/NGObjWeb/DynamicElements/WOxHTMLElemBuilder.m -=================================================================== ---- sope-appserver/NGObjWeb/DynamicElements/WOxHTMLElemBuilder.m (revision 1664) -+++ sope-appserver/NGObjWeb/DynamicElements/WOxHTMLElemBuilder.m (working copy) -@@ -223,6 +223,7 @@ - children = [_element hasChildNodes] - ? [_b buildNodes:[_element childNodes] templateBuilder:_b] - : (NSArray *)nil; -+ [children autorelease]; - - if ((count = [children count]) == 0) - return nil; -@@ -231,7 +232,7 @@ - return [[children objectAtIndex:0] retain]; - - return [[WOCompoundElement allocForCount:count -- zone:NULL] initWithContentElements:children]; -+ zone:NULL] initWithContentElements:children]; - } - - - (WOElement *)buildElement:(id)_element templateBuilder:(id)_b { -Index: sope-appserver/NGObjWeb/DynamicElements/_WOTemporaryHyperlink.m -=================================================================== ---- sope-appserver/NGObjWeb/DynamicElements/_WOTemporaryHyperlink.m (revision 1664) -+++ sope-appserver/NGObjWeb/DynamicElements/_WOTemporaryHyperlink.m (working copy) -@@ -135,6 +135,7 @@ - template = [[WOCompoundElement allocForCount:[_contents count] - zone:[self zone]] - initWithContentElements:_contents]; -+ [template autorelease]; - } - - return [self initWithName:_name -Index: sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h -=================================================================== ---- sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h (revision 1664) -+++ sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h (working copy) -@@ -41,7 +41,8 @@ - WOAssociation *pageName; - WOAssociation *actionClass; - WOAssociation *directActionName; -- -+ WOAssociation *isAbsolute; -+ - BOOL sidInUrl; - - /* 'ivar' associations */ -Index: sope-appserver/NGObjWeb/WOMessage.m -=================================================================== ---- sope-appserver/NGObjWeb/WOMessage.m (revision 1664) -+++ sope-appserver/NGObjWeb/WOMessage.m (working copy) -@@ -182,7 +182,7 @@ - NSString *key; - - keys = [_headers keyEnumerator]; -- while ((key = [keys nextObject])) { -+ while ((key = [[keys nextObject] lowercaseString])) { - id value; - - value = [_headers objectForKey:key]; -@@ -198,34 +198,39 @@ - } - - - (void)setHeader:(NSString *)_header forKey:(NSString *)_key { -- [self->header setObject:[_header stringValue] forKey:_key]; -+ [self->header setObject:[_header stringValue] -+ forKey:[_key lowercaseString]]; - } - - (NSString *)headerForKey:(NSString *)_key { -- return [[self->header objectEnumeratorForKey:_key] nextObject]; -+ return [[self->header objectEnumeratorForKey:[_key lowercaseString]] -+ nextObject]; - } - - - (void)appendHeader:(NSString *)_header forKey:(NSString *)_key { -- [self->header addObject:_header forKey:_key]; -+ [self->header addObject:_header forKey:[_key lowercaseString]]; - } - - (void)appendHeaders:(NSArray *)_headers forKey:(NSString *)_key { -- [self->header addObjects:_headers forKey:_key]; -+ [self->header addObjects:_headers forKey:[_key lowercaseString]]; - } - - - (void)setHeaders:(NSArray *)_headers forKey:(NSString *)_key { - NSEnumerator *e; - id value; -+ NSString *lowerKey; - -+ lowerKey = [_key lowercaseString]; - e = [_headers objectEnumerator]; - -- [self->header removeAllObjectsForKey:_key]; -+ [self->header removeAllObjectsForKey:lowerKey]; - - while ((value = [e nextObject])) -- [self->header addObject:value forKey:_key]; -+ [self->header addObject:value forKey:lowerKey]; - } - - (NSArray *)headersForKey:(NSString *)_key { - NSEnumerator *values; - -- if ((values = [self->header objectEnumeratorForKey:_key])) { -+ if ((values -+ = [self->header objectEnumeratorForKey:[_key lowercaseString]])) { - NSMutableArray *array = nil; - id value = nil; - -@@ -243,17 +248,14 @@ - NSEnumerator *values; - - if ((values = [self->header keyEnumerator])) { -- NSMutableArray *array = nil; -+ NSMutableArray *array; - id name = nil; -- array = [[NSMutableArray alloc] init]; -- -+ array = [NSMutableArray array]; -+ - while ((name = [values nextObject])) - [array addObject:name]; - -- name = [array copy]; -- [array release]; -- -- return [name autorelease]; -+ return array; - } - return nil; - } -Index: sope-appserver/NGObjWeb/SoObjects/SoObject.h -=================================================================== ---- sope-appserver/NGObjWeb/SoObjects/SoObject.h (revision 1664) -+++ sope-appserver/NGObjWeb/SoObjects/SoObject.h (working copy) -@@ -59,6 +59,8 @@ - - (NSString *)defaultMethodNameInContext:(id)_ctx; - - (id)lookupDefaultMethod; - -+- (BOOL)isFolderish; -+ - /* binding (returns self by default [unbound objects]) */ - - - (id)bindToObject:(id)_object inContext:(id)_ctx; -Index: sope-appserver/NGObjWeb/SoObjects/SoObject.m -=================================================================== ---- sope-appserver/NGObjWeb/SoObjects/SoObject.m (revision 1664) -+++ sope-appserver/NGObjWeb/SoObjects/SoObject.m (working copy) -@@ -30,31 +30,39 @@ - #include - #include "common.h" - --@interface NSObject(Folders) --- (BOOL)isFolderish; --@end -- - @implementation NSObject(SoObject) - - static int debugLookup = -1; - static int debugBaseURL = -1; - static int useRelativeURLs = -1; -+static int redirectInitted = -1; -+static NSURL *redirectURL = nil; -+ - static void _initialize(void) { -+ NSString *url; -+ NSUserDefaults *ud; -+ -+ ud = [NSUserDefaults standardUserDefaults]; -+ - if (debugLookup == -1) { -- debugLookup = [[NSUserDefaults standardUserDefaults] -- boolForKey:@"SoDebugKeyLookup"] ? 1 : 0; -+ debugLookup = [ud boolForKey:@"SoDebugKeyLookup"] ? 1 : 0; - NSLog(@"Note(SoObject): SoDebugKeyLookup is enabled!"); - } - if (debugBaseURL == -1) { -- debugBaseURL = [[NSUserDefaults standardUserDefaults] -- boolForKey:@"SoDebugBaseURL"] ? 1 : 0; -+ debugBaseURL = [ud boolForKey:@"SoDebugBaseURL"] ? 1 : 0; - NSLog(@"Note(SoObject): SoDebugBaseURL is enabled!"); - } - if (useRelativeURLs == -1) { -- useRelativeURLs = [[NSUserDefaults standardUserDefaults] -- boolForKey:@"WOUseRelativeURLs"] ?1:0; -+ useRelativeURLs = [ud boolForKey:@"WOUseRelativeURLs"] ?1:0; - NSLog(@"Note(SoObject): relative base URLs are enabled."); - } -+ if (redirectInitted == -1) { -+ url = [ud stringForKey:@"WOApplicationRedirectURL"]; -+ if ([url length]) { -+ redirectURL = [[NSURL alloc] initWithString: url]; -+ } -+ redirectInitted = 1; -+ } - } - - /* classes */ -@@ -241,6 +249,11 @@ - return pathArray; - } - -+- (BOOL) isFolderish -+{ -+ return NO; -+} -+ - - (NSString *)baseURLInContext:(id)_ctx { - NSString *baseURL; - id parent; -@@ -284,10 +297,8 @@ - /* add a trailing slash for folders */ - - if (![baseURL hasSuffix:@"/"]) { -- if ([self respondsToSelector:@selector(isFolderish)]) { -- if ([self isFolderish]) -- baseURL = [baseURL stringByAppendingString:@"/"]; -- } -+ if ([self isFolderish]) -+ baseURL = [baseURL stringByAppendingString:@"/"]; - } - - return baseURL; -@@ -318,56 +329,61 @@ - - rq = [_ctx request]; - ms = [[NSMutableString alloc] initWithCapacity:128]; -+ -+ if (redirectURL) { -+ [ms appendString: [redirectURL absoluteString]]; -+ } -+ else { -+ if (!useRelativeURLs) { -+ port = [[rq headerForKey:@"x-webobjects-server-port"] intValue]; - -- if (!useRelativeURLs) { -- port = [[rq headerForKey:@"x-webobjects-server-port"] intValue]; -- -- /* this is actually a bug in Apache */ -- if (port == 0) { -- static BOOL didWarn = NO; -- if (!didWarn) { -- [self warnWithFormat:@"(%s:%i): got an empty port from Apache!", -- __PRETTY_FUNCTION__, __LINE__]; -- didWarn = YES; -+ /* this is actually a bug in Apache */ -+ if (port == 0) { -+ static BOOL didWarn = NO; -+ if (!didWarn) { -+ [self warnWithFormat:@"(%s:%i): got an empty port from Apache!", -+ __PRETTY_FUNCTION__, __LINE__]; -+ didWarn = YES; -+ } -+ port = 80; - } -- port = 80; -- } - -- if ((tmp = [rq headerForKey:@"host"]) != nil) { -- /* check whether we have a host header with port */ -- if ([tmp rangeOfString:@":"].length == 0) -- tmp = nil; -- } -- if (tmp != nil) { /* we have a host header with port */ -- isHTTPS = -- [[rq headerForKey:@"x-webobjects-server-url"] hasPrefix:@"https"]; -- [ms appendString:isHTTPS ? @"https://" : @"http://"]; -- [ms appendString:tmp]; -- } -- else if ((tmp = [rq headerForKey:@"x-webobjects-server-url"]) != nil) { -- /* sometimes the URL is just wrong! (suggests port 80) */ -- if ([tmp hasSuffix:@":0"] && [tmp length] > 2) { // TODO: bad bad bad -- [self warnWithFormat:@"%s: got incorrect URL from Apache: '%@'", -- __PRETTY_FUNCTION__, tmp]; -- tmp = [tmp substringToIndex:([tmp length] - 2)]; -+ if ((tmp = [rq headerForKey:@"host"]) != nil) { -+ /* check whether we have a host header with port */ -+ if ([tmp rangeOfString:@":"].length == 0) -+ tmp = nil; - } -- else if ([tmp hasSuffix:@":443"] && [tmp hasPrefix:@"http://"]) { -- /* see OGo bug #1435, Debian Apache hack */ -- [self warnWithFormat:@"%s: got 'http' protocol but 443 port, " -- @"assuming Debian/Apache bug (OGo #1435): '%@'", -- __PRETTY_FUNCTION__, tmp]; -- tmp = [tmp substringWithRange:NSMakeRange(4, [tmp length] - 4 - 4)]; -- tmp = [@"https" stringByAppendingString:tmp]; -+ if (tmp != nil) { /* we have a host header with port */ -+ isHTTPS = -+ [[rq headerForKey:@"x-webobjects-server-url"] hasPrefix:@"https"]; -+ [ms appendString:isHTTPS ? @"https://" : @"http://"]; -+ [ms appendString:tmp]; - } -- [ms appendString:tmp]; -- } -- else { -- // TODO: isHTTPS always no in this case? -- [ms appendString:isHTTPS ? @"https://" : @"http://"]; -+ else if ((tmp = [rq headerForKey:@"x-webobjects-server-url"]) != nil) { -+ /* sometimes the URL is just wrong! (suggests port 80) */ -+ if ([tmp hasSuffix:@":0"] && [tmp length] > 2) { // TODO: bad bad bad -+ [self warnWithFormat:@"%s: got incorrect URL from Apache: '%@'", -+ __PRETTY_FUNCTION__, tmp]; -+ tmp = [tmp substringToIndex:([tmp length] - 2)]; -+ } -+ else if ([tmp hasSuffix:@":443"] && [tmp hasPrefix:@"http://"]) { -+ /* see OGo bug #1435, Debian Apache hack */ -+ [self warnWithFormat:@"%s: got 'http' protocol but 443 port, " -+ @"assuming Debian/Apache bug (OGo #1435): '%@'", -+ __PRETTY_FUNCTION__, tmp]; -+ tmp = [tmp substringWithRange:NSMakeRange(4, [tmp length] - 4 - 4)]; -+ tmp = [@"https" stringByAppendingString:tmp]; -+ } -+ [ms appendString:tmp]; -+ } -+ else { -+ // TODO: isHTTPS always no in this case? -+ [ms appendString:isHTTPS ? @"https://" : @"http://"]; - -- [ms appendString:[rq headerForKey:@"x-webobjects-server-name"]]; -- if ((isHTTPS ? (port != 443) : (port != 80)) && port != 0) -- [ms appendFormat:@":%i", port]; -+ [ms appendString:[rq headerForKey:@"x-webobjects-server-name"]]; -+ if ((isHTTPS ? (port != 443) : (port != 80)) && port != 0) -+ [ms appendFormat:@":%i", port]; -+ } - } - } - -Index: sope-appserver/NGObjWeb/NGObjWeb/WOAdaptor.h -=================================================================== ---- sope-appserver/NGObjWeb/NGObjWeb/WOAdaptor.h (revision 1664) -+++ sope-appserver/NGObjWeb/NGObjWeb/WOAdaptor.h (working copy) -@@ -27,6 +27,13 @@ - @class NSString, NSDictionary; - @class WOCoreApplication; - -+typedef enum { -+ WOChildMessageAccept = 0, -+ WOChildMessageReady, -+ WOChildMessageShutdown, -+ WOChildMessageMax -+} WOChildMessage; -+ - @interface WOAdaptor : NSObject - { - @protected -Index: sope-appserver/NGObjWeb/NGObjWeb/WOCoreApplication.h -=================================================================== ---- sope-appserver/NGObjWeb/NGObjWeb/WOCoreApplication.h (revision 1664) -+++ sope-appserver/NGObjWeb/NGObjWeb/WOCoreApplication.h (working copy) -@@ -31,6 +31,8 @@ - @class WOAdaptor, WORequest, WOResponse, WORequestHandler; - @class NSBundle; - -+@class NGActiveSocket, NGPassiveSocket; -+ - NGObjWeb_EXPORT NSString *WOApplicationWillFinishLaunchingNotification; - NGObjWeb_EXPORT NSString *WOApplicationDidFinishLaunchingNotification; - NGObjWeb_EXPORT NSString *WOApplicationWillTerminateNotification; -@@ -41,6 +43,9 @@ - NSRecursiveLock *lock; - NSLock *requestLock; - -+ NGActiveSocket *controlSocket; -+ NGPassiveSocket *listeningSocket; -+ - struct { - BOOL isTerminating:1; - } cappFlags; -@@ -55,6 +60,14 @@ - - (void)activateApplication; - - (void)deactivateApplication; - -+/* Watchdog helpers */ -+ -+- (void)setControlSocket: (NGActiveSocket *) newSocket; -+- (NGActiveSocket *)controlSocket; -+ -+- (void)setListeningSocket: (NGPassiveSocket *) newSocket; -+- (NGPassiveSocket *)listeningSocket; -+ - /* adaptors */ - - - (NSArray *)adaptors; -Index: sope-appserver/NGObjWeb/Templates/WOxElemBuilder.m -=================================================================== ---- sope-appserver/NGObjWeb/Templates/WOxElemBuilder.m (revision 1664) -+++ sope-appserver/NGObjWeb/Templates/WOxElemBuilder.m (working copy) -@@ -280,7 +280,7 @@ - if ((count = [_nodes length]) == 0) - return nil; - -- children = [NSMutableArray arrayWithCapacity:(count + 1)]; -+ children = [[NSMutableArray alloc] initWithCapacity:(count + 1)]; - - for (i = 0; i < count; i++) { - WOElement *e; -@@ -376,9 +376,9 @@ - WOElement *result; - - pool = [[NSAutoreleasePool alloc] init]; -- result = [[self buildNode:_document templateBuilder:self] retain]; -+ result = [self buildNode:_document templateBuilder:self]; - [pool release]; -- return [result autorelease]; -+ return result; - } - - /* association callbacks */ -@@ -773,6 +773,7 @@ - children = [_tag hasChildNodes] - ? [_b buildNodes:[_tag childNodes] templateBuilder:_b] - : (NSArray *)nil; -+ [children autorelease]; - - return [self wrapElements:children inElementOfClass:_class]; - } -Index: sope-appserver/NGObjWeb/Templates/WOWrapperTemplateBuilder.m -=================================================================== ---- sope-appserver/NGObjWeb/Templates/WOWrapperTemplateBuilder.m (revision 1664) -+++ sope-appserver/NGObjWeb/Templates/WOWrapperTemplateBuilder.m (working copy) -@@ -406,6 +406,7 @@ - NS_ENDHANDLER; - - [self->iTemplate setRootElement:rootElement]; -+ [rootElement release]; - template = self->iTemplate; - self->iTemplate = nil; - -@@ -423,7 +424,7 @@ - [script release]; - } - -- return [template autorelease]; -+ return template; - } - - /* creating associations from WO/hash tag attributes */ -Index: sope-appserver/NGObjWeb/Templates/WOxComponentElemBuilder.m -=================================================================== ---- sope-appserver/NGObjWeb/Templates/WOxComponentElemBuilder.m (revision 1664) -+++ sope-appserver/NGObjWeb/Templates/WOxComponentElemBuilder.m (working copy) -@@ -116,6 +116,7 @@ - children = [_element hasChildNodes] - ? [_b buildNodes:[_element childNodes] templateBuilder:_b] - : (NSArray *)nil; -+ [children autorelease]; - - /* build associations */ - -@@ -258,6 +259,7 @@ - children = [_element hasChildNodes] - ? [_b buildNodes:[_element childNodes] templateBuilder:_b] - : (NSArray *)nil; -+ [children autorelease]; - - if (compName == nil) - compName = [_element tagName]; -Index: sope-appserver/NGObjWeb/Templates/WOxTemplateBuilder.m -=================================================================== ---- sope-appserver/NGObjWeb/Templates/WOxTemplateBuilder.m (revision 1664) -+++ sope-appserver/NGObjWeb/Templates/WOxTemplateBuilder.m (working copy) -@@ -69,11 +69,11 @@ - - builder = [self builderForDocument:_doc]; - -- root = [[builder buildTemplateFromDocument:_doc] retain]; -+ root = [builder buildTemplateFromDocument:_doc]; - - template = [[self templateClass] alloc]; - template = [template initWithURL:_url rootElement:root]; -- template = [template autorelease]; -+ [root release]; - - /* transform builder info's into element defs ... */ - -@@ -150,10 +150,9 @@ - else - template = nil; - -- template = [template retain]; - [pool release]; - -- return [template autorelease]; -+ return template; - } - - @end /* WOxTemplateBuilder */ -Index: sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpAdaptor.h -=================================================================== ---- sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpAdaptor.h (revision 1664) -+++ sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpAdaptor.h (working copy) -@@ -28,11 +28,13 @@ - #include - - @class NSMutableArray; -+@class NGActiveSocket; - - @interface WOHttpAdaptor : WOAdaptor - { - @protected - id socket; -+ NGActiveSocket *controlSocket; - NSTimeInterval sendTimeout; - NSTimeInterval receiveTimeout; - -@@ -46,7 +48,6 @@ - NSMutableArray *delayedResponses; - } - --+ (BOOL)optionLogStream; - + (BOOL)optionLogPerf; - - @end -Index: sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m -=================================================================== ---- sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m (revision 1664) -+++ sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m (working copy) -@@ -48,8 +48,8 @@ - NSString *WOAsyncResponseReadyNotificationName = - @"WOAsyncResponseReadyNotification"; - NSString *WOAsyncResponse = @"WOAsyncResponse"; -+static BOOL WOHttpAdaptor_LogStream = NO; - -- - @interface WOCoreApplication(SimpleParserSelection) - - - (BOOL)shouldUseSimpleHTTPParserForTransaction:(id)_tx; -@@ -85,13 +85,14 @@ - ud = [NSUserDefaults standardUserDefaults]; - useSimpleParser = [ud boolForKey:@"WOHttpTransactionUseSimpleParser"]; - doCore = [[ud objectForKey:@"WOCoreOnHTTPAdaptorException"] boolValue]?1:0; -+ WOHttpAdaptor_LogStream = [ud boolForKey:@"WOHttpAdaptor_LogStream"]; - - adLogPath = [[ud stringForKey:@"WOAdaptorLogPath"] copy]; - if (adLogPath == nil) adLogPath = @""; - } - - - (BOOL)optionLogStream { -- return [WOHttpAdaptor optionLogStream]; -+ return WOHttpAdaptor_LogStream; - } - - (BOOL)optionLogPerf { - return perfLogger ? YES : NO; -@@ -108,6 +109,9 @@ - NSAssert(_app, @"missing application ..."); - self->socket = [_socket retain]; - self->application = [_app retain]; -+ if ([[_app recordingPath] length] > 0) -+ WOHttpAdaptor_LogStream = YES; -+ - return self; - } - -@@ -696,7 +700,7 @@ - *(&out) = nil; - - [self _httpValidateResponse:_response]; -- -+ - out = [(NGCTextStream *)[NGCTextStream alloc] initWithSource:_out]; - - NS_DURING { -@@ -705,6 +709,7 @@ - id body; - BOOL doZip; - BOOL isok = YES; -+ int length; - - doZip = [_response shouldZipResponseToRequest:_request]; - -@@ -738,7 +743,11 @@ - - /* add content length header */ - -- snprintf((char *)buf, sizeof(buf), "%d", [body length]); -+ if ((length = [body length]) == 0 -+ && ![[_response headerForKey: @"content-type"] hasPrefix:@"text/plain"]) { -+ [_response setHeader:@"text/plain" forKey:@"content-type"]; -+ } -+ snprintf((char *)buf, sizeof(buf), "%d", length); - t1 = [[NSString alloc] initWithCString:(char *)buf]; - [_response setHeader:t1 forKey:@"content-length"]; - [t1 release]; t1 = nil; -@@ -766,7 +775,7 @@ - NSString *value; - - if (!hasConnectionHeader) { -- if ([fieldName caseInsensitiveCompare:@"connection"]==NSOrderedSame) -+ if ([fieldName isEqualToString:@"connection"]) - hasConnectionHeader = YES; - } - -@@ -789,7 +798,7 @@ - NSLog(@" END: %@", fieldName); - #endif - } -- -+ - #if HEAVY_DEBUG - NSLog(@" HEADER:\n%@", header); - NSLog(@" OUT: %@", out); -Index: sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpAdaptor.m -=================================================================== ---- sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpAdaptor.m (revision 1664) -+++ sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpAdaptor.m (working copy) -@@ -71,18 +71,13 @@ - - static NGLogger *logger = nil; - static NGLogger *perfLogger = nil; --static BOOL WOHttpAdaptor_LogStream = NO; - static BOOL WOContactSNS = NO; - static BOOL WOCoreOnHTTPAdaptorException = NO; - static int WOHttpAdaptorSendTimeout = 10; - static int WOHttpAdaptorReceiveTimeout = 10; --static int WOHttpAdaptorForkCount = 0; - static id allow = nil; - static BOOL debugOn = NO; - --+ (BOOL)optionLogStream { -- return WOHttpAdaptor_LogStream; --} - + (BOOL)optionLogPerf { - return perfLogger != nil ? YES : NO; - } -@@ -108,8 +103,6 @@ - logger = [lm loggerForClass:self]; - perfLogger = [lm loggerForDefaultKey:@"WOProfileHttpAdaptor"]; - -- WOHttpAdaptor_LogStream = [ud boolForKey:@"WOHttpAdaptor_LogStream"]; -- - // TODO: this should be queried on demand to allow different defaults - WOContactSNS = [[ud objectForKey:@"WOContactSNS"] boolValue]; - -@@ -134,9 +127,6 @@ - allow = [allow copy]; - } - -- WOHttpAdaptorForkCount = -- [[ud objectForKey:@"WOHttpAdaptorForkCount"] intValue]; -- - if (WOCoreOnHTTPAdaptorException) - [logger warnWithFormat:@"will dump core on HTTP adaptor exception!"]; - } -@@ -219,33 +209,31 @@ - application:_application])) { - id arg = nil; - -- if ([[_application recordingPath] length] > 0) -- WOHttpAdaptor_LogStream = YES; -- - [self _registerForSignals]; -+ if (![_application controlSocket]) { -+ if ([_args count] < 1) -+ self->address = [self addressFromDefaultsOfApplication:_application]; -+ else -+ self->address = [self addressFromArguments:_args]; - -- if ([_args count] < 1) -- self->address = [self addressFromDefaultsOfApplication:_application]; -- else -- self->address = [self addressFromArguments:_args]; -+ self->address = [self->address retain]; - -- self->address = [self->address retain]; -+ if (self->address == nil) { -+ [_application errorWithFormat: -+ @"got no address for HTTP server (using arg '%@')", arg]; -+ [self release]; -+ return nil; -+ } - -- if (self->address == nil) { -- [_application errorWithFormat: -- @"got no address for HTTP server (using arg '%@')", arg]; -- [self release]; -- return nil; -- } -- -- if (!WOContactSNS) { -- [_application logWithFormat:@"%@ listening on address %@", -+ if (!WOContactSNS) { -+ [_application logWithFormat:@"%@ listening on address %@", - NSStringFromClass([self class]), - [(id)self->address stringValue]]; -+ } - } - - self->lock = [[NSRecursiveLock alloc] init]; -- -+ - self->maxThreadCount = [[WOCoreApplication workerThreadCount] intValue]; - - [self setSendTimeout:WOHttpAdaptorSendTimeout]; -@@ -259,6 +247,7 @@ - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [self->lock release]; - [self->socket release]; -+ [self->controlSocket release]; - [self->address release]; - [super dealloc]; - } -@@ -270,145 +259,76 @@ - return self->address; - } - --/* forking */ -- --static pid_t *childPIDs = NULL; --static BOOL isForkMaster = YES; -- --- (void)forkChildren { -- unsigned i; -- -- if (WOHttpAdaptorForkCount == 0) -- return; -- -- [self logWithFormat:@"Note: forking %d children for socket processing.", -- WOHttpAdaptorForkCount]; -- --#if !defined(__MINGW32__) -- [[UnixSignalHandler sharedHandler] -- addObserver:self selector:@selector(handleSIGCHLD:) -- forSignal:SIGCHLD immediatelyNotifyOnSignal:NO]; --#endif -- -- childPIDs = calloc(WOHttpAdaptorForkCount + 1, sizeof(pid_t)); -- for (i = 0; i < WOHttpAdaptorForkCount; i++) { -- childPIDs[i] = fork(); -- -- if (childPIDs[i] == 0) { -- /* child */ -- isForkMaster = NO; -- return; -- } -- else if (childPIDs[i] > 0) -- printf("Note: successfully forked child: %i\n", childPIDs[i]); -- else -- [self errorWithFormat:@"failed to fork child %i.", i]; -- } --} --- (void)killChildren { -- int i; -- -- if (!isForkMaster) -- return; -- -- for (i = 0; i < WOHttpAdaptorForkCount; i++) { -- if (childPIDs[i] != 0) -- kill(childPIDs[i], SIGKILL); -- } --} -- --- (void)checkStatusOfChildren { -- /* -- Note: currently this does not refork crashed processes. Reforking is harder -- than it may sound because the crash can happen at arbitary execution -- states. -- That is, the "master process" is not virgin anymore, eg it might have -- open database connections. -- -- So the solution might be to refork the whole cluster once a minimum -- backend threshold is reached. -- */ -- unsigned int i; -- -- if (!isForkMaster) -- return; -- -- for (i = 0; i < WOHttpAdaptorForkCount; i++) { -- pid_t result; -- int status; -- -- if (childPIDs[i] == 0) -- continue; -- -- result = waitpid(childPIDs[i], &status, WNOHANG); -- if (result == 0) /* did not exit yet */ -- continue; -- -- if (result == -1) { /* error */ -- [self errorWithFormat:@"failed to get status of child %i: %s", -- childPIDs[i], strerror(errno)]; -- continue; -- } -- -- [self logWithFormat:@"Note: child %i terminated.", childPIDs[i]]; -- childPIDs[i] = 0; -- } --} -- - /* events */ - - - (void)handleSIGPIPE:(int)_signal { - [self warnWithFormat:@"caught SIGPIPE !"]; - } --- (void)handleSIGCHLD:(int)_signal { -- [self checkStatusOfChildren]; --} - - - (void)registerForEvents { - int backlog; -+ WOChildMessage message; -+ -+ controlSocket = [[WOCoreApplication application] controlSocket]; -+ if (controlSocket) { -+ [controlSocket retain]; -+ ASSIGN(self->socket, [[WOCoreApplication application] listeningSocket]); -+ [[NSNotificationCenter defaultCenter] -+ addObserver:self -+ selector:@selector(acceptControlMessage:) -+ name:NSFileObjectBecameActiveNotificationName -+ object:nil]; -+ [(WORunLoop *)[WORunLoop currentRunLoop] -+ addFileObject:controlSocket -+ activities:NSPosixReadableActivity -+ forMode:NSDefaultRunLoopMode]; -+ message = WOChildMessageReady; -+ [controlSocket safeWriteBytes: &message -+ count: sizeof (WOChildMessage)]; -+ // [self logWithFormat: @"notified the watchdog that we are ready"]; -+ } -+ else { -+ backlog = [[WOCoreApplication listenQueueSize] intValue]; - -- backlog = [[WOCoreApplication listenQueueSize] intValue]; -+ if (backlog == 0) -+ backlog = 5; - -- if (backlog == 0) -- backlog = 5; -+ [self->socket release]; self->socket = nil; - -- [self->socket release]; self->socket = nil; -+ self->socket = -+ [[NGPassiveSocket alloc] initWithDomain:[self->address domain]]; - -- self->socket = -- [[NGPassiveSocket alloc] initWithDomain:[self->address domain]]; -+ [self->socket bindToAddress:self->address]; - -- [self->socket bindToAddress:self->address]; -- -- if ([[self->address domain] isEqual:[NGInternetSocketDomain domain]]) { -- if ([(NGInternetSocketAddress *)self->address port] == 0) { -- /* let the kernel choose an IP address */ -+ if ([[self->address domain] isEqual:[NGInternetSocketDomain domain]]) { -+ if ([(NGInternetSocketAddress *)self->address port] == 0) { -+ /* let the kernel choose an IP address */ - -- [self debugWithFormat:@"bound to wildcard: %@", self->address]; -- [self debugWithFormat:@"got local: %@", [self->socket localAddress]]; -+ [self debugWithFormat:@"bound to wildcard: %@", self->address]; -+ [self debugWithFormat:@"got local: %@", [self->socket localAddress]]; - -- self->address = [[self->socket localAddress] retain]; -+ self->address = [[self->socket localAddress] retain]; - -- [self logWithFormat:@"bound to kernel assigned address %@: %@", -+ [self logWithFormat:@"bound to kernel assigned address %@: %@", - self->address, self->socket]; -+ } - } -- } - -- [self->socket listenWithBacklog:backlog]; -+ [self->socket listenWithBacklog:backlog]; - -- [[NSNotificationCenter defaultCenter] -+ [[NSNotificationCenter defaultCenter] - addObserver:self selector:@selector(acceptConnection:) -- name:NSFileObjectBecameActiveNotificationName -- object:self->socket]; -- [(WORunLoop *)[WORunLoop currentRunLoop] -+ name:NSFileObjectBecameActiveNotificationName -+ object:self->socket]; -+ -+ [(WORunLoop *)[WORunLoop currentRunLoop] - addFileObject:self->socket - activities:NSPosixReadableActivity - forMode:NSDefaultRunLoopMode]; -- -- [self forkChildren]; -+ } - } -+ - - (void)unregisterForEvents { -- [self killChildren]; -- - [(WORunLoop *)[WORunLoop currentRunLoop] - removeFileObject:self->socket forMode:NSDefaultRunLoopMode]; - [[NSNotificationCenter defaultCenter] removeObserver:self]; -@@ -603,52 +523,93 @@ - return _connection; - } - -+- (NGActiveSocket *)_accept { -+ NGActiveSocket *connection; -+ -+ NS_DURING { -+ connection = [self->socket accept]; -+ if (!connection) -+ [self _serverCatched:[self->socket lastException]]; -+ else -+ [self debugWithFormat:@"accepted connection: %@", connection]; -+ } -+ NS_HANDLER { -+ connection = nil; -+ [self _serverCatched:localException]; -+ } -+ NS_ENDHANDLER; -+ -+ return connection; -+} -+ -+- (void)_handleConnection:(NGActiveSocket *)connection { -+ if (connection != nil) { -+ if (self->maxThreadCount <= 1) { -+ NS_DURING -+ [self _handleAcceptedConnection:[connection retain]]; -+ NS_HANDLER -+ [self _serverCatched:localException]; -+ NS_ENDHANDLER; -+ } -+ else { -+ [NSThread detachNewThreadSelector: -+ @selector(_handleAcceptedConnectionInThread:) -+ toTarget:self -+ withObject:[connection retain]]; -+ [self logWithFormat:@"detached new thread for request."]; -+ //[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]]; -+ } -+ connection = nil; -+ } -+} -+ -+- (void) acceptControlMessage: (NSNotification *) aNotification -+{ -+ NGActiveSocket *notificationSocket, *connection; -+ WOChildMessage message; -+ NSAutoreleasePool *pool; -+ -+ // NSLog (@"received control message"); -+ notificationSocket = [aNotification object]; -+ if (notificationSocket == controlSocket) { -+ // [self logWithFormat:@"child accepting message from socket: %@", controlSocket]; -+ while (![controlSocket safeReadBytes: &message -+ count: sizeof (WOChildMessage)]) -+ NSLog (@"renotifying watchdog"); -+ if (message == WOChildMessageAccept) { -+ pool = [NSAutoreleasePool new]; -+ connection = [self _accept]; -+ if ([controlSocket safeWriteBytes: &message -+ count: sizeof (WOChildMessage)]) -+ ; -+ [self _handleConnection: connection]; -+ message = WOChildMessageReady; -+ [controlSocket safeWriteBytes: &message count: sizeof (WOChildMessage)]; -+ [pool release]; -+ } -+ else if (message == WOChildMessageShutdown) { -+ [controlSocket safeWriteBytes: &message -+ count: sizeof (WOChildMessage)]; -+ [[WOCoreApplication application] terminate]; -+ } -+ } -+} -+ - - (void)acceptConnection:(id)_notification { -+ NGActiveSocket *connection; - #if USE_POOLS - NSAutoreleasePool *pool; -- *(&pool) = [[NSAutoreleasePool alloc] init]; -+ -+ pool = [[NSAutoreleasePool alloc] init]; - #endif - { -- NGActiveSocket *connection; -- -- NS_DURING { -- *(&connection) = (NGActiveSocket *)[self->socket accept]; -- if (connection == nil) -- [self _serverCatched:[self->socket lastException]]; -- else -- [self debugWithFormat:@"accepted connection: %@", connection]; -- } -- NS_HANDLER { -- connection = nil; -- [self _serverCatched:localException]; -- } -- NS_ENDHANDLER; -- -- connection = (NGActiveSocket *)[self _checkAccessOnConnection:connection]; -- -- if (connection != nil) { -- if (self->maxThreadCount <= 1) { -- NS_DURING -- [self _handleAcceptedConnection:[connection retain]]; -- NS_HANDLER -- [self _serverCatched:localException]; -- NS_ENDHANDLER; -- } -- else { -- [NSThread detachNewThreadSelector: -- @selector(_handleAcceptedConnectionInThread:) -- toTarget:self -- withObject:[connection retain]]; -- [self logWithFormat:@"detached new thread for request."]; -- //[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]]; -- } -- connection = nil; -- } -+ connection = [self _checkAccessOnConnection:[self _accept]]; -+ [self _handleConnection: connection]; - } - #if USE_POOLS - [pool release]; pool = nil; - #endif -- -+ - if (self->isTerminated) { - if (self->socket) { - [[NSNotificationCenter defaultCenter] -Index: sope-appserver/NGObjWeb/WOCoreApplication.m -=================================================================== ---- sope-appserver/NGObjWeb/WOCoreApplication.m (revision 1664) -+++ sope-appserver/NGObjWeb/WOCoreApplication.m (working copy) -@@ -75,6 +75,43 @@ - NGObjWeb_DECLARE id WOApp = nil; - static NSMutableArray *activeApps = nil; // THREAD - -++ (void)registerUserDefaults { -+ NSDictionary *owDefaults = nil; -+ NSString *apath; -+ -+ apath = [[self class] findNGObjWebResource:@"Defaults" ofType:@"plist"]; -+ if (apath == nil) -+ [self errorWithFormat:@"Cannot find Defaults.plist resource of " -+ @"NGObjWeb library!"]; -+#if HEAVY_DEBUG -+ else -+ [self debugWithFormat:@"Note: loading default defaults: %@", apath]; -+#endif -+ -+ owDefaults = [NSDictionary dictionaryWithContentsOfFile:apath]; -+ if (owDefaults) { -+ [[NSUserDefaults standardUserDefaults] registerDefaults:owDefaults]; -+#if HEAVY_DEBUG -+ [self debugWithFormat:@"did register NGObjWeb defaults: %@\n%@", -+ apath, owDefaults]; -+#endif -+ } -+ else { -+ [self errorWithFormat:@"could not load NGObjWeb defaults: '%@'", -+ apath]; -+ } -+} -+ -++ (void)initialize -+{ -+ static BOOL initialized = NO; -+ -+ if (!initialized) { -+ [self registerUserDefaults]; -+ initialized = YES; -+ } -+} -+ - + (id)application { - if (WOApp == nil) { - [self warnWithFormat:@"%s: some code called +application without an " -@@ -115,33 +152,6 @@ - } - } - --- (void)registerUserDefaults { -- NSDictionary *owDefaults = nil; -- NSString *apath; -- -- apath = [[self class] findNGObjWebResource:@"Defaults" ofType:@"plist"]; -- if (apath == nil) -- [self errorWithFormat:@"Cannot find Defaults.plist resource of " -- @"NGObjWeb library!"]; --#if HEAVY_DEBUG -- else -- [self debugWithFormat:@"Note: loading default defaults: %@", apath]; --#endif -- -- owDefaults = [NSDictionary dictionaryWithContentsOfFile:apath]; -- if (owDefaults) { -- [[NSUserDefaults standardUserDefaults] registerDefaults:owDefaults]; --#if HEAVY_DEBUG -- [self debugWithFormat:@"did register NGObjWeb defaults: %@\n%@", -- apath, owDefaults]; --#endif -- } -- else { -- [self errorWithFormat:@"could not load NGObjWeb defaults: '%@'", -- apath]; -- } --} -- - - (id)init { - #if COCOA_Foundation_LIBRARY - /* -@@ -157,7 +167,6 @@ - NSUserDefaults *ud; - NGLoggerManager *lm; - -- [self registerUserDefaults]; - ud = [NSUserDefaults standardUserDefaults]; - lm = [NGLoggerManager defaultLoggerManager]; - logger = [lm loggerForClass:[self class]]; -@@ -190,6 +199,9 @@ - forSignal:SIGHUP immediatelyNotifyOnSignal:NO]; - } - #endif -+ -+ controlSocket = nil; -+ listeningSocket = nil; - } - return self; - } -@@ -202,9 +214,32 @@ - [self->adaptors release]; - [self->requestLock release]; - [self->lock release]; -+ [self->listeningSocket release]; -+ [self->controlSocket release]; - [super dealloc]; - } - -+/* Watchdog helpers */ -+- (void)setControlSocket: (NGActiveSocket *) newSocket -+{ -+ ASSIGN(self->controlSocket, newSocket); -+} -+ -+- (NGActiveSocket *)controlSocket -+{ -+ return self->controlSocket; -+} -+ -+- (void)setListeningSocket: (NGPassiveSocket *) newSocket -+{ -+ ASSIGN(self->listeningSocket, newSocket); -+} -+ -+- (NGPassiveSocket *)listeningSocket -+{ -+ return self->listeningSocket; -+} -+ - /* NGLogging */ - - + (id)logger { -@@ -225,6 +260,7 @@ - /* STDIO is forbidden in signal handlers !!! no malloc !!! */ - #if 1 - self->cappFlags.isTerminating = 1; -+ [self->listeningSocket close]; - #else - static int termCount = 0; - unsigned pid; -@@ -786,7 +822,9 @@ - id woport; - id addr; - -- woport = [[self userDefaults] objectForKey:@"WOPort"]; -+ woport = [[self userDefaults] objectForKey:@"p"]; -+ if (!woport) -+ woport = [[self userDefaults] objectForKey:@"WOPort"]; - if ([woport isKindOfClass:[NSNumber class]]) - return woport; - woport = [woport stringValue]; -Index: sope-appserver/NGObjWeb/WOHTTPURLHandle.m -=================================================================== ---- sope-appserver/NGObjWeb/WOHTTPURLHandle.m (revision 1664) -+++ sope-appserver/NGObjWeb/WOHTTPURLHandle.m (working copy) -@@ -51,7 +51,7 @@ - } - - - (id)initWithURL:(NSURL *)_url cached:(BOOL)_flag { -- if (![[_url scheme] isEqualToString:@"http"]) { -+ if (![[_url scheme] hasPrefix:@"http"]) { - NSLog(@"%s: invalid URL scheme %@ for WOHTTPURLHandle !", - __PRETTY_FUNCTION__, [_url scheme]); - RELEASE(self); -Index: sope-appserver/NGObjWeb/NGHttp/NGHttpRequest.m -=================================================================== ---- sope-appserver/NGObjWeb/NGHttp/NGHttpRequest.m (revision 1664) -+++ sope-appserver/NGObjWeb/NGHttp/NGHttpRequest.m (working copy) -@@ -59,6 +59,8 @@ - /* RFC 3253 (DeltaV) */ - @"REPORT", - @"VERSION-CONTROL", -+ /* RFC 3744 (WebDAV ACL) */ -+ @"ACL", - /* RFC 4791 (CalDAV) */ - @"MKCALENDAR", - /* http://ietfreport.isoc.org/idref/draft-daboo-carddav/ (CardDAV) */