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; }
-
-
+
- diff --git a/UI/Templates/MailPartViewers/UIxMailPartICalViewer.wox b/UI/Templates/MailPartViewers/UIxMailPartICalViewer.wox index 12fca2152..4a09a2095 100644 --- a/UI/Templates/MailPartViewers/UIxMailPartICalViewer.wox +++ b/UI/Templates/MailPartViewers/UIxMailPartICalViewer.wox @@ -109,7 +109,6 @@ - @@ -118,52 +117,43 @@

- -

- - - -

- Status Update: - , - was: - . -

+ >
+
:
+
, + + . +
+
+
+
-
- +
-
-
- -

- - -

+
+
- -

+
+
+
- -

+
+
+
-