diff --git a/.gitignore b/.gitignore
index 8b936b2cb..88becdaa6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,5 @@ tags
*.swp
SoObjects/SOGo/SOGo.framework/
SoObjects/SOGo/derived_src/
+Tests/*/config.py
+*.pyc
diff --git a/Apache/SOGo-apple-ab.conf b/Apache/SOGo-apple-ab.conf
index 0f5516f6d..9c42bf1cd 100644
--- a/Apache/SOGo-apple-ab.conf
+++ b/Apache/SOGo-apple-ab.conf
@@ -1,4 +1,52 @@
-# use *:8843 for SSL
+#
+#
+# Keep only one of those vhost definition, comment out the other one
+#
+#
+
+# for https
+# don't forget to add a Listen parameter for port 8843:
+# Listen 8843
+
+ ServerName YOUR.SERVER.NAME
+
+ SSLEngine on
+
+ SSLProtocol -ALL +SSLv3 +TLSv1
+ SSLHonorCipherOrder On
+ SSLCipherSuite HIGH:MEDIUM:!ADH:!aNULL:!eNULL:!NULL
+ SSLCertificateFile /path/to/your/cert/cert.pem
+ SSLCertificateChainFile /path/to/your/cert/cert-chain-file.pem
+ SSLCertificateKeyFile /path/to/your/key/file.key
+
+ RewriteEngine Off
+ ProxyRequests Off
+ SetEnv proxy-nokeepalive 1
+ ProxyPreserveHost On
+ ProxyPassInterpolateEnv On
+ ProxyPass /principals http://127.0.0.1:20000/SOGo/dav/ interpolate
+ ProxyPass /SOGo http://127.0.0.1:20000/SOGo interpolate
+ ProxyPass / http://127.0.0.1:20000/SOGo/dav/ interpolate
+
+ Order allow,deny
+ Allow from all
+
+
+
+ RequestHeader set "x-webobjects-server-port" "8843"
+ RequestHeader set "x-webobjects-server-name" "CHANGETHIS:8843"
+ RequestHeader set "x-webobjects-server-url" "http://CHANGETHIS:8843"
+ RequestHeader set "x-webobjects-server-protocol" "HTTP/1.0"
+ AddDefaultCharset UTF-8
+
+
+ ErrorLog /var/log/apache2/ab-error.log
+ CustomLog /var/log/apache2/ab-access.log combined
+
+
+# plain http
+# Same here, don't forget to add a Listen parameter for port 8800:
+# Listen 8800
RewriteEngine Off
ProxyRequests Off
diff --git a/Apache/SOGo.conf b/Apache/SOGo.conf
index 853b5ae0e..e065c3240 100644
--- a/Apache/SOGo.conf
+++ b/Apache/SOGo.conf
@@ -66,3 +66,9 @@ ProxyPass /SOGo http://127.0.0.1:20000/SOGo retry=0
Allow from all
+# For apple autoconfiguration
+
+ RewriteEngine On
+ RewriteRule ^/.well-known/caldav/?$ /SOGo/dav [R=301]
+
+
diff --git a/ChangeLog b/ChangeLog
index 8eda0e0db..154cb2dbd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,895 @@
+commit d0b09ebe35d9bde78f627b6569660627c60c8e42
+Author: Francis Lachapelle
+Date: Thu Nov 7 14:14:39 2013 -0500
+
+ Update translations
+
+M UI/MailPartViewers/German.lproj/Localizable.strings
+M UI/MailPartViewers/Hungarian.lproj/Localizable.strings
+M UI/Scheduler/Hungarian.lproj/Localizable.strings
+
+commit 0361b7dfdb27fcb3adf1c0f735885f2cf710c890
+Author: Francis Lachapelle
+Date: Thu Nov 7 11:09:41 2013 -0500
+
+ Documentation - bump version to 2.1.0
+
+M Documentation/SOGo Installation Guide.odt
+M Documentation/SOGo Mobile Devices Configuration.odt
+M Documentation/SOGo Mozilla Thunderbird Configuration.odt
+M Documentation/SOGo Native Microsoft Outlook Configuration.odt
+
+commit 38b350382a565e585053561615528a7eed28c0fe
+Author: Francis Lachapelle
+Date: Thu Nov 7 10:13:30 2013 -0500
+
+ Update NEWS file
+
+M NEWS
+
+commit 73141a645e4b206bd536d71dfe2867a57ec6a21c
+Author: Francis Lachapelle
+Date: Wed Nov 6 21:36:09 2013 -0500
+
+ Update translations
+
+M SoObjects/Appointments/NorwegianBokmal.lproj/Localizable.strings
+M UI/AdministrationUI/NorwegianBokmal.lproj/Localizable.strings
+M UI/Common/NorwegianBokmal.lproj/Localizable.strings
+M UI/Contacts/NorwegianBokmal.lproj/Localizable.strings
+M UI/MailPartViewers/Catalan.lproj/Localizable.strings
+M UI/MailPartViewers/French.lproj/Localizable.strings
+M UI/MailPartViewers/NorwegianBokmal.lproj/Localizable.strings
+M UI/MailerUI/French.lproj/Localizable.strings
+M UI/MailerUI/NorwegianBokmal.lproj/Localizable.strings
+M UI/MainUI/NorwegianBokmal.lproj/Localizable.strings
+M UI/MainUI/Slovak.lproj/Localizable.strings
+M UI/PreferencesUI/Danish.lproj/Localizable.strings
+M UI/PreferencesUI/Icelandic.lproj/Localizable.strings
+M UI/PreferencesUI/NorwegianBokmal.lproj/Localizable.strings
+M UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings
+M UI/Scheduler/Czech.lproj/Localizable.strings
+M UI/Scheduler/Finnish.lproj/Localizable.strings
+M UI/Scheduler/Hungarian.lproj/Localizable.strings
+M UI/Scheduler/NorwegianBokmal.lproj/Localizable.strings
+M UI/Scheduler/Russian.lproj/Localizable.strings
+M UI/Scheduler/SpanishSpain.lproj/Localizable.strings
+
+commit f07526423f0f2a0fcac5a132aadc09188babba3c
+Author: Francis Lachapelle
+Date: Wed Nov 6 15:25:36 2013 -0500
+
+ Fix display of ICal event in message
+
+M UI/MailPartViewers/English.lproj/Localizable.strings
+M UI/Templates/MailPartViewers/UIxMailPartICalViewer.wox
+
+commit ba35a4b003318a0a4483e019c8726a9856b73fbb
+Author: Francis Lachapelle
+Date: Wed Nov 6 11:29:15 2013 -0500
+
+ Update CKEditor to version 4.2.2
+
+M UI/WebServerResources/ckeditor/build-config.js
+M UI/WebServerResources/ckeditor/ckeditor.js
+M UI/WebServerResources/ckeditor/contents.css
+M UI/WebServerResources/ckeditor/lang/ar.js
+M UI/WebServerResources/ckeditor/lang/ca.js
+M UI/WebServerResources/ckeditor/lang/cs.js
+M UI/WebServerResources/ckeditor/lang/cy.js
+M UI/WebServerResources/ckeditor/lang/da.js
+M UI/WebServerResources/ckeditor/lang/de.js
+M UI/WebServerResources/ckeditor/lang/en.js
+M UI/WebServerResources/ckeditor/lang/es.js
+M UI/WebServerResources/ckeditor/lang/fi.js
+M UI/WebServerResources/ckeditor/lang/fr.js
+M UI/WebServerResources/ckeditor/lang/hu.js
+M UI/WebServerResources/ckeditor/lang/is.js
+M UI/WebServerResources/ckeditor/lang/it.js
+M UI/WebServerResources/ckeditor/lang/nb.js
+M UI/WebServerResources/ckeditor/lang/nl.js
+M UI/WebServerResources/ckeditor/lang/no.js
+M UI/WebServerResources/ckeditor/lang/pl.js
+M UI/WebServerResources/ckeditor/lang/pt-br.js
+M UI/WebServerResources/ckeditor/lang/ru.js
+M UI/WebServerResources/ckeditor/lang/sk.js
+M UI/WebServerResources/ckeditor/lang/sv.js
+M UI/WebServerResources/ckeditor/lang/uk.js
+A UI/WebServerResources/ckeditor/plugins/wsc/dialogs/tmp.html
+M UI/WebServerResources/ckeditor/plugins/wsc/dialogs/wsc.js
+
+commit 47c4ad5807fb1f982035c4dcdd9a400289afa143
+Author: Ludovic Marcotte
+Date: Tue Oct 29 20:58:26 2013 -0400
+
+ Make sure the var is initilized to nil.
+
+M UI/Common/UIxParentFolderActions.m
+
+commit 0f3e31ebf146ec9afda2052f4cd7bd1aad14c8fa
+Author: Ludovic Marcotte
+Date: Wed Oct 23 16:37:03 2013 -0400
+
+ Added more tags to skip
+
+M UI/MailPartViewers/UIxMailPartHTMLViewer.m
+
+commit 87261f3280dd5de438c7db0a3a7c013775f7f9b8
+Author: Ludovic Marcotte
+Date: Wed Oct 23 16:04:37 2013 -0400
+
+ Fix for bug #2468.
+
+M UI/MailPartViewers/UIxMailPartHTMLViewer.m
+
+commit bd2759ecdf0eb99169d7992d0d70586e57f325b3
+Author: Ludovic Marcotte
+Date: Tue Oct 22 11:44:26 2013 -0400
+
+ Fix for bug #2433
+
+M SoObjects/Mailer/SOGoMailFolder.m
+
+commit be1bcf3c9b63c41362d1a007590bd905f71d901c
+Author: Ludovic Marcotte
+Date: Tue Oct 22 11:25:24 2013 -0400
+
+ Fix for bug #2461
+
+M SoObjects/Appointments/iCalEvent+SOGo.m
+
+commit 053b090affbd6a20f62e181d66058583926fca19
+Author: Ludovic Marcotte
+Date: Mon Oct 21 15:37:01 2013 -0400
+
+ Fix for bug #2235
+
+M SOPE/GDLContentStore/EOQualifier+GCS.m
+M SOPE/GDLContentStore/GCSFolder.m
+
+commit 189f2218a8d1f7d6e0b7e95e89abcd6c339ff9c9
+Author: Ludovic Marcotte
+Date: Mon Oct 21 15:26:43 2013 -0400
+
+ Fix for bug #2459
+
+M SoObjects/Mailer/GNUmakefile
+M SoObjects/Mailer/NSString+Mail.h
+M SoObjects/Mailer/NSString+Mail.m
+
+commit 656869a4a2e0572f9f4179707d3863860fa38632
+Author: Ludovic Marcotte
+Date: Fri Oct 18 13:16:30 2013 -0400
+
+ Fix for bug #1328
+
+M SoObjects/SOGo/LDAPSource.h
+M SoObjects/SOGo/LDAPSource.m
+
+commit 16f62e2393b7b9cd59ed1c2459dda45042fc821c
+Author: Ludovic Marcotte
+Date: Fri Oct 18 10:30:43 2013 -0400
+
+ Fix for bug #2434
+
+M UI/MailPartViewers/UIxMailPartHTMLViewer.m
+
+commit 9289615996ef9b6fd72a7a16be1cc3e1f73e8dce
+Author: Jean Raby
+Date: Thu Oct 17 11:45:07 2013 -0400
+
+ Added https vhost example for apple carddav
+
+M Apache/SOGo-apple-ab.conf
+
+commit fdea04c08c8e18d7a5f4caf9fbe5da18d7542f7f
+Author: Jean Raby
+Date: Tue Oct 15 10:49:21 2013 -0400
+
+ Added some verbose logging for expire-autoreply
+
+M Tools/SOGoToolExpireAutoReply.m
+
+commit edca3638ec4bea16823c94f97d14ee0c3ca648ab
+Author: Jean Raby
+Date: Fri Oct 11 13:41:44 2013 -0400
+
+ Fixup backup_dir to use sogo's home directory
+
+M Scripts/sogo-backup.sh
+
+commit 05990e9a14503cf1ea2dfcdf28616ea63ebc311e
+Author: Ludovic Marcotte
+Date: Mon Sep 30 10:50:27 2013 -0400
+
+ Fix for bug 2007
+
+M SoObjects/Appointments/SOGoAppointmentFolders.h
+M SoObjects/Appointments/SOGoAppointmentFolders.m
+M SoObjects/SOGo/NSString+Utilities.h
+M SoObjects/SOGo/NSString+Utilities.m
+M SoObjects/SOGo/SOGoParentFolder.m
+M UI/Scheduler/UIxCalMainActions.m
+
+commit 3cce9b2012e445e61a0b5c5daf17ab349a9ebb40
+Author: Jean Raby
+Date: Mon Sep 30 09:39:29 2013 -0400
+
+ Fix file permissions
+
+M packaging/debian-multiarch/rules
+M packaging/debian/rules
+
+commit 7dc65af3004ee000271851a995b918d08857ee9c
+Author: Ludovic Marcotte
+Date: Fri Sep 27 15:54:11 2013 -0400
+
+ Fix for bug #2386
+
+M SoObjects/SOGo/SOGoUser.m
+
+commit 84e999229bd2e0ca5c76b613dbfab7b15432bfcc
+Author: Ludovic Marcotte
+Date: Fri Sep 27 15:36:46 2013 -0400
+
+ Fix for bug #2270
+
+M UI/MailPartViewers/UIxMailPartLinkViewer.h
+M UI/MailPartViewers/UIxMailPartViewer.h
+M UI/MailPartViewers/UIxMailPartViewer.m
+M UI/MailPartViewers/UIxMailRenderingContext.m
+M UI/Templates/MailPartViewers/UIxMailPartLinkViewer.wox
+A UI/WebServerResources/mime-image-pdf.png
+
+commit 3dbfb0ed2d07baf9b7e3f17138bc932aec7880d3
+Author: Francis Lachapelle
+Date: Fri Sep 27 14:43:05 2013 -0400
+
+ Add Underline option to HTML editor
+
+M UI/WebServerResources/ckeditor/config.js
+
+commit d1f3417c3a22615ee438c59224942e40dfa27535
+Author: Francis Lachapelle
+Date: Fri Sep 27 14:22:35 2013 -0400
+
+ Update CKEditor to version 4.2.1
+
+ And added the table-related modules.
+
+M NEWS
+M UI/WebServerResources/ckeditor/build-config.js
+M UI/WebServerResources/ckeditor/ckeditor.js
+M UI/WebServerResources/ckeditor/config.js
+M UI/WebServerResources/ckeditor/contents.css
+M UI/WebServerResources/ckeditor/lang/ar.js
+M UI/WebServerResources/ckeditor/lang/ca.js
+M UI/WebServerResources/ckeditor/lang/cs.js
+M UI/WebServerResources/ckeditor/lang/cy.js
+M UI/WebServerResources/ckeditor/lang/da.js
+M UI/WebServerResources/ckeditor/lang/de.js
+M UI/WebServerResources/ckeditor/lang/en.js
+M UI/WebServerResources/ckeditor/lang/es.js
+M UI/WebServerResources/ckeditor/lang/fi.js
+M UI/WebServerResources/ckeditor/lang/fr.js
+M UI/WebServerResources/ckeditor/lang/hu.js
+M UI/WebServerResources/ckeditor/lang/is.js
+M UI/WebServerResources/ckeditor/lang/it.js
+M UI/WebServerResources/ckeditor/lang/nb.js
+M UI/WebServerResources/ckeditor/lang/nl.js
+M UI/WebServerResources/ckeditor/lang/no.js
+M UI/WebServerResources/ckeditor/lang/pl.js
+M UI/WebServerResources/ckeditor/lang/pt-br.js
+M UI/WebServerResources/ckeditor/lang/ru.js
+M UI/WebServerResources/ckeditor/lang/sk.js
+M UI/WebServerResources/ckeditor/lang/sv.js
+M UI/WebServerResources/ckeditor/lang/uk.js
+M UI/WebServerResources/ckeditor/plugins/about/dialogs/about.js
+A UI/WebServerResources/ckeditor/plugins/about/dialogs/hidpi/logo_ckeditor.png
+M UI/WebServerResources/ckeditor/plugins/about/dialogs/logo_ckeditor.png
+M UI/WebServerResources/ckeditor/plugins/clipboard/dialogs/paste.js
+M UI/WebServerResources/ckeditor/plugins/colordialog/dialogs/colordialog.js
+M UI/WebServerResources/ckeditor/plugins/dialog/dialogDefinition.js
+M UI/WebServerResources/ckeditor/plugins/icons.png
+A UI/WebServerResources/ckeditor/plugins/icons_hidpi.png
+M UI/WebServerResources/ckeditor/plugins/image/dialogs/image.js
+M UI/WebServerResources/ckeditor/plugins/link/dialogs/anchor.js
+M UI/WebServerResources/ckeditor/plugins/link/dialogs/link.js
+M UI/WebServerResources/ckeditor/plugins/link/images/anchor.png
+A UI/WebServerResources/ckeditor/plugins/link/images/hidpi/anchor.png
+A UI/WebServerResources/ckeditor/plugins/table/dialogs/table.js
+A UI/WebServerResources/ckeditor/plugins/tabletools/dialogs/tableCell.js
+M UI/WebServerResources/ckeditor/plugins/wsc/dialogs/wsc.js
+M UI/WebServerResources/ckeditor/skins/moono/dialog.css
+M UI/WebServerResources/ckeditor/skins/moono/dialog_ie.css
+M UI/WebServerResources/ckeditor/skins/moono/dialog_ie7.css
+M UI/WebServerResources/ckeditor/skins/moono/dialog_ie8.css
+M UI/WebServerResources/ckeditor/skins/moono/dialog_iequirks.css
+M UI/WebServerResources/ckeditor/skins/moono/dialog_opera.css
+M UI/WebServerResources/ckeditor/skins/moono/editor.css
+M UI/WebServerResources/ckeditor/skins/moono/editor_gecko.css
+M UI/WebServerResources/ckeditor/skins/moono/editor_ie.css
+M UI/WebServerResources/ckeditor/skins/moono/editor_ie7.css
+M UI/WebServerResources/ckeditor/skins/moono/editor_ie8.css
+M UI/WebServerResources/ckeditor/skins/moono/editor_iequirks.css
+M UI/WebServerResources/ckeditor/skins/moono/icons.png
+A UI/WebServerResources/ckeditor/skins/moono/icons_hidpi.png
+M UI/WebServerResources/ckeditor/skins/moono/images/close.png
+A UI/WebServerResources/ckeditor/skins/moono/images/hidpi/close.png
+A UI/WebServerResources/ckeditor/skins/moono/images/hidpi/lock-open.png
+A UI/WebServerResources/ckeditor/skins/moono/images/hidpi/lock.png
+A UI/WebServerResources/ckeditor/skins/moono/images/hidpi/refresh.png
+A UI/WebServerResources/ckeditor/skins/moono/images/lock-open.png
+A UI/WebServerResources/ckeditor/skins/moono/images/lock.png
+D UI/WebServerResources/ckeditor/skins/moono/images/mini.png
+A UI/WebServerResources/ckeditor/skins/moono/images/refresh.png
+M UI/WebServerResources/ckeditor/styles.js
+
+commit 7c7031333e11a8a35b7d2fce17b2da1ce96cd2e2
+Author: Ludovic Marcotte
+Date: Fri Sep 27 10:00:39 2013 -0400
+
+ Fix for bug #2221
+
+M UI/WebServerResources/SchedulerUI.js
+
+commit 1e484814261aac19322a2daebee6556bdfa126d6
+Author: Jean Raby
+Date: Thu Sep 26 08:51:42 2013 -0400
+
+ Updated description/default value for WOPort
+
+M Documentation/SOGo Installation Guide.odt
+
+commit 8ae1624604a97036dcc963e9bbc977c68adac6b2
+Author: Jean Raby
+Date: Thu Sep 26 08:49:17 2013 -0400
+
+ Added --noexpiry for administrator
+
+M Documentation/SOGo Native Microsoft Outlook Configuration.odt
+
+commit 7166f5a597035e376517a27c56579ff0ae0ae985
+Author: Ludovic Marcotte
+Date: Wed Sep 25 16:02:13 2013 -0400
+
+ Fix for bug #2399
+
+M SoObjects/Appointments/SOGoAppointmentFolder.m
+
+commit 55052ea36f1573e60d0cad9266ded0b0733eaefa
+Author: Ludovic Marcotte
+Date: Wed Sep 25 14:40:48 2013 -0400
+
+ Fix for bug #2240
+
+M SOPE/NGCards/iCalToDo.m
+
+commit 99d38417cccbe7730a566f7bb7457359bbdf713b
+Author: Ludovic Marcotte
+Date: Wed Sep 25 13:51:42 2013 -0400
+
+ Fix for bug #2354
+
+M OpenChange/RTFHandler.m
+
+commit 29eed182a7f795f9fd01466a641bef0ad99e7660
+Author: Ludovic Marcotte
+Date: Wed Sep 25 10:41:07 2013 -0400
+
+ Updated the OpenChange code related to UTF-7 changes for IMAP folders
+
+M OpenChange/MAPIStoreMailContext.m
+M OpenChange/MAPIStoreMailFolder.m
+
+commit 744610dbe1b819b2e75ce4ca29844da1596c3ace
+Author: Ludovic Marcotte
+Date: Wed Sep 25 08:46:34 2013 -0400
+
+ Fixed tests regarding new WebDAV sync responses
+
+M Tests/Integration/test-davacl.py
+M Tests/Integration/webdavsync-tool.py
+
+commit d2b739d261a01652307972b0def1ffc0074ddffa
+Author: Ludovic Marcotte
+Date: Tue Sep 24 16:01:23 2013 -0400
+
+ Fix for bug #2318
+
+M NEWS
+M UI/MailerUI/UIxMailAccountActions.m
+M UI/WebServerResources/MailerUI.js
+
+commit 2ba8254eccb5a1f42844044d008170fc1c1715a8
+Author: Ludovic Marcotte
+Date: Tue Sep 24 09:29:46 2013 -0400
+
+ Fix for bug #1275
+
+M SoObjects/SOGo/SOGoGCSFolder.m
+
+commit 28e600a4e6e0b988b23a9c6ad77e26e42d55a163
+Author: Jean Raby
+Date: Fri Sep 20 15:37:34 2013 -0400
+
+ Set default listening address to 127.0.0.1:20000
+
+ No reason to listen on 0.0.0.0 by default
+
+M NEWS
+M SoObjects/SOGo/SOGoDefaults.plist
+
+commit 91f1ab6a60af2404b49dc435c246b5836ccb3f91
+Author: Ludovic Marcotte
+Date: Thu Sep 19 16:14:08 2013 -0400
+
+ Fix for bug #2217
+
+M NEWS
+M SoObjects/Mailer/SOGoDraftObject.m
+M UI/MailerUI/UIxMailEditor.m
+
+commit 32a534919dbffe1bcffe129cb203f23687596180
+Author: Jean Raby
+Date: Thu Sep 19 11:11:29 2013 -0400
+
+ update NEWS. ldap fixes
+
+M NEWS
+
+commit 5b77c2b7246fa584e7e81a151270a155e0a0bf39
+Author: Ludovic Marcotte
+Date: Thu Sep 19 10:49:42 2013 -0400
+
+ Stability fix when we're untable to determine the message class type
+
+M OpenChange/MAPIStoreDBMessage.m
+
+commit 70086e5ee6e20508b1346656ca6395e98efe3dc4
+Author: Ludovic Marcotte
+Date: Thu Sep 19 09:56:28 2013 -0400
+
+ Fix for bug #1935
+
+M OpenChange/MAPIStoreMailVolatileMessage.m
+
+commit 7ddc1b9e2d2696e80a3d9e81e96dc5a0ff81b738
+Author: Ludovic Marcotte
+Date: Wed Sep 18 14:03:07 2013 -0400
+
+ Avoid type-issues generating wrong GlobCnt - leading to OpenChange crashes during the sync process.
+
+M OpenChange/MAPIStoreGCSFolder.m
+M OpenChange/MAPIStoreObject.m
+M OpenChange/NSData+MAPIStore.m
+
+commit 6d93db96e4cc4e1b5a63dde151a09be6d5719ba5
+Author: Francis Lachapelle
+Date: Tue Sep 17 11:17:40 2013 -0400
+
+ Update NEWS file
+
+M NEWS
+
+commit 27445d3b85af9bf0d7aafa03e478ccc867ed5234
+Author: Jean Raby
+Date: Tue Sep 17 09:27:46 2013 -0400
+
+ update news
+
+M NEWS
+
+commit 60d6abe542cbed0bb4017edd404971b092627f36
+Author: Jean Raby
+Date: Tue Sep 17 09:07:53 2013 -0400
+
+ Use HTTP/1.0 to avoid chunked replies
+
+ Fixes^WWorkaround #2408
+
+M SoObjects/SOGo/SOGoCASSession.m
+
+commit baacf8516d5c1e9d0198bcef12fd3b83b2816878
+Author: Ludovic Marcotte
+Date: Mon Sep 16 11:21:23 2013 -0400
+
+ Updated NEWS file regarding previous commit
+
+M NEWS
+
+commit 193720cfbbdf67f871ad561024407db656fe4107
+Author: Ludovic Marcotte
+Date: Mon Sep 16 10:59:45 2013 -0400
+
+ Fix for s/mime verification issues with some openssl versions
+
+M UI/MailPartViewers/UIxMailPartSignedViewer.m
+
+commit ca4d89fb086a52fa57d3b0f6ff784258bdef79c7
+Author: Jean Raby
+Date: Fri Sep 13 11:24:16 2013 -0400
+
+ update with latest fixes
+
+M NEWS
+
+commit 906985c1f3ea9ee59a346a153d2f570aad684b80
+Author: Jean Raby
+Date: Fri Sep 13 11:19:44 2013 -0400
+
+ Call MSExchangeHostname on SOGoDNSource only
+
+ Fixes #2418
+
+M SoObjects/Appointments/SOGoFreeBusyObject.m
+
+commit de8bf64c70ca5f0b3cc9741d2bb933c0aef1e833
+Author: Jean Raby
+Date: Fri Sep 13 11:16:28 2013 -0400
+
+ Local pool when appending contacts to response
+
+ Avoids using too much memory when doing a contact lookup with many matches
+
+M SoObjects/Contacts/SOGoFolder+CardDAV.m
+
+commit 0c38a9e5551c39a0483192bfc4f5cb6511261fae
+Author: Jean Raby
+Date: Fri Sep 13 11:13:02 2013 -0400
+
+ whitespace tabkill
+
+M SoObjects/Contacts/SOGoFolder+CardDAV.m
+
+commit 3c6c90d4346ce19e3245466d22ee3f659c1ac8e9
+Author: Francis Lachapelle
+Date: Fri Sep 13 09:33:28 2013 -0400
+
+ Reload webmail when changing "remote images" pref
+
+M UI/WebServerResources/UIxPreferences.js
+
+commit 72a4b075d6201baa438462937420fcef4c677f23
+Author: Francis Lachapelle
+Date: Thu Sep 12 17:08:02 2013 -0400
+
+ Mail popup: respect "remote inline images" prefs
+
+ Fixes #2417
+
+M UI/Templates/MailerUI/UIxMailPopupView.wox
+M UI/WebServerResources/UIxMailPopupView.js
+
+commit 24c0fb1cc458b54bdc7f40bb3b0efdc8f15e0300
+Author: Francis Lachapelle
+Date: Thu Sep 12 16:24:14 2013 -0400
+
+ Fix change listener on calendar list select input
+
+ Fixes #2353
+
+M UI/WebServerResources/UIxComponentEditor.js
+
+commit 7241e3e30e8ffdc9a03c6709783d0f800a754a75
+Author: Jean Raby
+Date: Thu Sep 12 10:14:47 2013 -0400
+
+ Added rewrite rule for apple autoconfiguration url
+
+ Rewrite rules are no inherited by virtualhosts when they are declared in conf.d
+ This means that you'll have to explicitly include SOGo.conf from 000-default
+ on debian/ubuntu for this redirection to work properly.
+
+M Apache/SOGo.conf
+
+commit 1d705dc00b788e75a55ceb538f35ce2a15414a48
+Author: Jean Raby
+Date: Tue Sep 10 13:58:04 2013 -0400
+
+ Next version: 2.1.0
+
+M NEWS
+M Version
+
+commit df42ab2a46f1c4cb520bcfa208cf2f2569678776
+Author: Jean Raby
+Date: Mon Sep 9 10:07:07 2013 -0400
+
+ Run 3 sogod process by default instead on only 1
+
+M Scripts/sogo-default
+M Scripts/sogo-init.d-redhat
+M Scripts/sogo-init.d-sles
+M packaging/debian-multiarch/sogo.init
+M packaging/debian/sogo.init
+
+commit f59c77a9509642877ac2722092fb935c6f5819dd
+Author: Jean Raby
+Date: Fri Sep 6 13:49:04 2013 -0400
+
+ Update news
+
+M NEWS
+
+commit cd4abe4b5b3c085b2d0b7fa93633fcbea4470417
+Author: Ludovic Marcotte
+Date: Fri Sep 6 13:48:44 2013 -0400
+
+ Fix for bug 2398
+
+M OpenChange/RTFHandler.m
+
+commit 69b0f9fcbf078c0a0ddc8249b89d702222e497e9
+Author: Francis Lachapelle
+Date: Tue Sep 3 12:05:13 2013 -0400
+
+ Mail notifications: Escape HTML in wox templates
+
+ We don't escape the values in the classes but in the templates.
+
+M SoObjects/Appointments/SOGoAptMailNotification.m
+M UI/Templates/Appointments/SOGoAptMailDeletion.wox
+
+commit dceead3997d00db403e0803f33ba14b9cc061095
+Author: Jean Raby
+Date: Tue Sep 3 09:59:01 2013 -0400
+
+ Fixup sogo spool cleanup cronjob
+
+ Add -user sogo to be on the safe side.
+ Change call to /bin/rmdir by -delete to avoid error messages.
+ Find would call rmdir and then do an openat() on the deleted directory,
+ which would obviously fail.
+
+ Fixes #2372
+
+M Scripts/tmpwatch
+M packaging/debian-multiarch/sogo.cron.daily
+M packaging/debian/sogo.cron.daily
+
+commit 573c2ec114be4cf70b1aa7b82bf573fabcc64b65
+Author: Jean Raby
+Date: Thu Aug 29 15:51:05 2013 -0400
+
+ updated News
+
+M NEWS
+
+commit e9d8b729b6131af5abbdd46df070838644ee7908
+Author: Jean Raby
+Date: Thu Aug 29 14:34:25 2013 -0400
+
+ Bump version file to 2.0.8 for nightly builds
+
+M Version
+
+commit 1e7dfc0934852de2beb3ba45d4e9f869381886a7
+Author: Jean Raby
+Date: Thu Aug 29 14:32:34 2013 -0400
+
+ Updated cron sections for credentials files
+
+ Added a note regarding password change against AD/Samba4
+
+M Documentation/SOGo Installation Guide.odt
+
+commit d7e6648396acfb4cafbfb7a8b338a3e292c7ba19
+Author: Jean Raby
+Date: Wed Aug 28 17:11:07 2013 -0400
+
+ Reworked password change logic and add AD support
+
+M SoObjects/SOGo/LDAPSource.m
+
+commit 65603201f7d639626374a3680504fd3192d88ce5
+Author: Jean Raby
+Date: Wed Aug 28 10:05:36 2013 -0400
+
+ ignore pyc files and config.py
+
+M .gitignore
+
+commit 9fd6f75c4e876972b2e223fc76dd8b2edb5cff0a
+Author: Jean Raby
+Date: Wed Aug 28 09:47:10 2013 -0400
+
+ Update crontab for SMTP AUTH credentials
+
+M Scripts/sogo.cron
+
+commit b96f25f99f16bf747e625dad3f29d93802b57d03
+Author: Jean Raby
+Date: Tue Aug 27 14:44:28 2013 -0400
+
+ updated NEWS
+
+M NEWS
+
+commit e6ab0a590a7776331270f02a83cd123d41f14c1f
+Author: Jean Raby
+Date: Tue Aug 27 13:12:03 2013 -0400
+
+ Support using SMTP AUTH creds for email alarms
+
+ Credentials must be supplied using '-p /path/to/credsFile'.
+ The credentials file should contain a single line with the format 'user:pass'
+
+ While there, add a usage message
+
+M Tools/SOGoEAlarmsNotifier.h
+M Tools/SOGoEAlarmsNotifier.m
+
+commit be531100c6fc4c4099b382b128d9ff295ff03f2b
+Author: Jean Raby
+Date: Tue Aug 27 13:04:08 2013 -0400
+
+ Use SOGoCredentialsFile to avoid duplicated code
+
+M Tools/SOGoToolExpireAutoReply.m
+M Tools/SOGoToolUserPreferences.m
+
+commit e946a67ddf4d3f6da669208935a6e8e230252a92
+Author: Jean Raby
+Date: Tue Aug 27 13:02:06 2013 -0400
+
+ Special case for auth with SOGoStaticAuthenticator
+
+M SoObjects/SOGo/SOGoMailer.m
+
+commit 2fe87f14fd4c6f7ea7a020abc6185b8901b09162
+Author: Jean Raby
+Date: Tue Aug 27 12:59:03 2013 -0400
+
+ Add SOGoStaticAuthenticator
+
+ New authenticator that is not linked to a SOGoUser.
+ Will be used for SMTP AUTH by sogo-elalarm-notify.
+
+M SoObjects/SOGo/GNUmakefile
+A SoObjects/SOGo/SOGoStaticAuthenticator.h
+A SoObjects/SOGo/SOGoStaticAuthenticator.m
+
+commit b2f012cae21339a290af2fd6f57a32871062a6b8
+Author: Jean Raby
+Date: Tue Aug 27 12:56:07 2013 -0400
+
+ Add SOGoCredentialsFile
+
+ New class to read credentials files as used by sogo-tool and sogo-ealarm-notify
+
+M SoObjects/SOGo/GNUmakefile
+A SoObjects/SOGo/SOGoCredentialsFile.h
+A SoObjects/SOGo/SOGoCredentialsFile.m
+
+commit 33659aa947cbc4609d57b4f5040dc422460fa1be
+Author: Francis Lachapelle
+Date: Tue Aug 27 12:01:41 2013 -0400
+
+ Increase height of alarm editor
+
+ Only when email alarms are enabled.
+
+M UI/WebServerResources/UIxComponentEditor.js
+
+commit df1ab29872fa025c89e096292d811a3ca7c9e82e
+Author: Francis Lachapelle
+Date: Tue Aug 27 09:04:26 2013 -0400
+
+ Fix position of red "now" line
+
+ Fixes #2373
+
+M NEWS
+M UI/WebServerResources/SchedulerUI.js
+
+commit 61e59b864e34f911c50e95a62b6ab6cf5cfa2dba
+Author: Jean Raby
+Date: Tue Aug 27 08:33:50 2013 -0400
+
+ Bump copyright
+
+M Tools/SOGoEAlarmsNotifier.m
+M Tools/SOGoToolExpireAutoReply.m
+M Tools/SOGoToolUserPreferences.m
+
+commit 0a590ba3886093da13c8391e33dcb61c4066014f
+Author: Francis Lachapelle
+Date: Mon Aug 26 08:59:43 2013 -0400
+
+ Fix Finnish mail reply/forward templates
+
+M NEWS
+M SoObjects/Mailer/GNUmakefile
+M SoObjects/Mailer/SOGoMailForward.h
+M SoObjects/Mailer/SOGoMailForward.m
+M SoObjects/Mailer/SOGoMailReply.h
+M SoObjects/Mailer/SOGoMailReply.m
+
+commit ab92516dd0da7f057c7056c46f51abb22d6b04dc
+Author: Ludovic Marcotte
+Date: Fri Aug 9 11:39:15 2013 -0400
+
+ Fix for bug #1431
+
+M UI/Scheduler/UIxCalUserRightsEditor.m
+
+commit 7b90b892fc0a1a2f333a82c49759812725556ffb
+Author: Ludovic Marcotte
+Date: Wed Aug 7 08:49:59 2013 -0400
+
+ Fix for bug #2385
+
+M UI/MailPartViewers/UIxMailPartViewer.m
+
+commit b654ffb806d370467991111f93f55df2854eb82b
+Author: Jean Raby
+Date: Fri Aug 2 16:56:36 2013 -0400
+
+ add webdavsync-tool.py
+
+ first draft of a small tool to simulate a TB calendar sync
+
+A Tests/Integration/webdavsync-tool.py
+
+commit 6de689bbe2808660909a81939d7933c38669fe52
+Author: Jean Raby
+Date: Fri Aug 2 15:41:24 2013 -0400
+
+ Add depth support to CalendarMultiget
+
+M Tests/Integration/webdavlib.py
+
+commit 7eb8b9c2c36534a5cd2c851b83b9b95bc89e807e
+Author: Jean Raby
+Date: Fri Aug 2 09:51:41 2013 -0400
+
+ Add SxVMemLimit to sogo.conf
+
+M Scripts/sogo.conf
+
+commit 3877f3001fb5e9e425b495599e7618596136efe9
+Author: Jean Raby
+Date: Thu Aug 1 12:48:42 2013 -0400
+
+ replace xml.dom.ext by xml.dom.minidom
+
+M Tests/Integration/propfind.py
+
+commit 4d2c734781ccfc4f9506c506ecec3e4f7d816b79
+Author: Ludovic Marcotte
+Date: Mon Jul 29 14:32:58 2013 -0400
+
+ Revert "Try to use a local pool to avoid huge memory consumption"
+
+ This reverts commit e57d875e0abcd95e0fc06690c269e387cd2aa61d.
+
+M SOPE/NGCards/versitCardsSaxDriver/VSSaxDriver.m
+
+commit e57d875e0abcd95e0fc06690c269e387cd2aa61d
+Author: Ludovic Marcotte
+Date: Mon Jul 29 09:43:21 2013 -0400
+
+ Try to use a local pool to avoid huge memory consumption
+
+M SOPE/NGCards/versitCardsSaxDriver/VSSaxDriver.m
+
+commit b1df03adc71d7f8d530f49b8e0406b5151fb0609
+Author: Ludovic Marcotte
+Date: Wed Jul 24 10:54:55 2013 -0400
+
+ Fix for old runtimes.
+
+M OpenChange/BSONCodec.m
+
+commit bd776152db4f05ba13a58795f2eae0fc98b4e9cb
+Author: Francis Lachapelle
+Date: Tue Jul 23 10:02:13 2013 -0400
+
+ Update ChangeLog
+
+M ChangeLog
+
commit 734c164ae02df4e2313003d143486eff67f42c5e
Author: Ludovic Marcotte
Date: Tue Jul 23 09:25:24 2013 -0400
diff --git a/Documentation/SOGo Installation Guide.odt b/Documentation/SOGo Installation Guide.odt
index 6419ee008..53970d031 100644
Binary files a/Documentation/SOGo Installation Guide.odt and b/Documentation/SOGo Installation Guide.odt differ
diff --git a/Documentation/SOGo Mobile Devices Configuration.odt b/Documentation/SOGo Mobile Devices Configuration.odt
index 72f703344..69246f4d8 100644
Binary files a/Documentation/SOGo Mobile Devices Configuration.odt and b/Documentation/SOGo Mobile Devices Configuration.odt differ
diff --git a/Documentation/SOGo Mozilla Thunderbird Configuration.odt b/Documentation/SOGo Mozilla Thunderbird Configuration.odt
index 9277ed018..77c7b7d55 100644
Binary files a/Documentation/SOGo Mozilla Thunderbird Configuration.odt and b/Documentation/SOGo Mozilla Thunderbird Configuration.odt differ
diff --git a/Documentation/SOGo Native Microsoft Outlook Configuration.odt b/Documentation/SOGo Native Microsoft Outlook Configuration.odt
index 9bb9d126a..ef069b4a8 100644
Binary files a/Documentation/SOGo Native Microsoft Outlook Configuration.odt and b/Documentation/SOGo Native Microsoft Outlook Configuration.odt differ
diff --git a/NEWS b/NEWS
index 3866b8770..0d9ca6137 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,53 @@
+2.1.0 (2013-11-07)
+------------------
+
+Enhancements
+ - improved order of user rights in calendar module (#1431)
+ - increased height of alarm editor when email alarms are enabled
+ - added SMTP AUTH support for sogo-ealarms-notify
+ - added support for LDAP password change against AD/Samba4
+ - added Apache configuration for Apple autoconfiguration (#2248)
+ - the init scripts now start 3 sogod processes by default instead of 1
+ - SOGo now also sends a plain/text parts when sending HTML mails (#2217)
+ - SOGo now listens on 127.0.0.1:20000 by default (instead of *:20000)
+ - SOGo new uses the latest WebDAV sync response type (#1275)
+ - updated CKEditor to version 4.2.2 and added the tables-related modules (#2410)
+ - improved display of vEvents in messages
+
+Bug fixes
+ - fixed handling of an incomplete attachment filename (#2385)
+ - fixed Finnish mail reply/forward templates (#2401)
+ - fixed position of red line of current time (#2373)
+ - fixed crontab error (#2372)
+ - avoid using too many LDAP connections while looping through LDAP results
+ - don't encode HTML entities in mail subject of notification (#2402)
+ - fixed crash of Samba when sending an invitation (#2398)
+ - fixed selection of destination calendar when saving a task or an event (#2353)
+ - fixed "display remote images" preference for message in a popup (#2417)
+ - avoid crash when handling malformed or non-ASCII HTTP credentials (#2358)
+ - fixed crash in DAV free-busy lookups when using SQL addressbooks (#2418)
+ - disabled verbose logging of SMTP sessions by default
+ - fixed high CPU usage when there are no available child processes and added logging when such a condition occurs
+ - fixed memory consumption issues when doing dav lookups with huge result set
+ - fixed S/MIME verification issues with certain OpenSSL versions
+ - worked around an issue with chunked encoding of CAS replies (#2408)
+ - fixed OpenChange corruption issue regarding predecessors change list (#2405)
+ - avoid unnecessary UTF-7 conversions (#2318)
+ - improved RTF parser to fix vCards (#2354)
+ - fixed definition of the COMPLETED attribute of vTODO (#2240)
+ - fixed DAV:resource-id property when sharing calendars (#2399)
+ - fixed reload of multiple external web calendars (#2221)
+ - fixed display of PDF files sent from Thunderbird (#2270)
+ - fixed TLS support for IMAP (#2386)
+ - fixed creation of web calendar when added using sogo-tool (#2007)
+ - avoid crash when parsing HTML tags of a message (#2434)
+ - fixed handling of LDAP groups with no email address (#1328)
+ - fixed encoding of messages with non-ASCII characters (#2459)
+ - fixed compilation with clang 3.2 (#2235)
+ - truncated long fields of quick records to avoid an SQL error (#2461)
+ - fixed IMAP ACLs (#2433)
+ - removed inline JavaScript when viewing HTML messages (#2468)
+
2.0.7 (2013-07-19)
------------------
@@ -19,15 +69,15 @@ Bug fixes
------------------
Bug fixes
- - Properly escape the foldername to avoid XSS issues
- - Fix loading of MSExchangeFreeBusySOAPResponseMap
+ - properly escape the foldername to avoid XSS issues
+ - fixed loading of MSExchangeFreeBusySOAPResponseMap
2.0.6a (2013-06-25)
------------------
Bug fixes
- - Documentation fixes
- - Added missing file for CAS single logout
+ - documentation fixes
+ - added missing file for CAS single logout
2.0.6 (2013-06-21)
------------------
@@ -58,8 +108,8 @@ Bug fixes
------------------
Bug fixes
- - Fixed an issue when parsing user CN with leading or trailing spaces (#2287)
- - Fixed a crash that occured when saving contacts or tasks via Outlook
+ - fixed an issue when parsing user CN with leading or trailing spaces (#2287)
+ - fixed a crash that occured when saving contacts or tasks via Outlook
2.0.5 (2013-04-11)
------------------
diff --git a/OpenChange/BSONCodec.m b/OpenChange/BSONCodec.m
index 518900ba2..58625a59f 100644
--- a/OpenChange/BSONCodec.m
+++ b/OpenChange/BSONCodec.m
@@ -85,13 +85,17 @@ static NSDictionary *BSONTypes()
@implementation NSObject (BSONObjectCoding)
- (NSData *) BSONEncode
{
- if (!class_conformsToProtocol([self class], @protocol(BSONObjectCoding)))
+ if (![self conformsToProtocol: @protocol(BSONObjectCoding)])
[NSException raise: NSInvalidArgumentException format: @"BSON encoding is only valid on objects conforming to the BSONObjectEncoding protocol."];
id myself = (id ) self;
NSMutableDictionary *values = [[myself BSONDictionary] mutableCopy];
+#if (defined(__GNU_LIBOBJC__) && (__GNU_LIBOBJC__ >= 20100911)) || defined(APPLE_RUNTIME) || defined(__GNUSTEP_RUNTIME__)
const char* className = class_getName([self class]);
+#else
+ const char* className = [self class]->name;
+#endif
[values setObject: [NSData dataWithBytes: (void *)className length: strlen(className)] forKey: CLASS_NAME_MARKER];
NSData *retval = [values BSONEncode];
[values release];
diff --git a/OpenChange/MAPIStoreDBMessage.m b/OpenChange/MAPIStoreDBMessage.m
index 997f46570..074c205ea 100644
--- a/OpenChange/MAPIStoreDBMessage.m
+++ b/OpenChange/MAPIStoreDBMessage.m
@@ -23,6 +23,7 @@
#import
#import
#import
+#import
#import
#import
@@ -34,6 +35,7 @@
#import "MAPIStoreDBMessage.h"
#import "MAPIStoreTypes.h"
#import "NSObject+MAPIStore.h"
+#import "NSString+MAPIStore.h"
#undef DEBUG
#include
@@ -99,6 +101,21 @@
return objectVersion;
}
+//
+// FIXME: how this can happen?
+//
+// We might get there if for some reasons, all classes weren't able
+// to tell us the message class.
+//
+- (int) getPidTagMessageClass: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
+{
+ *data = [@"IPM.Note" asUnicodeInMemCtx: memCtx];
+
+ [self logWithFormat: @"METHOD '%s' - unable to determine message class. Falling back to IPM.Note", __FUNCTION__];
+
+ return MAPISTORE_SUCCESS;
+}
+
- (int) getProperties: (struct mapistore_property_data *) data
withTags: (enum MAPITAGS *) tags
andCount: (uint16_t) columnCount
diff --git a/OpenChange/MAPIStoreGCSFolder.m b/OpenChange/MAPIStoreGCSFolder.m
index 750a255a4..52d2b0866 100644
--- a/OpenChange/MAPIStoreGCSFolder.m
+++ b/OpenChange/MAPIStoreGCSFolder.m
@@ -259,7 +259,6 @@ static Class NSNumberK;
}
}
*/
-
- (void) _setChangeKey: (NSData *) changeKey
forMessageEntry: (NSMutableDictionary *) messageEntry
inChangeListOnly: (BOOL) inChangeListOnly
@@ -462,6 +461,9 @@ static Class NSNumberK;
[messageEntry setObject: changeNumber forKey: @"version"];
newChangeNum = [changeNumber unsignedLongLongValue];
+
+ // A GLOBCNT structure is a 6-byte global namespace counter,
+ // we strip the first 2 bytes. The first two bytes is the ReplicaId
changeKey = [self getReplicaKeyFromGlobCnt: newChangeNum >> 16];
[self _setChangeKey: changeKey forMessageEntry: messageEntry
inChangeListOnly: NO];
diff --git a/OpenChange/MAPIStoreMailContext.m b/OpenChange/MAPIStoreMailContext.m
index 83dc70e1f..79ea0b62e 100644
--- a/OpenChange/MAPIStoreMailContext.m
+++ b/OpenChange/MAPIStoreMailContext.m
@@ -24,6 +24,7 @@
#import
#import
#import
+#import
#import
#import
#import
@@ -156,7 +157,7 @@ MakeDisplayFolderName (NSString *folderName)
stringData = [NSString stringWithFormat: @"%@%@",
urlBase, [currentName stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
context->url = [stringData asUnicodeInMemCtx: context];
- stringData = [[currentName substringFromIndex: 6] fromCSSIdentifier];
+ stringData = [[[currentName substringFromIndex: 6] fromCSSIdentifier] stringByDecodingImap4FolderName];
context->name = [stringData asUnicodeInMemCtx: context];
context->main_folder = false;
context->role = MAPISTORE_MAIL_ROLE;
@@ -188,7 +189,7 @@ MakeDisplayFolderName (NSString *folderName)
if ([newFolder create])
mapistoreURI = [NSString stringWithFormat: @"sogo://%@:%@@mail/%@/",
userName, userName,
- [folderName stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
+ [[folderName stringByEncodingImap4FolderName] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
else
mapistoreURI = nil;
[MAPIApp setUserContext: nil];
diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m
index f06508962..3aa86688d 100644
--- a/OpenChange/MAPIStoreMailFolder.m
+++ b/OpenChange/MAPIStoreMailFolder.m
@@ -36,6 +36,7 @@
#import
#import
#import
+#import
#import
#import
#import
@@ -177,7 +178,7 @@ static Class SOGoMailFolderK, MAPIStoreMailFolderK, MAPIStoreOutboxFolderK;
if (folderName)
{
nameInContainer = [NSString stringWithFormat: @"folder%@",
- [folderName asCSSIdentifier]];
+ [[folderName stringByEncodingImap4FolderName] asCSSIdentifier]];
newFolder = [SOGoMailFolderK objectWithName: nameInContainer
inContainer: sogoObject];
if ([newFolder create])
@@ -315,7 +316,7 @@ static Class SOGoMailFolderK, MAPIStoreMailFolderK, MAPIStoreOutboxFolderK;
if (![subfolderName hasPrefix: @"folder"])
abort ();
- strippedName = [subfolderName substringFromIndex: 6];
+ strippedName = [[subfolderName substringFromIndex: 6] stringByDecodingImap4FolderName];
[representation appendFormat: @"/%@", strippedName];
return representation;
diff --git a/OpenChange/MAPIStoreMailVolatileMessage.m b/OpenChange/MAPIStoreMailVolatileMessage.m
index 513b94f26..ed60a8620 100644
--- a/OpenChange/MAPIStoreMailVolatileMessage.m
+++ b/OpenChange/MAPIStoreMailVolatileMessage.m
@@ -543,6 +543,7 @@ FillMessageHeadersFromProperties (NGMutableHashMap *headers,
NSDictionary *recipients;
NSUInteger type, bccLimit;
SOGoUser *activeUser;
+ NSNumber *priority;
activeUser
= [SOGoUser
@@ -596,6 +597,21 @@ FillMessageHeadersFromProperties (NGMutableHashMap *headers,
[headers addObject: [date rfc822DateString] forKey: @"date"];
}
[headers addObject: @"1.0" forKey: @"MIME-Version"];
+
+ priority = [mailProperties objectForKey: MAPIPropertyKey (PidTagImportance)];
+
+ if ([priority intValue] == 2)
+ {
+ [headers addObject: @"1 (Highest)" forKey: @"X-Priority"];
+ }
+ else if ([priority intValue] == 1)
+ {
+ [headers removeAllObjectsForKey: @"X-Priority"];
+ }
+ else
+ {
+ [headers addObject: @"5 (Lowest)" forKey: @"X-Priority"];
+ }
}
static NSArray *
diff --git a/OpenChange/MAPIStoreObject.m b/OpenChange/MAPIStoreObject.m
index 7d4bb3219..1d468915c 100644
--- a/OpenChange/MAPIStoreObject.m
+++ b/OpenChange/MAPIStoreObject.m
@@ -284,6 +284,9 @@ static Class NSExceptionK, MAPIStoreFolderK;
return MAPISTORE_SUCCESS;
}
+//
+// The GlobCnt is 6 bytes long.
+//
- (NSData *) getReplicaKeyFromGlobCnt: (uint64_t) objectCnt
{
struct mapistore_connection_info *connInfo;
diff --git a/OpenChange/NSData+MAPIStore.m b/OpenChange/NSData+MAPIStore.m
index b2bdedc97..44b6dcf85 100644
--- a/OpenChange/NSData+MAPIStore.m
+++ b/OpenChange/NSData+MAPIStore.m
@@ -148,6 +148,7 @@ static void _fillFlatUIDWithGUID (struct FlatUID_r *flatUID, const struct GUID *
- (struct XID *) asXIDInMemCtx: (void *) memCtx
{
struct XID *xid;
+ uint8_t *bytes;
NSUInteger max;
max = [self length];
@@ -158,7 +159,9 @@ static void _fillFlatUIDWithGUID (struct FlatUID_r *flatUID, const struct GUID *
[self _extractGUID: &xid->GUID];
xid->Size = max - 16;
- xid->Data = talloc_memdup (xid, [self bytes] + 16, xid->Size);
+
+ bytes = (uint8_t *) [self bytes];
+ xid->Data = talloc_memdup (xid, (bytes+16), xid->Size);
}
else
{
diff --git a/OpenChange/RTFHandler.m b/OpenChange/RTFHandler.m
index 27afe3c00..1e15ebaa8 100644
--- a/OpenChange/RTFHandler.m
+++ b/OpenChange/RTFHandler.m
@@ -694,10 +694,18 @@ const unsigned short ansicpg874[256] = {
}
else if (*(_bytes+1) == '*')
{
- while (*_bytes != '}')
+ int cc = 1;
+
+ do
{
+ if (*_bytes == '{')
+ cc++;
+ if (*_bytes == '}')
+ cc--;
+
ADVANCE;
}
+ while (cc != 0);
continue;
}
@@ -793,6 +801,10 @@ const unsigned short ansicpg874[256] = {
{
// ignore
}
+ else if ([s hasPrefix: @"fromtext"])
+ {
+ // ignore
+ }
else if ([s hasPrefix: @"f"] && [s length] > 1)
{
RTFFontInfo *fontInfo;
diff --git a/SOPE/GDLContentStore/EOQualifier+GCS.m b/SOPE/GDLContentStore/EOQualifier+GCS.m
index 255525ed7..9c1940058 100644
--- a/SOPE/GDLContentStore/EOQualifier+GCS.m
+++ b/SOPE/GDLContentStore/EOQualifier+GCS.m
@@ -27,7 +27,7 @@
#import "EOQualifier+GCS.h"
-#if __GNU_LIBOBJC__ >= 20100911
+#if (defined(__GNU_LIBOBJC__) && (__GNU_LIBOBJC__ >= 20100911)) || defined(APPLE_RUNTIME) || defined(__GNUSTEP_RUNTIME__)
# define sel_eq(__A__,__B__) sel_isEqual(__A__,__B__)
#endif
diff --git a/SOPE/GDLContentStore/GCSFolder.m b/SOPE/GDLContentStore/GCSFolder.m
index af49f91ce..ac5efa58e 100644
--- a/SOPE/GDLContentStore/GCSFolder.m
+++ b/SOPE/GDLContentStore/GCSFolder.m
@@ -44,7 +44,7 @@
#import "EOQualifier+GCS.h"
#import "GCSStringFormatter.h"
-#if __GNU_LIBOBJC__ >= 20100911
+#if (defined(__GNU_LIBOBJC__) && (__GNU_LIBOBJC__ >= 20100911)) || defined(APPLE_RUNTIME) || defined(__GNUSTEP_RUNTIME__)
# define sel_eq(__A__,__B__) sel_isEqual(__A__,__B__)
#endif
diff --git a/SOPE/NGCards/iCalToDo.m b/SOPE/NGCards/iCalToDo.m
index 08f5d3f7b..6d5bc7837 100644
--- a/SOPE/NGCards/iCalToDo.m
+++ b/SOPE/NGCards/iCalToDo.m
@@ -72,7 +72,7 @@
- (void) setCompleted: (NSCalendarDate *) newCompletedDate
{
[(iCalDateTime *) [self uniqueChildWithTag: @"completed"]
- setDate: newCompletedDate];
+ setDateTime: newCompletedDate];
if (newCompletedDate)
[self setStatus: @"COMPLETED"];
else
diff --git a/Scripts/sogo-backup.sh b/Scripts/sogo-backup.sh
index 12b804435..9edeb4397 100755
--- a/Scripts/sogo-backup.sh
+++ b/Scripts/sogo-backup.sh
@@ -4,7 +4,7 @@ set -o pipefail
#set -x
PROGNAME="$(basename $0)"
-BACKUP_DIR=/home/sogo/backups
+BACKUP_DIR=~sogo/backups
SOGO_TOOL=/usr/sbin/sogo-tool
DAYS_TO_KEEP="30"
diff --git a/Scripts/sogo-default b/Scripts/sogo-default
index 59bf39d73..df42a09a4 100644
--- a/Scripts/sogo-default
+++ b/Scripts/sogo-default
@@ -1,5 +1,5 @@
-# The amount of processes that should be spawned (Default: 1)
-# PREFORK=1
+# The amount of processes that should be spawned (Default: 3)
+# PREFORK=3
# The name of the account under which SOGo will be running (Default: sogo)
# USER=sogo
diff --git a/Scripts/sogo-init.d-redhat b/Scripts/sogo-init.d-redhat
index 76fea17f5..f320dd25b 100755
--- a/Scripts/sogo-init.d-redhat
+++ b/Scripts/sogo-init.d-redhat
@@ -34,7 +34,7 @@ DAEMON=/usr/sbin/sogod
DESC="SOGo"
USER=$NAME
-PREFORK=1
+PREFORK=3
PIDFILE=/var/run/$NAME/$NAME.pid
LOGFILE=/var/log/$NAME/$NAME.log
diff --git a/Scripts/sogo-init.d-sles b/Scripts/sogo-init.d-sles
index d4f3afbc1..2a4b720ad 100755
--- a/Scripts/sogo-init.d-sles
+++ b/Scripts/sogo-init.d-sles
@@ -37,7 +37,7 @@ DAEMON=/usr/sbin/sogod
DESC="SOGo"
USER=$NAME
-PREFORK=1
+PREFORK=3
PIDFILE=/var/run/$NAME/$NAME.pid
LOGFILE=/var/log/$NAME/$NAME.log
diff --git a/Scripts/sogo.conf b/Scripts/sogo.conf
index 8ae3f001f..5af5d4229 100644
--- a/Scripts/sogo.conf
+++ b/Scripts/sogo.conf
@@ -92,13 +92,14 @@
// PublicDAndTViewer,
// ConfidentialDAndTViewer
//);
- //SOGoSuperUsernames = (sogo1, sogo2); //This is an array - keep the parens!
+ //SOGoSuperUsernames = (sogo1, sogo2); // This is an array - keep the parens!
+ //SxVMemLimit = 384
/* Debug */
+ //SOGoDebugRequests = YES;
//SoDebugBaseURL = YES;
//ImapDebugEnabled = YES;
//LDAPDebugEnabled = YES;
- //SOGoDebugRequests = YES;
//PGDebugEnabled = YES;
//MySQL4DebugEnabled = YES;
//SOGoUIxDebugEnabled = YES;
diff --git a/Scripts/sogo.cron b/Scripts/sogo.cron
index 85c9f740c..5e1450093 100644
--- a/Scripts/sogo.cron
+++ b/Scripts/sogo.cron
@@ -10,6 +10,8 @@
#* * * * * sogo /usr/sbin/sogo-tool expire-sessions 60
# Email alarms - runs every minutes
+# If you need to use SMTP AUTH for outgoing mails, specify credentials to use
+# with '-p /path/to/credentialsFile' (same format as the sieve credentials)
#* * * * * sogo /usr/sbin/sogo-ealarms-notify
# Daily backups
diff --git a/Scripts/tmpwatch b/Scripts/tmpwatch
index 5aa1eb521..b834a417d 100644
--- a/Scripts/tmpwatch
+++ b/Scripts/tmpwatch
@@ -4,4 +4,4 @@
SOGOSPOOL=/var/spool/sogo
/usr/sbin/tmpwatch 24 "$SOGOSPOOL"
-find "$SOGOSPOOL" -depth -mindepth 1 -type d -empty -exec /bin/rmdir {} \; 2> /dev/null
+find "$SOGOSPOOL" -mindepth 1 -type d -user sogo -empty -delete > /dev/null
diff --git a/SoObjects/Appointments/NorwegianBokmal.lproj/Localizable.strings b/SoObjects/Appointments/NorwegianBokmal.lproj/Localizable.strings
index 4ba121e56..3a5b2227e 100644
--- a/SoObjects/Appointments/NorwegianBokmal.lproj/Localizable.strings
+++ b/SoObjects/Appointments/NorwegianBokmal.lproj/Localizable.strings
@@ -8,23 +8,15 @@ vtodo_class1 = "(Privat oppgave)";
vtodo_class2 = "(Konfidensiell oppgave)";
/* Receipts */
-"Title:" = "Tittel:";
-"Start:" = "Start:";
-"End:" = "Slutt:";
-
-"Receipt: users invited to a meeting" = "Kvittering: brukere invitert til et møte";
-"You have invited the following attendees(s):" = "Du har invitert følende deltagere:";
-"... to attend the following event:" = "... til å delta i følgende hendelse:";
-
-"Receipt: invitation updated" = "Kvittering: invitasjon oppdatert";
-"The following attendees(s):" = "Følgende deltager(e):";
-"... have been notified of the changes to the following event:" = "... har blitt informert om endringene i følgende hendelse:";
-
-"Receipt: attendees removed from an event" = "Kvittering: deltagere fjernet fra en hendelse";
-"You have removed the following attendees(s):" = "Du har tatt bort følgende deltagere:";
-"... from the following event:" = "... fra følgende hendelse:";
+"The event \"%{Summary}\" was created" = "Hendelsen \"%{Summary}\" ble opprettet";
+"The event \"%{Summary}\" was deleted" = "Hendelsen \"%{Summary}\" ble slettet";
+"The event \"%{Summary}\" was updated" = "Hendelsen \"%{Summary}\" ble oppdatert";
+"The following attendees(s) were notified:" = "Følgende deltaker(e) ble varslet:";
+"The following attendees(s) were added:" = "Følgende deltaker(e) ble lagt til:";
+"The following attendees(s) were removed:" = "Følgende deltaker(e) ble fjernet:";
/* IMIP messages */
+"calendar_label" = "Kalender:";
"startDate_label" = "Start:";
"endDate_label" = "Slutt:";
"due_label" = "Forfallsdato:";
@@ -35,27 +27,31 @@ vtodo_class2 = "(Konfidensiell oppgave)";
/* Invitation */
"Event Invitation: \"%{Summary}\"" = "Hendelseinvitasjon: \"%{Summary}\"";
"(sent by %{SentBy}) " = "(sendt av %{SentBy})";
-"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "";
-"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText} har invitert deg til %{Summary}.\n\nStart: %{StartDate} %{StartTime}\nSlutt: %{EndDate} %{EndTime}\nBeskrivelse: %{Description}";
+"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText} har invitert deg til %{Summary}.⏎ ⏎ Start: %{StartDate}⏎ Slutt: %{EndDate}⏎ Beskrivelse: %{Description}";
+"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText} har invitert deg til %{Summary}.\n\nStart: %{StartDate} klokken %{StartTime}\nSlutt: %{EndDate} klokken %{EndTime}\nBeskrivelse: %{Description}";
/* Deletion */
"Event Cancelled: \"%{Summary}\"" = "Hendelse avlyst: \"%{Summary}\"";
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"
-= "";
+= "%{Organizer} %{SentByText} har avlyst hendelsen: %{Summary}.⏎ ⏎ Start: %{StartDate}⏎ Slutt: %{EndDate}⏎ Beskrivelse: %{Description}";
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"
-= "%{Organizer} %{SentByText} har avlyst : %{Summary}.\n\nStart: %{StartDate} %{StartTime}\nEnd: %{EndDate} %{EndTime}\nBeskrivelse: %{Description}";
+= "%{Organizer} %{SentByText} har avlyst : %{Summary}.\n\nStart: %{StartDate} klokken %{StartTime}\nEnd: %{EndDate} klokken %{EndTime}\nBeskrivelse: %{Description}";
/* Update */
"The appointment \"%{Summary}\" for the %{OldStartDate} has changed"
-= "";
+= "Avtalen \"%{Summary}\", %{OldStartDate} er endret";
"The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed"
= "Avtalen \"%{Summary}\" for %{OldStartDate} klokken %{OldStartTime} er endret.";
"The following parameters have changed in the \"%{Summary}\" meeting:"
-= "Følgende parametre er endret for \"%{Summary}\" møtet:";
+= "Følgende parametre er endret for \"%{Summary}\"-møtet:";
"Please accept or decline those changes."
= "Vennligst godta eller avvis endringene.";
/* Reply */
+"Accepted invitation: \"%{Summary}\"" = "Aksepterte invitasjonen: \"%{Summary}\"";
+"Declined invitation: \"%{Summary}\"" = "Avviste invitasjonen: \"%{Summary}\"";
+"Delegated invitation: \"%{Summary}\"" = "Delegerte invitasjonen: \"%{Summary}\"";
+"Not yet decided on invitation: \"%{Summary}\"" = "Fortsatt ikke svart på invitasjonen: \"%{Summary}";
"%{Attendee} %{SentByText}has accepted your event invitation."
= "%{Attendee} %{SentByText} har godtatt invitasjonen.";
"%{Attendee} %{SentByText}has declined your event invitation."
@@ -63,7 +59,8 @@ vtodo_class2 = "(Konfidensiell oppgave)";
"%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}."
= "%{Attendee} %{SentByText} har delegert invitasjonen til %{Delegate}.";
"%{Attendee} %{SentByText}has not yet decided upon your event invitation."
-= "%{Attendee} %{SentByText} had ends ikke var på invitasjonen.";
+= "%{Attendee} %{SentByText} har ikke svart på invitasjonen.";
/* Resources */
-"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\"." = "Maksimalt antall samtidige bookinger (%{NumberOfSimultaneousBookings}) er nåd for ressurs \"%{Cn} %{SystemEmail}\".";
+"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "Kan ikke få tilgang til ressurs: \"%{Cn} %{SystemEmail}\"";
+"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Maksimum antall samtidige reservasjoner (%{NumberOfSimultaneousBookings}) er nådd for ressursen \"%{Cn} %{SystemEmail}\". Kolliderende hendelse er \"%{EventTitle}\", som starter %{StartDate}.";
diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m
index 395133ac8..03cbb118b 100644
--- a/SoObjects/Appointments/SOGoAppointmentFolder.m
+++ b/SoObjects/Appointments/SOGoAppointmentFolder.m
@@ -2236,10 +2236,39 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
return @"";
}
+/*
+ RFC5842 states:
+
+ 3.1. DAV:resource-id Property
+
+ The DAV:resource-id property is a REQUIRED property that enables
+ clients to determine whether two bindings are to the same resource.
+ The value of DAV:resource-id is a URI, and may use any registered URI
+ scheme that guarantees the uniqueness of the value across all
+ resources for all time (e.g., the urn:uuid: URN namespace defined in
+ [RFC4122] or the opaquelocktoken: URI scheme defined in [RFC4918]).
+
+
+
+ ...
+
+ so we must STRIP any username prefix, to make the ID global.
+
+*/
- (NSString *) davResourceId
{
+ NSString *name, *prefix;
+
+ prefix = [NSString stringWithFormat: @"%@_", [self ownerInContext: context]];
+ name = [self nameInContainer];
+
+ if ([name hasPrefix: prefix])
+ {
+ name = [name substringFromIndex: [prefix length]];
+ }
+
return [NSString stringWithFormat: @"urn:uuid:%@:calendars:%@",
- [self ownerInContext: context], [self nameInContainer]];
+ [self ownerInContext: context], name];
}
- (NSArray *) davScheduleCalendarTransparency
diff --git a/SoObjects/Appointments/SOGoAppointmentFolders.h b/SoObjects/Appointments/SOGoAppointmentFolders.h
index a4b84a6dc..c196d5dc5 100644
--- a/SoObjects/Appointments/SOGoAppointmentFolders.h
+++ b/SoObjects/Appointments/SOGoAppointmentFolders.h
@@ -1,8 +1,6 @@
/* SOGoAppointmentFolders.h - this file is part of SOGo
*
- * Copyright (C) 2007 Inverse inc.
- *
- * Author: Wolfgang Sourdeau
+ * Copyright (C) 2007-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,8 +33,8 @@
NSMutableArray *folderObjectKeys;
}
-- (SOGoWebAppointmentFolder *) newWebCalendarWithName: (NSString *) folderDisplayName
- atURL: (NSString *) url;
+- (SOGoWebAppointmentFolder *) newWebCalendarWithURL: (NSString *) urlString
+ nameInContainer: (NSString *) name;
- (void) reloadWebCalendars: (BOOL) forceReload;
diff --git a/SoObjects/Appointments/SOGoAppointmentFolders.m b/SoObjects/Appointments/SOGoAppointmentFolders.m
index b2dde6b4d..883564a7e 100644
--- a/SoObjects/Appointments/SOGoAppointmentFolders.m
+++ b/SoObjects/Appointments/SOGoAppointmentFolders.m
@@ -1,9 +1,7 @@
/* SOGoAppointmentFolders.m - this file is part of SOGo
*
- * Copyright (C) 2007-2010 Inverse inc.
- *
- * Author: Wolfgang Sourdeau
+ * Copyright (C) 2007-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -133,18 +131,29 @@ static SoSecurityManager *sm = nil;
return [self labelForKey: @"Personal Calendar" inContext: context];
}
-- (SOGoWebAppointmentFolder *)
- newWebCalendarWithName: (NSString *) folderDisplayName
- atURL: (NSString *) urlString
+
+
+- (SOGoWebAppointmentFolder *) newWebCalendarWithURL: (NSString *) urlString
+ nameInContainer: (NSString *) name
{
- NSException *error;
- SOGoAppointmentFolder *aptFolder;
+ NSString *folderDisplayName, *tmp;
SOGoWebAppointmentFolder *webCalendar;
- NSString *name;
+ SOGoAppointmentFolder *aptFolder;
+ NSException *error;
NSURL *url;
+ folderDisplayName = [self labelForKey: @"Web Calendar"];
webCalendar = nil;
+ tmp = [urlString lastPathComponent];
+ if (tmp)
+ {
+ if ([[tmp pathExtension] caseInsensitiveCompare: @"ics"] == NSOrderedSame)
+ folderDisplayName = [tmp substringToIndex: [tmp length] - 4];
+ else
+ folderDisplayName = tmp;
+ }
+
if ([folderDisplayName length] > 0 && [urlString length] > 0)
{
url = [NSURL URLWithString: urlString];
@@ -154,6 +163,10 @@ static SoSecurityManager *sm = nil;
nameInContainer: &name];
if (!error)
{
+ // We make sure we initialized our subfolfers list. This can happen
+ // when auto-creating Web calendars during the logon process.
+ [self subFolders];
+
aptFolder = [subFolders objectForKey: name];
[aptFolder setFolderPropertyValue: urlString
inCategory: @"WebCalendars"];
@@ -561,9 +574,25 @@ static SoSecurityManager *sm = nil;
folder = [SOGoWebAppointmentFolder
folderWithSubscriptionReference: ref
inContainer: self];
- if (folder
- && (forceReload || [folder reloadOnLogin]))
- [folder loadWebCalendar];
+
+ if (forceReload || [folder reloadOnLogin] || !folder)
+ {
+ if (!folder)
+ {
+ NSString *s, *urlString;
+
+ urlString = [[calSettings objectForKey: @"WebCalendars"] objectForKey: ref];
+ s = [ref lastPathComponent];
+
+ // See bug #2007. Some admins want to subscribe users to Web calendars
+ // using sogo-tool. If they do that, the db tables won't be created
+ // so we must detect that here and create them upon login.
+ folder = [self newWebCalendarWithURL: urlString
+ nameInContainer: s];
+ }
+
+ [folder loadWebCalendar];
+ }
}
}
diff --git a/SoObjects/Appointments/SOGoAptMailNotification.m b/SoObjects/Appointments/SOGoAptMailNotification.m
index 0d0db981e..4c26191ae 100644
--- a/SoObjects/Appointments/SOGoAptMailNotification.m
+++ b/SoObjects/Appointments/SOGoAptMailNotification.m
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2006-2012 Inverse inc.
+ Copyright (C) 2006-2013 Inverse inc.
Copyright (C) 2000-2005 SKYRIX Software AG
This file is part of SOGo.
@@ -142,12 +142,12 @@
- (NSString *) location
{
- return [[apt location] stringByEscapingHTMLString];
+ return [apt location];
}
- (NSString *) summary
{
- return [[apt summary] stringByEscapingHTMLString];
+ return [apt summary];
}
- (void) setOrganizerName: (NSString *) theString
diff --git a/SoObjects/Appointments/SOGoFreeBusyObject.m b/SoObjects/Appointments/SOGoFreeBusyObject.m
index 13622ae4f..18f08e10b 100644
--- a/SoObjects/Appointments/SOGoFreeBusyObject.m
+++ b/SoObjects/Appointments/SOGoFreeBusyObject.m
@@ -294,7 +294,9 @@
contact = [contacts lastObject];
email = [contact valueForKey: @"c_email"];
source = [contact objectForKey: @"source"];
- if ([email length] && [source MSExchangeHostname])
+ if ([email length]
+ && [source conformsToProtocol: @protocol (SOGoDNSource)]
+ && [source MSExchangeHostname])
{
exchangeFreeBusy = [[MSExchangeFreeBusy alloc] init];
[exchangeFreeBusy autorelease];
diff --git a/SoObjects/Appointments/iCalEvent+SOGo.m b/SoObjects/Appointments/iCalEvent+SOGo.m
index dc01b4284..6856d89fb 100644
--- a/SoObjects/Appointments/iCalEvent+SOGo.m
+++ b/SoObjects/Appointments/iCalEvent+SOGo.m
@@ -64,6 +64,9 @@
return isStillRelevent;
}
+//
+//
+//
- (NSMutableDictionary *) quickRecord
{
NSMutableDictionary *row;
@@ -88,7 +91,15 @@
title = [self summary];
if (![title isNotNull])
title = @"";
+
+ if ([title length] > 1000)
+ title = [title substringToIndex: 1000];
+
location = [self location];
+
+ if ([location length] > 255)
+ location = [location substringToIndex: 255];
+
sequence = [self sequence];
accessClass = [self symbolicAccessClass];
isAllDay = [self isAllDay];
diff --git a/SoObjects/Contacts/SOGoFolder+CardDAV.m b/SoObjects/Contacts/SOGoFolder+CardDAV.m
index 3466e940e..2644e228f 100644
--- a/SoObjects/Contacts/SOGoFolder+CardDAV.m
+++ b/SoObjects/Contacts/SOGoFolder+CardDAV.m
@@ -21,6 +21,7 @@
*/
#import
+#import
#import
#import
@@ -65,7 +66,7 @@
@""];
[r appendContentString: baseURL];
if (![baseURL hasSuffix: @"/"])
- [r appendContentString: @"/"];
+ [r appendContentString: @"/"];
[r appendContentString: name];
[r appendContentString: @""
@""
@@ -89,9 +90,10 @@
- (void) _appendComponentsMatchingFilters: (NSArray *) filters
toResponse: (WOResponse *) response
- context: (id) localContext
+ context: (id) localContext
{
- unsigned int count, max;
+ unsigned int count,i , max;
+ NSAutoreleasePool *pool;
NSDictionary *currentFilter, *contact;
NSEnumerator *contacts;
NSString *baseURL, *domain;
@@ -103,16 +105,27 @@
for (count = 0; count < max; count++)
{
currentFilter = [filters objectAtIndex: count];
- contacts = [[(id)self lookupContactsWithFilter: [[currentFilter allValues] lastObject]
- onCriteria: @"name_or_address"
- sortBy: @"c_givenname"
- ordering: NSOrderedDescending
- inDomain: domain]
- objectEnumerator];
-
+ contacts =
+ [[(id)self lookupContactsWithFilter: [[currentFilter allValues] lastObject]
+ onCriteria: @"name_or_address"
+ sortBy: @"c_givenname"
+ ordering: NSOrderedDescending
+ inDomain: domain] objectEnumerator];
+
+ pool = [[NSAutoreleasePool alloc] init];
+ i = 0;
while ((contact = [contacts nextObject]))
- [self _appendObject: contact withBaseURL: baseURL
- toREPORTResponse: response];
+ {
+ [self _appendObject: contact withBaseURL: baseURL
+ toREPORTResponse: response];
+ if (i % 10 == 0)
+ {
+ RELEASE(pool);
+ pool = [[NSAutoreleasePool alloc] init];
+ }
+ i++;
+ }
+ RELEASE(pool);
}
}
@@ -123,10 +136,10 @@
newString = [theString lowercaseString];
return ([newString isEqualToString: @"sn"]
- || [newString isEqualToString: @"givenname"]
- || [newString isEqualToString: @"email"]
- || [newString isEqualToString: @"mail"]
- || [newString isEqualToString: @"telephonenumber"]);
+ || [newString isEqualToString: @"givenname"]
+ || [newString isEqualToString: @"email"]
+ || [newString isEqualToString: @"mail"]
+ || [newString isEqualToString: @"telephonenumber"]);
}
- (NSDictionary *) _parseContactFilter: (id ) filterElement
@@ -145,12 +158,12 @@
ranges = [filterElement getElementsByTagName: @"text-match"];
if ([(NSArray *) ranges count]
- && [(NSArray *) [[ranges objectAtIndex: 0] childNodes] count])
- {
- filterData = [NSMutableDictionary dictionary];
- [filterData setObject: [(NGDOMNode *)[ranges objectAtIndex: 0] textValue]
- forKey: [filterElement attribute: @"name"]];
- }
+ && [(NSArray *) [[ranges objectAtIndex: 0] childNodes] count])
+ {
+ filterData = [NSMutableDictionary dictionary];
+ [filterData setObject: [(NGDOMNode *)[ranges objectAtIndex: 0] textValue]
+ forKey: [filterElement attribute: @"name"]];
+ }
}
return filterData;
@@ -166,7 +179,7 @@
filters = [NSMutableArray array];
children = [(NSArray *)[parentNode getElementsByTagName: @"prop-filter"]
- objectEnumerator];
+ objectEnumerator];
while ((node = [children nextObject]))
{
filter = [self _parseContactFilter: node];
@@ -193,7 +206,7 @@
[self _appendComponentsMatchingFilters: filters
toResponse: r
- context: queryContext];
+ context: queryContext];
[r appendContentString: @""];
return r;
diff --git a/SoObjects/Mailer/GNUmakefile b/SoObjects/Mailer/GNUmakefile
index 7934e878a..eb7df2a86 100644
--- a/SoObjects/Mailer/GNUmakefile
+++ b/SoObjects/Mailer/GNUmakefile
@@ -57,6 +57,8 @@ Mailer_RESOURCE_FILES += \
SOGoMailDutchReply.wo \
SOGoMailEnglishForward.wo \
SOGoMailEnglishReply.wo \
+ SOGoMailFinnishForward.wo \
+ SOGoMailFinnishReply.wo \
SOGoMailFrenchForward.wo \
SOGoMailFrenchReply.wo \
SOGoMailGermanForward.wo \
@@ -90,6 +92,7 @@ Mailer_RESOURCE_FILES += \
ADDITIONAL_INCLUDE_DIRS += -I../../SOPE/
+ADDITIONAL_INCLUDE_DIRS += $(shell xml2-config --cflags)
ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/
-include GNUmakefile.preamble
diff --git a/SoObjects/Mailer/NSString+Mail.h b/SoObjects/Mailer/NSString+Mail.h
index c99b6b57c..e967622b5 100644
--- a/SoObjects/Mailer/NSString+Mail.h
+++ b/SoObjects/Mailer/NSString+Mail.h
@@ -1,8 +1,6 @@
/* NSString+Mail.h - this file is part of SOGo
*
- * Copyright (C) 2007 Inverse inc.
- *
- * Author: Wolfgang Sourdeau
+ * Copyright (C) 2007-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/SoObjects/Mailer/NSString+Mail.m b/SoObjects/Mailer/NSString+Mail.m
index d9f9cc5f1..94f8e9b4f 100644
--- a/SoObjects/Mailer/NSString+Mail.m
+++ b/SoObjects/Mailer/NSString+Mail.m
@@ -1,8 +1,6 @@
/* NSString+Mail.m - this file is part of SOGo
*
- * Copyright (C) 2008 Inverse inc.
- *
- * Author: Wolfgang Sourdeau
+ * Copyright (C) 2008-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,10 +31,12 @@
#import
#import
+#include
+
#import "NSString+Mail.h"
#import "NSData+Mail.h"
-#if 1
+#if 0
#define showWhoWeAre() \
[self logWithFormat: @"invoked '%@'", NSStringFromSelector (_cmd)]
#else
@@ -97,6 +97,11 @@
return self;
}
+- (xmlCharEncoding) contentEncoding
+{
+ return XML_CHAR_ENCODING_UTF8;
+}
+
- (void) dealloc
{
[ignoreContentTags release];
@@ -234,11 +239,12 @@
}
- (void) characters: (unichar *) characters
- length: (int) length
+ length: (NSUInteger) length
{
if (!ignoreContent)
- [result appendString: [NSString stringWithCharacters: characters
- length: length]];
+ {
+ [result appendString: [NSString stringWithCharacters: characters length: length]];
+ }
}
- (void) ignorableWhitespace: (unichar *) whitespaces
@@ -339,14 +345,17 @@
- (NSString *) htmlToText
{
- id parser;
_SOGoHTMLToTextContentHandler *handler;
+ id parser;
+ NSData *d;
parser = [[SaxXMLReaderFactory standardXMLReaderFactory]
createXMLReaderForMimeType: @"text/html"];
handler = [_SOGoHTMLToTextContentHandler htmlToTextContentHandler];
[parser setContentHandler: handler];
- [parser parseFromSource: self];
+
+ d = [self dataUsingEncoding: NSUTF8StringEncoding];
+ [parser parseFromSource: d];
return [handler result];
}
diff --git a/SoObjects/Mailer/SOGoDraftObject.m b/SoObjects/Mailer/SOGoDraftObject.m
index 1332070c8..4f2cdab95 100644
--- a/SoObjects/Mailer/SOGoDraftObject.m
+++ b/SoObjects/Mailer/SOGoDraftObject.m
@@ -171,12 +171,17 @@ static NSString *headerKeys[] = {@"subject", @"to", @"cc", @"bcc",
@implementation SOGoDraftObject
static NGMimeType *MultiMixedType = nil;
+static NGMimeType *MultiAlternativeType = nil;
static NSString *userAgent = nil;
+ (void) initialize
{
MultiMixedType = [NGMimeType mimeType: @"multipart" subType: @"mixed"];
[MultiMixedType retain];
+
+ MultiAlternativeType = [NGMimeType mimeType: @"multipart" subType: @"alternative"];
+ [MultiAlternativeType retain];
+
userAgent = [NSString stringWithFormat: @"SOGoMail %@",
SOGoVersion];
[userAgent retain];
@@ -981,8 +986,33 @@ static NSString *userAgent = nil;
return error;
}
-/* NGMime representations */
+//
+// Only called when converting text/html to text/plain parts
+//
+- (NGMimeBodyPart *) plainTextBodyPartForText
+{
+ NGMutableHashMap *map;
+ NGMimeBodyPart *bodyPart;
+ NSString *plainText;
+ /* prepare header of body part */
+ map = [[[NGMutableHashMap alloc] initWithCapacity: 1] autorelease];
+
+ [map setObject: contentTypeValue forKey: @"content-type"];
+
+ /* prepare body content */
+ bodyPart = [[[NGMimeBodyPart alloc] initWithHeader:map] autorelease];
+
+ plainText = [text htmlToText];
+ [bodyPart setBody: plainText];
+
+ return bodyPart;
+}
+
+
+//
+//
+//
- (NGMimeBodyPart *) bodyPartForText
{
/*
@@ -992,25 +1022,14 @@ static NSString *userAgent = nil;
NGMimeBodyPart *bodyPart;
/* prepare header of body part */
-
map = [[[NGMutableHashMap alloc] initWithCapacity: 1] autorelease];
// TODO: set charset in header!
- [map setObject: @"text/plain" forKey: @"content-type"];
if (text)
[map setObject: (isHTML ? htmlContentTypeValue : contentTypeValue)
forKey: @"content-type"];
-
-// if ((body = text) != nil) {
-// if ([body isKindOfClass: [NSString class]]) {
-// [map setObject: contentTypeValue
-// forKey: @"content-type"];
-// // body = [body dataUsingEncoding:NSUTF8StringEncoding];
-// }
-// }
/* prepare body content */
-
bodyPart = [[[NGMimeBodyPart alloc] initWithHeader:map] autorelease];
[bodyPart setBody: text];
@@ -1020,32 +1039,29 @@ static NSString *userAgent = nil;
- (NGMimeMessage *) mimeMessageForContentWithHeaderMap: (NGMutableHashMap *) map
{
NGMimeMessage *message;
-// BOOL addSuffix;
- id body;
+ id body;
- [map setObject: @"text/plain" forKey: @"content-type"];
- body = text;
- if (body)
+ message = [[[NGMimeMessage alloc] initWithHeader:map] autorelease];
+
+ if (!isHTML)
{
-// if ([body isKindOfClass:[NSString class]])
- /* Note: just 'utf8' is displayed wrong in Mail.app */
- [map setObject: (isHTML ? htmlContentTypeValue : contentTypeValue)
- forKey: @"content-type"];
-// body = [body dataUsingEncoding:NSUTF8StringEncoding];
-// else if ([body isKindOfClass:[NSData class]] && addSuffix) {
-// body = [[body mutableCopy] autorelease];
-// }
-// else if (addSuffix) {
-// [self warnWithFormat: @"Note: cannot add Internet marker to body: %@",
-// NSStringFromClass([body class])];
-// }
-
- message = [[[NGMimeMessage alloc] initWithHeader:map] autorelease];
- [message setBody: body];
+ [map setObject: contentTypeValue forKey: @"content-type"];
+ body = text;
}
else
- message = nil;
+ {
+ body = [[[NGMimeMultipartBody alloc] initWithPart: message] autorelease];
+ [map addObject: MultiAlternativeType forKey: @"content-type"];
+ // Add the HTML part
+ [body addBodyPart: [self bodyPartForText]];
+
+ // Get the text part from it and add it too
+ [body addBodyPart: [self plainTextBodyPartForText]];
+ }
+
+ [message setBody: body];
+
return message;
}
@@ -1232,21 +1248,54 @@ static NSString *userAgent = nil;
return bodyParts;
}
+- (NGMimeBodyPart *) mimeMultipartAlternative
+{
+ NGMimeMultipartBody *textParts;
+ NGMutableHashMap *header;
+ NGMimeBodyPart *part;
+
+ header = [NGMutableHashMap hashMap];
+ [header addObject: MultiAlternativeType forKey: @"content-type"];
+
+ part = [NGMimeBodyPart bodyPartWithHeader: header];
+
+ textParts = [[NGMimeMultipartBody alloc] initWithPart: part];
+
+ // Add the HTML part
+ [textParts addBodyPart: [self bodyPartForText]];
+
+ // Get the text part from it and add it too
+ [textParts addBodyPart: [self plainTextBodyPartForText]];
+
+ [part setBody: textParts];
+ RELEASE(textParts);
+
+ return part;
+}
+
- (NGMimeMessage *) mimeMultiPartMessageWithHeaderMap: (NGMutableHashMap *) map
andBodyParts: (NSArray *) _bodyParts
{
NGMimeMessage *message;
NGMimeMultipartBody *mBody;
- NGMimeBodyPart *part;
NSEnumerator *e;
+ id part;
[map addObject: MultiMixedType forKey: @"content-type"];
message = [[NGMimeMessage alloc] initWithHeader: map];
[message autorelease];
mBody = [[NGMimeMultipartBody alloc] initWithPart: message];
+
+ if (!isHTML)
+ {
+ part = [self bodyPartForText];
+ }
+ else
+ {
+ part = [self mimeMultipartAlternative];
+ }
- part = [self bodyPartForText];
[mBody addBodyPart: part];
e = [_bodyParts objectEnumerator];
diff --git a/SoObjects/Mailer/SOGoMailFolder.m b/SoObjects/Mailer/SOGoMailFolder.m
index ad7c6bbe3..c74f8ec70 100644
--- a/SoObjects/Mailer/SOGoMailFolder.m
+++ b/SoObjects/Mailer/SOGoMailFolder.m
@@ -1179,7 +1179,7 @@ static NSString *defaultUserID = @"anyone";
stringByAppendingString: [uid substringFromIndex: 1]];
else if ([[[context activeUser] domainDefaults] forceExternalLoginWithEmail])
{
- return [[[context activeUser] primaryIdentity] objectForKey: @"email"];
+ return [[[SOGoUser userWithLogin: uid] primaryIdentity] objectForKey: @"email"];
}
else
return uid;
diff --git a/SoObjects/Mailer/SOGoMailForward.h b/SoObjects/Mailer/SOGoMailForward.h
index 032733692..a330a033a 100644
--- a/SoObjects/Mailer/SOGoMailForward.h
+++ b/SoObjects/Mailer/SOGoMailForward.h
@@ -58,6 +58,9 @@
@interface SOGoMailEnglishForward : SOGoMailForward
@end
+@interface SOGoMailFinnishForward : SOGoMailForward
+@end
+
@interface SOGoMailFrenchForward : SOGoMailForward
@end
diff --git a/SoObjects/Mailer/SOGoMailForward.m b/SoObjects/Mailer/SOGoMailForward.m
index 3fcdb840a..ad7f12c23 100644
--- a/SoObjects/Mailer/SOGoMailForward.m
+++ b/SoObjects/Mailer/SOGoMailForward.m
@@ -262,6 +262,9 @@
@implementation SOGoMailEnglishForward
@end
+@implementation SOGoMailFinnishForward
+@end
+
@implementation SOGoMailFrenchForward
@end
diff --git a/SoObjects/Mailer/SOGoMailReply.h b/SoObjects/Mailer/SOGoMailReply.h
index 20b698f76..e519138bb 100644
--- a/SoObjects/Mailer/SOGoMailReply.h
+++ b/SoObjects/Mailer/SOGoMailReply.h
@@ -63,6 +63,9 @@
@interface SOGoMailEnglishReply : SOGoMailReply
@end
+@interface SOGoMailFinnishReply : SOGoMailReply
+@end
+
@interface SOGoMailFrenchReply : SOGoMailReply
@end
diff --git a/SoObjects/Mailer/SOGoMailReply.m b/SoObjects/Mailer/SOGoMailReply.m
index 5738d520f..8755306ee 100644
--- a/SoObjects/Mailer/SOGoMailReply.m
+++ b/SoObjects/Mailer/SOGoMailReply.m
@@ -120,6 +120,9 @@
@implementation SOGoMailEnglishReply
@end
+@implementation SOGoMailFinnishReply
+@end
+
@implementation SOGoMailFrenchReply
@end
diff --git a/SoObjects/SOGo/GNUmakefile b/SoObjects/SOGo/GNUmakefile
index 43bce3e54..f9010db09 100644
--- a/SoObjects/SOGo/GNUmakefile
+++ b/SoObjects/SOGo/GNUmakefile
@@ -55,6 +55,7 @@ SOGo_HEADER_FILES = \
SOGoCASSession.h \
SOGoDAVAuthenticator.h \
SOGoProxyAuthenticator.h \
+ SOGoStaticAuthenticator.h \
SOGoWebAuthenticator.h \
SOGoWebDAVAclManager.h \
SOGoWebDAVValue.h \
@@ -67,7 +68,9 @@ SOGo_HEADER_FILES = \
WORequest+SOGo.h \
WOResourceManager+SOGo.h \
WOResponse+SOGo.h \
- WOContext+SOGo.h
+ WOContext+SOGo.h \
+ \
+ SOGoCredentialsFile.h
# daemon tool
all::
@@ -124,6 +127,7 @@ SOGo_OBJC_FILES = \
SOGoCASSession.m \
SOGoDAVAuthenticator.m \
SOGoProxyAuthenticator.m \
+ SOGoStaticAuthenticator.m \
SOGoWebAuthenticator.m \
SOGoWebDAVAclManager.m \
SOGoWebDAVValue.m \
@@ -136,7 +140,10 @@ SOGo_OBJC_FILES = \
WORequest+SOGo.m \
WOResourceManager+SOGo.m \
WOResponse+SOGo.m \
- WOContext+SOGo.m
+ WOContext+SOGo.m \
+ \
+ SOGoCredentialsFile.m
+
SOGo_RESOURCE_FILES = \
SOGoDefaults.plist \
diff --git a/SoObjects/SOGo/LDAPSource.h b/SoObjects/SOGo/LDAPSource.h
index 13b37f876..6dd6a2325 100644
--- a/SoObjects/SOGo/LDAPSource.h
+++ b/SoObjects/SOGo/LDAPSource.h
@@ -1,10 +1,6 @@
/* LDAPSource.h - this file is part of SOGo
*
- * Copyright (C) 2007-2011 Inverse inc.
- *
- * Author: Wolfgang Sourdeau
- * Ludovic Marcotte
- * Francis Lachapelle
+ * Copyright (C) 2007-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -125,8 +121,6 @@ andMultipleBookingsField: (NSString *) newMultipleBookingsField;
- (NGLdapEntry *) lookupGroupEntryByUID: (NSString *) theUID;
- (NGLdapEntry *) lookupGroupEntryByEmail: (NSString *) theEmail;
-- (NGLdapEntry *) lookupGroupEntryByAttribute: (NSString *) theAttribute
- andValue: (NSString *) theValue;
@end
diff --git a/SoObjects/SOGo/LDAPSource.m b/SoObjects/SOGo/LDAPSource.m
index 0abf57afa..af71b29eb 100644
--- a/SoObjects/SOGo/LDAPSource.m
+++ b/SoObjects/SOGo/LDAPSource.m
@@ -1,10 +1,6 @@
/* LDAPSource.m - this file is part of SOGo
*
- * Copyright (C) 2007-2012 Inverse inc.
- *
- * Author: Wolfgang Sourdeau
- * Ludovic Marcotte
- * Francis Lachapelle
+ * Copyright (C) 2007-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -632,7 +628,25 @@ static Class NSStringK;
IDField, [login escapedForLDAPDN], baseDN];
if (userDN)
{
- if (!passwordPolicy)
+ if ([bindConnection isADCompatible])
+ {
+ if ([bindConnection bindWithMethod: @"simple"
+ binddn: userDN
+ credentials: oldPassword])
+ {
+ didChange = [bindConnection changeADPasswordAtDn: userDN
+ oldPassword: oldPassword
+ newPassword: newPassword];
+ }
+ }
+ else if (passwordPolicy)
+ {
+ didChange = [bindConnection changePasswordAtDn: userDN
+ oldPassword: oldPassword
+ newPassword: newPassword
+ perr: (void *)perr];
+ }
+ else
{
// We don't use a password policy - we simply use
// a modify-op to change the password
@@ -668,11 +682,6 @@ static Class NSStringK;
didChange = NO;
}
}
- else
- didChange = [bindConnection changePasswordAtDn: userDN
- oldPassword: oldPassword
- newPassword: newPassword
- perr: (void *)perr];
}
}
}
@@ -1232,40 +1241,31 @@ static Class NSStringK;
return [_dnCache objectForKey: theLogin];
}
-- (NGLdapEntry *) lookupGroupEntryByUID: (NSString *) theUID
-{
- return [self lookupGroupEntryByAttribute: UIDField
- andValue: theUID];
-}
-
-- (NGLdapEntry *) lookupGroupEntryByEmail: (NSString *) theEmail
-{
-#warning We should support MailFieldNames
- return [self lookupGroupEntryByAttribute: @"mail"
- andValue: theEmail];
-}
-
-// This method should accept multiple attributes
-- (NGLdapEntry *) lookupGroupEntryByAttribute: (NSString *) theAttribute
- andValue: (NSString *) theValue
+- (NGLdapEntry *) _lookupGroupEntryByAttributes: (NSArray *) theAttributes
+ andValue: (NSString *) theValue
{
EOQualifier *qualifier;
- NSString *s;
NGLdapEntry *ldapEntry;
-
- if ([theValue length] > 0)
+ NSString *s;
+
+ if ([theValue length] > 0 && [theAttributes count] > 0)
{
- s = [NSString stringWithFormat: @"(%@='%@')",
- theAttribute, SafeLDAPCriteria(theValue)];
+ if ([theAttributes count] == 1)
+ {
+ s = [NSString stringWithFormat: @"(%@='%@')",
+ [theAttributes lastObject], SafeLDAPCriteria(theValue)];
+
+ }
+ else
+ {
+ NSString *fieldFormat;
+
+ fieldFormat = [NSString stringWithFormat: @"(%%@='%@')", SafeLDAPCriteria(theValue)];
+ s = [[theAttributes stringsWithFormat: fieldFormat]
+ componentsJoinedByString: @" OR "];
+ }
+
qualifier = [EOQualifier qualifierWithQualifierFormat: s];
-
- // We look for additional attributes - the ones related to group
- // membership
- // attributes = [NSMutableArray arrayWithArray: [self _searchAttributes]];
- // [attributes addObject: @"member"];
- // [attributes addObject: @"uniqueMember"];
- // [attributes addObject: @"memberUid"];
- // [attributes addObject: @"memberOf"];
ldapEntry = [self _lookupLDAPEntry: qualifier];
}
else
@@ -1274,6 +1274,18 @@ static Class NSStringK;
return ldapEntry;
}
+- (NGLdapEntry *) lookupGroupEntryByUID: (NSString *) theUID
+{
+ return [self _lookupGroupEntryByAttributes: [NSArray arrayWithObject: UIDField]
+ andValue: theUID];
+}
+
+- (NGLdapEntry *) lookupGroupEntryByEmail: (NSString *) theEmail
+{
+ return [self _lookupGroupEntryByAttributes: mailFields
+ andValue: theEmail];
+}
+
- (void) setSourceID: (NSString *) newSourceID
{
ASSIGN (sourceID, newSourceID);
diff --git a/SoObjects/SOGo/NSString+Utilities.h b/SoObjects/SOGo/NSString+Utilities.h
index df82535e2..245df3a3e 100644
--- a/SoObjects/SOGo/NSString+Utilities.h
+++ b/SoObjects/SOGo/NSString+Utilities.h
@@ -1,9 +1,6 @@
/* NSString+Utilities.h - this file is part of SOGo
*
- * Copyright (C) 2006-2011 Inverse inc.
- *
- * Author: Wolfgang Sourdeau
- * Ludovic Marcotte
+ * Copyright (C) 2006-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/SoObjects/SOGo/NSString+Utilities.m b/SoObjects/SOGo/NSString+Utilities.m
index afca514b9..59241ba4b 100644
--- a/SoObjects/SOGo/NSString+Utilities.m
+++ b/SoObjects/SOGo/NSString+Utilities.m
@@ -2,9 +2,6 @@
*
* Copyright (C) 2006-2013 Inverse inc.
*
- * Author: Wolfgang Sourdeau
- * Ludovic Marcotte
- *
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
diff --git a/SoObjects/SOGo/SOGoCASSession.m b/SoObjects/SOGo/SOGoCASSession.m
index ce0f8917e..4d684c382 100644
--- a/SoObjects/SOGo/SOGoCASSession.m
+++ b/SoObjects/SOGo/SOGoCASSession.m
@@ -390,7 +390,7 @@
[httpConnection autorelease];
request = [[WORequest alloc] initWithMethod: @"GET"
uri: [requestURL hostlessURL]
- httpVersion: @"HTTP/1.1"
+ httpVersion: @"HTTP/1.0"
headers: nil content: nil
userInfo: nil];
[request autorelease];
diff --git a/SoObjects/SOGo/SOGoCredentialsFile.h b/SoObjects/SOGo/SOGoCredentialsFile.h
new file mode 100644
index 000000000..b6946faba
--- /dev/null
+++ b/SoObjects/SOGo/SOGoCredentialsFile.h
@@ -0,0 +1,43 @@
+/* SOGoCredentialsFile.h - this file is part of SOGo
+ *
+ * Copyright (C) 2013 Inverse inc.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SOGOCREDENTIALSFILE_H
+#define SOGOCREDENTIALSFILE_H
+
+#import
+
+@interface SOGoCredentialsFile : NSObject
+{
+ NSString *_credentialsFile;
+ NSString *_username, *_password;
+}
+
++ (id) credentialsFromFile: (NSString *) file;
+
+- (id) initFromFile: (NSString *) file
+ withEncoding: (NSStringEncoding) enc;
+
+- (NSString *) username;
+- (NSString *) password;
+- (NSString *) credentialsFile;
+
+@end
+
+#endif /* SOGOCREDENTIALSFILE_H */
diff --git a/SoObjects/SOGo/SOGoCredentialsFile.m b/SoObjects/SOGo/SOGoCredentialsFile.m
new file mode 100644
index 000000000..a13a7483e
--- /dev/null
+++ b/SoObjects/SOGo/SOGoCredentialsFile.m
@@ -0,0 +1,113 @@
+/* SOGoCredentialsFile.m - this file is part of SOGo
+ *
+ * Copyright (C) 2013 Inverse inc.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import
+#import
+#import
+
+#import "SOGoCredentialsFile.h"
+
+@implementation SOGoCredentialsFile
+
++ (id) credentialsFromFile: (NSString *) file
+{
+ SOGoCredentialsFile *newCreds;
+ newCreds = [[self alloc] initFromFile: file
+ withEncoding: NSUTF8StringEncoding];
+ [newCreds autorelease];
+ return newCreds;
+}
+
+
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ _username = nil;
+ _password = nil;
+ _credentialsFile = nil;
+ }
+ return self;
+}
+
+- (void) dealloc
+{
+ [_username release];
+ [_password release];
+ [_credentialsFile release];
+ [super dealloc];
+}
+
+- (id) initFromFile: (NSString *) file
+ withEncoding: (NSStringEncoding) enc
+{
+ id ret;
+ NSData *credentialsData;
+ NSRange r;
+ NSString *creds;
+
+ ret = nil;
+ if (file)
+ {
+ if ((self = [self init]))
+ {
+ credentialsData = [NSData dataWithContentsOfFile: file];
+ if (credentialsData == nil)
+ NSLog(@"Failed to load credentials file: %@", file);
+ else
+ {
+ creds = [[NSString alloc] initWithData: credentialsData
+ encoding: enc];
+ [creds autorelease];
+ creds = [creds stringByTrimmingCharactersInSet:
+ [NSCharacterSet characterSetWithCharactersInString: @"\r\n"]];
+ r = [creds rangeOfString: @":"];
+ if (r.location == NSNotFound)
+ NSLog(@"Invalid credentials file content, missing ':' separator (%@)", file);
+ else
+ {
+ _username = [[creds substringToIndex: r.location] retain];
+ _password = [[creds substringFromIndex: r.location+1] retain];
+ _credentialsFile = [file retain];
+ ret = self;
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+
+- (NSString *) username
+{
+ return self->_username;
+}
+
+- (NSString *) password
+{
+ return self->_password;
+}
+
+- (NSString *) credentialsFile
+{
+ return self->_credentialsFile;
+}
+
+@end
diff --git a/SoObjects/SOGo/SOGoDefaults.plist b/SoObjects/SOGo/SOGoDefaults.plist
index 69e506d8e..bb68c62d7 100644
--- a/SoObjects/SOGo/SOGoDefaults.plist
+++ b/SoObjects/SOGo/SOGoDefaults.plist
@@ -4,6 +4,8 @@
WOLogFile = "/var/log/sogo/sogo.log";
WOPidFile = "/var/run/sogo/sogo.pid";
+ WOPort = "127.0.0.1:20000";
+
NGImap4ConnectionStringSeparator = "/";
NGImap4ConnectionGroupIdPrefix = "$";
NGImap4DisableIMAP4Pooling = YES;
diff --git a/SoObjects/SOGo/SOGoGCSFolder.m b/SoObjects/SOGo/SOGoGCSFolder.m
index 7933c6d17..f5b2ee691 100644
--- a/SoObjects/SOGo/SOGoGCSFolder.m
+++ b/SoObjects/SOGo/SOGoGCSFolder.m
@@ -1195,6 +1195,41 @@ static NSArray *childRecordFields = nil;
return propstats;
}
+/*
+ draft-1:
+
+
+
+
+ /SOGo/dav/sogo2/Calendar/personal/351dc1af-2aa3-4d14-9704-eadbcfecaf7e.ics
+ HTTP/1.1 200 OK
+
+
+ "gcs00000001"
+ HTTP/1.1 200 OK
+
+
+ 1322100412
+
+
+ draft-2 and up:
+
+
+
+
+ /caldav.php/user1/home/DAYPARTY-77C6-4FB7-BDD3-6882E2F1BE74.ics
+
+
+ "165746adbab8bc0c8336a63cc5332ff2"
+ Dow, 01 Jan 2000 00:00:00 GMT
+
+ HTTP/1.1 200 OK
+
+
+ urn:,1322100412
+
+*/
+
- (NSDictionary *) _syncResponseWithProperties: (NSArray *) properties
andMethodSelectors: (SEL *) selectors
fromRecord: (NSDictionary *) record
@@ -1238,7 +1273,7 @@ static NSArray *childRecordFields = nil;
andMethodSelectors: selectors
fromRecord: record]];
- return davElementWithContent (@"sync-response", XMLNS_WEBDAV, children);
+ return davElementWithContent (@"response", XMLNS_WEBDAV, children);
}
- (void) _appendComponentProperties: (NSArray *) properties
diff --git a/SoObjects/SOGo/SOGoMailer.m b/SoObjects/SOGo/SOGoMailer.m
index c19d303f9..bbf59540d 100644
--- a/SoObjects/SOGo/SOGoMailer.m
+++ b/SoObjects/SOGo/SOGoMailer.m
@@ -35,6 +35,7 @@
#import "NSString+Utilities.h"
#import "SOGoAuthenticator.h"
#import "SOGoDomainDefaults.h"
+#import "SOGoStaticAuthenticator.h"
#import "SOGoSystemDefaults.h"
#import "SOGoUser.h"
#import "SOGoUserManager.h"
@@ -153,9 +154,13 @@
[client connectToAddress: addr];
if ([authenticationType isEqualToString: @"plain"])
{
- login = [[SOGoUserManager sharedUserManager]
- getExternalLoginForUID: [[authenticator userInContext: woContext] loginInDomain]
- inDomain: [[authenticator userInContext: woContext] domain]];
+ /* XXX Allow static credentials by peeking at the classname */
+ if ([authenticator isKindOfClass: [SOGoStaticAuthenticator class]])
+ login = [(SOGoStaticAuthenticator *)authenticator username];
+ else
+ login = [[SOGoUserManager sharedUserManager]
+ getExternalLoginForUID: [[authenticator userInContext: woContext] loginInDomain]
+ inDomain: [[authenticator userInContext: woContext] domain]];
password = [authenticator passwordInContext: woContext];
if ([login length] == 0
diff --git a/SoObjects/SOGo/SOGoParentFolder.m b/SoObjects/SOGo/SOGoParentFolder.m
index a3cb35394..e806beca0 100644
--- a/SoObjects/SOGo/SOGoParentFolder.m
+++ b/SoObjects/SOGo/SOGoParentFolder.m
@@ -364,7 +364,11 @@ static SoSecurityManager *sm = nil;
NSString *newFolderID;
NSException *error;
- newFolderID = [self globallyUniqueObjectId];
+ newFolderID = *newNameInContainer;
+
+ if (!newFolderID)
+ newFolderID = [self globallyUniqueObjectId];
+
error = [self newFolderWithName: name
andNameInContainer: newFolderID];
if (error)
diff --git a/SoObjects/SOGo/SOGoStaticAuthenticator.h b/SoObjects/SOGo/SOGoStaticAuthenticator.h
new file mode 100644
index 000000000..cb12c0276
--- /dev/null
+++ b/SoObjects/SOGo/SOGoStaticAuthenticator.h
@@ -0,0 +1,51 @@
+/* SOGoStaticAuthenticator.h - this file is part of SOGo
+ *
+ * Copyright (C) 2013 Inverse inc.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SOGOSTATICAUTHENTICATOR_H
+#define SOGOSTATICAUTHENTICATOR_H
+
+#import
+
+
+#import "SOGoAuthenticator.h"
+
+/*
+ SOGoStaticAuthenticator
+
+*/
+
+@interface SOGoStaticAuthenticator : NSObject
+{
+ NSString *_username;
+ NSString *_password;
+}
+
++ (id) authenticatorWithUser: (NSString *) user
+ andPassword: (NSString *) password;
+
+- (id) initWithUser: (NSString *) user
+ andPassword: (NSString *) password;
+
+- (NSString *) username;
+
+@end
+
+#endif /* SOGOSTATICAUTHENTICATOR_H */
+
diff --git a/SoObjects/SOGo/SOGoStaticAuthenticator.m b/SoObjects/SOGo/SOGoStaticAuthenticator.m
new file mode 100644
index 000000000..af8daf0a2
--- /dev/null
+++ b/SoObjects/SOGo/SOGoStaticAuthenticator.m
@@ -0,0 +1,87 @@
+/* SOGoStaticAuthenticator.m - this file is part of SOGo
+ *
+ * Copyright (C) 2013 Inverse inc.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import
+
+#import "SOGoStaticAuthenticator.h"
+
+@implementation SOGoStaticAuthenticator
+
++ (id) authenticatorWithUser: (NSString *) user
+ andPassword: (NSString *) password
+{
+ SOGoStaticAuthenticator *newAuthenticator;
+ newAuthenticator = [[self alloc] initWithUser: user
+ andPassword: password];
+ [newAuthenticator autorelease];
+ return newAuthenticator;
+}
+
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ _username = nil;
+ _password = nil;
+ }
+ return self;
+}
+
+- (void) dealloc
+{
+ [_username release];
+ [_password release];
+ [super dealloc];
+}
+
+- (id) initWithUser: (NSString *) user
+ andPassword: (NSString *) password;
+{
+ if ((self = [self init]))
+ {
+ _username = [user retain];
+ _password = [password retain];
+ }
+ return self;
+}
+
+- (NSString *) passwordInContext: (WOContext *) context
+{
+ return _password;
+}
+
+- (SOGoUser *) userInContext: (WOContext *) context
+{
+ return nil;
+}
+
+- (NSString *) username
+{
+ return _username;
+}
+
+- (NSString *) imapPasswordInContext: (WOContext *) context
+ forURL: (NSURL *) server
+ forceRenew: (BOOL) renew
+{
+ return _password;
+}
+
+@end
diff --git a/SoObjects/SOGo/SOGoUser.m b/SoObjects/SOGo/SOGoUser.m
index 3fff2bb5a..c46331d78 100644
--- a/SoObjects/SOGo/SOGoUser.m
+++ b/SoObjects/SOGo/SOGoUser.m
@@ -1,15 +1,15 @@
/*
- Copyright (C) 2006-2011 Inverse inc.
+ Copyright (C) 2006-2013 Inverse inc.
Copyright (C) 2005 SKYRIX Software AG
- This file is part of OpenGroupware.org.
+ This file is part of SOGo.
- OGo is free software; you can redistribute it and/or modify it under
+ SOGo is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
- OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+ SOGo 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.
@@ -622,19 +622,29 @@
// 3. port & encryption
scheme = [cUrl scheme] ? [cUrl scheme] : [url scheme];
+ query = [cUrl query] ? [cUrl query] : [url query];
+
if (scheme
&& [scheme caseInsensitiveCompare: @"imaps"] == NSOrderedSame)
{
- encryption = @"ssl";
- defaultPort = 993;
+ if (query && [query caseInsensitiveCompare: @"tls=YES"] == NSOrderedSame)
+ {
+ defaultPort = 143;
+ encryption = @"tls";
+ }
+ else
+ {
+ encryption = @"ssl";
+ defaultPort = 993;
+ }
}
else
{
- query = [cUrl query] ? [cUrl query] : [url query];
if (query && [query caseInsensitiveCompare: @"tls=YES"] == NSOrderedSame)
encryption = @"tls";
else
encryption = @"none";
+
defaultPort = 143;
}
port = [cUrl port] ? [cUrl port] : [url port];
diff --git a/Tests/Integration/propfind.py b/Tests/Integration/propfind.py
index 9b4ad29f1..117cf0409 100755
--- a/Tests/Integration/propfind.py
+++ b/Tests/Integration/propfind.py
@@ -6,7 +6,7 @@ import webdavlib
import sys
import getopt
-import xml.dom.ext
+import xml.dom.minidom
def parseArguments():
arguments = {}
@@ -43,4 +43,7 @@ print propfind.response["body"]
if propfind.response.has_key("document"):
sys.stderr.write("document tree:\n")
- xml.dom.ext.PrettyPrint(propfind.response["document"])
+ elem = propfind.response["document"]
+ dom = xml.dom.minidom.parseString(xml.etree.ElementTree.tostring(elem))
+ print dom.toprettyxml()
+
diff --git a/Tests/Integration/test-davacl.py b/Tests/Integration/test-davacl.py
index 986a27be5..a254f25f9 100755
--- a/Tests/Integration/test-davacl.py
+++ b/Tests/Integration/test-davacl.py
@@ -110,7 +110,7 @@ class DAVCalendarSuperUserAclTest(unittest.TestCase):
["{urn:ietf:params:xml:ns:caldav}calendar-data"])
self.client.execute(sync_query)
if sync_query.response["status"] != 404:
- event = self._calendarDataInMultistatus(sync_query, "{DAV:}sync-response")
+ event = self._calendarDataInMultistatus(sync_query, "{DAV:}response")
return event
@@ -581,7 +581,7 @@ class DAVCalendarAclTest(DAVAclTest):
self.subscriber_client.execute(sync_query)
if sync_query.response["status"] != 404:
event = self._calendarDataInMultistatus(sync_query, url,
- "{DAV:}sync-response")
+ "{DAV:}response")
return event
diff --git a/Tests/Integration/webdavlib.py b/Tests/Integration/webdavlib.py
index a97cc10a5..0e0f7c384 100644
--- a/Tests/Integration/webdavlib.py
+++ b/Tests/Integration/webdavlib.py
@@ -379,8 +379,8 @@ class CalDAVPOST(WebDAVQuery):
return self.content
class CalDAVCalendarMultiget(WebDAVREPORT):
- def __init__(self, url, properties, hrefs):
- WebDAVQuery.__init__(self, url)
+ def __init__(self, url, properties, hrefs, depth = None):
+ WebDAVQuery.__init__(self, url, depth)
multiget_tag = self.ns_mgr.register("calendar-multiget", xmlns_caldav)
self.top_node = _WD_XMLTreeElement(multiget_tag)
if properties is not None and len(properties) > 0:
diff --git a/Tests/Integration/webdavsync-tool.py b/Tests/Integration/webdavsync-tool.py
new file mode 100644
index 000000000..8aa2a2729
--- /dev/null
+++ b/Tests/Integration/webdavsync-tool.py
@@ -0,0 +1,106 @@
+#!/usr/bin/python
+
+import getopt
+import sys
+import urlparse
+import webdavlib
+import xml.dom.minidom
+
+def usage() :
+ msg ="""Usage:
+ %s [-h] [-s sync-token] -u uri\n""" % sys.argv[0]
+
+ sys.stderr.write(msg);
+
+def getAllCollections(client, uri):
+ collections = []
+ depth = 1
+
+ propfind = webdavlib.WebDAVPROPFIND(uri, ["allprop"], depth)
+ client.execute(propfind)
+ client.conn.close()
+ doc = propfind.response["document"]
+ for response in doc.iter("{DAV:}response"):
+ propstat = response.find("{DAV:}propstat")
+ if propstat is not None:
+ prop = propstat.find("{DAV:}prop")
+ if prop is not None:
+ resourcetype = prop.find("{DAV:}resourcetype")
+ if resourcetype.find("{DAV:}collection") is not None:
+ href = prop.find("{DAV:}href")
+ if href is not None and href.text != uri:
+ collections.append(href.text)
+ return collections
+
+def changedItemsFromCollection(client, collection, synctoken=None):
+ # get all changed hrefs since synctoken
+ hrefs = []
+ syncquery = webdavlib.WebDAVSyncQuery(collection, synctoken, [ "getcontenttype", "getetag" ])
+ client.execute(syncquery)
+ client.conn.close()
+ if (syncquery.response["status"] != 207):
+ raise Exception("Bad http response code: %d" % syncquery.response["status"])
+ doc = syncquery.response["document"]
+
+ # extract all hrefs
+ for syncResponse in doc.iter("{DAV:}response"):
+ href = syncResponse.find("{DAV:}href")
+ if href is not None:
+ hrefs.append(href.text)
+
+ return hrefs
+
+
+def main():
+ depth = 1
+ synctoken = "1"
+ url = None
+
+ try:
+ opts, args = getopt.getopt (sys.argv[1:], "hs:u:", \
+ ("sync-token=", "url="));
+ except getopt.GetoptError:
+ usage()
+ exit(1)
+
+ for o, v in opts :
+ if o == "-h" :
+ usage()
+ exit(1)
+ elif o == "-s" or o == "--sync-token" :
+ synctoken = v
+ elif o == "-u" or o == "--url" :
+ url = v
+
+ if url is None:
+ usage()
+ exit(1)
+
+ o = urlparse.urlparse(url)
+ hostname = o.hostname
+ port = o.port
+ username = o.username
+ password = o.password
+ uri = o.path
+
+ client = webdavlib.WebDAVClient(hostname, port, username, password)
+
+ collections = getAllCollections(client, uri)
+ if len(collections) == 0:
+ print "No collections found!"
+ sys.exit(1)
+
+ for collection in collections:
+ changedItems = changedItemsFromCollection(client, collection)
+ # fetch the href data
+ if len(changedItems) > 0:
+ multiget = webdavlib.CalDAVCalendarMultiget(collection,
+ ["getetag", "{%s}calendar-data" % webdavlib.xmlns_caldav],
+ changedItems, depth)
+ client.execute(multiget)
+ client.conn.close()
+ if (multiget.response["status"] != 207):
+ raise Exception("Bad http response code: %d" % multiget.response["status"])
+
+if __name__ == "__main__":
+ main()
diff --git a/Tools/SOGoEAlarmsNotifier.h b/Tools/SOGoEAlarmsNotifier.h
index 8cd964d9f..692b5260d 100644
--- a/Tools/SOGoEAlarmsNotifier.h
+++ b/Tools/SOGoEAlarmsNotifier.h
@@ -25,8 +25,11 @@
#import
+#import
+
@interface SOGoEAlarmsNotifier : NSObject
{
+ SOGoStaticAuthenticator *staticAuthenticator;
}
- (BOOL) run;
diff --git a/Tools/SOGoEAlarmsNotifier.m b/Tools/SOGoEAlarmsNotifier.m
index a8906c60a..81de6528d 100644
--- a/Tools/SOGoEAlarmsNotifier.m
+++ b/Tools/SOGoEAlarmsNotifier.m
@@ -1,6 +1,6 @@
/* SOGoEAlarmsNotifier.m - this file is part of SOGo
*
- * Copyright (C) 2011 Inverse inc.
+ * Copyright (C) 2011-2013 Inverse inc.
*
* Author: Wolfgang Sourdeau
*
@@ -27,6 +27,7 @@
#import
#import
#import
+#import
#import
#import
@@ -38,12 +39,14 @@
#import
#import
+#import "SOGo/SOGoCredentialsFile.h"
#import
#import
#import
-#import
#import
#import
+#import
+#import
#import
#import
#import
@@ -52,6 +55,21 @@
@implementation SOGoEAlarmsNotifier
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ staticAuthenticator = nil;
+ }
+ return self;
+}
+
+- (void) dealloc
+{
+ [staticAuthenticator release];
+ [super dealloc];
+}
+
- (NSString *) _messageID
{
static int pid = 0;
@@ -124,11 +142,10 @@
[message setBody: content];
to = [attendee rfc822Email];
- /* TODO: SMTP authentication for services */
[mailer sendMimePart: message
toRecipients: [NSArray arrayWithObject: to]
sender: from
- withAuthenticator: nil inContext: nil];
+ withAuthenticator: staticAuthenticator inContext: nil];
}
- (void) _processAlarm: (iCalAlarm *) alarm
@@ -160,14 +177,45 @@
withMailer: mailer];
}
+- (void) usage
+{
+ fprintf (stderr, "sogo-ealarms-notify [-p credentialFile] [-h]\n\n"
+ " -p credentialFile Specify the file containing credentials to use for SMTP AUTH\n"
+ " The file should contain a single line:\n"
+ " username:password\n"
+ " -h This message\n"
+ "\n"
+ "This program should be configured to run every minute from a crontab.\n");
+}
+
- (BOOL) run
{
SOGoEMailAlarmsManager *eaMgr;
+ SOGoCredentialsFile *cf;
NSCalendarDate *startDate, *toDate;
NSArray *alarms;
NSMutableArray *owners;
+ NSString *credsFilename;
int count, max;
+ if ([[NSUserDefaults standardUserDefaults] stringForKey: @"h"])
+ {
+ [self usage];
+ return YES;
+ }
+
+ credsFilename = [[NSUserDefaults standardUserDefaults] stringForKey: @"p"];
+ if (credsFilename)
+ {
+ cf = [SOGoCredentialsFile credentialsFromFile: credsFilename];
+ if (!cf)
+ return NO;
+ staticAuthenticator =
+ [SOGoStaticAuthenticator authenticatorWithUser: [cf username]
+ andPassword: [cf password]];
+ [staticAuthenticator retain];
+ }
+
[[SOGoProductLoader productLoader]
loadProducts: [NSArray arrayWithObject: @"Appointments.SOGo"]];
diff --git a/Tools/SOGoToolExpireAutoReply.m b/Tools/SOGoToolExpireAutoReply.m
index 5e65e6a82..ddfa3890d 100644
--- a/Tools/SOGoToolExpireAutoReply.m
+++ b/Tools/SOGoToolExpireAutoReply.m
@@ -1,6 +1,6 @@
/* SOGoToolUserPreferences.m - this file is part of SOGo
*
- * Copyright (C) 2011 Inverse inc.
+ * Copyright (C) 2011-2013 Inverse inc.
*
* Author: Francis Lachapelle
*
@@ -37,10 +37,11 @@
#import
#import
-#import
-#import
-#import
+#import "SOGo/SOGoCredentialsFile.h"
#import
+#import
+#import
+#import
#import "SOGoTool.h"
@@ -149,6 +150,8 @@
while ((infos = [channel fetchAttributes: attrs withZone: NULL]))
{
user = [infos objectForKey: @"c_uid"];
+ if (verbose)
+ NSLog(@"Checking user %@\n", user);
c_defaults = [infos objectForKey: @"c_defaults"];
if ([c_defaults isNotNull])
{
@@ -180,9 +183,9 @@
- (BOOL) run
{
- NSData *credsData;
NSRange r;
- NSString *creds, *credsFile, *authname, *authpwd;
+ NSString *creds, *credsFilename, *authname, *authpwd;
+ SOGoCredentialsFile *cf;
BOOL rc;
int max;
@@ -192,41 +195,34 @@
authpwd = nil;
rc = NO;
- credsFile = [[NSUserDefaults standardUserDefaults] stringForKey: @"p"];
- if (credsFile)
+ credsFilename = [[NSUserDefaults standardUserDefaults] stringForKey: @"p"];
+ if (credsFilename)
{
- credsData = [NSData dataWithContentsOfFile: credsFile];
- if (credsData == nil)
- {
- NSLog(@"Error reading credential file '%@'", credsFile);
- return NO;
- }
- creds = [[NSString alloc] initWithData: credsData
- encoding: NSUTF8StringEncoding];
- [creds autorelease];
- creds = [creds stringByTrimmingCharactersInSet:
- [NSCharacterSet characterSetWithCharactersInString: @"\r\n"]];
+ cf = [SOGoCredentialsFile credentialsFromFile: credsFilename];
+ authname = [cf username];
+ authpwd = [cf password];
}
+ /* DEPRECATED: this is only kept around to avoid breaking existing setups */
if (max > 0)
{
/* assume we got the creds directly on the cli */
creds = [sanitizedArguments objectAtIndex: 0];
+ if (creds)
+ {
+ r = [creds rangeOfString: @":"];
+ if (r.location == NSNotFound)
+ {
+ NSLog(@"Invalid credential string format (user:pass)");
+ }
+ else
+ {
+ authname = [creds substringToIndex: r.location];
+ authpwd = [creds substringFromIndex: r.location+1];
+ }
+ }
}
- if (creds)
- {
- r = [creds rangeOfString: @":"];
- if (r.location == NSNotFound)
- {
- NSLog(@"Invalid credential string format (user:pass)");
- }
- else
- {
- authname = [creds substringToIndex: r.location];
- authpwd = [creds substringFromIndex: r.location+1];
- }
- }
if (authname && authpwd)
{
diff --git a/Tools/SOGoToolUserPreferences.m b/Tools/SOGoToolUserPreferences.m
index 39118e777..3d1f982a2 100644
--- a/Tools/SOGoToolUserPreferences.m
+++ b/Tools/SOGoToolUserPreferences.m
@@ -1,6 +1,6 @@
/* SOGoToolUserPreferences.m - this file is part of SOGo
*
- * Copyright (C) 2011 Inverse inc.
+ * Copyright (C) 2011-2013 Inverse inc.
*
* Author: Ludovic Marcotte
*
@@ -28,6 +28,7 @@
#import
#import
+#import "SOGo/SOGoCredentialsFile.h"
#import
#import
#import
@@ -109,34 +110,17 @@ typedef enum
[theKey caseInsensitiveCompare: @"Vacation"] == NSOrderedSame)
{
/* credentials file handling */
- NSData *credsData;
- NSRange r;
- NSString *credsFile, *creds, *authname, *authpwd;
- authname = nil;
- authpwd = nil;
+ NSString *credsFilename, *authname, *authpwd;
+ SOGoCredentialsFile *cf;
-
- credsFile = [[NSUserDefaults standardUserDefaults] stringForKey: @"p"];
- if (credsFile)
+ credsFilename = [[NSUserDefaults standardUserDefaults] stringForKey: @"p"];
+ if (credsFilename)
{
- /* TODO: add back support for user:pwd here? */
- credsData = [NSData dataWithContentsOfFile: credsFile];
- if (credsData == nil)
- {
- NSLog(@"Error reading credential file '%@'", credsFile);
- return NO;
- }
-
- creds = [[NSString alloc] initWithData: credsData
- encoding: NSUTF8StringEncoding];
- [creds autorelease];
- creds = [creds stringByTrimmingCharactersInSet:
- [NSCharacterSet characterSetWithCharactersInString: @"\r\n"]];
-
- r = [creds rangeOfString: @":"];
- authname = [creds substringToIndex: r.location];
- authpwd = [creds substringFromIndex: r.location+1];
+ cf = [SOGoCredentialsFile credentialsFromFile: credsFilename];
+ authname = [cf username];
+ authpwd = [cf password];
}
+
if (authname == nil || authpwd == nil)
{
NSLog(@"To update Sieve scripts, you must provide the \"-p credentialFile\" parameter");
diff --git a/UI/AdministrationUI/NorwegianBokmal.lproj/Localizable.strings b/UI/AdministrationUI/NorwegianBokmal.lproj/Localizable.strings
index 24585729b..3a99c5187 100644
--- a/UI/AdministrationUI/NorwegianBokmal.lproj/Localizable.strings
+++ b/UI/AdministrationUI/NorwegianBokmal.lproj/Localizable.strings
@@ -9,7 +9,7 @@
"ACLs" = "Adgangsrettigheter";
/* Modules titles */
-"ACLs_title" = "Håntering av adgangsrettigheter for brukermapper";
+"ACLs_title" = "Håndtering av adgangsrettigheter for brukermapper";
/* Modules descriptions */
-"ACLs_description" = "
Administrasjonsmodulen for adgangsrettigheter muliggjør endring av adgangsrettigheter for brukerens kalendre og adressebøker.
For å endre adgangsrettigheter på en brukermappe, skriv brukernavnet i søkefeltet oppe i vinduet og dobbelklikk på ønskede mappe.
";
+"ACLs_description" = "
Administrasjonsmodulen for adgangsrettigheter muliggjør endring av adgangsrettigheter for brukerens kalendre og adressebøker.
For å endre adgangsrettigheter for en brukermappe, skriv brukernavnet i søkefeltet oppe i vinduet og dobbelklikk på ønskede mappe.
";
diff --git a/UI/Common/NorwegianBokmal.lproj/Localizable.strings b/UI/Common/NorwegianBokmal.lproj/Localizable.strings
index 71c96b922..ffbb7e833 100644
--- a/UI/Common/NorwegianBokmal.lproj/Localizable.strings
+++ b/UI/Common/NorwegianBokmal.lproj/Localizable.strings
@@ -11,11 +11,12 @@
"Mail" = "E-post";
"Preferences" = "Innstillinger";
"Administration" = "Administrasjon";
-"Disconnect" = "Logg ut";
+"Disconnect" = "Koble fra";
"Right Administration" = "Rettighetsinnstillinger";
"Log Console (dev.)" = "Loggkonsoll";
"User" = "Bruker";
+"Vacation message is enabled" = "Fraværsmelding er aktivert.";
"Help" = "Hjelp";
@@ -23,24 +24,30 @@
"noJavascriptRetry" = "Forsøk igjen";
"Owner:" = "Eier:";
-"Publish the Free/Busy information" = "Publiser ledig/opptatt informasjon";
+"Publish the Free/Busy information" = "Publiser ledig/opptatt-informasjon";
"Add..." = "Legg til...";
"Remove" = "Fjern";
-"Subscribe User" = "Abonner bruker";
+"Subscribe User" = "Abonnér bruker";
"Any Authenticated User" = "Enhver autentisert bruker";
"Public Access" = "Offentlig tilgang";
"Any user not listed above" = "Enhver bruker som ikke er listet ovenfor";
-"Anybody accessing this resource from the public area" = "Enhver aksesserer denne ressursen fra det offentlige området";
+"Anybody accessing this resource from the public area" = "Enhver som bruker denne ressursen fra det offentlige området";
"Sorry, the user rights can not be configured for that object." = "Beklager, brukerrettighetene kan ikke konfigureres for objektet.";
+"Any user with an account on this system will be able to access your mailbox \"%{0}\". Are you certain you trust them all?"
+ = "Enhver bruker med konto på dette systemet vil kunne se mailboksen \"%{0}\". Er du sikker på at du stoler på alle sammen?";
"Any user with an account on this system will be able to access your calendar \"%{0}\". Are you certain you trust them all?"
- = "Alle brukere med konto på systemet vil kunne aksessere kalenderen \"%{0}\". Er du sikker på at du stoler på alle?";
+ = "Alle brukere med konto på systemet vil kunne se kalenderen \"%{0}\". Er du sikker på at du stoler på alle sammen?";
"Potentially anyone on the Internet will be able to access your calendar \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?"
- = "Potensielt kan hvem som helst på Internett aksessere kalenderen \"%{0}\", selv om de ikke har konto på systemet. Er denne informasjonen passende for åpent Internett?";
+ = "Potensielt kan hvem som helst på internett se kalenderen \"%{0}\", selv om de ikke har konto på systemet. Er denne informasjonen passende for det åpne internett?";
+"Any user with an account on this system will be able to access your address book \"%{0}\". Are you certain you trust them all?"
+ = "Enhver bruker med konto på dette systemet vil kunne se adresseboken \"%{0}\". Er du sikker på at du stoler på alle sammen?";
+"Potentially anyone on the Internet will be able to access your address book \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?"
+ = "Potensielt hvem som helst på internett vil kunne se adresseboken \"%{0}\", selv om de ikke har konto på systemet. Er denne informasjonen passende for det åpne internett?";
"Give Access" = "Gi tilgang";
"Keep Private" = "Behold privat";
@@ -68,17 +75,17 @@
"You don't have the required privileges to perform the operation."
= "Du har ikke rettigheter til å utføre operasjonen.";
-"noEmailForDelegation" = "Du må angi adressen til personen du delegerer din invitasjon.";
+"noEmailForDelegation" = "Du må angi adressen til personen du delegerer din invitasjon til.";
"delegate is organizer" = "Personen du delegerer til er arrangør. Vennligst deleger til en annen person.";
"delegate is a participant" = "Delegaten er allerede en deltaker.";
-"delegate is a group" = "Den angitte adressen er en gruppe. Du kan bare delegere til unike personer.";
+"delegate is a group" = "Den angitte adressen er en gruppe. Du kan bare delegere til enkeltpersoner.";
"Snooze for " = "Slumre i";
-"5 minutes" = "5 minutt";
-"10 minutes" = "10 minutt";
-"15 minutes" = "15 minutt";
-"30 minutes" = "30 minutt";
-"45 minutes" = "45 minutt";
+"5 minutes" = "5 minutter";
+"10 minutes" = "10 minutter";
+"15 minutes" = "15 minutter";
+"30 minutes" = "30 minutter";
+"45 minutes" = "45 minutter";
"1 hour" = "1 time";
diff --git a/UI/Common/UIxParentFolderActions.m b/UI/Common/UIxParentFolderActions.m
index 98cc81480..3021687d2 100644
--- a/UI/Common/UIxParentFolderActions.m
+++ b/UI/Common/UIxParentFolderActions.m
@@ -40,6 +40,8 @@
NSString *name, *nameInContainer;
name = [[context request] formValueForKey: @"name"];
+ nameInContainer = nil;
+
if ([name length] > 0)
{
if (![[self clientObject] hasLocalSubFolderNamed: name])
diff --git a/UI/Contacts/NorwegianBokmal.lproj/Localizable.strings b/UI/Contacts/NorwegianBokmal.lproj/Localizable.strings
index b4b299330..c4eb8bf81 100644
--- a/UI/Contacts/NorwegianBokmal.lproj/Localizable.strings
+++ b/UI/Contacts/NorwegianBokmal.lproj/Localizable.strings
@@ -6,12 +6,12 @@
"Other" = "Annet";
"Address Books" = "Adressebøker";
-"Addressbook" = "Adresseboken";
+"Addressbook" = "Adressebok";
"Addresses" = "Adresser";
"Update" = "Oppdatere";
"Cancel" = "Avbryt";
"Common" = "Felles";
-"Contact editor" = "Kontakteditor";
+"Contact editor" = "Kontaktinnstillinger";
"Contact viewer" = "Kontaktviser";
"Email" = "E-post";
"Screen Name" = "Skjermnavn";
@@ -29,20 +29,20 @@
"Work Phone" = "Jobbtelefon";
"Phone" = "Telefon";
"Phones" = "Telefoner";
-"Postal" = "Postnummer";
+"Postal" = "Postadresse";
"Save" = "Lagre";
"Internet" = "Internett";
"Unit" = "Avdeling";
"delete" = "slett";
"edit" = "endre";
-"invalidemailwarn" = "Meldingen er ikke komplett";
+"invalidemailwarn" = "Den spesifiserte e-posten er ikke gyldig";
"invaliddatewarn" = "Den spesifiserte datoen er ikke gyldig.";
"new" = "ny";
"Preferred Phone" = "Foretrukket telefon";
"Move To" = "Flytt til";
"Copy To" = "Kopier til";
-"Add to:" = "Legg til:";
+"Add to:" = "Legg til i:";
/* Tooltips */
@@ -51,10 +51,10 @@
"Edit the selected card" = "Rediger markert adressekort";
"Send a mail message" = "Send en e-post";
"Delete selected card or address book" = "Slett markert adressekort eller adressebok";
-"Reload all contacts" = "Reload alle kontakter";
+"Reload all contacts" = "Last inn alle kontakter på nytt";
"htmlMailFormat_UNKNOWN" = "Ukjent";
-"htmlMailFormat_FALSE" = "Uformatert Text";
+"htmlMailFormat_FALSE" = "Ren tekst";
"htmlMailFormat_TRUE" = "HTML";
"Name or Email" = "Navn eller e-post";
@@ -77,14 +77,14 @@
"Preferred" = "Foretrukket";
"Display:" = "Vise:";
-"Display Name:" = "Visningsnamn:";
+"Display Name:" = "Visningsnavn:";
"Email:" = "E-post:";
"Additional Email:" = "Ytterlige e-post:";
"Phone Number:" = "Telefonnummer:";
"Prefers to receive messages formatted as:" = "Foretrekker å motta melding formatert som:";
"Screen Name:" = "Skjermnavn:";
-"Categories:" = "Katagorier:";
+"Categories:" = "Kategorier:";
"First:" = "Fornavn:";
"Last:" = "Etternavn:";
@@ -98,34 +98,34 @@
"Pager:" = "Personsøker:";
/* categories */
-"contacts_category_labels" = "Colleague, Competitor, Customer, Friend, Family, Business Partner, Provider, Press, VIP";
-"Categories" = "Katagorier";
-"New category" = "Ny katagori";
+"contacts_category_labels" = "Kollega, Konkurrent, Kunde, Venn, Familie, Forretningspartner, Leverandør, Presse, VIP";
+"Categories" = "Kategorier";
+"New category" = "Ny kategori";
/* adresses */
"Title:" = "Tittel:";
"Service:" = "Funksjon:";
"Company:" = "Foretak:";
-"Department:" = "Avdelning:";
-"Organization:" = "Organisation:";
+"Department:" = "Avdeling:";
+"Organization:" = "Organisasjon:";
"Address:" = "Adresse:";
"City:" = "Poststed: ";
"State_Province:" = "Landsdel:";
"ZIP_Postal Code:" = "Postnummer:";
"Country:" = "Land:";
-"Web Page:" = "Webside:";
+"Web Page:" = "Nettside:";
"Work" = "Arbeid";
-"Other Infos" = "Øvrig";
+"Other Infos" = "Øvrig informasjon";
"Note:" = "Anmerkning:";
"Timezone:" = "Tidssone:";
"Birthday:" = "Fødselsdag:";
-"Birthday (yyyy-mm-dd):" = "Fødselsdag (yyyy-mm-dd):";
-"Freebusy URL:" = "Freebusy URL:";
+"Birthday (yyyy-mm-dd):" = "Fødselsdag (åååå-mm-dd):";
+"Freebusy URL:" = "Ledigopptatt URL:";
"Add as..." = "Legg til som...";
-"Recipient" = "Mottakere";
+"Recipient" = "Mottaker";
"Carbon Copy" = "Kopi";
"Blind Carbon Copy" = "Blindkopi";
@@ -135,7 +135,7 @@
"Name of the Address Book" = "Navn på adressebok";
"Are you sure you want to delete the selected address book?"
-= "Er du siker på at du vil ta bort den markerte adresseboken?";
+= "Er du sikker på at du vil ta bort den markerte adresseboken?";
"You cannot remove nor unsubscribe from a public addressbook."
= "Du kan ikke fjerne eller avbryte abonnement på en offentlig adressebok.";
"You cannot remove nor unsubscribe from your personal addressbook."
@@ -145,7 +145,7 @@
= "Er du sikker på at du vil slette de markerte kontaktene?";
"You cannot delete the card of \"%{0}\"."
-= "Du kan ikke slette adresskortet \"%{0}\".";
+= "Du kan ikke slette adressekortet \"%{0}\".";
"Address Book Name" = "Navn på adressebok";
@@ -159,18 +159,18 @@
"For user" = "For bruker";
"Any Authenticated User" = "Alle autentiserte brukere";
-"Public Access" = "Public Access";
+"Public Access" = "Offentlig tilgang";
"This person can add cards to this addressbook."
-= "Personen kan legge til addressekort i adresseboken.";
+= "Personen kan legge til adressekort i adresseboken.";
"This person can edit the cards of this addressbook."
-= "Personen kan endra addresskort i adresseboken.";
+= "Personen kan endre adressekort i adresseboken.";
"This person can list the content of this addressbook."
-= "Personen kan liste inneholdet i adresseboken.";
+= "Personen kan liste innholdet i adresseboken.";
"This person can read the cards of this addressbook."
-= "Personen kan vise addressekort i adresseboken.";
+= "Personen kan vise adressekort i adresseboken.";
"This person can erase cards from this addressbook."
-= "Personen kan slette addressekort i adresseboken.";
+= "Personen kan slette adressekort i adresseboken.";
"The selected contact has no email address."
= "Den markerte kontakten har ingen e-postadresse.";
@@ -188,16 +188,18 @@
"List details" = "Informasjon om mailinglisten";
"List name:" = "Navn på mailingliste:";
"List nickname:" = "Kallenavn til mailingliste:";
-"List description:" = "Beskrivelse:";
+"List description:" = "Beskrivelse av mailingliste:";
"Members" = "Medlemmer";
"Contacts" = "Kontakter";
"Add" = "Legg til";
"Lists can't be moved or copied." = "Mailinglister kan ikke flyttes eller kopieres.";
"Export" = "Eksportere";
"Export Address Book..." = "Eksportere Adressebok...";
+"View Raw Source" = "Vis råkilde";
"Import Cards" = "Importere adressekort";
-"Select a vCard or LDIF file." = "Velg et vCard eller LDIF fil.";
+"Select a vCard or LDIF file." = "Velg et vCard eller LDIF-fil.";
"Upload" = "Last opp";
+"Uploading" = "Laster opp";
"Done" = "Ferdig";
"An error occured while importing contacts." = "En feil oppstod under importen av kontakter.";
"No card was imported." = "Ingen adressekort ble importert.";
diff --git a/UI/MailPartViewers/Catalan.lproj/Localizable.strings b/UI/MailPartViewers/Catalan.lproj/Localizable.strings
index bcf01ebcc..c55d613ec 100644
--- a/UI/MailPartViewers/Catalan.lproj/Localizable.strings
+++ b/UI/MailPartViewers/Catalan.lproj/Localizable.strings
@@ -9,8 +9,7 @@ organized_by_you = "en sou l'organitzador.";
you_are_an_attendee = "hi participeu";
add_info_text = "iMIP 'ADD' encara no funciona.";
publish_info_text = "El remitent us informa de l'esdeveniment adjunt.";
-cancel_info_text = "La vostra invitació o l'esdeveniment han estat
-cancel·lats.";
+cancel_info_text = "La vostra invitació o l'esdeveniment han estat \ncancel·lats.";
request_info_no_attendee = "Heu proposat un esdeveniment. Rebeu aquest correu com a notificació, però no hi figureu com a participant.";
Appointment = "Cita";
diff --git a/UI/MailPartViewers/English.lproj/Localizable.strings b/UI/MailPartViewers/English.lproj/Localizable.strings
index cda317fe4..a23ee4125 100644
--- a/UI/MailPartViewers/English.lproj/Localizable.strings
+++ b/UI/MailPartViewers/English.lproj/Localizable.strings
@@ -12,6 +12,8 @@ publish_info_text = "The sender informs you of the attached event.";
cancel_info_text = "Your invitation or the whole event was canceled.";
request_info_no_attendee = "is proposing a meeting to the attendees. You receive this mail as a notification, you are not scheduled as a participant.";
Appointment = "Appointment";
+"Status Update" = "Status Update";
+was = "was";
Organizer = "Organizer";
Time = "Time";
diff --git a/UI/MailPartViewers/French.lproj/Localizable.strings b/UI/MailPartViewers/French.lproj/Localizable.strings
index 49f29ee8d..982d7c088 100644
--- a/UI/MailPartViewers/French.lproj/Localizable.strings
+++ b/UI/MailPartViewers/French.lproj/Localizable.strings
@@ -12,6 +12,8 @@ publish_info_text = "L'expéditeur vous informe de l'événement attaché.";
cancel_info_text = "Votre invitation ou l'événement au complet a été annulé.";
request_info_no_attendee = "propose une réunion entre les invités. Ce message tient seulement lieu d'avis, vous n'êtes pas indiqué comme invité.";
Appointment = "Événement";
+"Status Update" = "Changement d'état";
+was = "était";
Organizer = "Organisateur";
Time = "Date";
diff --git a/UI/MailPartViewers/German.lproj/Localizable.strings b/UI/MailPartViewers/German.lproj/Localizable.strings
index 2f80a2755..ce7e66585 100644
--- a/UI/MailPartViewers/German.lproj/Localizable.strings
+++ b/UI/MailPartViewers/German.lproj/Localizable.strings
@@ -12,6 +12,8 @@ publish_info_text = "Der Absender informiert Sie über den angefügten Termin.";
cancel_info_text = "Ihre Einladung zu dem Termin, oder der gesamte Termin wurde abgesagt.";
request_info_no_attendee = "schlägt den Teilnehmern einen Termin vor. Sie sind kein vorgesehener Teilnehmer und erhalten diese Nachricht lediglich als Hinweis.";
Appointment = "Termin";
+"Status Update" = "Statusänderung";
+was = "war";
Organizer = "Organisator";
Time = "Zeit";
diff --git a/UI/MailPartViewers/Hungarian.lproj/Localizable.strings b/UI/MailPartViewers/Hungarian.lproj/Localizable.strings
index 3f408c280..761579d61 100644
--- a/UI/MailPartViewers/Hungarian.lproj/Localizable.strings
+++ b/UI/MailPartViewers/Hungarian.lproj/Localizable.strings
@@ -12,6 +12,8 @@ publish_info_text = "Ez az üzenet egy eseményről szóló meghívót tartalmaz
cancel_info_text = "A meghívást vagy az eseményt törölték.";
request_info_no_attendee = "javasol egy találkozót a résztvevőknek. Ön tájékoztatásul kapja ezt az üzenetet, nincs a résztvevők között.";
Appointment = "Találkozó";
+"Status Update" = "Állapot frissítés";
+was = "előző";
Organizer = "Szervező";
Time = "Idő";
@@ -19,7 +21,7 @@ Attendees = "Résztvevők";
request_info = "meghívja önt résztvevőnek egy találkozóra.";
"Add to calendar" = "Hozzáadás a naptárhoz";
"Delete from calendar" = "Törlés a naptárból";
-"Update status" = "Állapot frissítése";
+"Update status" = "Frissítés állapota";
Accept = "Elfogad";
Decline = "Elutasít";
Tentative = "Bizonytalan";
diff --git a/UI/MailPartViewers/NorwegianBokmal.lproj/Localizable.strings b/UI/MailPartViewers/NorwegianBokmal.lproj/Localizable.strings
index 4961df1cd..2088ec87d 100644
--- a/UI/MailPartViewers/NorwegianBokmal.lproj/Localizable.strings
+++ b/UI/MailPartViewers/NorwegianBokmal.lproj/Localizable.strings
@@ -1,5 +1,5 @@
ACCEPTED = "akseptert";
-COMPLETED = "avsluttet";
+COMPLETED = "fullført";
DECLINED = "avvist";
DELEGATED = "delegert";
"IN-PROCESS" = "pågående";
@@ -7,10 +7,10 @@ DELEGATED = "delegert";
TENTATIVE = "foreløpig";
organized_by_you = "organisert av deg";
you_are_an_attendee = "du er en deltager";
-add_info_text = "iMIP 'ADD' støttes ikke enda av SOGo.";
+add_info_text = "iMIP 'ADD'-forespørsler støttes ikke enda av SOGo.";
publish_info_text = "Avsenderen informerer deg om vedlagte arrangement.";
cancel_info_text = "Din invitasjon eller hele arrangementet er avlyst.";
-request_info_no_attendee = "forslår et møte til deltakerene. Du har fått meldingen for informasjon, men er ikke palnlagt som en deltaker.";
+request_info_no_attendee = "foreslår et møte til deltakerne. Du har fått informasjon, men er ikke planlagt som en deltaker.";
Appointment = "Møte";
Organizer = "Arrangør";
@@ -19,7 +19,7 @@ Attendees = "Deltakere";
request_info = "inviterer deg til å delta i et møte.";
"Add to calendar" = "Legg inn i kalenderen";
"Delete from calendar" = "Ta bort fra kalenderen";
-"Update status" = "Oppdatere status";
+"Update status" = "Oppdater status";
Accept = "Godta";
Decline = "Avslå";
Tentative = "Foreløpig";
diff --git a/UI/MailPartViewers/UIxMailPartHTMLViewer.m b/UI/MailPartViewers/UIxMailPartHTMLViewer.m
index aa2176d06..99d43abdd 100644
--- a/UI/MailPartViewers/UIxMailPartHTMLViewer.m
+++ b/UI/MailPartViewers/UIxMailPartHTMLViewer.m
@@ -262,7 +262,7 @@ static NSData* _sanitizeContent(NSData *theData)
buf = malloc((j+1) * sizeof(char));
memset (buf, 0, j+1);
memcpy (buf, bytes, j);
- found_tag = [NSString stringWithCString: buf encoding: NSASCIIStringEncoding];
+ found_tag = [NSString stringWithCString: buf encoding: NSUTF8StringEncoding];
tags = [VoidTags objectEnumerator];
tag = [tags nextObject];
@@ -562,6 +562,39 @@ static NSData* _sanitizeContent(NSData *theData)
&& ![value hasPrefix: @"mailto:"]
&& ![value hasPrefix: @"#"]);
}
+ else if (
+ // Mouse Events
+ [name isEqualToString: @"onclick"] ||
+ [name isEqualToString: @"ondblclick"] ||
+ [name isEqualToString: @"onmousedown"] ||
+ [name isEqualToString: @"onmousemove"] ||
+ [name isEqualToString: @"onmouseout"] ||
+ [name isEqualToString: @"onmouseup"] ||
+ [name isEqualToString: @"onmouseover"] ||
+
+ // Keyboard Events
+ [name isEqualToString: @"onkeydown"] ||
+ [name isEqualToString: @"onkeypress"] ||
+ [name isEqualToString: @"onkeyup"] ||
+
+ // Frame/Object Events
+ [name isEqualToString: @"onabort"] ||
+ [name isEqualToString: @"onerror"] ||
+ [name isEqualToString: @"onload"] ||
+ [name isEqualToString: @"onresize"] ||
+ [name isEqualToString: @"onscroll"] ||
+ [name isEqualToString: @"onunload"] ||
+
+ // Form Events
+ [name isEqualToString: @"onblur"] ||
+ [name isEqualToString: @"onchange"] ||
+ [name isEqualToString: @"onfocus"] ||
+ [name isEqualToString: @"onreset"] ||
+ [name isEqualToString: @"onselect"] ||
+ [name isEqualToString: @"onsubmit"])
+ {
+ skipAttribute = YES;
+ }
else
value = [_attributes valueAtIndex: count];
if (!skipAttribute)
diff --git a/UI/MailPartViewers/UIxMailPartLinkViewer.h b/UI/MailPartViewers/UIxMailPartLinkViewer.h
index d89421511..5777f9863 100644
--- a/UI/MailPartViewers/UIxMailPartLinkViewer.h
+++ b/UI/MailPartViewers/UIxMailPartLinkViewer.h
@@ -1,14 +1,15 @@
/*
+ Copyright (C) 2007-2013 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG
- This file is part of OpenGroupware.org.
+ This file is part of SOGo.
- OGo is free software; you can redistribute it and/or modify it under
+ SOGo is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
- OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+ SOGo 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.
@@ -37,7 +38,7 @@
encoding = BASE64;
parameterList = {
"x-unix-mode" = 0666;
- name = "IncoWEBOpenGroupwarepresentation.pdf";
+ name = "SOGo.pdf";
};
size = 1314916;
subtype = PDF; type = application;
diff --git a/UI/MailPartViewers/UIxMailPartSignedViewer.m b/UI/MailPartViewers/UIxMailPartSignedViewer.m
index 34a8110a7..16692657a 100644
--- a/UI/MailPartViewers/UIxMailPartSignedViewer.m
+++ b/UI/MailPartViewers/UIxMailPartSignedViewer.m
@@ -52,6 +52,8 @@
success = NO;
store = X509_STORE_new ();
+ OpenSSL_add_all_algorithms ();
+
if (store)
{
lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file());
@@ -92,8 +94,7 @@
PKCS7 *p7;
int err, i;
-
- *sslError = 0;
+ memset(sslError, 0, 1024);
ERR_clear_error();
diff --git a/UI/MailPartViewers/UIxMailPartViewer.h b/UI/MailPartViewers/UIxMailPartViewer.h
index fd0423203..ce8f35f67 100644
--- a/UI/MailPartViewers/UIxMailPartViewer.h
+++ b/UI/MailPartViewers/UIxMailPartViewer.h
@@ -83,6 +83,8 @@
- (NSString *)pathToAttachmentObject; /* link to SoObject */
- (NSString *)pathToAttachment; /* download link */
+- (NSString *) mimeImageURL;
+
@end
#endif /* __Mailer_UIxMailPartViewer_H__ */
diff --git a/UI/MailPartViewers/UIxMailPartViewer.m b/UI/MailPartViewers/UIxMailPartViewer.m
index 51e8752a6..21aeec623 100644
--- a/UI/MailPartViewers/UIxMailPartViewer.m
+++ b/UI/MailPartViewers/UIxMailPartViewer.m
@@ -266,7 +266,7 @@
NSMutableString *filename;
NSString *extension;
- filename = [self filename];
+ filename = [NSMutableString stringWithString: [self filename]];
if (![filename length])
[filename appendFormat: @"%@-%@",
[self labelForKey: @"Untitled"],
@@ -304,7 +304,7 @@
return url;
}
-- (NSString *) mimeImageUrl
+- (NSString *) mimeImageURL
{
NSString *mimeImageFile, *mimeImageUrl;
diff --git a/UI/MailPartViewers/UIxMailRenderingContext.m b/UI/MailPartViewers/UIxMailRenderingContext.m
index 37fcdceb1..03df297cc 100644
--- a/UI/MailPartViewers/UIxMailRenderingContext.m
+++ b/UI/MailPartViewers/UIxMailRenderingContext.m
@@ -213,8 +213,10 @@ static BOOL showNamedTextAttachmentsInline = NO;
return [self iCalViewer];
}
- // Tiffs aren't well-supported
- if ([mt isEqualToString:@"image"] && ![st isEqualToString: @"tiff"])
+ // TIFF files aren't well-supported and Thunderbird sometimes send PDF
+ // files over as image/pdf !
+ if ([mt isEqualToString:@"image"] &&
+ !([st isEqualToString: @"tiff"] || [st isEqualToString: @"pdf"]))
{
if ([self _shouldDisplayAsAttachment: _info textPart: NO])
return [self linkViewer];
diff --git a/UI/MailerUI/French.lproj/Localizable.strings b/UI/MailerUI/French.lproj/Localizable.strings
index e761a1a08..f54cc94be 100644
--- a/UI/MailerUI/French.lproj/Localizable.strings
+++ b/UI/MailerUI/French.lproj/Localizable.strings
@@ -282,7 +282,7 @@
= "Les messages ne peuvent être déplacés dans la corbeille. Voulez-vous les supprimer immédiatement?";
/* Message editing */
-"error_missingsubject" = "Le message n'as pas de sujet. Êtes-vous certain de vouloir l'envoyer?";
+"error_missingsubject" = "Le message n'a pas de sujet. Êtes-vous certain de vouloir l'envoyer?";
"error_missingrecipients" = "Veuillez spécifier au moins un destinataire.";
"Send Anyway" = "Envoyer sans sujet";
diff --git a/UI/MailerUI/NorwegianBokmal.lproj/Localizable.strings b/UI/MailerUI/NorwegianBokmal.lproj/Localizable.strings
index 8d38c34fa..1b384df68 100644
--- a/UI/MailerUI/NorwegianBokmal.lproj/Localizable.strings
+++ b/UI/MailerUI/NorwegianBokmal.lproj/Localizable.strings
@@ -28,14 +28,14 @@
"Select a recipient from an Address Book" = "Velg en mottaker fra adressebok";
"Include an attachment" = "Legg til et vedlegg";
"Save this message" = "Lagre denne meldingen";
-"Get new messages" = "Hent ny melding";
+"Get new messages" = "Hent ny e-post";
"Create a new message" = "Ny e-postmelding";
"Go to address book" = "Gå til adresseboken";
"Reply to the message" = "Svar avsender";
"Reply to sender and all recipients" = "Svar avsender og alle mottakere";
-"Forward selected message" = "Videresend den valgte melding";
-"Delete selected message or folder" = "Slett den merkete meldingen eller mappen";
-"Mark the selected messages as junk" = "Merk de markerte meldingene som søppelpost";
+"Forward selected message" = "Videresend valgt melding";
+"Delete selected message or folder" = "Slett merket melding eller mappe";
+"Mark the selected messages as junk" = "Merk markerte meldinger som søppelpost";
"Print this message" = "Skriv ut denne e-postmeldingen";
"Stop the current transfer" = "Stopp pågående overføring";
"Attachment" = "Vedlegg";
@@ -48,13 +48,13 @@
"Calendar" = "Kalender";
"Addressbook" = "Adressebok";
"Mail" = "E-post";
-"Right Administration" = "Rettighetsadministration";
+"Right Administration" = "Rettighetsadministrasjon";
"Help" = "Hjelp";
/* Mail account main windows */
-"Welcome to the SOGo Mailer. Use the folder tree on the left to browse your mail accounts!" = "Velkommen til SOGo Mailer. Bruk mappeviseren på venstre side for å bla i gjennom dine e-postkontoer!";
+"Welcome to the SOGo Mailer. Use the folder tree on the left to browse your mail accounts!" = "Velkommen til SOGo Mailer. Bruk mappeviseren på venstre side for å bla gjennom dine e-postkontoer!";
"Read messages" = "Les meldinger";
"Write a new message" = "Skriv en ny melding";
@@ -73,16 +73,16 @@
"Read mails from this folder" = "Les meldinger fra denne mappen";
"Mark mails read and unread" = "Markere meldinger som leste og uleste";
"Modify the flags of the mails in this folder" = "Endre flagg til meldingene i denne mappen";
-"Insert, copy and move mails into this folder" = "Legg inn, kopiere og flytt meldinger til mappen";
+"Insert, copy and move mails into this folder" = "Legg inn, kopier og flytt meldinger til mappen";
"Post mails" = "Send e-postmeldinger";
"Add subfolders to this folder" = "Legg til undermapper til denne mappen";
-"Remove this folder" = "Ta bort mappen";
+"Remove this folder" = "Fjern mappen";
"Erase mails from this folder" = "Slett meldinger fra mappen";
"Expunge this folder" = "Fjern mappen";
"Archive This Folder" = "Arkiver denne mappen";
"Modify the acl of this folder" = "Endre adgangsrettigheter til mappen";
-"Saved Messages.zip" = "Lagrete Meldinger.zip";
+"Saved Messages.zip" = "Lagrede Meldinger.zip";
"Update" = "Oppdater";
"Cancel" = "Avbryt";
@@ -113,7 +113,7 @@
"Return Receipt" = "Returkvittering";
"The sender of this message has asked to be notified when you read this message. Do you with to notify the sender?" = "Avsender har bedt om å bli varslet når du leser denne meldingen. Ønsker du å varsle avsenderen?";
"Return Receipt (displayed) - %@"= "Returkvittering (vist) - %@";
-"This is a Return Receipt for the mail that you sent to %@.\n\nNote: This Return Receipt only acknowledges that the message was displayed on the recipient's computer. There is no guarantee that the recipient has read or understood the message contents." = "Dette er en returkvittering på e-posten som du sendte til %@.\n\nMerk: Denne returkvitteringen forteller bare at meldingen ble vist hos mottaker. Det er ingen garanti at mottaker har lest eller forstått innholdet i e-postmeldingen.";
+"This is a Return Receipt for the mail that you sent to %@.\n\nNote: This Return Receipt only acknowledges that the message was displayed on the recipient's computer. There is no guarantee that the recipient has read or understood the message contents." = "Dette er en returkvittering for e-posten du sendte til %@.\n\nMerk: Denne returkvitteringen forteller bare at meldingen ble vist hos mottaker. Det er ingen garanti at mottaker har lest eller forstått innholdet i e-postmeldingen.";
"Priority" = "Prioritet";
"highest" = "Høyest";
@@ -130,7 +130,7 @@
/* Popup "show" */
"all" = "alle";
-"read" = "les";
+"read" = "leste";
"unread" = "ulest";
"deleted" = "slettet";
"flagged" = "flagget";
@@ -192,13 +192,13 @@
"Mark Folder Read" = "Merk mappe som lest...";
"New Folder..." = "Ny mappe...";
"Compact This Folder" = "Komprimer mappen";
-"Search Messages..." = "Søk meldinger...";
+"Search Messages..." = "Søk i meldinger...";
"Sharing..." = "Deling...";
"New Subfolder..." = "Ny undermappe...";
"Rename Folder..." = "Endre navn på mappe...";
"Delete Folder" = "Slett mappe";
"Use This Folder For" = "Bruk mappen til";
-"Get Messages for Account" = "Hent nya meldinger for konto";
+"Get Messages for Account" = "Hent nye meldinger for konto";
"Properties..." = "Egenskaper...";
"Delegation..." = "Delegasjon...";
@@ -211,7 +211,7 @@
"Open Message In New Window" = "Åpne melding i nytt vindu";
"Reply to Sender Only" = "Svar kun til avsender";
"Reply to All" = "Svar alle";
-"Edit As New..." = "Redigere som nytt...";
+"Edit As New..." = "Rediger som ny...";
"Move To" = "Flytt til";
"Copy To" = "Kopier til";
"Label" = "Etikett";
@@ -248,22 +248,21 @@
"Enter the new name of your folder :"
= "Skriv navnet på mappen: ";
"Do you really want to move this folder into the trash ?"
- = "Vil du virkelig flytte mappen till papirkurven?";
-"Operation failed" = "Operasjonen misslykkes";
+ = "Vil du virkelig flytte mappen til papirkurven?";
+"Operation failed" = "Operasjonen mislykkes";
"Quota" = "Disktildeling";
"quotasFormat" = "%{0}% brukt av %{1} MB";
-"Please select a message." = "Marker en melding.";
-"Please select a message to print." = "Marker en melding som skal skrives ut.";
-"Please select only one message to print." = "Marker bare en melding som skal skrives ut.";
-"The message you have selected doesn't exist anymore." = "Meldingen som du markerte finnes ikke lengre.";
-
+"Please select a message." = "Markér en melding.";
+"Please select a message to print." = "Markér en melding som skal skrives ut.";
+"Please select only one message to print." = "Markér bare én melding som skal skrives ut.";
+"The message you have selected doesn't exist anymore." = "Meldingen du markerte finnes ikke lengre.";
"The folder with name \"%{0}\" could not be created."
= "Mappen \"%{0}\" kunne ikke opprettes.";
"This folder could not be renamed to \"%{0}\"."
-= "Mappen kunnne ikke bytte navn til \"%{0}\".";
+= "Mappen kunne ikke bytte navn til \"%{0}\".";
"The folder could not be deleted."
= "Mappen kunne ikke slettes.";
"The trash could not be emptied."
@@ -271,7 +270,7 @@
"The folder functionality could not be changed."
= "Mappens funksjon kunne ikke endres.";
-"You need to choose a non-virtual folder!" = "Du må velge en ikke virtuell mappe!";
+"You need to choose a non-virtual folder!" = "Du må velge en ikke-virtuell mappe!";
"Moving a message into its own folder is impossible!"
= "Det er ikke mulig å flytte en e-postmelding til samme mappe!";
@@ -283,14 +282,15 @@
= "Meldingene kunne ikke flyttes til søppelmappen. Vil du slette dem umiddelbart?";
/* Message editing */
-"error_validationfailed" = "Validering misslykket";
-"error_missingsubject" = "Emnefelt mangler";
-"error_missingrecipients" = "Ingen mottagere er angitt";
+"error_missingsubject" = "Emnefelt mangler. Vil du likevel sende meldingen?";
+"error_missingrecipients" = "Ingen mottakere er angitt";
+"Send Anyway" = "Send likevel";
/* Message sending */
"cannot send message: (smtp) all recipients discarded" = "Kan ikke sende melding: alle mottakeradresser er ugyldige.";
"cannot send message (smtp) - recipients discarded:" = "Kan ikke sende melding. Følgende mottakeradresser er ugyldige:";
-"cannot send message: (smtp) error when connecting" = "Kan ikke sende melding: problem med å prate med SMTP-tjener.";
+"cannot send message: (smtp) error when connecting" = "Kan ikke sende melding: tilkoblingsproblem med SMTP-tjener.";
-"Name" = "Navn";
+/* Contacts list in mail editor */
"Email" = "E-post";
+"Name" = "Navn";
diff --git a/UI/MailerUI/UIxMailAccountActions.m b/UI/MailerUI/UIxMailAccountActions.m
index 2b3c293d6..f3b519728 100644
--- a/UI/MailerUI/UIxMailAccountActions.m
+++ b/UI/MailerUI/UIxMailAccountActions.m
@@ -32,6 +32,7 @@
#import
#import
#import
+#import
#import
#import
@@ -123,7 +124,7 @@
- (NSArray *) _jsonFolders: (NSEnumerator *) rawFolders
{
- NSString *currentFolder, *currentDisplayName, *currentFolderType, *login, *fullName;
+ NSString *currentFolder, *currentDecodedFolder, *currentDisplayName, *currentFolderType, *login, *fullName;
NSMutableArray *pathComponents;
SOGoUserManager *userManager;
NSDictionary *folderData;
@@ -138,17 +139,19 @@
// are never reused and "autoreleased" at the end. This loop would consume
// lots of LDAP connections during its execution.
pool = [[NSAutoreleasePool alloc] init];
- currentFolderType = [self _folderType: currentFolder];
+
+ currentDecodedFolder = [currentFolder stringByDecodingImap4FolderName];
+ currentFolderType = [self _folderType: currentDecodedFolder];
// We translate the "Other Users" and "Shared Folders" namespaces.
// While we're at it, we also translate the user's mailbox names
// to the full name of the person.
- if (otherUsersFolderName && [currentFolder hasPrefix: otherUsersFolderName])
+ if (otherUsersFolderName && [currentDecodedFolder hasPrefix: otherUsersFolderName])
{
// We have a string like /Other Users/lmarcotte/... under Cyrus, but we could
// also have something like /shared under Dovecot. So we swap the username only
// if we have one, of course.
- pathComponents = [NSMutableArray arrayWithArray: [currentFolder pathComponents]];
+ pathComponents = [NSMutableArray arrayWithArray: [currentDecodedFolder pathComponents]];
if ([pathComponents count] > 2)
{
@@ -166,14 +169,14 @@
else
{
currentDisplayName = [NSString stringWithFormat: @"/%@%@", [self labelForKey: @"OtherUsersFolderName"],
- [currentFolder substringFromIndex: [otherUsersFolderName length]]];
+ [currentDecodedFolder substringFromIndex: [otherUsersFolderName length]]];
}
}
- else if (sharedFoldersName && [currentFolder hasPrefix: sharedFoldersName])
+ else if (sharedFoldersName && [currentDecodedFolder hasPrefix: sharedFoldersName])
currentDisplayName = [NSString stringWithFormat: @"/%@%@", [self labelForKey: @"SharedFoldersName"],
- [currentFolder substringFromIndex: [sharedFoldersName length]]];
+ [currentDecodedFolder substringFromIndex: [sharedFoldersName length]]];
else
- currentDisplayName = currentFolder;
+ currentDisplayName = currentDecodedFolder;
folderData = [NSDictionary dictionaryWithObjectsAndKeys:
currentFolder, @"path",
diff --git a/UI/MailerUI/UIxMailEditor.m b/UI/MailerUI/UIxMailEditor.m
index 0c695bcc8..5e3e0caa2 100644
--- a/UI/MailerUI/UIxMailEditor.m
+++ b/UI/MailerUI/UIxMailEditor.m
@@ -567,8 +567,8 @@ static NSArray *infoKeys = nil;
{
info = [self storeInfo];
[co setHeaders: info];
- [co setText: text];
[co setIsHTML: isHTML];
+ [co setText: (isHTML ? [NSString stringWithFormat: @"%@", text] : text)];;
error = [co storeInfo];
if (error)
{
diff --git a/UI/MainUI/NorwegianBokmal.lproj/Localizable.strings b/UI/MainUI/NorwegianBokmal.lproj/Localizable.strings
index 4d74d0970..d0f97272e 100644
--- a/UI/MainUI/NorwegianBokmal.lproj/Localizable.strings
+++ b/UI/MainUI/NorwegianBokmal.lproj/Localizable.strings
@@ -7,12 +7,12 @@
"Domain:" = "Domene:";
"Remember username" = "Husk brukernavn";
-"Connect" = "Logg inn";
+"Connect" = "Koble til";
"Wrong username or password." = "Feil brukernavn eller passord.";
-"cookiesNotEnabled" = "Du kan ikke logge inn fordi nettleser ikke har aktivert infokapsler (cookies). Endre innstillinger i nettleseren din slik at infokapsler (cookies) er tillatt.";
+"cookiesNotEnabled" = "Du kan ikke logge inn fordi nettleser ikke har aktivert infokapsler (cookies). Endre innstillinger i nettleseren din slik at infokapsler er tillatt.";
-"browserNotCompatible" = "Versjonen av nettleseren du anvender støttes ikke av denne webmailen. Vi anbefaler at du bruker Firefox. Klikk på linken under for å laste ned den siste versionen av Firefox.";
+"browserNotCompatible" = "Versjonen av nettleseren du anvender støttes ikke av denne webmailen. Vi anbefaler at du bruker Firefox. Klikk på lenken under for å laste ned den siste versjonen av Firefox.";
"alternativeBrowsers" = "Alternativt kan du også forsøke følgende kompatible nettlesere";
"alternativeBrowserSafari" = "Alternativt kan du også bruke Safari.";
"Download" = "Last ned";
@@ -44,19 +44,19 @@
"Welsh" = "Cymraeg";
"About" = "Om";
-"AboutBox" = "Utviklet av Inverse, SOGo er en komplett gruppevaretjener med foks på skalerbarhet og enkel bruk.
\nSOGo tilbyr ett rikt AJAX-basert webgrensesnitt, og støtter mange 3. parts klienter gjennom standardprotokoller som CalDAV og CardDAV.
\nSOGo er distribuert under GNU GPL versjon 2 eller senere, og enkelte deler er distribuert under GNU LGPL versjon 2. Dette er fri programvare: du står fritt til å endre og videredistribuere den. Den kommer med ABSOLUTT INGEN GARANTI, i det omfang som er tillatt av anvendelig lov. Sjekk denne siden for support-muligheter.";
+"AboutBox" = "Utviklet av Inverse, SOGo er en komplett gruppevaretjener med fokus på skalerbarhet og enkel bruk.
\nSOGo tilbyr ett rikt AJAX-basert webgrensesnitt, og støtter mange 3. parts klienter gjennom standardprotokoller som CalDAV og CardDAV.
\nSOGo er distribuert under GNU GPL versjon 2 eller senere, og enkelte deler er distribuert under GNU LGPL versjon 2. Dette er fri programvare: du står fritt til å endre og videredistribuere den. Den kommer med ABSOLUTT INGEN GARANTI, i det omfang som er tillatt av anvendelig lov. Sjekk denne siden for support-muligheter.";
-"Your account was locked due to too many failed attempts." = "Din konto har blitt låst på grunn av for mange misslykkete innlogginger.";
+"Your account was locked due to too many failed attempts." = "Din konto har blitt låst på grunn av for mange mislykkede innlogginger.";
"Your account was locked due to an expired password." = "Din konto har blitt låst fordi ditt passord er utløpt.";
-"Login failed due to unhandled error case: " = "Login feilet av uventet årsak:";
+"Login failed due to unhandled error case: " = "Innlogging feilet av uventet årsak:";
"Change your Password" = "Endre ditt passord";
"The password was changed successfully." = "Passordet ble endret.";
"Your password has expired, please enter a new one below:" = "Ditt passord har utløpt, vennligst fyll ut et nytt under:";
"Password must not be empty." = "Passordet må ikke være tomt.";
"The passwords do not match. Please try again." = "Passordene stemmer ikke overens. Vennligst prøv igjen.";
-"Password Grace Period" = "";
+"Password Grace Period" = "Sett forvarsel før passordet må byttes";
"You have %{0} logins remaining before your account is locked. Please change your password in the preference dialog." = "Du har %{0} gjenværende innlogginger før din konto blir låst. Vennligst endre ditt passord i preferanse-dialogen.";
-"Password about to expire" = "Passordet er på tur til å utløpe";
+"Password about to expire" = "Passordet utløper snart";
"Your password is going to expire in %{0} %{1}." = "Ditt passord vil utløpe om %{0} %{1}.";
"days" = "dager";
"hours" = "timer";
@@ -66,12 +66,12 @@
"Password change failed - Permission denied" = "Feil ved endring av passord - tillatelse nektet";
"Password change failed - Insufficient password quality" = "Feil ved endring av passord - Utilstrekkelig passordkvalitet";
"Password change failed - Password is too short" = "Feil ved endring av passord - Passordet er for kort";
-"Password change failed - Password is too young" = "Feil ved endring av passord - Password is too young";
-"Password change failed - Password is in history" = "Feil ved endring av passord - Password is in history";
-"Unhandled policy error: %{0}" = "";
-"Unhandled error response" = "";
+"Password change failed - Password is too young" = "Feil ved endring av passord - Passordet er nylig brukt";
+"Password change failed - Password is in history" = "Feil ved endring av passord - Passordet har blitt brukt før";
+"Unhandled policy error: %{0}" = "Uhåndtert policyfeil: %{0}";
+"Unhandled error response" = "Uhåndtert feilmelding.";
"Password change is not supported." = "Passordendring er ikke støttet.";
-"Unhandled HTTP error code: %{0}" = "";
+"Unhandled HTTP error code: %{0}" = "Uhåndtert HTTP-feilkode: %{0}";
"New password:" = "Nytt passord:";
"Confirmation:" = "Bekreftelse:";
"Cancel" = "Avbryt";
diff --git a/UI/MainUI/Slovak.lproj/Localizable.strings b/UI/MainUI/Slovak.lproj/Localizable.strings
index 2aa4c5e0d..37d8b6713 100644
--- a/UI/MainUI/Slovak.lproj/Localizable.strings
+++ b/UI/MainUI/Slovak.lproj/Localizable.strings
@@ -19,6 +19,7 @@
"Language:" = "Jazyk:";
"choose" = "Výber ...";
+"Arabic" = "العربية";
"Catalan" = "Katalánsky";
"Czech" = "Česky";
"Danish" = "Dansk (Danmark)";
diff --git a/UI/PreferencesUI/Danish.lproj/Localizable.strings b/UI/PreferencesUI/Danish.lproj/Localizable.strings
index 761afcd81..90d420a71 100644
--- a/UI/PreferencesUI/Danish.lproj/Localizable.strings
+++ b/UI/PreferencesUI/Danish.lproj/Localizable.strings
@@ -210,11 +210,11 @@
"Danish" = "Dansk (Danmark)";
"Dutch" = "Nederlands";
"English" = "English";
-"Finnish" = "Finsk";
+"Finnish" = "Suomi";
"French" = "Français";
"German" = "Deutsch";
"Hungarian" = "Magyar";
-"Icelandic" = "Islandsk";
+"Icelandic" = "Íslenska";
"Italian" = "Italiano";
"NorwegianBokmal" = "Norsk";
"NorwegianNynorsk" = "Nynorsk";
diff --git a/UI/PreferencesUI/Icelandic.lproj/Localizable.strings b/UI/PreferencesUI/Icelandic.lproj/Localizable.strings
index bc9ff1330..31e569cb9 100644
--- a/UI/PreferencesUI/Icelandic.lproj/Localizable.strings
+++ b/UI/PreferencesUI/Icelandic.lproj/Localizable.strings
@@ -185,7 +185,6 @@
"German" = "Deutsch";
"Hungarian" = "Magyar";
"Icelandic" = "Íslenska";
-"Icelandic" = "Íslenska";
"Italian" = "Italiano";
"NorwegianBokmal" = "Norsk bokmål";
"NorwegianNynorsk" = "Norsk nynorsk";
diff --git a/UI/PreferencesUI/NorwegianBokmal.lproj/Localizable.strings b/UI/PreferencesUI/NorwegianBokmal.lproj/Localizable.strings
index 616b2fdf5..08a03d1f2 100644
--- a/UI/PreferencesUI/NorwegianBokmal.lproj/Localizable.strings
+++ b/UI/PreferencesUI/NorwegianBokmal.lproj/Localizable.strings
@@ -6,8 +6,8 @@
"General" = "Generelt";
"Calendar Options" = "Kalenderinnstillinger";
"Contacts Options" = "Kontaktinnstillinger";
-"Mail Options" = "E-post innstillinger";
-"IMAP Accounts" = "IMAP kontoer";
+"Mail Options" = "E-postinnstillinger";
+"IMAP Accounts" = "IMAP-kontoer";
"Vacation" = "Fravær";
"Forward" = "Videresend";
"Password" = "Passord";
@@ -18,7 +18,7 @@
"Delete" = "Fjern";
/* contacts categories */
-"contacts_category_labels" = "Familie, Foretningspartner, Kollega, Konkurrent, Kunde, Leverandør, Presse, Venn, VIP";
+"contacts_category_labels" = "Kollega, Konkurrent, Kunde, Venn, Familie, Foretningspartner, Leverandør, Presse, VIP";
/* vacation (auto-reply) */
"Enable vacation auto reply" = "Aktiver auto-svar ved fravær";
@@ -29,10 +29,10 @@
"Do not send responses to mailing lists" = "Ikke send svar til e-postlister";
"Disable auto reply on" = "Skru av auto-svar";
"Please specify your message and your email addresses for which you want to enable auto reply."
-= "Skriv melding og angi din e-postadresse som du vil aktivera auto-svar på.";
+= "Skriv melding og angi din e-postadresse som du vil aktivere auto-svar for.";
"Your vacation message must not end with a single dot on a line." = "Fraværsmeldingen kan ikke slutte med ett ensomt punktum på en linje. ";
"End date of your auto reply must be in the future."
-= "Slutt-dato for auto-svar må være i fremtiden.";
+= "Slutt-dato for auto-svar må være i framtiden.";
/* forward messages */
"Forward incoming messages" = "Videresend innkommende e-post";
@@ -87,6 +87,7 @@
"timeFmt_1" = "%H:%M";
"timeFmt_2" = "";
"timeFmt_3" = "";
+"timeFmt_4" = "";
/* calendar */
"Week begins on :" = "Uken begynner med:";
@@ -101,11 +102,11 @@
"Default reminder :" = "Standardpåminnelse:";
"firstWeekOfYear_January1" = "Begynner den 1. januar";
-"firstWeekOfYear_First4DayWeek" = "Første 4-dagersuken i året";
+"firstWeekOfYear_First4DayWeek" = "Første firedagersuken i året";
"firstWeekOfYear_FirstFullWeek" = "Første hele uken i året";
/* Default Calendar */
-"Default calendar :" = "Standard kalender";
+"Default calendar :" = "Standard kalender:";
"selectedCalendar" = "Valgte kalender";
"personalCalendar" = "Personlig kalender";
"firstCalendar" = "Første aktiverte kalender";
@@ -129,17 +130,18 @@
"Check for new mail:" = "Hent ny post:";
"messagecheck_manually" = "Manuelt";
"messagecheck_every_minute" = "Hvert minutt";
-"messagecheck_every_2_minutes" = "Hvert 2 minutt";
-"messagecheck_every_5_minutes" = "Hvert 5 minutt";
-"messagecheck_every_10_minutes" = "Hvert 10 minutt";
-"messagecheck_every_20_minutes" = "Hvert 20 minutt";
-"messagecheck_every_30_minutes" = "Hvert 30 minutt";
+"messagecheck_every_2_minutes" = "Hvert 2. minutt";
+"messagecheck_every_5_minutes" = "Hvert 5. minutt";
+"messagecheck_every_10_minutes" = "Hvert 10. minutt";
+"messagecheck_every_20_minutes" = "Hvert 20. minutt";
+"messagecheck_every_30_minutes" = "Hvert 30. minutt";
"messagecheck_once_per_hour" = "Hver time";
-"Forward messages:" = "Videresend melding:";
+"Forward messages:" = "Videresend meldinger:";
"messageforward_inline" = "Innsatt";
"messageforward_attached" = "Vedlegg";
+"When replying to a message:" = "Ved svar på melding: ";
"replyplacement_above" = "Start svaret ovenfor";
"replyplacement_below" = "Start svaret under";
"And place my signature" = "Legg til min signatur";
@@ -148,23 +150,32 @@
"Compose messages in" = "Opprett melding i";
"composemessagestype_html" = "HTML";
"composemessagestype_text" = "Ren text";
+"Display remote inline images" = "Vis bilder lenket til fra andre nettsteder";
+"displayremoteinlineimages_never" = "Aldri";
+"displayremoteinlineimages_always" = "Alltid";
/* IMAP Accounts */
-"New Mail Account" = "Ny epostkonto";
+"New Mail Account" = "Ny e-postkonto";
"Server Name:" = "Servernavn:";
"Port:" = "Port:";
+"Encryption:" = "Kryptering:";
+"None" = "Ingen";
"User Name:" = "Brukernavn:";
"Password:" = "Passord:";
-"Full Name:" = "Fullt Navn:";
+"Full Name:" = "Fullt navn:";
"Email:" = "E-post:";
+"Reply To Email:" = "Svar til e-post:";
"Signature:" = "Signatur:";
"(Click to create)" = "(Klikk for å opprette)";
"Signature" = "Signatur";
"Please enter your signature below:" = "Vennligst fyll ut signatur under:";
+"Please specify a valid sender address." = "Vennligst angi en gyldig avsenderadresse.";
+"Please specify a valid reply-to address." = "Vennligst angi en gyldig svar-til-adresse.";
+
/* Additional Parameters */
"Additional Parameters" = "Øvrige parametre";
@@ -174,11 +185,11 @@
"Change" = "Endre";
/* Event+task classifications */
-"Default events classification :" = "Default events classification :";
-"Default tasks classification :" = "Default tasks classification :";
-"PUBLIC_item" = "Public";
-"CONFIDENTIAL_item" = "Confidential";
-"PRIVATE_item" = "Private";
+"Default events classification :" = "Standard hendelsesklassifikasjon:";
+"Default tasks classification :" = "Standard oppgaveklassifisering";
+"PUBLIC_item" = "Offentlig";
+"CONFIDENTIAL_item" = "Konfidensiell";
+"PRIVATE_item" = "Privat";
/* Event+task categories */
"category_none" = "Ingen";
@@ -208,9 +219,9 @@
"NorwegianBokmal" = "Norsk bokmål";
"NorwegianNynorsk" = "Norsk nynorsk";
"BrazilianPortuguese" = "Português brasileiro";
-"Polish" = "Polski";
+"Polish" = "Polsk";
"Russian" = "Русский";
-"Slovak" = "Slovensky";
+"Slovak" = "Slovensk";
"SpanishSpain" = "Español (España)";
"SpanishArgentina" = "Español (Argentina)";
"Swedish" = "Svenska";
@@ -221,12 +232,12 @@
"When I receive a request for a return receipt:" = "Når jeg mottar anmodning om en returkvittering:";
"Never send a return receipt" = "Send aldri en returkvittering";
"Allow return receipts for some messages" = "Tillat returkvittering for noen meldinger";
-"If I'm not in the To or Cc of the message:" = "Hvis jeg ikke er i Til eller Cc feltet i meldingen:";
+"If I'm not in the To or Cc of the message:" = "Hvis jeg ikke er i Til- eller Cc-feltet i meldingen:";
"If the sender is outside my domain:" = "Hvis senderen er utenfor mitt domene:";
"In all other cases:" = "I alle andre tilfeller:";
-"Never send" = "Send aldri";
-"Always send" = "Send alltid";
+"Never send" = "Aldri send";
+"Always send" = "Alltid send";
"Ask me" = "Spør meg";
/* Filters - UIxPreferences */
@@ -242,6 +253,7 @@
"match any of the following rules:" = "samsvarer med en av følgende regler:";
"match all messages" = "samsvarer med alle meldinger";
"Perform these actions:" = "Utfør disse handlingene:";
+"Untitled Filter" = "Ikke navngitt filter";
"Subject" = "Emne";
"From" = "Fra";
@@ -264,11 +276,11 @@
"is" = "er";
"is not" = "er ikke";
"contains" = "inneholder";
-"does not contain" = "inneholder ikker";
-"matches" = "samsvarer";
-"does not match" = "samsvarer ikke";
-"matches regex" = "samsvarer regex";
-"does not match regex" = "samvarer ikke regex";
+"does not contain" = "inneholder ikke";
+"matches" = "samsvarer med";
+"does not match" = "samsvarer ikke med";
+"matches regex" = "samsvarer med regex";
+"does not match regex" = "samvarer ikke med regex";
"Seen" = "Sett";
"Deleted" = "Slettet";
@@ -282,15 +294,16 @@
"Label 4" = "Etikett 4";
"Label 5" = "Etikett 5";
+"The password was changed successfully." = "Passordet ble endret.";
"Password must not be empty." = "Passord kan ikke være tomme.";
"The passwords do not match. Please try again." = "Passordene er ikke like. Prøv igjen.";
"Password change failed" = "Passordendring feilet";
-"Password change failed - Permission denied" = "Passordendring feilet -- ikke tilgang";
-"Password change failed - Insufficient password quality" = "Passordendring feilet -- for dårlig passord";
-"Password change failed - Password is too short" = "Passordendring feilet -- passordet er for kort";
-"Password change failed - Password is too young" = "Passordendring feilet -- passordet er nylig brukt før";
-"Password change failed - Password is in history" = "Passordendring feilet -- passordet er brukt før";
-"Unhandled policy error: %{0}" = "";
-"Unhandled error response" = "";
+"Password change failed - Permission denied" = "Passordendring feilet - ikke tilgang";
+"Password change failed - Insufficient password quality" = "Passordendring feilet - for dårlig passord";
+"Password change failed - Password is too short" = "Passordendring feilet - passordet er for kort";
+"Password change failed - Password is too young" = "Passordendring feilet - passordet er nylig brukt før";
+"Password change failed - Password is in history" = "Passordendring feilet - passordet er brukt før";
+"Unhandled policy error: %{0}" = "Uhåndtert policy-feil: %{0}";
+"Unhandled error response" = "Uhåndtert feilrespons";
"Password change is not supported." = "Passordendring er ikke støttet.";
-"Unhandled HTTP error code: %{0}" = "";
+"Unhandled HTTP error code: %{0}" = "Uhåndtert HTTP feilkode: %{0}";
diff --git a/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings b/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings
index fa67e8d55..b287a970a 100644
--- a/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings
+++ b/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings
@@ -141,6 +141,7 @@
"messageforward_inline" = "Incorporado";
"messageforward_attached" = "Como adjunto";
+"When replying to a message:" = "Cuando responda a un mensaje:";
"replyplacement_above" = "Empezar mi respuesta sobre el texto citado";
"replyplacement_below" = "Empieza mi respuesta bajo el texto citado";
"And place my signature" = "Y añadir mi firma";
@@ -149,12 +150,17 @@
"Compose messages in" = "Redactar los mensajes en";
"composemessagestype_html" = "HTML";
"composemessagestype_text" = "Texto plano";
+"Display remote inline images" = "Mostrar las imágenes remotas";
+"displayremoteinlineimages_never" = "Nunca";
+"displayremoteinlineimages_always" = "Siempre";
/* IMAP Accounts */
"New Mail Account" = "Nueva Cuenta de Correo";
"Server Name:" = "Nombre del servidor:";
"Port:" = "Puerto:";
+"Encryption:" = "Cifrado:";
+"None" = "Sin cifrar";
"User Name:" = "Nombre de usuario:";
"Password:" = "Contraseña:";
diff --git a/UI/Scheduler/Czech.lproj/Localizable.strings b/UI/Scheduler/Czech.lproj/Localizable.strings
index b64e18b5d..d625e8210 100644
--- a/UI/Scheduler/Czech.lproj/Localizable.strings
+++ b/UI/Scheduler/Czech.lproj/Localizable.strings
@@ -376,7 +376,7 @@
"Show Time as Free" = "Čas zobrazit jako volný";
/* email notifications */
-"Send Appointment Notifications" = "Poslat připomenutí";
+"Send Appointment Notifications" = "Poslat upozornění na schůzku";
/* validation errors */
diff --git a/UI/Scheduler/Finnish.lproj/Localizable.strings b/UI/Scheduler/Finnish.lproj/Localizable.strings
index 41c47154f..de789251f 100644
--- a/UI/Scheduler/Finnish.lproj/Localizable.strings
+++ b/UI/Scheduler/Finnish.lproj/Localizable.strings
@@ -179,6 +179,8 @@
"Reminder:" = "Muistuttaja:";
"General:" = "Yleinen:";
"Reply:" = "Vastaus:";
+"Created by:" = "Luonut:";
+
"Target:" = "Kohde:";
@@ -373,6 +375,9 @@
"Show Time as Free" = "Näytä aika vapaana";
+/* email notifications */
+"Send Appointment Notifications" = "Lähetä tapaamismuistutukset";
+
/* validation errors */
validate_notitle = "Otsikkoa ei ole asetettu, jatka?";
diff --git a/UI/Scheduler/Hungarian.lproj/Localizable.strings b/UI/Scheduler/Hungarian.lproj/Localizable.strings
index ac80ad6b5..96965355e 100644
--- a/UI/Scheduler/Hungarian.lproj/Localizable.strings
+++ b/UI/Scheduler/Hungarian.lproj/Localizable.strings
@@ -179,6 +179,8 @@
"Reminder:" = "Emlékeztető:";
"General:" = "Általános:";
"Reply:" = "Válasz:";
+"Created by:" = "Létrehozta:";
+
"Target:" = "Cél:";
@@ -373,6 +375,9 @@
"Show Time as Free" = "Ne jelezzen foglaltságot";
+/* email notifications */
+"Send Appointment Notifications" = "Találkozó értesítések küldése";
+
/* validation errors */
validate_notitle = "A cím nincs megadva, folytatja?";
diff --git a/UI/Scheduler/NorwegianBokmal.lproj/Localizable.strings b/UI/Scheduler/NorwegianBokmal.lproj/Localizable.strings
index 4f0eca37a..7c4713516 100644
--- a/UI/Scheduler/NorwegianBokmal.lproj/Localizable.strings
+++ b/UI/Scheduler/NorwegianBokmal.lproj/Localizable.strings
@@ -1,3 +1,4 @@
+/* this file is in UTF-8 format! */
/* Tooltips */
@@ -51,15 +52,16 @@
"Contacts" = "Kontakter";
"New Calendar..." = "Ny kalender...";
-"Delete Calendar" = "Slett kalender";
+"Delete Calendar" = "Slett kalender...";
"Unsubscribe Calendar" = "Avslutt abonnement på kalender";
"Sharing..." = "Deling...";
-"Export Calendar..." = "Eksorter kalender...";
+"Export Calendar..." = "Eksporter kalender...";
"Import Events..." = "Importer hendelser...";
"Import Events" = "Importer hendelser";
-"Select an iCalendar file (.ics)." = "Velg en iCalendar fil (.ics).";
+"Select an iCalendar file (.ics)." = "Velg en iCalendar-fil (.ics).";
"Upload" = "Last opp";
-"Publish Calendar..." = "Publiser Kalender...";
+"Uploading" = "Laster opp";
+"Publish Calendar..." = "Publiser kalender...";
"Reload Remote Calendars" = "Last på nytt fjernkalendre";
"Properties" = "Egenskaper";
"Done" = "Klar";
@@ -98,14 +100,14 @@
"View All" = "Vis alle";
"View the Date & Time" = "Vis tid og dato";
-"Modify" = "Endra";
+"Modify" = "Endre";
"Respond To" = "Svar";
"None" = "Ingen";
"This person can create objects in my calendar."
-= "Personen kan opprette objekt i min kalender.";
+= "Personen kan opprette objekter i min kalender.";
"This person can erase objects from my calendar."
-= "Personen kan fjerne objekt i min kalender.";
+= "Personen kan fjerne objekter i min kalender.";
/* Button Titles */
@@ -159,7 +161,7 @@
"Email" = "E-post";
"Status:" = "Status:";
"% complete" = "% utført";
-"Location:" = "Plass:";
+"Location:" = "Sted:";
"Priority:" = "Prioritet:";
"Privacy" = "Personvern";
"Cycle" = "Intervall";
@@ -169,7 +171,7 @@
"Duration" = "Varighet";
"Attendees:" = "Deltakere:";
"Resources" = "Ressurser";
-"Organizer:" = "Organisatør:";
+"Organizer:" = "Organisator:";
"Description:" = "Beskrivelse:";
"Document:" = "Dokument:";
"Category:" = "Kategori:";
@@ -178,6 +180,7 @@
"General:" = "Generell:";
"Reply:" = "Svar:";
+
"Target:" = "Mål:";
"attributes" = "attributter";
@@ -193,22 +196,22 @@
"empty title" = "Ingen tittel";
"private appointment" = "Privat møte";
-"Change..." = "Endra...";
+"Change..." = "Endre...";
/* Appointments (participation state) */
-"partStat_NEEDS-ACTION" = "Trenger handling";
-"partStat_ACCEPTED" = "Jeg kan delta";
+"partStat_NEEDS-ACTION" = "Jeg vil bekrefte senere";
+"partStat_ACCEPTED" = "Jeg vil delta";
"partStat_DECLINED" = "Jeg kan ikke delta";
-"partStat_TENTATIVE" = "Jeg kommer tilbake";
+"partStat_TENTATIVE" = "Jeg kommer kanskje";
"partStat_DELEGATED" = "Jeg delegerer";
"partStat_OTHER" = "Annet";
/* Appointments (error messages) */
"Conflicts found!" = "Konflikter funnet!";
-"Invalid iCal data!" = "Ugyldig iCal data!";
-"Could not create iCal data!" = "Kunne ikke opprette iCal data!";
+"Invalid iCal data!" = "Ugyldig iCal-data!";
+"Could not create iCal data!" = "Kunne ikke opprette iCal-data!";
/* Searching */
@@ -301,12 +304,12 @@
"Week(s)" = "Uke(r)";
"On" = "På";
"Month(s)" = "Måned(er)";
-"The" = "";
+"The" = " Den";
"Recur on day(s)" = "Gjentas på dag(er)";
"Year(s)" = "År";
"cycle_of" = "av";
"No end date" = "Ingen sluttdato";
-"Create" = "Oprett";
+"Create" = "Opprett";
"appointment(s)" = "avtale(r)";
"Repeat until" = "Gjenta til";
@@ -322,7 +325,7 @@
"category_none" = "Ingen";
"category_labels" = "Arbeid,Diverse,Favoritter,Fødselsdager,Helgdager,Idéer,Konkurranser,Kunder,Ledighet,Leverandører,Oppfølging,Personlig,Presenter,Prosjekt,Møter,Reiser,Status,Telefonsamtaler,Ærend";
-"repeat_NEVER" = "Ikke gjenta";
+"repeat_NEVER" = "Gjentas ikke";
"repeat_DAILY" = "Daglig";
"repeat_WEEKLY" = "Ukentlig";
"repeat_BI-WEEKLY" = "Annenhver uke";
@@ -351,15 +354,15 @@
"reminder_DAYS" = "dager";
"reminder_BEFORE" = "før";
"reminder_AFTER" = "etter";
-"reminder_START" = "hendelser starter";
-"reminder_END" = "hendelser slutter";
+"reminder_START" = "hendelsen starter";
+"reminder_END" = "hendelsen slutter";
"Reminder Details" = "Påminnelsedetaljer";
"Choose a Reminder Action" = "Velg en påminnelsesmåte";
"Show an Alert" = "Vis en alarm";
"Send an E-mail" = "Send en E-post";
-"Email Organizer" = "E-post organisator";
-"Email Attendees" = "E-post deltakere";
+"Email Organizer" = "E-post-organisator";
+"Email Attendees" = "E-post-deltakere";
"zoom_400" = "400%";
"zoom_200" = "200%";
@@ -371,6 +374,8 @@
"Show Time as Free" = "Vis tid som ledig";
+/* email notifications */
+
/* validation errors */
validate_notitle = "Ingen tittel er angitt, fortsette?";
@@ -378,6 +383,7 @@ validate_invalid_startdate = "Feil startdato!";
validate_invalid_enddate = "Feil sluttdato!";
validate_endbeforestart = "Angitt sluttdato inntreffer før angitt startdato.";
+"Events" = "Hendelser";
"Tasks" = "Oppgaver";
"Show completed tasks" = "Vis utførte oppgave";
@@ -403,7 +409,7 @@ validate_endbeforestart = "Angitt sluttdato inntreffer før angitt startdato.
"New Event..." = "Ny hendelse...";
"New Task..." = "Ny oppgave...";
"Edit Selected Event..." = "Endre hendelse...";
-"Delete Selected Event" = "Slett hendelse";
+"Delete Selected Event" = "Slett valgt hendelse";
"Select All" = "Velg alle";
"Workweek days only" = "Bare arbeidsdager";
"Tasks in View" = "Oppgaver i visning";
@@ -412,14 +418,14 @@ validate_endbeforestart = "Angitt sluttdato inntreffer før angitt startdato.
"taskDeleteConfirmation" = "Sletting av oppgaven er permanent.\nVil du fortsette?";
"You cannot remove nor unsubscribe from your personal calendar."
-= "Du kan ikke slette eller avbryta abonnement på en personlig kalender.";
+= "Du kan ikke slette eller avbryte abonnement på en personlig kalender.";
"Are you sure you want to delete the calendar \"%{0}\"?"
= "Er du sikker på at du vil slette kalenderen \"%{0}\"?";
/* Legend */
"Participant" = "Deltakelse kreves";
"Optional Participant" = "Deltakelse valgfritt";
-"Non Participant" = "Ingen deltaker";
+"Non Participant" = "Ingen deltakelse";
"Chair" = "Stol";
"Needs action" = "Trenger handling";
@@ -430,13 +436,13 @@ validate_endbeforestart = "Angitt sluttdato inntreffer før angitt startdato.
"Free" = "Ledig";
"Busy" = "Opptatt";
"Maybe busy" = "Kanskje opptatt";
-"No free-busy information" = "Ingen ledig/opptatt informasjon";
+"No free-busy information" = "Ingen ledig/opptatt-informasjon";
/* FreeBusy panel buttons and labels */
"Suggest time slot:" = "Foreslå tid:";
"Zoom:" = "Forstørr:";
-"Previous slot" = "Forrige spor";
-"Next slot" = "Neste spor";
+"Previous slot" = "Forrige tidspunkt";
+"Next slot" = "Neste tidspunkt";
"Previous hour" = "Forrige time";
"Next hour" = "Neste time";
"Work days only" = "Bare arbeidsdager";
@@ -445,28 +451,32 @@ validate_endbeforestart = "Angitt sluttdato inntreffer før angitt startdato.
"and" = "og";
"A time conflict exists with one or more attendees.\nWould you like to keep the current settings anyway?"
-= "En tidskonflikt eksisterer med en eller flere detakere.\nVil du likevel beholde de nåværende innstillingene?";
+= "En tidskonflikt eksisterer med en eller flere deltakere.\nVil du likevel beholde de nåværende innstillingene?";
/* apt list */
"Title" = "Tittel";
"Start" = "Start";
"End" = "Slutt";
-"Due Date" = "Dato";
-"Location" = "Plass";
+"Due Date" = "Forfallsdato";
+"Location" = "Sted";
+
"(Private Event)" = "(Privat hendelse)";
vevent_class0 = "(Offentlig hendelse)";
vevent_class1 = "(Privat hendelse)";
vevent_class2 = "(Konfidensiell hendelse)";
+"Priority" = "Prioritet";
+"Category" = "Kategori";
+
vtodo_class0 = "(Offentlig oppgave)";
vtodo_class1 = "(Privat oppgave)";
vtodo_class2 = "(Konfidensiell oppgave)";
-"closeThisWindowMessage" = "Takk! Du kan lukke vinduet eller din visning";
+"closeThisWindowMessage" = "Takk! Du kan nå lukke vinduet eller se din";
"Multicolumn Day View" = "Flerkolonne dagsvisning";
-"Please select an event or a task." = "Marker en hendelse eller oppgave.";
+"Please select an event or a task." = "Markér en hendelse eller oppgave.";
"editRepeatingItem" = "Objektet du redigerer har gjentakelser. Vil du redigere alle forekomster eller bare denne forekomsten?";
"button_thisOccurrenceOnly" = "Bare denne forekomsten";
@@ -483,9 +493,14 @@ vtodo_class2 = "(Konfidensiell oppgave)";
"Tag:" = "Merkelapp:";
"Display" = "Vis";
-"Show alarms" = "Vis alarm";
+"Show alarms" = "Vis alarmer";
"Show tasks" = "Vis oppgaver";
+"Notifications" = "Varslinger";
+"Receive a mail when I modify my calendar" = "Motta e-post når jeg oppdaterer kalenderen min";
+"Receive a mail when someone else modifies my calendar" = "Motta e-post når andre oppdaterer kalenderen min";
+"When I modify my calendar, send a mail to:" = "Når jeg endrer kalenderen, send e-post til:";
+
"Links to this Calendar" = "Linker til denne kalenderen";
"Authenticated User Access" = "Autentisert brukertilgang";
"CalDAV URL" = "CalDAV url";
@@ -500,12 +515,12 @@ vtodo_class2 = "(Konfidensiell oppgave)";
"yearFieldInvalid" = "Angi en numerisk verdi i årsfeltet større enn eller lik 1.";
"appointmentFieldInvalid" = "Angi en numerisk verdi i møtesfeltet større enn eller lik 1.";
"recurrenceUnsupported" = "Denne type gjentakelse støttes ikke i dag.";
-"Please specify a calendar name." = "Vennligst angi ett kalendernavn.";
+"Please specify a calendar name." = "Vennligst angi et kalendernavn.";
"tagNotDefined" = "Du må angi en merkelapp om du vil synkronisere kalenderen.";
"tagAlreadyExists" = "Merkelappen du spesifiserte er allerede knyttet til en annen kalender.";
-"tagHasChanged" = "Om du endrer merkelappen på din kalender trenger du å laste dataene i din mobiltelefon på nytt.\nFortsätta?";
+"tagHasChanged" = "Om du endrer merkelappen på din kalender trenger du å laste dataene i din mobiltelefon på nytt.\nFortsette?";
"tagWasAdded" = "Om du vil synkronisere kalenderen trenger du å laste dataene i din mobiltelefon på nytt.\nFortsette?";
-"tagWasRemoved" = "Om fjerner kalenderen fra synkronisering trenger du å laste dataene i din mobiltelefon på nytt.\nFortsetta?";
+"tagWasRemoved" = "Om du fjerner kalenderen fra synkronisering trenger du å laste dataene i din mobiltelefon på nytt.\nFortsette?";
"DestinationCalendarError" = "Kilde- og målkalendere er de samme. Prøv å kopiere til en annen kalender.";
"EventCopyError" = "Kopiering feilet. Vennligst prøv å kopiere til en annen kalender.";
@@ -514,12 +529,11 @@ vtodo_class2 = "(Konfidensiell oppgave)";
"Delete Task" = "Slett oppgave";
"Delete Event" = "Slett hendelse";
"Copy event to my calendar" = "Kopier hendelse til min kalender";
+"View Raw Source" = "Vis kilde";
"Subscribe to a web calendar..." = "Abonnere på en internett-kalender...";
"URL of the Calendar" = "URL til kalenderen";
"Web Calendar" = "Internett-kalender";
"Reload on login" = "Last på nytt ved innlogging";
"Invalid number." = "Ugyldig tall.";
-
-"Category" = "Kategori";
-"Priority" = "Prioritet";
+"Please identify yourself to %{0}" = "Vennligst identifiser deg for %{0}";
diff --git a/UI/Scheduler/Russian.lproj/Localizable.strings b/UI/Scheduler/Russian.lproj/Localizable.strings
index 8dec3259c..ac361dd93 100644
--- a/UI/Scheduler/Russian.lproj/Localizable.strings
+++ b/UI/Scheduler/Russian.lproj/Localizable.strings
@@ -90,7 +90,7 @@
"label_Public" = "Публичное событие";
"label_Private" = "Личное событие";
-"label_Confidential" = "Показывать только время и дату";
+"label_Confidential" = "Конфиденциальное";
"label_Viewer" = "Показать все";
"label_DAndTViewer" = "Показать дату и время";
diff --git a/UI/Scheduler/SpanishSpain.lproj/Localizable.strings b/UI/Scheduler/SpanishSpain.lproj/Localizable.strings
index a04ec37ee..a448e2e52 100644
--- a/UI/Scheduler/SpanishSpain.lproj/Localizable.strings
+++ b/UI/Scheduler/SpanishSpain.lproj/Localizable.strings
@@ -179,6 +179,8 @@
"Reminder:" = "Recordatorio:";
"General:" = "General:";
"Reply:" = "Responder:";
+"Created by:" = "Creado por:";
+
"Target:" = "URL documento:";
@@ -373,6 +375,9 @@
"Show Time as Free" = "Mostrar tiempo como disponible";
+/* email notifications */
+"Send Appointment Notifications" = "Enviar avisos de evento";
+
/* validation errors */
validate_notitle = "Sin título, ¿continuar?";
diff --git a/UI/Scheduler/UIxCalMainActions.m b/UI/Scheduler/UIxCalMainActions.m
index e416d221c..756c65b8c 100644
--- a/UI/Scheduler/UIxCalMainActions.m
+++ b/UI/Scheduler/UIxCalMainActions.m
@@ -37,24 +37,6 @@
@implementation UIxCalMainActions
-- (NSString *) displayNameForUrl: (NSString *) calendarURL
-{
- NSString *rc, *tmp;
-
- tmp = [calendarURL lastPathComponent];
- if (tmp)
- {
- if ([[tmp pathExtension] caseInsensitiveCompare: @"ics"] == NSOrderedSame)
- rc = [tmp substringToIndex: [tmp length] - 4];
- else
- rc = tmp;
- }
- else
- rc = [self labelForKey: @"Web Calendar"];
-
- return rc;
-}
-
- (WOResponse *) addWebCalendarAction
{
WORequest *r;
@@ -70,11 +52,12 @@
if ([urlString length] > 0)
{
folders = [self clientObject];
- displayName = [self displayNameForUrl: urlString];
- folder = [folders newWebCalendarWithName: displayName
- atURL: urlString];
+ folder = [folders newWebCalendarWithURL: urlString
+ nameInContainer: nil];
+
if (folder)
{
+ displayName = [folder displayName];
response = [self responseWithStatus: 200];
[response setHeader: @"application/json" forKey: @"content-type"];
diff --git a/UI/Scheduler/UIxCalUserRightsEditor.m b/UI/Scheduler/UIxCalUserRightsEditor.m
index 8c8bda47a..00534bff8 100644
--- a/UI/Scheduler/UIxCalUserRightsEditor.m
+++ b/UI/Scheduler/UIxCalUserRightsEditor.m
@@ -133,10 +133,10 @@
- (NSArray *) objectRights
{
return ([uid isEqualToString: @"anonymous"]
- ? [NSArray arrayWithObjects: @"Viewer", @"DAndTViewer", @"None",
+ ? [NSArray arrayWithObjects: @"None", @"DAndTViewer", @"Viewer",
nil]
- : [NSArray arrayWithObjects: @"Viewer", @"DAndTViewer", @"Modifier",
- @"Responder", @"None", nil]);
+ : [NSArray arrayWithObjects: @"None", @"DAndTViewer", @"Viewer",
+ @"Responder", @"Modifier", nil]);
}
- (void) setCurrentRight: (NSString *) newCurrentRight
diff --git a/UI/Templates/Appointments/SOGoAptMailDeletion.wox b/UI/Templates/Appointments/SOGoAptMailDeletion.wox
index b19a19f2f..aea834b62 100644
--- a/UI/Templates/Appointments/SOGoAptMailDeletion.wox
+++ b/UI/Templates/Appointments/SOGoAptMailDeletion.wox
@@ -24,9 +24,9 @@ h1, dd, .dl-list dt { margin-left: 130px; }