Merge to 2.1.0

This commit is contained in:
Francis Lachapelle 2013-11-07 14:43:19 -05:00
commit 449d838dc2
186 changed files with 3174 additions and 1178 deletions

2
.gitignore vendored
View file

@ -9,3 +9,5 @@ tags
*.swp *.swp
SoObjects/SOGo/SOGo.framework/ SoObjects/SOGo/SOGo.framework/
SoObjects/SOGo/derived_src/ SoObjects/SOGo/derived_src/
Tests/*/config.py
*.pyc

View file

@ -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
<VirtualHost *: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
<Location />
Order allow,deny
Allow from all
</Location>
<Proxy http://127.0.0.1:20000>
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
</Proxy>
ErrorLog /var/log/apache2/ab-error.log
CustomLog /var/log/apache2/ab-access.log combined
</VirtualHost>
# plain http
# Same here, don't forget to add a Listen parameter for port 8800:
# Listen 8800
<VirtualHost *:8800> <VirtualHost *:8800>
RewriteEngine Off RewriteEngine Off
ProxyRequests Off ProxyRequests Off

View file

@ -66,3 +66,9 @@ ProxyPass /SOGo http://127.0.0.1:20000/SOGo retry=0
Allow from all Allow from all
</Proxy> </Proxy>
# For apple autoconfiguration
<IfModule rewrite_module>
RewriteEngine On
RewriteRule ^/.well-known/caldav/?$ /SOGo/dav [R=301]
</IfModule>

892
ChangeLog
View file

@ -1,3 +1,895 @@
commit d0b09ebe35d9bde78f627b6569660627c60c8e42
Author: Francis Lachapelle <flachapelle@inverse.ca>
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 <flachapelle@inverse.ca>
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 <flachapelle@inverse.ca>
Date: Thu Nov 7 10:13:30 2013 -0500
Update NEWS file
M NEWS
commit 73141a645e4b206bd536d71dfe2867a57ec6a21c
Author: Francis Lachapelle <flachapelle@inverse.ca>
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 <flachapelle@inverse.ca>
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 <flachapelle@inverse.ca>
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 <lmarcotte@inverse.ca>
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 <lmarcotte@inverse.ca>
Date: Wed Oct 23 16:37:03 2013 -0400
Added more tags to skip
M UI/MailPartViewers/UIxMailPartHTMLViewer.m
commit 87261f3280dd5de438c7db0a3a7c013775f7f9b8
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Wed Oct 23 16:04:37 2013 -0400
Fix for bug #2468.
M UI/MailPartViewers/UIxMailPartHTMLViewer.m
commit bd2759ecdf0eb99169d7992d0d70586e57f325b3
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Tue Oct 22 11:44:26 2013 -0400
Fix for bug #2433
M SoObjects/Mailer/SOGoMailFolder.m
commit be1bcf3c9b63c41362d1a007590bd905f71d901c
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Tue Oct 22 11:25:24 2013 -0400
Fix for bug #2461
M SoObjects/Appointments/iCalEvent+SOGo.m
commit 053b090affbd6a20f62e181d66058583926fca19
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
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 <lmarcotte@inverse.ca>
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 <lmarcotte@inverse.ca>
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 <lmarcotte@inverse.ca>
Date: Fri Oct 18 10:30:43 2013 -0400
Fix for bug #2434
M UI/MailPartViewers/UIxMailPartHTMLViewer.m
commit 9289615996ef9b6fd72a7a16be1cc3e1f73e8dce
Author: Jean Raby <jraby@inverse.ca>
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 <jraby@inverse.ca>
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 <jraby@inverse.ca>
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 <lmarcotte@inverse.ca>
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 <jraby@inverse.ca>
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 <lmarcotte@inverse.ca>
Date: Fri Sep 27 15:54:11 2013 -0400
Fix for bug #2386
M SoObjects/SOGo/SOGoUser.m
commit 84e999229bd2e0ca5c76b613dbfab7b15432bfcc
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
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 <flachapelle@inverse.ca>
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 <flachapelle@inverse.ca>
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 <lmarcotte@inverse.ca>
Date: Fri Sep 27 10:00:39 2013 -0400
Fix for bug #2221
M UI/WebServerResources/SchedulerUI.js
commit 1e484814261aac19322a2daebee6556bdfa126d6
Author: Jean Raby <jraby@inverse.ca>
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 <jraby@inverse.ca>
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 <lmarcotte@inverse.ca>
Date: Wed Sep 25 16:02:13 2013 -0400
Fix for bug #2399
M SoObjects/Appointments/SOGoAppointmentFolder.m
commit 55052ea36f1573e60d0cad9266ded0b0733eaefa
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Wed Sep 25 14:40:48 2013 -0400
Fix for bug #2240
M SOPE/NGCards/iCalToDo.m
commit 99d38417cccbe7730a566f7bb7457359bbdf713b
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Wed Sep 25 13:51:42 2013 -0400
Fix for bug #2354
M OpenChange/RTFHandler.m
commit 29eed182a7f795f9fd01466a641bef0ad99e7660
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
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 <lmarcotte@inverse.ca>
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 <lmarcotte@inverse.ca>
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 <lmarcotte@inverse.ca>
Date: Tue Sep 24 09:29:46 2013 -0400
Fix for bug #1275
M SoObjects/SOGo/SOGoGCSFolder.m
commit 28e600a4e6e0b988b23a9c6ad77e26e42d55a163
Author: Jean Raby <jraby@inverse.ca>
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 <lmarcotte@inverse.ca>
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 <jraby@inverse.ca>
Date: Thu Sep 19 11:11:29 2013 -0400
update NEWS. ldap fixes
M NEWS
commit 5b77c2b7246fa584e7e81a151270a155e0a0bf39
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
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 <lmarcotte@inverse.ca>
Date: Thu Sep 19 09:56:28 2013 -0400
Fix for bug #1935
M OpenChange/MAPIStoreMailVolatileMessage.m
commit 7ddc1b9e2d2696e80a3d9e81e96dc5a0ff81b738
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
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 <flachapelle@inverse.ca>
Date: Tue Sep 17 11:17:40 2013 -0400
Update NEWS file
M NEWS
commit 27445d3b85af9bf0d7aafa03e478ccc867ed5234
Author: Jean Raby <jraby@inverse.ca>
Date: Tue Sep 17 09:27:46 2013 -0400
update news
M NEWS
commit 60d6abe542cbed0bb4017edd404971b092627f36
Author: Jean Raby <jraby@inverse.ca>
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 <lmarcotte@inverse.ca>
Date: Mon Sep 16 11:21:23 2013 -0400
Updated NEWS file regarding previous commit
M NEWS
commit 193720cfbbdf67f871ad561024407db656fe4107
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
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 <jraby@inverse.ca>
Date: Fri Sep 13 11:24:16 2013 -0400
update with latest fixes
M NEWS
commit 906985c1f3ea9ee59a346a153d2f570aad684b80
Author: Jean Raby <jraby@inverse.ca>
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 <jraby@inverse.ca>
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 <jraby@inverse.ca>
Date: Fri Sep 13 11:13:02 2013 -0400
whitespace tabkill
M SoObjects/Contacts/SOGoFolder+CardDAV.m
commit 3c6c90d4346ce19e3245466d22ee3f659c1ac8e9
Author: Francis Lachapelle <flachapelle@inverse.ca>
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 <flachapelle@inverse.ca>
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 <flachapelle@inverse.ca>
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 <jraby@inverse.ca>
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 <jraby@inverse.ca>
Date: Tue Sep 10 13:58:04 2013 -0400
Next version: 2.1.0
M NEWS
M Version
commit df42ab2a46f1c4cb520bcfa208cf2f2569678776
Author: Jean Raby <jraby@inverse.ca>
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 <jraby@inverse.ca>
Date: Fri Sep 6 13:49:04 2013 -0400
Update news
M NEWS
commit cd4abe4b5b3c085b2d0b7fa93633fcbea4470417
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Fri Sep 6 13:48:44 2013 -0400
Fix for bug 2398
M OpenChange/RTFHandler.m
commit 69b0f9fcbf078c0a0ddc8249b89d702222e497e9
Author: Francis Lachapelle <flachapelle@inverse.ca>
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 <jraby@inverse.ca>
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 <jraby@inverse.ca>
Date: Thu Aug 29 15:51:05 2013 -0400
updated News
M NEWS
commit e9d8b729b6131af5abbdd46df070838644ee7908
Author: Jean Raby <jraby@inverse.ca>
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 <jraby@inverse.ca>
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 <jraby@inverse.ca>
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 <jraby@inverse.ca>
Date: Wed Aug 28 10:05:36 2013 -0400
ignore pyc files and config.py
M .gitignore
commit 9fd6f75c4e876972b2e223fc76dd8b2edb5cff0a
Author: Jean Raby <jraby@inverse.ca>
Date: Wed Aug 28 09:47:10 2013 -0400
Update crontab for SMTP AUTH credentials
M Scripts/sogo.cron
commit b96f25f99f16bf747e625dad3f29d93802b57d03
Author: Jean Raby <jraby@inverse.ca>
Date: Tue Aug 27 14:44:28 2013 -0400
updated NEWS
M NEWS
commit e6ab0a590a7776331270f02a83cd123d41f14c1f
Author: Jean Raby <jraby@inverse.ca>
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 <jraby@inverse.ca>
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 <jraby@inverse.ca>
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 <jraby@inverse.ca>
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 <jraby@inverse.ca>
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 <flachapelle@inverse.ca>
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 <flachapelle@inverse.ca>
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 <jraby@inverse.ca>
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 <flachapelle@inverse.ca>
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 <lmarcotte@inverse.ca>
Date: Fri Aug 9 11:39:15 2013 -0400
Fix for bug #1431
M UI/Scheduler/UIxCalUserRightsEditor.m
commit 7b90b892fc0a1a2f333a82c49759812725556ffb
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Wed Aug 7 08:49:59 2013 -0400
Fix for bug #2385
M UI/MailPartViewers/UIxMailPartViewer.m
commit b654ffb806d370467991111f93f55df2854eb82b
Author: Jean Raby <jraby@inverse.ca>
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 <jraby@inverse.ca>
Date: Fri Aug 2 15:41:24 2013 -0400
Add depth support to CalendarMultiget
M Tests/Integration/webdavlib.py
commit 7eb8b9c2c36534a5cd2c851b83b9b95bc89e807e
Author: Jean Raby <jraby@inverse.ca>
Date: Fri Aug 2 09:51:41 2013 -0400
Add SxVMemLimit to sogo.conf
M Scripts/sogo.conf
commit 3877f3001fb5e9e425b495599e7618596136efe9
Author: Jean Raby <jraby@inverse.ca>
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 <lmarcotte@inverse.ca>
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 <lmarcotte@inverse.ca>
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 <lmarcotte@inverse.ca>
Date: Wed Jul 24 10:54:55 2013 -0400
Fix for old runtimes.
M OpenChange/BSONCodec.m
commit bd776152db4f05ba13a58795f2eae0fc98b4e9cb
Author: Francis Lachapelle <flachapelle@inverse.ca>
Date: Tue Jul 23 10:02:13 2013 -0400
Update ChangeLog
M ChangeLog
commit 734c164ae02df4e2313003d143486eff67f42c5e commit 734c164ae02df4e2313003d143486eff67f42c5e
Author: Ludovic Marcotte <lmarcotte@inverse.ca> Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Tue Jul 23 09:25:24 2013 -0400 Date: Tue Jul 23 09:25:24 2013 -0400

62
NEWS
View file

@ -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) 2.0.7 (2013-07-19)
------------------ ------------------
@ -19,15 +69,15 @@ Bug fixes
------------------ ------------------
Bug fixes Bug fixes
- Properly escape the foldername to avoid XSS issues - properly escape the foldername to avoid XSS issues
- Fix loading of MSExchangeFreeBusySOAPResponseMap - fixed loading of MSExchangeFreeBusySOAPResponseMap
2.0.6a (2013-06-25) 2.0.6a (2013-06-25)
------------------ ------------------
Bug fixes Bug fixes
- Documentation fixes - documentation fixes
- Added missing file for CAS single logout - added missing file for CAS single logout
2.0.6 (2013-06-21) 2.0.6 (2013-06-21)
------------------ ------------------
@ -58,8 +108,8 @@ Bug fixes
------------------ ------------------
Bug fixes Bug fixes
- Fixed an issue when parsing user CN with leading or trailing spaces (#2287) - 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 a crash that occured when saving contacts or tasks via Outlook
2.0.5 (2013-04-11) 2.0.5 (2013-04-11)
------------------ ------------------

View file

@ -85,13 +85,17 @@ static NSDictionary *BSONTypes()
@implementation NSObject (BSONObjectCoding) @implementation NSObject (BSONObjectCoding)
- (NSData *) BSONEncode - (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."]; [NSException raise: NSInvalidArgumentException format: @"BSON encoding is only valid on objects conforming to the BSONObjectEncoding protocol."];
id <BSONObjectCoding> myself = (id <BSONObjectCoding>) self; id <BSONObjectCoding> myself = (id <BSONObjectCoding>) self;
NSMutableDictionary *values = [[myself BSONDictionary] mutableCopy]; 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]); 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]; [values setObject: [NSData dataWithBytes: (void *)className length: strlen(className)] forKey: CLASS_NAME_MARKER];
NSData *retval = [values BSONEncode]; NSData *retval = [values BSONEncode];
[values release]; [values release];

View file

@ -23,6 +23,7 @@
#import <Foundation/NSArray.h> #import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h> #import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDictionary.h> #import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h> #import <Foundation/NSValue.h>
#import <NGExtensions/NSObject+Logs.h> #import <NGExtensions/NSObject+Logs.h>
@ -34,6 +35,7 @@
#import "MAPIStoreDBMessage.h" #import "MAPIStoreDBMessage.h"
#import "MAPIStoreTypes.h" #import "MAPIStoreTypes.h"
#import "NSObject+MAPIStore.h" #import "NSObject+MAPIStore.h"
#import "NSString+MAPIStore.h"
#undef DEBUG #undef DEBUG
#include <mapistore/mapistore.h> #include <mapistore/mapistore.h>
@ -99,6 +101,21 @@
return objectVersion; 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 - (int) getProperties: (struct mapistore_property_data *) data
withTags: (enum MAPITAGS *) tags withTags: (enum MAPITAGS *) tags
andCount: (uint16_t) columnCount andCount: (uint16_t) columnCount

View file

@ -259,7 +259,6 @@ static Class NSNumberK;
} }
} }
*/ */
- (void) _setChangeKey: (NSData *) changeKey - (void) _setChangeKey: (NSData *) changeKey
forMessageEntry: (NSMutableDictionary *) messageEntry forMessageEntry: (NSMutableDictionary *) messageEntry
inChangeListOnly: (BOOL) inChangeListOnly inChangeListOnly: (BOOL) inChangeListOnly
@ -462,6 +461,9 @@ static Class NSNumberK;
[messageEntry setObject: changeNumber forKey: @"version"]; [messageEntry setObject: changeNumber forKey: @"version"];
newChangeNum = [changeNumber unsignedLongLongValue]; 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]; changeKey = [self getReplicaKeyFromGlobCnt: newChangeNum >> 16];
[self _setChangeKey: changeKey forMessageEntry: messageEntry [self _setChangeKey: changeKey forMessageEntry: messageEntry
inChangeListOnly: NO]; inChangeListOnly: NO];

View file

@ -24,6 +24,7 @@
#import <Foundation/NSDictionary.h> #import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h> #import <Foundation/NSString.h>
#import <Foundation/NSURL.h> #import <Foundation/NSURL.h>
#import <NGImap4/NSString+Imap4.h>
#import <NGExtensions/NSString+misc.h> #import <NGExtensions/NSString+misc.h>
#import <Mailer/SOGoMailAccount.h> #import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoMailFolder.h> #import <Mailer/SOGoMailFolder.h>
@ -156,7 +157,7 @@ MakeDisplayFolderName (NSString *folderName)
stringData = [NSString stringWithFormat: @"%@%@", stringData = [NSString stringWithFormat: @"%@%@",
urlBase, [currentName stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; urlBase, [currentName stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
context->url = [stringData asUnicodeInMemCtx: context]; context->url = [stringData asUnicodeInMemCtx: context];
stringData = [[currentName substringFromIndex: 6] fromCSSIdentifier]; stringData = [[[currentName substringFromIndex: 6] fromCSSIdentifier] stringByDecodingImap4FolderName];
context->name = [stringData asUnicodeInMemCtx: context]; context->name = [stringData asUnicodeInMemCtx: context];
context->main_folder = false; context->main_folder = false;
context->role = MAPISTORE_MAIL_ROLE; context->role = MAPISTORE_MAIL_ROLE;
@ -188,7 +189,7 @@ MakeDisplayFolderName (NSString *folderName)
if ([newFolder create]) if ([newFolder create])
mapistoreURI = [NSString stringWithFormat: @"sogo://%@:%@@mail/%@/", mapistoreURI = [NSString stringWithFormat: @"sogo://%@:%@@mail/%@/",
userName, userName, userName, userName,
[folderName stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; [[folderName stringByEncodingImap4FolderName] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
else else
mapistoreURI = nil; mapistoreURI = nil;
[MAPIApp setUserContext: nil]; [MAPIApp setUserContext: nil];

View file

@ -36,6 +36,7 @@
#import <NGExtensions/NSString+misc.h> #import <NGExtensions/NSString+misc.h>
#import <NGImap4/NGImap4Connection.h> #import <NGImap4/NGImap4Connection.h>
#import <NGImap4/NGImap4Client.h> #import <NGImap4/NGImap4Client.h>
#import <NGImap4/NSString+Imap4.h>
#import <Mailer/SOGoDraftsFolder.h> #import <Mailer/SOGoDraftsFolder.h>
#import <Mailer/SOGoMailAccount.h> #import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoMailAccounts.h> #import <Mailer/SOGoMailAccounts.h>
@ -177,7 +178,7 @@ static Class SOGoMailFolderK, MAPIStoreMailFolderK, MAPIStoreOutboxFolderK;
if (folderName) if (folderName)
{ {
nameInContainer = [NSString stringWithFormat: @"folder%@", nameInContainer = [NSString stringWithFormat: @"folder%@",
[folderName asCSSIdentifier]]; [[folderName stringByEncodingImap4FolderName] asCSSIdentifier]];
newFolder = [SOGoMailFolderK objectWithName: nameInContainer newFolder = [SOGoMailFolderK objectWithName: nameInContainer
inContainer: sogoObject]; inContainer: sogoObject];
if ([newFolder create]) if ([newFolder create])
@ -315,7 +316,7 @@ static Class SOGoMailFolderK, MAPIStoreMailFolderK, MAPIStoreOutboxFolderK;
if (![subfolderName hasPrefix: @"folder"]) if (![subfolderName hasPrefix: @"folder"])
abort (); abort ();
strippedName = [subfolderName substringFromIndex: 6]; strippedName = [[subfolderName substringFromIndex: 6] stringByDecodingImap4FolderName];
[representation appendFormat: @"/%@", strippedName]; [representation appendFormat: @"/%@", strippedName];
return representation; return representation;

View file

@ -543,6 +543,7 @@ FillMessageHeadersFromProperties (NGMutableHashMap *headers,
NSDictionary *recipients; NSDictionary *recipients;
NSUInteger type, bccLimit; NSUInteger type, bccLimit;
SOGoUser *activeUser; SOGoUser *activeUser;
NSNumber *priority;
activeUser activeUser
= [SOGoUser = [SOGoUser
@ -596,6 +597,21 @@ FillMessageHeadersFromProperties (NGMutableHashMap *headers,
[headers addObject: [date rfc822DateString] forKey: @"date"]; [headers addObject: [date rfc822DateString] forKey: @"date"];
} }
[headers addObject: @"1.0" forKey: @"MIME-Version"]; [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 * static NSArray *

View file

@ -284,6 +284,9 @@ static Class NSExceptionK, MAPIStoreFolderK;
return MAPISTORE_SUCCESS; return MAPISTORE_SUCCESS;
} }
//
// The GlobCnt is 6 bytes long.
//
- (NSData *) getReplicaKeyFromGlobCnt: (uint64_t) objectCnt - (NSData *) getReplicaKeyFromGlobCnt: (uint64_t) objectCnt
{ {
struct mapistore_connection_info *connInfo; struct mapistore_connection_info *connInfo;

View file

@ -148,6 +148,7 @@ static void _fillFlatUIDWithGUID (struct FlatUID_r *flatUID, const struct GUID *
- (struct XID *) asXIDInMemCtx: (void *) memCtx - (struct XID *) asXIDInMemCtx: (void *) memCtx
{ {
struct XID *xid; struct XID *xid;
uint8_t *bytes;
NSUInteger max; NSUInteger max;
max = [self length]; max = [self length];
@ -158,7 +159,9 @@ static void _fillFlatUIDWithGUID (struct FlatUID_r *flatUID, const struct GUID *
[self _extractGUID: &xid->GUID]; [self _extractGUID: &xid->GUID];
xid->Size = max - 16; 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 else
{ {

View file

@ -694,10 +694,18 @@ const unsigned short ansicpg874[256] = {
} }
else if (*(_bytes+1) == '*') else if (*(_bytes+1) == '*')
{ {
while (*_bytes != '}') int cc = 1;
do
{ {
if (*_bytes == '{')
cc++;
if (*_bytes == '}')
cc--;
ADVANCE; ADVANCE;
} }
while (cc != 0);
continue; continue;
} }
@ -793,6 +801,10 @@ const unsigned short ansicpg874[256] = {
{ {
// ignore // ignore
} }
else if ([s hasPrefix: @"fromtext"])
{
// ignore
}
else if ([s hasPrefix: @"f"] && [s length] > 1) else if ([s hasPrefix: @"f"] && [s length] > 1)
{ {
RTFFontInfo *fontInfo; RTFFontInfo *fontInfo;

View file

@ -27,7 +27,7 @@
#import "EOQualifier+GCS.h" #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__) # define sel_eq(__A__,__B__) sel_isEqual(__A__,__B__)
#endif #endif

View file

@ -44,7 +44,7 @@
#import "EOQualifier+GCS.h" #import "EOQualifier+GCS.h"
#import "GCSStringFormatter.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__) # define sel_eq(__A__,__B__) sel_isEqual(__A__,__B__)
#endif #endif

View file

@ -72,7 +72,7 @@
- (void) setCompleted: (NSCalendarDate *) newCompletedDate - (void) setCompleted: (NSCalendarDate *) newCompletedDate
{ {
[(iCalDateTime *) [self uniqueChildWithTag: @"completed"] [(iCalDateTime *) [self uniqueChildWithTag: @"completed"]
setDate: newCompletedDate]; setDateTime: newCompletedDate];
if (newCompletedDate) if (newCompletedDate)
[self setStatus: @"COMPLETED"]; [self setStatus: @"COMPLETED"];
else else

View file

@ -4,7 +4,7 @@ set -o pipefail
#set -x #set -x
PROGNAME="$(basename $0)" PROGNAME="$(basename $0)"
BACKUP_DIR=/home/sogo/backups BACKUP_DIR=~sogo/backups
SOGO_TOOL=/usr/sbin/sogo-tool SOGO_TOOL=/usr/sbin/sogo-tool
DAYS_TO_KEEP="30" DAYS_TO_KEEP="30"

View file

@ -1,5 +1,5 @@
# The amount of processes that should be spawned (Default: 1) # The amount of processes that should be spawned (Default: 3)
# PREFORK=1 # PREFORK=3
# The name of the account under which SOGo will be running (Default: sogo) # The name of the account under which SOGo will be running (Default: sogo)
# USER=sogo # USER=sogo

View file

@ -34,7 +34,7 @@ DAEMON=/usr/sbin/sogod
DESC="SOGo" DESC="SOGo"
USER=$NAME USER=$NAME
PREFORK=1 PREFORK=3
PIDFILE=/var/run/$NAME/$NAME.pid PIDFILE=/var/run/$NAME/$NAME.pid
LOGFILE=/var/log/$NAME/$NAME.log LOGFILE=/var/log/$NAME/$NAME.log

View file

@ -37,7 +37,7 @@ DAEMON=/usr/sbin/sogod
DESC="SOGo" DESC="SOGo"
USER=$NAME USER=$NAME
PREFORK=1 PREFORK=3
PIDFILE=/var/run/$NAME/$NAME.pid PIDFILE=/var/run/$NAME/$NAME.pid
LOGFILE=/var/log/$NAME/$NAME.log LOGFILE=/var/log/$NAME/$NAME.log

View file

@ -92,13 +92,14 @@
// PublicDAndTViewer, // PublicDAndTViewer,
// ConfidentialDAndTViewer // ConfidentialDAndTViewer
//); //);
//SOGoSuperUsernames = (sogo1, sogo2); //This is an array - keep the parens! //SOGoSuperUsernames = (sogo1, sogo2); // This is an array - keep the parens!
//SxVMemLimit = 384
/* Debug */ /* Debug */
//SOGoDebugRequests = YES;
//SoDebugBaseURL = YES; //SoDebugBaseURL = YES;
//ImapDebugEnabled = YES; //ImapDebugEnabled = YES;
//LDAPDebugEnabled = YES; //LDAPDebugEnabled = YES;
//SOGoDebugRequests = YES;
//PGDebugEnabled = YES; //PGDebugEnabled = YES;
//MySQL4DebugEnabled = YES; //MySQL4DebugEnabled = YES;
//SOGoUIxDebugEnabled = YES; //SOGoUIxDebugEnabled = YES;

View file

@ -10,6 +10,8 @@
#* * * * * sogo /usr/sbin/sogo-tool expire-sessions 60 #* * * * * sogo /usr/sbin/sogo-tool expire-sessions 60
# Email alarms - runs every minutes # 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 #* * * * * sogo /usr/sbin/sogo-ealarms-notify
# Daily backups # Daily backups

View file

@ -4,4 +4,4 @@
SOGOSPOOL=/var/spool/sogo SOGOSPOOL=/var/spool/sogo
/usr/sbin/tmpwatch 24 "$SOGOSPOOL" /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

View file

@ -8,23 +8,15 @@ vtodo_class1 = "(Privat oppgave)";
vtodo_class2 = "(Konfidensiell oppgave)"; vtodo_class2 = "(Konfidensiell oppgave)";
/* Receipts */ /* Receipts */
"Title:" = "Tittel:"; "The event \"%{Summary}\" was created" = "Hendelsen \"%{Summary}\" ble opprettet";
"Start:" = "Start:"; "The event \"%{Summary}\" was deleted" = "Hendelsen \"%{Summary}\" ble slettet";
"End:" = "Slutt:"; "The event \"%{Summary}\" was updated" = "Hendelsen \"%{Summary}\" ble oppdatert";
"The following attendees(s) were notified:" = "Følgende deltaker(e) ble varslet:";
"Receipt: users invited to a meeting" = "Kvittering: brukere invitert til et møte"; "The following attendees(s) were added:" = "Følgende deltaker(e) ble lagt til:";
"You have invited the following attendees(s):" = "Du har invitert følende deltagere:"; "The following attendees(s) were removed:" = "Følgende deltaker(e) ble fjernet:";
"... 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:";
/* IMIP messages */ /* IMIP messages */
"calendar_label" = "Kalender:";
"startDate_label" = "Start:"; "startDate_label" = "Start:";
"endDate_label" = "Slutt:"; "endDate_label" = "Slutt:";
"due_label" = "Forfallsdato:"; "due_label" = "Forfallsdato:";
@ -35,27 +27,31 @@ vtodo_class2 = "(Konfidensiell oppgave)";
/* Invitation */ /* Invitation */
"Event Invitation: \"%{Summary}\"" = "Hendelseinvitasjon: \"%{Summary}\""; "Event Invitation: \"%{Summary}\"" = "Hendelseinvitasjon: \"%{Summary}\"";
"(sent by %{SentBy}) " = "(sendt av %{SentBy})"; "(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}\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} %{StartTime}\nSlutt: %{EndDate} %{EndTime}\nBeskrivelse: %{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 */ /* Deletion */
"Event Cancelled: \"%{Summary}\"" = "Hendelse avlyst: \"%{Summary}\""; "Event Cancelled: \"%{Summary}\"" = "Hendelse avlyst: \"%{Summary}\"";
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" "%{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}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 */ /* Update */
"The appointment \"%{Summary}\" for the %{OldStartDate} has changed" "The appointment \"%{Summary}\" for the %{OldStartDate} has changed"
= ""; = "Avtalen \"%{Summary}\", %{OldStartDate} er endret";
"The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed" "The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed"
= "Avtalen \"%{Summary}\" for %{OldStartDate} klokken %{OldStartTime} er endret."; = "Avtalen \"%{Summary}\" for %{OldStartDate} klokken %{OldStartTime} er endret.";
"The following parameters have changed in the \"%{Summary}\" meeting:" "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." "Please accept or decline those changes."
= "Vennligst godta eller avvis endringene."; = "Vennligst godta eller avvis endringene.";
/* Reply */ /* 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}has accepted your event invitation."
= "%{Attendee} %{SentByText} har godtatt invitasjonen."; = "%{Attendee} %{SentByText} har godtatt invitasjonen.";
"%{Attendee} %{SentByText}has declined your event invitation." "%{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}has delegated the invitation to %{Delegate}."
= "%{Attendee} %{SentByText} har delegert invitasjonen til %{Delegate}."; = "%{Attendee} %{SentByText} har delegert invitasjonen til %{Delegate}.";
"%{Attendee} %{SentByText}has not yet decided upon your event invitation." "%{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 */ /* 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}.";

View file

@ -2236,10 +2236,39 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
return @""; 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]).
<!ELEMENT resource-id (href)>
...
so we must STRIP any username prefix, to make the ID global.
*/
- (NSString *) davResourceId - (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:%@", return [NSString stringWithFormat: @"urn:uuid:%@:calendars:%@",
[self ownerInContext: context], [self nameInContainer]]; [self ownerInContext: context], name];
} }
- (NSArray *) davScheduleCalendarTransparency - (NSArray *) davScheduleCalendarTransparency

View file

@ -1,8 +1,6 @@
/* SOGoAppointmentFolders.h - this file is part of SOGo /* SOGoAppointmentFolders.h - this file is part of SOGo
* *
* Copyright (C) 2007 Inverse inc. * Copyright (C) 2007-2013 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
* This file is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -35,8 +33,8 @@
NSMutableArray *folderObjectKeys; NSMutableArray *folderObjectKeys;
} }
- (SOGoWebAppointmentFolder *) newWebCalendarWithName: (NSString *) folderDisplayName - (SOGoWebAppointmentFolder *) newWebCalendarWithURL: (NSString *) urlString
atURL: (NSString *) url; nameInContainer: (NSString *) name;
- (void) reloadWebCalendars: (BOOL) forceReload; - (void) reloadWebCalendars: (BOOL) forceReload;

View file

@ -1,9 +1,7 @@
/* SOGoAppointmentFolders.m - this file is part of SOGo /* SOGoAppointmentFolders.m - this file is part of SOGo
* *
* Copyright (C) 2007-2010 Inverse inc. * Copyright (C) 2007-2013 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
* This file is free software; you can redistribute it and/or modify * 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 * 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]; return [self labelForKey: @"Personal Calendar" inContext: context];
} }
- (SOGoWebAppointmentFolder *)
newWebCalendarWithName: (NSString *) folderDisplayName
atURL: (NSString *) urlString - (SOGoWebAppointmentFolder *) newWebCalendarWithURL: (NSString *) urlString
nameInContainer: (NSString *) name
{ {
NSException *error; NSString *folderDisplayName, *tmp;
SOGoAppointmentFolder *aptFolder;
SOGoWebAppointmentFolder *webCalendar; SOGoWebAppointmentFolder *webCalendar;
NSString *name; SOGoAppointmentFolder *aptFolder;
NSException *error;
NSURL *url; NSURL *url;
folderDisplayName = [self labelForKey: @"Web Calendar"];
webCalendar = nil; 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) if ([folderDisplayName length] > 0 && [urlString length] > 0)
{ {
url = [NSURL URLWithString: urlString]; url = [NSURL URLWithString: urlString];
@ -154,6 +163,10 @@ static SoSecurityManager *sm = nil;
nameInContainer: &name]; nameInContainer: &name];
if (!error) 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 = [subFolders objectForKey: name];
[aptFolder setFolderPropertyValue: urlString [aptFolder setFolderPropertyValue: urlString
inCategory: @"WebCalendars"]; inCategory: @"WebCalendars"];
@ -561,9 +574,25 @@ static SoSecurityManager *sm = nil;
folder = [SOGoWebAppointmentFolder folder = [SOGoWebAppointmentFolder
folderWithSubscriptionReference: ref folderWithSubscriptionReference: ref
inContainer: self]; inContainer: self];
if (folder
&& (forceReload || [folder reloadOnLogin])) if (forceReload || [folder reloadOnLogin] || !folder)
[folder loadWebCalendar]; {
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];
}
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2006-2012 Inverse inc. Copyright (C) 2006-2013 Inverse inc.
Copyright (C) 2000-2005 SKYRIX Software AG Copyright (C) 2000-2005 SKYRIX Software AG
This file is part of SOGo. This file is part of SOGo.
@ -142,12 +142,12 @@
- (NSString *) location - (NSString *) location
{ {
return [[apt location] stringByEscapingHTMLString]; return [apt location];
} }
- (NSString *) summary - (NSString *) summary
{ {
return [[apt summary] stringByEscapingHTMLString]; return [apt summary];
} }
- (void) setOrganizerName: (NSString *) theString - (void) setOrganizerName: (NSString *) theString

View file

@ -294,7 +294,9 @@
contact = [contacts lastObject]; contact = [contacts lastObject];
email = [contact valueForKey: @"c_email"]; email = [contact valueForKey: @"c_email"];
source = [contact objectForKey: @"source"]; source = [contact objectForKey: @"source"];
if ([email length] && [source MSExchangeHostname]) if ([email length]
&& [source conformsToProtocol: @protocol (SOGoDNSource)]
&& [source MSExchangeHostname])
{ {
exchangeFreeBusy = [[MSExchangeFreeBusy alloc] init]; exchangeFreeBusy = [[MSExchangeFreeBusy alloc] init];
[exchangeFreeBusy autorelease]; [exchangeFreeBusy autorelease];

View file

@ -64,6 +64,9 @@
return isStillRelevent; return isStillRelevent;
} }
//
//
//
- (NSMutableDictionary *) quickRecord - (NSMutableDictionary *) quickRecord
{ {
NSMutableDictionary *row; NSMutableDictionary *row;
@ -88,7 +91,15 @@
title = [self summary]; title = [self summary];
if (![title isNotNull]) if (![title isNotNull])
title = @""; title = @"";
if ([title length] > 1000)
title = [title substringToIndex: 1000];
location = [self location]; location = [self location];
if ([location length] > 255)
location = [location substringToIndex: 255];
sequence = [self sequence]; sequence = [self sequence];
accessClass = [self symbolicAccessClass]; accessClass = [self symbolicAccessClass];
isAllDay = [self isAllDay]; isAllDay = [self isAllDay];

View file

@ -21,6 +21,7 @@
*/ */
#import <Foundation/NSArray.h> #import <Foundation/NSArray.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSDictionary.h> #import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h> #import <Foundation/NSEnumerator.h>
@ -65,7 +66,7 @@
@"<D:href>"]; @"<D:href>"];
[r appendContentString: baseURL]; [r appendContentString: baseURL];
if (![baseURL hasSuffix: @"/"]) if (![baseURL hasSuffix: @"/"])
[r appendContentString: @"/"]; [r appendContentString: @"/"];
[r appendContentString: name]; [r appendContentString: name];
[r appendContentString: @"</D:href>" [r appendContentString: @"</D:href>"
@"<D:propstat>" @"<D:propstat>"
@ -89,9 +90,10 @@
- (void) _appendComponentsMatchingFilters: (NSArray *) filters - (void) _appendComponentsMatchingFilters: (NSArray *) filters
toResponse: (WOResponse *) response toResponse: (WOResponse *) response
context: (id) localContext context: (id) localContext
{ {
unsigned int count, max; unsigned int count,i , max;
NSAutoreleasePool *pool;
NSDictionary *currentFilter, *contact; NSDictionary *currentFilter, *contact;
NSEnumerator *contacts; NSEnumerator *contacts;
NSString *baseURL, *domain; NSString *baseURL, *domain;
@ -103,16 +105,27 @@
for (count = 0; count < max; count++) for (count = 0; count < max; count++)
{ {
currentFilter = [filters objectAtIndex: count]; currentFilter = [filters objectAtIndex: count];
contacts = [[(id<SOGoContactFolder>)self lookupContactsWithFilter: [[currentFilter allValues] lastObject] contacts =
onCriteria: @"name_or_address" [[(id<SOGoContactFolder>)self lookupContactsWithFilter: [[currentFilter allValues] lastObject]
sortBy: @"c_givenname" onCriteria: @"name_or_address"
ordering: NSOrderedDescending sortBy: @"c_givenname"
inDomain: domain] ordering: NSOrderedDescending
objectEnumerator]; inDomain: domain] objectEnumerator];
pool = [[NSAutoreleasePool alloc] init];
i = 0;
while ((contact = [contacts nextObject])) 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]; newString = [theString lowercaseString];
return ([newString isEqualToString: @"sn"] return ([newString isEqualToString: @"sn"]
|| [newString isEqualToString: @"givenname"] || [newString isEqualToString: @"givenname"]
|| [newString isEqualToString: @"email"] || [newString isEqualToString: @"email"]
|| [newString isEqualToString: @"mail"] || [newString isEqualToString: @"mail"]
|| [newString isEqualToString: @"telephonenumber"]); || [newString isEqualToString: @"telephonenumber"]);
} }
- (NSDictionary *) _parseContactFilter: (id <DOMElement>) filterElement - (NSDictionary *) _parseContactFilter: (id <DOMElement>) filterElement
@ -145,12 +158,12 @@
ranges = [filterElement getElementsByTagName: @"text-match"]; ranges = [filterElement getElementsByTagName: @"text-match"];
if ([(NSArray *) ranges count] if ([(NSArray *) ranges count]
&& [(NSArray *) [[ranges objectAtIndex: 0] childNodes] count]) && [(NSArray *) [[ranges objectAtIndex: 0] childNodes] count])
{ {
filterData = [NSMutableDictionary dictionary]; filterData = [NSMutableDictionary dictionary];
[filterData setObject: [(NGDOMNode *)[ranges objectAtIndex: 0] textValue] [filterData setObject: [(NGDOMNode *)[ranges objectAtIndex: 0] textValue]
forKey: [filterElement attribute: @"name"]]; forKey: [filterElement attribute: @"name"]];
} }
} }
return filterData; return filterData;
@ -166,7 +179,7 @@
filters = [NSMutableArray array]; filters = [NSMutableArray array];
children = [(NSArray *)[parentNode getElementsByTagName: @"prop-filter"] children = [(NSArray *)[parentNode getElementsByTagName: @"prop-filter"]
objectEnumerator]; objectEnumerator];
while ((node = [children nextObject])) while ((node = [children nextObject]))
{ {
filter = [self _parseContactFilter: node]; filter = [self _parseContactFilter: node];
@ -193,7 +206,7 @@
[self _appendComponentsMatchingFilters: filters [self _appendComponentsMatchingFilters: filters
toResponse: r toResponse: r
context: queryContext]; context: queryContext];
[r appendContentString: @"</D:multistatus>"]; [r appendContentString: @"</D:multistatus>"];
return r; return r;

View file

@ -57,6 +57,8 @@ Mailer_RESOURCE_FILES += \
SOGoMailDutchReply.wo \ SOGoMailDutchReply.wo \
SOGoMailEnglishForward.wo \ SOGoMailEnglishForward.wo \
SOGoMailEnglishReply.wo \ SOGoMailEnglishReply.wo \
SOGoMailFinnishForward.wo \
SOGoMailFinnishReply.wo \
SOGoMailFrenchForward.wo \ SOGoMailFrenchForward.wo \
SOGoMailFrenchReply.wo \ SOGoMailFrenchReply.wo \
SOGoMailGermanForward.wo \ SOGoMailGermanForward.wo \
@ -90,6 +92,7 @@ Mailer_RESOURCE_FILES += \
ADDITIONAL_INCLUDE_DIRS += -I../../SOPE/ ADDITIONAL_INCLUDE_DIRS += -I../../SOPE/
ADDITIONAL_INCLUDE_DIRS += $(shell xml2-config --cflags)
ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/ ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/
-include GNUmakefile.preamble -include GNUmakefile.preamble

View file

@ -1,8 +1,6 @@
/* NSString+Mail.h - this file is part of SOGo /* NSString+Mail.h - this file is part of SOGo
* *
* Copyright (C) 2007 Inverse inc. * Copyright (C) 2007-2013 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
* This file is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

View file

@ -1,8 +1,6 @@
/* NSString+Mail.m - this file is part of SOGo /* NSString+Mail.m - this file is part of SOGo
* *
* Copyright (C) 2008 Inverse inc. * Copyright (C) 2008-2013 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
* This file is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -33,10 +31,12 @@
#import <NGExtensions/NSString+misc.h> #import <NGExtensions/NSString+misc.h>
#import <NGExtensions/NSObject+Logs.h> #import <NGExtensions/NSObject+Logs.h>
#include <libxml/encoding.h>
#import "NSString+Mail.h" #import "NSString+Mail.h"
#import "NSData+Mail.h" #import "NSData+Mail.h"
#if 1 #if 0
#define showWhoWeAre() \ #define showWhoWeAre() \
[self logWithFormat: @"invoked '%@'", NSStringFromSelector (_cmd)] [self logWithFormat: @"invoked '%@'", NSStringFromSelector (_cmd)]
#else #else
@ -97,6 +97,11 @@
return self; return self;
} }
- (xmlCharEncoding) contentEncoding
{
return XML_CHAR_ENCODING_UTF8;
}
- (void) dealloc - (void) dealloc
{ {
[ignoreContentTags release]; [ignoreContentTags release];
@ -234,11 +239,12 @@
} }
- (void) characters: (unichar *) characters - (void) characters: (unichar *) characters
length: (int) length length: (NSUInteger) length
{ {
if (!ignoreContent) if (!ignoreContent)
[result appendString: [NSString stringWithCharacters: characters {
length: length]]; [result appendString: [NSString stringWithCharacters: characters length: length]];
}
} }
- (void) ignorableWhitespace: (unichar *) whitespaces - (void) ignorableWhitespace: (unichar *) whitespaces
@ -339,14 +345,17 @@
- (NSString *) htmlToText - (NSString *) htmlToText
{ {
id <NSObject, SaxXMLReader> parser;
_SOGoHTMLToTextContentHandler *handler; _SOGoHTMLToTextContentHandler *handler;
id <NSObject, SaxXMLReader> parser;
NSData *d;
parser = [[SaxXMLReaderFactory standardXMLReaderFactory] parser = [[SaxXMLReaderFactory standardXMLReaderFactory]
createXMLReaderForMimeType: @"text/html"]; createXMLReaderForMimeType: @"text/html"];
handler = [_SOGoHTMLToTextContentHandler htmlToTextContentHandler]; handler = [_SOGoHTMLToTextContentHandler htmlToTextContentHandler];
[parser setContentHandler: handler]; [parser setContentHandler: handler];
[parser parseFromSource: self];
d = [self dataUsingEncoding: NSUTF8StringEncoding];
[parser parseFromSource: d];
return [handler result]; return [handler result];
} }

View file

@ -171,12 +171,17 @@ static NSString *headerKeys[] = {@"subject", @"to", @"cc", @"bcc",
@implementation SOGoDraftObject @implementation SOGoDraftObject
static NGMimeType *MultiMixedType = nil; static NGMimeType *MultiMixedType = nil;
static NGMimeType *MultiAlternativeType = nil;
static NSString *userAgent = nil; static NSString *userAgent = nil;
+ (void) initialize + (void) initialize
{ {
MultiMixedType = [NGMimeType mimeType: @"multipart" subType: @"mixed"]; MultiMixedType = [NGMimeType mimeType: @"multipart" subType: @"mixed"];
[MultiMixedType retain]; [MultiMixedType retain];
MultiAlternativeType = [NGMimeType mimeType: @"multipart" subType: @"alternative"];
[MultiAlternativeType retain];
userAgent = [NSString stringWithFormat: @"SOGoMail %@", userAgent = [NSString stringWithFormat: @"SOGoMail %@",
SOGoVersion]; SOGoVersion];
[userAgent retain]; [userAgent retain];
@ -981,8 +986,33 @@ static NSString *userAgent = nil;
return error; 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 - (NGMimeBodyPart *) bodyPartForText
{ {
/* /*
@ -992,25 +1022,14 @@ static NSString *userAgent = nil;
NGMimeBodyPart *bodyPart; NGMimeBodyPart *bodyPart;
/* prepare header of body part */ /* prepare header of body part */
map = [[[NGMutableHashMap alloc] initWithCapacity: 1] autorelease]; map = [[[NGMutableHashMap alloc] initWithCapacity: 1] autorelease];
// TODO: set charset in header! // TODO: set charset in header!
[map setObject: @"text/plain" forKey: @"content-type"];
if (text) if (text)
[map setObject: (isHTML ? htmlContentTypeValue : contentTypeValue) [map setObject: (isHTML ? htmlContentTypeValue : contentTypeValue)
forKey: @"content-type"]; 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 */ /* prepare body content */
bodyPart = [[[NGMimeBodyPart alloc] initWithHeader:map] autorelease]; bodyPart = [[[NGMimeBodyPart alloc] initWithHeader:map] autorelease];
[bodyPart setBody: text]; [bodyPart setBody: text];
@ -1020,31 +1039,28 @@ static NSString *userAgent = nil;
- (NGMimeMessage *) mimeMessageForContentWithHeaderMap: (NGMutableHashMap *) map - (NGMimeMessage *) mimeMessageForContentWithHeaderMap: (NGMutableHashMap *) map
{ {
NGMimeMessage *message; NGMimeMessage *message;
// BOOL addSuffix; id body;
id body;
[map setObject: @"text/plain" forKey: @"content-type"]; message = [[[NGMimeMessage alloc] initWithHeader:map] autorelease];
body = text;
if (body) if (!isHTML)
{ {
// if ([body isKindOfClass:[NSString class]]) [map setObject: contentTypeValue forKey: @"content-type"];
/* Note: just 'utf8' is displayed wrong in Mail.app */ body = text;
[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];
} }
else 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; return message;
} }
@ -1232,13 +1248,38 @@ static NSString *userAgent = nil;
return bodyParts; 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 - (NGMimeMessage *) mimeMultiPartMessageWithHeaderMap: (NGMutableHashMap *) map
andBodyParts: (NSArray *) _bodyParts andBodyParts: (NSArray *) _bodyParts
{ {
NGMimeMessage *message; NGMimeMessage *message;
NGMimeMultipartBody *mBody; NGMimeMultipartBody *mBody;
NGMimeBodyPart *part;
NSEnumerator *e; NSEnumerator *e;
id part;
[map addObject: MultiMixedType forKey: @"content-type"]; [map addObject: MultiMixedType forKey: @"content-type"];
@ -1246,7 +1287,15 @@ static NSString *userAgent = nil;
[message autorelease]; [message autorelease];
mBody = [[NGMimeMultipartBody alloc] initWithPart: message]; mBody = [[NGMimeMultipartBody alloc] initWithPart: message];
part = [self bodyPartForText]; if (!isHTML)
{
part = [self bodyPartForText];
}
else
{
part = [self mimeMultipartAlternative];
}
[mBody addBodyPart: part]; [mBody addBodyPart: part];
e = [_bodyParts objectEnumerator]; e = [_bodyParts objectEnumerator];

View file

@ -1179,7 +1179,7 @@ static NSString *defaultUserID = @"anyone";
stringByAppendingString: [uid substringFromIndex: 1]]; stringByAppendingString: [uid substringFromIndex: 1]];
else if ([[[context activeUser] domainDefaults] forceExternalLoginWithEmail]) else if ([[[context activeUser] domainDefaults] forceExternalLoginWithEmail])
{ {
return [[[context activeUser] primaryIdentity] objectForKey: @"email"]; return [[[SOGoUser userWithLogin: uid] primaryIdentity] objectForKey: @"email"];
} }
else else
return uid; return uid;

View file

@ -58,6 +58,9 @@
@interface SOGoMailEnglishForward : SOGoMailForward @interface SOGoMailEnglishForward : SOGoMailForward
@end @end
@interface SOGoMailFinnishForward : SOGoMailForward
@end
@interface SOGoMailFrenchForward : SOGoMailForward @interface SOGoMailFrenchForward : SOGoMailForward
@end @end

View file

@ -262,6 +262,9 @@
@implementation SOGoMailEnglishForward @implementation SOGoMailEnglishForward
@end @end
@implementation SOGoMailFinnishForward
@end
@implementation SOGoMailFrenchForward @implementation SOGoMailFrenchForward
@end @end

View file

@ -63,6 +63,9 @@
@interface SOGoMailEnglishReply : SOGoMailReply @interface SOGoMailEnglishReply : SOGoMailReply
@end @end
@interface SOGoMailFinnishReply : SOGoMailReply
@end
@interface SOGoMailFrenchReply : SOGoMailReply @interface SOGoMailFrenchReply : SOGoMailReply
@end @end

View file

@ -120,6 +120,9 @@
@implementation SOGoMailEnglishReply @implementation SOGoMailEnglishReply
@end @end
@implementation SOGoMailFinnishReply
@end
@implementation SOGoMailFrenchReply @implementation SOGoMailFrenchReply
@end @end

View file

@ -55,6 +55,7 @@ SOGo_HEADER_FILES = \
SOGoCASSession.h \ SOGoCASSession.h \
SOGoDAVAuthenticator.h \ SOGoDAVAuthenticator.h \
SOGoProxyAuthenticator.h \ SOGoProxyAuthenticator.h \
SOGoStaticAuthenticator.h \
SOGoWebAuthenticator.h \ SOGoWebAuthenticator.h \
SOGoWebDAVAclManager.h \ SOGoWebDAVAclManager.h \
SOGoWebDAVValue.h \ SOGoWebDAVValue.h \
@ -67,7 +68,9 @@ SOGo_HEADER_FILES = \
WORequest+SOGo.h \ WORequest+SOGo.h \
WOResourceManager+SOGo.h \ WOResourceManager+SOGo.h \
WOResponse+SOGo.h \ WOResponse+SOGo.h \
WOContext+SOGo.h WOContext+SOGo.h \
\
SOGoCredentialsFile.h
# daemon tool # daemon tool
all:: all::
@ -124,6 +127,7 @@ SOGo_OBJC_FILES = \
SOGoCASSession.m \ SOGoCASSession.m \
SOGoDAVAuthenticator.m \ SOGoDAVAuthenticator.m \
SOGoProxyAuthenticator.m \ SOGoProxyAuthenticator.m \
SOGoStaticAuthenticator.m \
SOGoWebAuthenticator.m \ SOGoWebAuthenticator.m \
SOGoWebDAVAclManager.m \ SOGoWebDAVAclManager.m \
SOGoWebDAVValue.m \ SOGoWebDAVValue.m \
@ -136,7 +140,10 @@ SOGo_OBJC_FILES = \
WORequest+SOGo.m \ WORequest+SOGo.m \
WOResourceManager+SOGo.m \ WOResourceManager+SOGo.m \
WOResponse+SOGo.m \ WOResponse+SOGo.m \
WOContext+SOGo.m WOContext+SOGo.m \
\
SOGoCredentialsFile.m
SOGo_RESOURCE_FILES = \ SOGo_RESOURCE_FILES = \
SOGoDefaults.plist \ SOGoDefaults.plist \

View file

@ -1,10 +1,6 @@
/* LDAPSource.h - this file is part of SOGo /* LDAPSource.h - this file is part of SOGo
* *
* Copyright (C) 2007-2011 Inverse inc. * Copyright (C) 2007-2013 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Ludovic Marcotte <lmarcotte@inverse.ca>
* Francis Lachapelle <flachapelle@inverse.ca>
* *
* This file is free software; you can redistribute it and/or modify * 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 * 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 *) lookupGroupEntryByUID: (NSString *) theUID;
- (NGLdapEntry *) lookupGroupEntryByEmail: (NSString *) theEmail; - (NGLdapEntry *) lookupGroupEntryByEmail: (NSString *) theEmail;
- (NGLdapEntry *) lookupGroupEntryByAttribute: (NSString *) theAttribute
andValue: (NSString *) theValue;
@end @end

View file

@ -1,10 +1,6 @@
/* LDAPSource.m - this file is part of SOGo /* LDAPSource.m - this file is part of SOGo
* *
* Copyright (C) 2007-2012 Inverse inc. * Copyright (C) 2007-2013 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Ludovic Marcotte <lmarcotte@inverse.ca>
* Francis Lachapelle <flachapelle@inverse.ca>
* *
* This file is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -632,7 +628,25 @@ static Class NSStringK;
IDField, [login escapedForLDAPDN], baseDN]; IDField, [login escapedForLDAPDN], baseDN];
if (userDN) 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 // We don't use a password policy - we simply use
// a modify-op to change the password // a modify-op to change the password
@ -668,11 +682,6 @@ static Class NSStringK;
didChange = NO; 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]; return [_dnCache objectForKey: theLogin];
} }
- (NGLdapEntry *) lookupGroupEntryByUID: (NSString *) theUID - (NGLdapEntry *) _lookupGroupEntryByAttributes: (NSArray *) theAttributes
{ andValue: (NSString *) theValue
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
{ {
EOQualifier *qualifier; EOQualifier *qualifier;
NSString *s;
NGLdapEntry *ldapEntry; NGLdapEntry *ldapEntry;
NSString *s;
if ([theValue length] > 0) if ([theValue length] > 0 && [theAttributes count] > 0)
{ {
s = [NSString stringWithFormat: @"(%@='%@')", if ([theAttributes count] == 1)
theAttribute, SafeLDAPCriteria(theValue)]; {
qualifier = [EOQualifier qualifierWithQualifierFormat: s]; s = [NSString stringWithFormat: @"(%@='%@')",
[theAttributes lastObject], SafeLDAPCriteria(theValue)];
// We look for additional attributes - the ones related to group }
// membership else
// attributes = [NSMutableArray arrayWithArray: [self _searchAttributes]]; {
// [attributes addObject: @"member"]; NSString *fieldFormat;
// [attributes addObject: @"uniqueMember"];
// [attributes addObject: @"memberUid"]; fieldFormat = [NSString stringWithFormat: @"(%%@='%@')", SafeLDAPCriteria(theValue)];
// [attributes addObject: @"memberOf"]; s = [[theAttributes stringsWithFormat: fieldFormat]
componentsJoinedByString: @" OR "];
}
qualifier = [EOQualifier qualifierWithQualifierFormat: s];
ldapEntry = [self _lookupLDAPEntry: qualifier]; ldapEntry = [self _lookupLDAPEntry: qualifier];
} }
else else
@ -1274,6 +1274,18 @@ static Class NSStringK;
return ldapEntry; 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 - (void) setSourceID: (NSString *) newSourceID
{ {
ASSIGN (sourceID, newSourceID); ASSIGN (sourceID, newSourceID);

View file

@ -1,9 +1,6 @@
/* NSString+Utilities.h - this file is part of SOGo /* NSString+Utilities.h - this file is part of SOGo
* *
* Copyright (C) 2006-2011 Inverse inc. * Copyright (C) 2006-2013 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Ludovic Marcotte <lmarcotte@inverse.ca>
* *
* This file is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

View file

@ -2,9 +2,6 @@
* *
* Copyright (C) 2006-2013 Inverse inc. * Copyright (C) 2006-2013 Inverse inc.
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Ludovic Marcotte <lmarcotte@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)

View file

@ -390,7 +390,7 @@
[httpConnection autorelease]; [httpConnection autorelease];
request = [[WORequest alloc] initWithMethod: @"GET" request = [[WORequest alloc] initWithMethod: @"GET"
uri: [requestURL hostlessURL] uri: [requestURL hostlessURL]
httpVersion: @"HTTP/1.1" httpVersion: @"HTTP/1.0"
headers: nil content: nil headers: nil content: nil
userInfo: nil]; userInfo: nil];
[request autorelease]; [request autorelease];

View file

@ -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 <Foundation/NSObject.h>
@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 */

View file

@ -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 <Foundation/NSCharacterSet.h>
#import <Foundation/NSData.h>
#import <Foundation/NSString.h>
#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

View file

@ -4,6 +4,8 @@
WOLogFile = "/var/log/sogo/sogo.log"; WOLogFile = "/var/log/sogo/sogo.log";
WOPidFile = "/var/run/sogo/sogo.pid"; WOPidFile = "/var/run/sogo/sogo.pid";
WOPort = "127.0.0.1:20000";
NGImap4ConnectionStringSeparator = "/"; NGImap4ConnectionStringSeparator = "/";
NGImap4ConnectionGroupIdPrefix = "$"; NGImap4ConnectionGroupIdPrefix = "$";
NGImap4DisableIMAP4Pooling = YES; NGImap4DisableIMAP4Pooling = YES;

View file

@ -1195,6 +1195,41 @@ static NSArray *childRecordFields = nil;
return propstats; return propstats;
} }
/*
draft-1:
<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:">
<D:sync-response>
<D:href>/SOGo/dav/sogo2/Calendar/personal/351dc1af-2aa3-4d14-9704-eadbcfecaf7e.ics</D:href>
<D:status>HTTP/1.1 200 OK</D:status>
<D:propstat>
<D:prop>
<D:getetag>&quot;gcs00000001&quot;</D:getetag></D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:sync-response>
<D:sync-token>1322100412</D:sync-token>
</D:multistatus>
draft-2 and up:
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:">
<response>
<href>/caldav.php/user1/home/DAYPARTY-77C6-4FB7-BDD3-6882E2F1BE74.ics</href>
<propstat>
<prop>
<getetag>"165746adbab8bc0c8336a63cc5332ff2"</getetag>
<getlastmodified>Dow, 01 Jan 2000 00:00:00 GMT</getlastmodified>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<sync-token>urn:,1322100412</sync-token>
</multistatus>
*/
- (NSDictionary *) _syncResponseWithProperties: (NSArray *) properties - (NSDictionary *) _syncResponseWithProperties: (NSArray *) properties
andMethodSelectors: (SEL *) selectors andMethodSelectors: (SEL *) selectors
fromRecord: (NSDictionary *) record fromRecord: (NSDictionary *) record
@ -1238,7 +1273,7 @@ static NSArray *childRecordFields = nil;
andMethodSelectors: selectors andMethodSelectors: selectors
fromRecord: record]]; fromRecord: record]];
return davElementWithContent (@"sync-response", XMLNS_WEBDAV, children); return davElementWithContent (@"response", XMLNS_WEBDAV, children);
} }
- (void) _appendComponentProperties: (NSArray *) properties - (void) _appendComponentProperties: (NSArray *) properties

View file

@ -35,6 +35,7 @@
#import "NSString+Utilities.h" #import "NSString+Utilities.h"
#import "SOGoAuthenticator.h" #import "SOGoAuthenticator.h"
#import "SOGoDomainDefaults.h" #import "SOGoDomainDefaults.h"
#import "SOGoStaticAuthenticator.h"
#import "SOGoSystemDefaults.h" #import "SOGoSystemDefaults.h"
#import "SOGoUser.h" #import "SOGoUser.h"
#import "SOGoUserManager.h" #import "SOGoUserManager.h"
@ -153,9 +154,13 @@
[client connectToAddress: addr]; [client connectToAddress: addr];
if ([authenticationType isEqualToString: @"plain"]) if ([authenticationType isEqualToString: @"plain"])
{ {
login = [[SOGoUserManager sharedUserManager] /* XXX Allow static credentials by peeking at the classname */
getExternalLoginForUID: [[authenticator userInContext: woContext] loginInDomain] if ([authenticator isKindOfClass: [SOGoStaticAuthenticator class]])
inDomain: [[authenticator userInContext: woContext] domain]]; login = [(SOGoStaticAuthenticator *)authenticator username];
else
login = [[SOGoUserManager sharedUserManager]
getExternalLoginForUID: [[authenticator userInContext: woContext] loginInDomain]
inDomain: [[authenticator userInContext: woContext] domain]];
password = [authenticator passwordInContext: woContext]; password = [authenticator passwordInContext: woContext];
if ([login length] == 0 if ([login length] == 0

View file

@ -364,7 +364,11 @@ static SoSecurityManager *sm = nil;
NSString *newFolderID; NSString *newFolderID;
NSException *error; NSException *error;
newFolderID = [self globallyUniqueObjectId]; newFolderID = *newNameInContainer;
if (!newFolderID)
newFolderID = [self globallyUniqueObjectId];
error = [self newFolderWithName: name error = [self newFolderWithName: name
andNameInContainer: newFolderID]; andNameInContainer: newFolderID];
if (error) if (error)

View file

@ -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 <Foundation/NSObject.h>
#import "SOGoAuthenticator.h"
/*
SOGoStaticAuthenticator
*/
@interface SOGoStaticAuthenticator : NSObject <SOGoAuthenticator>
{
NSString *_username;
NSString *_password;
}
+ (id) authenticatorWithUser: (NSString *) user
andPassword: (NSString *) password;
- (id) initWithUser: (NSString *) user
andPassword: (NSString *) password;
- (NSString *) username;
@end
#endif /* SOGOSTATICAUTHENTICATOR_H */

View file

@ -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 <Foundation/NSString.h>
#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

View file

@ -1,15 +1,15 @@
/* /*
Copyright (C) 2006-2011 Inverse inc. Copyright (C) 2006-2013 Inverse inc.
Copyright (C) 2005 SKYRIX Software AG 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 the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any Free Software Foundation; either version 2, or (at your option) any
later version. 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 WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details. License for more details.
@ -622,19 +622,29 @@
// 3. port & encryption // 3. port & encryption
scheme = [cUrl scheme] ? [cUrl scheme] : [url scheme]; scheme = [cUrl scheme] ? [cUrl scheme] : [url scheme];
query = [cUrl query] ? [cUrl query] : [url query];
if (scheme if (scheme
&& [scheme caseInsensitiveCompare: @"imaps"] == NSOrderedSame) && [scheme caseInsensitiveCompare: @"imaps"] == NSOrderedSame)
{ {
encryption = @"ssl"; if (query && [query caseInsensitiveCompare: @"tls=YES"] == NSOrderedSame)
defaultPort = 993; {
defaultPort = 143;
encryption = @"tls";
}
else
{
encryption = @"ssl";
defaultPort = 993;
}
} }
else else
{ {
query = [cUrl query] ? [cUrl query] : [url query];
if (query && [query caseInsensitiveCompare: @"tls=YES"] == NSOrderedSame) if (query && [query caseInsensitiveCompare: @"tls=YES"] == NSOrderedSame)
encryption = @"tls"; encryption = @"tls";
else else
encryption = @"none"; encryption = @"none";
defaultPort = 143; defaultPort = 143;
} }
port = [cUrl port] ? [cUrl port] : [url port]; port = [cUrl port] ? [cUrl port] : [url port];

View file

@ -6,7 +6,7 @@ import webdavlib
import sys import sys
import getopt import getopt
import xml.dom.ext import xml.dom.minidom
def parseArguments(): def parseArguments():
arguments = {} arguments = {}
@ -43,4 +43,7 @@ print propfind.response["body"]
if propfind.response.has_key("document"): if propfind.response.has_key("document"):
sys.stderr.write("document tree:\n") 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()

View file

@ -110,7 +110,7 @@ class DAVCalendarSuperUserAclTest(unittest.TestCase):
["{urn:ietf:params:xml:ns:caldav}calendar-data"]) ["{urn:ietf:params:xml:ns:caldav}calendar-data"])
self.client.execute(sync_query) self.client.execute(sync_query)
if sync_query.response["status"] != 404: if sync_query.response["status"] != 404:
event = self._calendarDataInMultistatus(sync_query, "{DAV:}sync-response") event = self._calendarDataInMultistatus(sync_query, "{DAV:}response")
return event return event
@ -581,7 +581,7 @@ class DAVCalendarAclTest(DAVAclTest):
self.subscriber_client.execute(sync_query) self.subscriber_client.execute(sync_query)
if sync_query.response["status"] != 404: if sync_query.response["status"] != 404:
event = self._calendarDataInMultistatus(sync_query, url, event = self._calendarDataInMultistatus(sync_query, url,
"{DAV:}sync-response") "{DAV:}response")
return event return event

View file

@ -379,8 +379,8 @@ class CalDAVPOST(WebDAVQuery):
return self.content return self.content
class CalDAVCalendarMultiget(WebDAVREPORT): class CalDAVCalendarMultiget(WebDAVREPORT):
def __init__(self, url, properties, hrefs): def __init__(self, url, properties, hrefs, depth = None):
WebDAVQuery.__init__(self, url) WebDAVQuery.__init__(self, url, depth)
multiget_tag = self.ns_mgr.register("calendar-multiget", xmlns_caldav) multiget_tag = self.ns_mgr.register("calendar-multiget", xmlns_caldav)
self.top_node = _WD_XMLTreeElement(multiget_tag) self.top_node = _WD_XMLTreeElement(multiget_tag)
if properties is not None and len(properties) > 0: if properties is not None and len(properties) > 0:

View file

@ -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()

View file

@ -25,8 +25,11 @@
#import <Foundation/NSObject.h> #import <Foundation/NSObject.h>
#import <SOGo/SOGoStaticAuthenticator.h>
@interface SOGoEAlarmsNotifier : NSObject @interface SOGoEAlarmsNotifier : NSObject
{ {
SOGoStaticAuthenticator *staticAuthenticator;
} }
- (BOOL) run; - (BOOL) run;

View file

@ -1,6 +1,6 @@
/* SOGoEAlarmsNotifier.m - this file is part of SOGo /* SOGoEAlarmsNotifier.m - this file is part of SOGo
* *
* Copyright (C) 2011 Inverse inc. * Copyright (C) 2011-2013 Inverse inc.
* *
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca> * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
@ -27,6 +27,7 @@
#import <Foundation/NSDictionary.h> #import <Foundation/NSDictionary.h>
#import <Foundation/NSProcessInfo.h> #import <Foundation/NSProcessInfo.h>
#import <Foundation/NSString.h> #import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <NGExtensions/NGHashMap.h> #import <NGExtensions/NGHashMap.h>
#import <NGExtensions/NGQuotedPrintableCoding.h> #import <NGExtensions/NGQuotedPrintableCoding.h>
@ -38,12 +39,14 @@
#import <NGCards/iCalEntityObject.h> #import <NGCards/iCalEntityObject.h>
#import <NGCards/iCalPerson.h> #import <NGCards/iCalPerson.h>
#import "SOGo/SOGoCredentialsFile.h"
#import <SOGo/NSCalendarDate+SOGo.h> #import <SOGo/NSCalendarDate+SOGo.h>
#import <SOGo/NSString+Utilities.h> #import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoDomainDefaults.h> #import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoSystemDefaults.h>
#import <SOGo/SOGoMailer.h> #import <SOGo/SOGoMailer.h>
#import <SOGo/SOGoProductLoader.h> #import <SOGo/SOGoProductLoader.h>
#import <SOGo/SOGoStaticAuthenticator.h>
#import <SOGo/SOGoSystemDefaults.h>
#import <SOGo/SOGoUser.h> #import <SOGo/SOGoUser.h>
#import <Appointments/iCalPerson+SOGo.h> #import <Appointments/iCalPerson+SOGo.h>
#import <Appointments/SOGoEMailAlarmsManager.h> #import <Appointments/SOGoEMailAlarmsManager.h>
@ -52,6 +55,21 @@
@implementation SOGoEAlarmsNotifier @implementation SOGoEAlarmsNotifier
- (id) init
{
if ((self = [super init]))
{
staticAuthenticator = nil;
}
return self;
}
- (void) dealloc
{
[staticAuthenticator release];
[super dealloc];
}
- (NSString *) _messageID - (NSString *) _messageID
{ {
static int pid = 0; static int pid = 0;
@ -124,11 +142,10 @@
[message setBody: content]; [message setBody: content];
to = [attendee rfc822Email]; to = [attendee rfc822Email];
/* TODO: SMTP authentication for services */
[mailer sendMimePart: message [mailer sendMimePart: message
toRecipients: [NSArray arrayWithObject: to] toRecipients: [NSArray arrayWithObject: to]
sender: from sender: from
withAuthenticator: nil inContext: nil]; withAuthenticator: staticAuthenticator inContext: nil];
} }
- (void) _processAlarm: (iCalAlarm *) alarm - (void) _processAlarm: (iCalAlarm *) alarm
@ -160,14 +177,45 @@
withMailer: mailer]; 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 - (BOOL) run
{ {
SOGoEMailAlarmsManager *eaMgr; SOGoEMailAlarmsManager *eaMgr;
SOGoCredentialsFile *cf;
NSCalendarDate *startDate, *toDate; NSCalendarDate *startDate, *toDate;
NSArray *alarms; NSArray *alarms;
NSMutableArray *owners; NSMutableArray *owners;
NSString *credsFilename;
int count, max; 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] [[SOGoProductLoader productLoader]
loadProducts: [NSArray arrayWithObject: @"Appointments.SOGo"]]; loadProducts: [NSArray arrayWithObject: @"Appointments.SOGo"]];

View file

@ -1,6 +1,6 @@
/* SOGoToolUserPreferences.m - this file is part of SOGo /* SOGoToolUserPreferences.m - this file is part of SOGo
* *
* Copyright (C) 2011 Inverse inc. * Copyright (C) 2011-2013 Inverse inc.
* *
* Author: Francis Lachapelle <flachapelle@inverse.ca> * Author: Francis Lachapelle <flachapelle@inverse.ca>
* *
@ -37,10 +37,11 @@
#import <NGExtensions/NSNull+misc.h> #import <NGExtensions/NSNull+misc.h>
#import <SOGo/NSString+Utilities.h> #import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoUser.h> #import "SOGo/SOGoCredentialsFile.h"
#import <SOGo/SOGoSystemDefaults.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoSieveManager.h> #import <SOGo/SOGoSieveManager.h>
#import <SOGo/SOGoSystemDefaults.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import "SOGoTool.h" #import "SOGoTool.h"
@ -149,6 +150,8 @@
while ((infos = [channel fetchAttributes: attrs withZone: NULL])) while ((infos = [channel fetchAttributes: attrs withZone: NULL]))
{ {
user = [infos objectForKey: @"c_uid"]; user = [infos objectForKey: @"c_uid"];
if (verbose)
NSLog(@"Checking user %@\n", user);
c_defaults = [infos objectForKey: @"c_defaults"]; c_defaults = [infos objectForKey: @"c_defaults"];
if ([c_defaults isNotNull]) if ([c_defaults isNotNull])
{ {
@ -180,9 +183,9 @@
- (BOOL) run - (BOOL) run
{ {
NSData *credsData;
NSRange r; NSRange r;
NSString *creds, *credsFile, *authname, *authpwd; NSString *creds, *credsFilename, *authname, *authpwd;
SOGoCredentialsFile *cf;
BOOL rc; BOOL rc;
int max; int max;
@ -192,41 +195,34 @@
authpwd = nil; authpwd = nil;
rc = NO; rc = NO;
credsFile = [[NSUserDefaults standardUserDefaults] stringForKey: @"p"]; credsFilename = [[NSUserDefaults standardUserDefaults] stringForKey: @"p"];
if (credsFile) if (credsFilename)
{ {
credsData = [NSData dataWithContentsOfFile: credsFile]; cf = [SOGoCredentialsFile credentialsFromFile: credsFilename];
if (credsData == nil) authname = [cf username];
{ authpwd = [cf password];
NSLog(@"Error reading credential file '%@'", credsFile);
return NO;
}
creds = [[NSString alloc] initWithData: credsData
encoding: NSUTF8StringEncoding];
[creds autorelease];
creds = [creds stringByTrimmingCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString: @"\r\n"]];
} }
/* DEPRECATED: this is only kept around to avoid breaking existing setups */
if (max > 0) if (max > 0)
{ {
/* assume we got the creds directly on the cli */ /* assume we got the creds directly on the cli */
creds = [sanitizedArguments objectAtIndex: 0]; 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) if (authname && authpwd)
{ {

View file

@ -1,6 +1,6 @@
/* SOGoToolUserPreferences.m - this file is part of SOGo /* SOGoToolUserPreferences.m - this file is part of SOGo
* *
* Copyright (C) 2011 Inverse inc. * Copyright (C) 2011-2013 Inverse inc.
* *
* Author: Ludovic Marcotte <lmarcotte@inverse.ca> * Author: Ludovic Marcotte <lmarcotte@inverse.ca>
* *
@ -28,6 +28,7 @@
#import <Foundation/NSUserDefaults.h> #import <Foundation/NSUserDefaults.h>
#import <SOGo/NSString+Utilities.h> #import <SOGo/NSString+Utilities.h>
#import "SOGo/SOGoCredentialsFile.h"
#import <SOGo/SOGoUser.h> #import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h> #import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoUserSettings.h> #import <SOGo/SOGoUserSettings.h>
@ -109,34 +110,17 @@ typedef enum
[theKey caseInsensitiveCompare: @"Vacation"] == NSOrderedSame) [theKey caseInsensitiveCompare: @"Vacation"] == NSOrderedSame)
{ {
/* credentials file handling */ /* credentials file handling */
NSData *credsData; NSString *credsFilename, *authname, *authpwd;
NSRange r; SOGoCredentialsFile *cf;
NSString *credsFile, *creds, *authname, *authpwd;
authname = nil;
authpwd = nil;
credsFilename = [[NSUserDefaults standardUserDefaults] stringForKey: @"p"];
credsFile = [[NSUserDefaults standardUserDefaults] stringForKey: @"p"]; if (credsFilename)
if (credsFile)
{ {
/* TODO: add back support for user:pwd here? */ cf = [SOGoCredentialsFile credentialsFromFile: credsFilename];
credsData = [NSData dataWithContentsOfFile: credsFile]; authname = [cf username];
if (credsData == nil) authpwd = [cf password];
{
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];
} }
if (authname == nil || authpwd == nil) if (authname == nil || authpwd == nil)
{ {
NSLog(@"To update Sieve scripts, you must provide the \"-p credentialFile\" parameter"); NSLog(@"To update Sieve scripts, you must provide the \"-p credentialFile\" parameter");

View file

@ -9,7 +9,7 @@
"ACLs" = "Adgangsrettigheter"; "ACLs" = "Adgangsrettigheter";
/* Modules titles */ /* Modules titles */
"ACLs_title" = "Håntering av adgangsrettigheter for brukermapper"; "ACLs_title" = "Håndtering av adgangsrettigheter for brukermapper";
/* Modules descriptions */ /* Modules descriptions */
"ACLs_description" = "<p>Administrasjonsmodulen for adgangsrettigheter muliggjør endring av adgangsrettigheter for brukerens kalendre og adressebøker.</p><p>For å endre adgangsrettigheter en brukermappe, skriv brukernavnet i søkefeltet oppe i vinduet og dobbelklikk på ønskede mappe.</p>"; "ACLs_description" = "<p>Administrasjonsmodulen for adgangsrettigheter muliggjør endring av adgangsrettigheter for brukerens kalendre og adressebøker.</p><p>For å endre adgangsrettigheter for en brukermappe, skriv brukernavnet i søkefeltet oppe i vinduet og dobbelklikk på ønskede mappe.</p>";

View file

@ -11,11 +11,12 @@
"Mail" = "E-post"; "Mail" = "E-post";
"Preferences" = "Innstillinger"; "Preferences" = "Innstillinger";
"Administration" = "Administrasjon"; "Administration" = "Administrasjon";
"Disconnect" = "Logg ut"; "Disconnect" = "Koble fra";
"Right Administration" = "Rettighetsinnstillinger"; "Right Administration" = "Rettighetsinnstillinger";
"Log Console (dev.)" = "Loggkonsoll"; "Log Console (dev.)" = "Loggkonsoll";
"User" = "Bruker"; "User" = "Bruker";
"Vacation message is enabled" = "Fraværsmelding er aktivert.";
"Help" = "Hjelp"; "Help" = "Hjelp";
@ -23,24 +24,30 @@
"noJavascriptRetry" = "Forsøk igjen"; "noJavascriptRetry" = "Forsøk igjen";
"Owner:" = "Eier:"; "Owner:" = "Eier:";
"Publish the Free/Busy information" = "Publiser ledig/opptatt informasjon"; "Publish the Free/Busy information" = "Publiser ledig/opptatt-informasjon";
"Add..." = "Legg til..."; "Add..." = "Legg til...";
"Remove" = "Fjern"; "Remove" = "Fjern";
"Subscribe User" = "Abonner bruker"; "Subscribe User" = "Abonnér bruker";
"Any Authenticated User" = "Enhver autentisert bruker"; "Any Authenticated User" = "Enhver autentisert bruker";
"Public Access" = "Offentlig tilgang"; "Public Access" = "Offentlig tilgang";
"Any user not listed above" = "Enhver bruker som ikke er listet ovenfor"; "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."; "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?" "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?" "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"; "Give Access" = "Gi tilgang";
"Keep Private" = "Behold privat"; "Keep Private" = "Behold privat";
@ -68,17 +75,17 @@
"You don't have the required privileges to perform the operation." "You don't have the required privileges to perform the operation."
= "Du har ikke rettigheter til å utføre operasjonen."; = "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 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 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"; "Snooze for " = "Slumre i";
"5 minutes" = "5 minutt"; "5 minutes" = "5 minutter";
"10 minutes" = "10 minutt"; "10 minutes" = "10 minutter";
"15 minutes" = "15 minutt"; "15 minutes" = "15 minutter";
"30 minutes" = "30 minutt"; "30 minutes" = "30 minutter";
"45 minutes" = "45 minutt"; "45 minutes" = "45 minutter";
"1 hour" = "1 time"; "1 hour" = "1 time";

View file

@ -40,6 +40,8 @@
NSString *name, *nameInContainer; NSString *name, *nameInContainer;
name = [[context request] formValueForKey: @"name"]; name = [[context request] formValueForKey: @"name"];
nameInContainer = nil;
if ([name length] > 0) if ([name length] > 0)
{ {
if (![[self clientObject] hasLocalSubFolderNamed: name]) if (![[self clientObject] hasLocalSubFolderNamed: name])

View file

@ -6,12 +6,12 @@
"Other" = "Annet"; "Other" = "Annet";
"Address Books" = "Adressebøker"; "Address Books" = "Adressebøker";
"Addressbook" = "Adresseboken"; "Addressbook" = "Adressebok";
"Addresses" = "Adresser"; "Addresses" = "Adresser";
"Update" = "Oppdatere"; "Update" = "Oppdatere";
"Cancel" = "Avbryt"; "Cancel" = "Avbryt";
"Common" = "Felles"; "Common" = "Felles";
"Contact editor" = "Kontakteditor"; "Contact editor" = "Kontaktinnstillinger";
"Contact viewer" = "Kontaktviser"; "Contact viewer" = "Kontaktviser";
"Email" = "E-post"; "Email" = "E-post";
"Screen Name" = "Skjermnavn"; "Screen Name" = "Skjermnavn";
@ -29,20 +29,20 @@
"Work Phone" = "Jobbtelefon"; "Work Phone" = "Jobbtelefon";
"Phone" = "Telefon"; "Phone" = "Telefon";
"Phones" = "Telefoner"; "Phones" = "Telefoner";
"Postal" = "Postnummer"; "Postal" = "Postadresse";
"Save" = "Lagre"; "Save" = "Lagre";
"Internet" = "Internett"; "Internet" = "Internett";
"Unit" = "Avdeling"; "Unit" = "Avdeling";
"delete" = "slett"; "delete" = "slett";
"edit" = "endre"; "edit" = "endre";
"invalidemailwarn" = "Meldingen er ikke komplett"; "invalidemailwarn" = "Den spesifiserte e-posten er ikke gyldig";
"invaliddatewarn" = "Den spesifiserte datoen er ikke gyldig."; "invaliddatewarn" = "Den spesifiserte datoen er ikke gyldig.";
"new" = "ny"; "new" = "ny";
"Preferred Phone" = "Foretrukket telefon"; "Preferred Phone" = "Foretrukket telefon";
"Move To" = "Flytt til"; "Move To" = "Flytt til";
"Copy To" = "Kopier til"; "Copy To" = "Kopier til";
"Add to:" = "Legg til:"; "Add to:" = "Legg til i:";
/* Tooltips */ /* Tooltips */
@ -51,10 +51,10 @@
"Edit the selected card" = "Rediger markert adressekort"; "Edit the selected card" = "Rediger markert adressekort";
"Send a mail message" = "Send en e-post"; "Send a mail message" = "Send en e-post";
"Delete selected card or address book" = "Slett markert adressekort eller adressebok"; "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_UNKNOWN" = "Ukjent";
"htmlMailFormat_FALSE" = "Uformatert Text"; "htmlMailFormat_FALSE" = "Ren tekst";
"htmlMailFormat_TRUE" = "HTML"; "htmlMailFormat_TRUE" = "HTML";
"Name or Email" = "Navn eller e-post"; "Name or Email" = "Navn eller e-post";
@ -77,14 +77,14 @@
"Preferred" = "Foretrukket"; "Preferred" = "Foretrukket";
"Display:" = "Vise:"; "Display:" = "Vise:";
"Display Name:" = "Visningsnamn:"; "Display Name:" = "Visningsnavn:";
"Email:" = "E-post:"; "Email:" = "E-post:";
"Additional Email:" = "Ytterlige e-post:"; "Additional Email:" = "Ytterlige e-post:";
"Phone Number:" = "Telefonnummer:"; "Phone Number:" = "Telefonnummer:";
"Prefers to receive messages formatted as:" = "Foretrekker å motta melding formatert som:"; "Prefers to receive messages formatted as:" = "Foretrekker å motta melding formatert som:";
"Screen Name:" = "Skjermnavn:"; "Screen Name:" = "Skjermnavn:";
"Categories:" = "Katagorier:"; "Categories:" = "Kategorier:";
"First:" = "Fornavn:"; "First:" = "Fornavn:";
"Last:" = "Etternavn:"; "Last:" = "Etternavn:";
@ -98,34 +98,34 @@
"Pager:" = "Personsøker:"; "Pager:" = "Personsøker:";
/* categories */ /* categories */
"contacts_category_labels" = "Colleague, Competitor, Customer, Friend, Family, Business Partner, Provider, Press, VIP"; "contacts_category_labels" = "Kollega, Konkurrent, Kunde, Venn, Familie, Forretningspartner, Leverandør, Presse, VIP";
"Categories" = "Katagorier"; "Categories" = "Kategorier";
"New category" = "Ny katagori"; "New category" = "Ny kategori";
/* adresses */ /* adresses */
"Title:" = "Tittel:"; "Title:" = "Tittel:";
"Service:" = "Funksjon:"; "Service:" = "Funksjon:";
"Company:" = "Foretak:"; "Company:" = "Foretak:";
"Department:" = "Avdelning:"; "Department:" = "Avdeling:";
"Organization:" = "Organisation:"; "Organization:" = "Organisasjon:";
"Address:" = "Adresse:"; "Address:" = "Adresse:";
"City:" = "Poststed: "; "City:" = "Poststed: ";
"State_Province:" = "Landsdel:"; "State_Province:" = "Landsdel:";
"ZIP_Postal Code:" = "Postnummer:"; "ZIP_Postal Code:" = "Postnummer:";
"Country:" = "Land:"; "Country:" = "Land:";
"Web Page:" = "Webside:"; "Web Page:" = "Nettside:";
"Work" = "Arbeid"; "Work" = "Arbeid";
"Other Infos" = "Øvrig"; "Other Infos" = "Øvrig informasjon";
"Note:" = "Anmerkning:"; "Note:" = "Anmerkning:";
"Timezone:" = "Tidssone:"; "Timezone:" = "Tidssone:";
"Birthday:" = "Fødselsdag:"; "Birthday:" = "Fødselsdag:";
"Birthday (yyyy-mm-dd):" = "Fødselsdag (yyyy-mm-dd):"; "Birthday (yyyy-mm-dd):" = "Fødselsdag (åååå-mm-dd):";
"Freebusy URL:" = "Freebusy URL:"; "Freebusy URL:" = "Ledigopptatt URL:";
"Add as..." = "Legg til som..."; "Add as..." = "Legg til som...";
"Recipient" = "Mottakere"; "Recipient" = "Mottaker";
"Carbon Copy" = "Kopi"; "Carbon Copy" = "Kopi";
"Blind Carbon Copy" = "Blindkopi"; "Blind Carbon Copy" = "Blindkopi";
@ -135,7 +135,7 @@
"Name of the Address Book" = "Navn på adressebok"; "Name of the Address Book" = "Navn på adressebok";
"Are you sure you want to delete the selected address book?" "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." "You cannot remove nor unsubscribe from a public addressbook."
= "Du kan ikke fjerne eller avbryte abonnement på en offentlig adressebok."; = "Du kan ikke fjerne eller avbryte abonnement på en offentlig adressebok.";
"You cannot remove nor unsubscribe from your personal addressbook." "You cannot remove nor unsubscribe from your personal addressbook."
@ -145,7 +145,7 @@
= "Er du sikker på at du vil slette de markerte kontaktene?"; = "Er du sikker på at du vil slette de markerte kontaktene?";
"You cannot delete the card of \"%{0}\"." "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"; "Address Book Name" = "Navn på adressebok";
@ -159,18 +159,18 @@
"For user" = "For bruker"; "For user" = "For bruker";
"Any Authenticated User" = "Alle autentiserte brukere"; "Any Authenticated User" = "Alle autentiserte brukere";
"Public Access" = "Public Access"; "Public Access" = "Offentlig tilgang";
"This person can add cards to this addressbook." "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." "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." "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." "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." "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." "The selected contact has no email address."
= "Den markerte kontakten har ingen e-postadresse."; = "Den markerte kontakten har ingen e-postadresse.";
@ -188,16 +188,18 @@
"List details" = "Informasjon om mailinglisten"; "List details" = "Informasjon om mailinglisten";
"List name:" = "Navn på mailingliste:"; "List name:" = "Navn på mailingliste:";
"List nickname:" = "Kallenavn til mailingliste:"; "List nickname:" = "Kallenavn til mailingliste:";
"List description:" = "Beskrivelse:"; "List description:" = "Beskrivelse av mailingliste:";
"Members" = "Medlemmer"; "Members" = "Medlemmer";
"Contacts" = "Kontakter"; "Contacts" = "Kontakter";
"Add" = "Legg til"; "Add" = "Legg til";
"Lists can't be moved or copied." = "Mailinglister kan ikke flyttes eller kopieres."; "Lists can't be moved or copied." = "Mailinglister kan ikke flyttes eller kopieres.";
"Export" = "Eksportere"; "Export" = "Eksportere";
"Export Address Book..." = "Eksportere Adressebok..."; "Export Address Book..." = "Eksportere Adressebok...";
"View Raw Source" = "Vis råkilde";
"Import Cards" = "Importere adressekort"; "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"; "Upload" = "Last opp";
"Uploading" = "Laster opp";
"Done" = "Ferdig"; "Done" = "Ferdig";
"An error occured while importing contacts." = "En feil oppstod under importen av kontakter."; "An error occured while importing contacts." = "En feil oppstod under importen av kontakter.";
"No card was imported." = "Ingen adressekort ble importert."; "No card was imported." = "Ingen adressekort ble importert.";

View file

@ -9,8 +9,7 @@ organized_by_you = "en sou l'organitzador.";
you_are_an_attendee = "hi participeu"; you_are_an_attendee = "hi participeu";
add_info_text = "iMIP 'ADD' encara no funciona."; add_info_text = "iMIP 'ADD' encara no funciona.";
publish_info_text = "El remitent us informa de l'esdeveniment adjunt."; publish_info_text = "El remitent us informa de l'esdeveniment adjunt.";
cancel_info_text = "La vostra invitació o l'esdeveniment han estat cancel_info_text = "La vostra invitació o l'esdeveniment han estat \ncancel·lats.";
cancel·lats.";
request_info_no_attendee = "Heu proposat un esdeveniment. Rebeu aquest correu com a notificació, però no hi figureu com a participant."; request_info_no_attendee = "Heu proposat un esdeveniment. Rebeu aquest correu com a notificació, però no hi figureu com a participant.";
Appointment = "Cita"; Appointment = "Cita";

View file

@ -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."; 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."; 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"; Appointment = "Appointment";
"Status Update" = "Status Update";
was = "was";
Organizer = "Organizer"; Organizer = "Organizer";
Time = "Time"; Time = "Time";

View file

@ -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é."; 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é."; 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"; Appointment = "Événement";
"Status Update" = "Changement d'état";
was = "était";
Organizer = "Organisateur"; Organizer = "Organisateur";
Time = "Date"; Time = "Date";

View file

@ -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."; 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."; 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"; Appointment = "Termin";
"Status Update" = "Statusänderung";
was = "war";
Organizer = "Organisator"; Organizer = "Organisator";
Time = "Zeit"; Time = "Zeit";

View file

@ -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."; 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."; 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ó"; Appointment = "Találkozó";
"Status Update" = "Állapot frissítés";
was = "előző";
Organizer = "Szervező"; Organizer = "Szervező";
Time = "Idő"; Time = "Idő";
@ -19,7 +21,7 @@ Attendees = "Résztvevők";
request_info = "meghívja önt résztvevőnek egy találkozóra."; request_info = "meghívja önt résztvevőnek egy találkozóra.";
"Add to calendar" = "Hozzáadás a naptárhoz"; "Add to calendar" = "Hozzáadás a naptárhoz";
"Delete from calendar" = "Törlés a naptárból"; "Delete from calendar" = "Törlés a naptárból";
"Update status" = "Állapot frissítése"; "Update status" = "Frissítés állapota";
Accept = "Elfogad"; Accept = "Elfogad";
Decline = "Elutasít"; Decline = "Elutasít";
Tentative = "Bizonytalan"; Tentative = "Bizonytalan";

View file

@ -1,5 +1,5 @@
ACCEPTED = "akseptert"; ACCEPTED = "akseptert";
COMPLETED = "avsluttet"; COMPLETED = "fullført";
DECLINED = "avvist"; DECLINED = "avvist";
DELEGATED = "delegert"; DELEGATED = "delegert";
"IN-PROCESS" = "pågående"; "IN-PROCESS" = "pågående";
@ -7,10 +7,10 @@ DELEGATED = "delegert";
TENTATIVE = "foreløpig"; TENTATIVE = "foreløpig";
organized_by_you = "organisert av deg"; organized_by_you = "organisert av deg";
you_are_an_attendee = "du er en deltager"; 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."; publish_info_text = "Avsenderen informerer deg om vedlagte arrangement.";
cancel_info_text = "Din invitasjon eller hele arrangementet er avlyst."; 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"; Appointment = "Møte";
Organizer = "Arrangør"; Organizer = "Arrangør";
@ -19,7 +19,7 @@ Attendees = "Deltakere";
request_info = "inviterer deg til å delta i et møte."; request_info = "inviterer deg til å delta i et møte.";
"Add to calendar" = "Legg inn i kalenderen"; "Add to calendar" = "Legg inn i kalenderen";
"Delete from calendar" = "Ta bort fra kalenderen"; "Delete from calendar" = "Ta bort fra kalenderen";
"Update status" = "Oppdatere status"; "Update status" = "Oppdater status";
Accept = "Godta"; Accept = "Godta";
Decline = "Avslå"; Decline = "Avslå";
Tentative = "Foreløpig"; Tentative = "Foreløpig";

View file

@ -262,7 +262,7 @@ static NSData* _sanitizeContent(NSData *theData)
buf = malloc((j+1) * sizeof(char)); buf = malloc((j+1) * sizeof(char));
memset (buf, 0, j+1); memset (buf, 0, j+1);
memcpy (buf, bytes, j); memcpy (buf, bytes, j);
found_tag = [NSString stringWithCString: buf encoding: NSASCIIStringEncoding]; found_tag = [NSString stringWithCString: buf encoding: NSUTF8StringEncoding];
tags = [VoidTags objectEnumerator]; tags = [VoidTags objectEnumerator];
tag = [tags nextObject]; tag = [tags nextObject];
@ -562,6 +562,39 @@ static NSData* _sanitizeContent(NSData *theData)
&& ![value hasPrefix: @"mailto:"] && ![value hasPrefix: @"mailto:"]
&& ![value hasPrefix: @"#"]); && ![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 else
value = [_attributes valueAtIndex: count]; value = [_attributes valueAtIndex: count];
if (!skipAttribute) if (!skipAttribute)

View file

@ -1,14 +1,15 @@
/* /*
Copyright (C) 2007-2013 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG 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 the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any Free Software Foundation; either version 2, or (at your option) any
later version. 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 WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details. License for more details.
@ -37,7 +38,7 @@
encoding = BASE64; encoding = BASE64;
parameterList = { parameterList = {
"x-unix-mode" = 0666; "x-unix-mode" = 0666;
name = "IncoWEBOpenGroupwarepresentation.pdf"; name = "SOGo.pdf";
}; };
size = 1314916; size = 1314916;
subtype = PDF; type = application; subtype = PDF; type = application;

View file

@ -52,6 +52,8 @@
success = NO; success = NO;
store = X509_STORE_new (); store = X509_STORE_new ();
OpenSSL_add_all_algorithms ();
if (store) if (store)
{ {
lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file()); lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file());
@ -92,8 +94,7 @@
PKCS7 *p7; PKCS7 *p7;
int err, i; int err, i;
memset(sslError, 0, 1024);
*sslError = 0;
ERR_clear_error(); ERR_clear_error();

View file

@ -83,6 +83,8 @@
- (NSString *)pathToAttachmentObject; /* link to SoObject */ - (NSString *)pathToAttachmentObject; /* link to SoObject */
- (NSString *)pathToAttachment; /* download link */ - (NSString *)pathToAttachment; /* download link */
- (NSString *) mimeImageURL;
@end @end
#endif /* __Mailer_UIxMailPartViewer_H__ */ #endif /* __Mailer_UIxMailPartViewer_H__ */

View file

@ -266,7 +266,7 @@
NSMutableString *filename; NSMutableString *filename;
NSString *extension; NSString *extension;
filename = [self filename]; filename = [NSMutableString stringWithString: [self filename]];
if (![filename length]) if (![filename length])
[filename appendFormat: @"%@-%@", [filename appendFormat: @"%@-%@",
[self labelForKey: @"Untitled"], [self labelForKey: @"Untitled"],
@ -304,7 +304,7 @@
return url; return url;
} }
- (NSString *) mimeImageUrl - (NSString *) mimeImageURL
{ {
NSString *mimeImageFile, *mimeImageUrl; NSString *mimeImageFile, *mimeImageUrl;

View file

@ -213,8 +213,10 @@ static BOOL showNamedTextAttachmentsInline = NO;
return [self iCalViewer]; return [self iCalViewer];
} }
// Tiffs aren't well-supported // TIFF files aren't well-supported and Thunderbird sometimes send PDF
if ([mt isEqualToString:@"image"] && ![st isEqualToString: @"tiff"]) // files over as image/pdf !
if ([mt isEqualToString:@"image"] &&
!([st isEqualToString: @"tiff"] || [st isEqualToString: @"pdf"]))
{ {
if ([self _shouldDisplayAsAttachment: _info textPart: NO]) if ([self _shouldDisplayAsAttachment: _info textPart: NO])
return [self linkViewer]; return [self linkViewer];

View file

@ -282,7 +282,7 @@
= "Les messages ne peuvent être déplacés dans la corbeille. Voulez-vous les supprimer immédiatement?"; = "Les messages ne peuvent être déplacés dans la corbeille. Voulez-vous les supprimer immédiatement?";
/* Message editing */ /* 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."; "error_missingrecipients" = "Veuillez spécifier au moins un destinataire.";
"Send Anyway" = "Envoyer sans sujet"; "Send Anyway" = "Envoyer sans sujet";

View file

@ -28,14 +28,14 @@
"Select a recipient from an Address Book" = "Velg en mottaker fra adressebok"; "Select a recipient from an Address Book" = "Velg en mottaker fra adressebok";
"Include an attachment" = "Legg til et vedlegg"; "Include an attachment" = "Legg til et vedlegg";
"Save this message" = "Lagre denne meldingen"; "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"; "Create a new message" = "Ny e-postmelding";
"Go to address book" = "Gå til adresseboken"; "Go to address book" = "Gå til adresseboken";
"Reply to the message" = "Svar avsender"; "Reply to the message" = "Svar avsender";
"Reply to sender and all recipients" = "Svar avsender og alle mottakere"; "Reply to sender and all recipients" = "Svar avsender og alle mottakere";
"Forward selected message" = "Videresend den valgte melding"; "Forward selected message" = "Videresend valgt melding";
"Delete selected message or folder" = "Slett den merkete meldingen eller mappen"; "Delete selected message or folder" = "Slett merket melding eller mappe";
"Mark the selected messages as junk" = "Merk de markerte meldingene som søppelpost"; "Mark the selected messages as junk" = "Merk markerte meldinger som søppelpost";
"Print this message" = "Skriv ut denne e-postmeldingen"; "Print this message" = "Skriv ut denne e-postmeldingen";
"Stop the current transfer" = "Stopp pågående overføring"; "Stop the current transfer" = "Stopp pågående overføring";
"Attachment" = "Vedlegg"; "Attachment" = "Vedlegg";
@ -48,13 +48,13 @@
"Calendar" = "Kalender"; "Calendar" = "Kalender";
"Addressbook" = "Adressebok"; "Addressbook" = "Adressebok";
"Mail" = "E-post"; "Mail" = "E-post";
"Right Administration" = "Rettighetsadministration"; "Right Administration" = "Rettighetsadministrasjon";
"Help" = "Hjelp"; "Help" = "Hjelp";
/* Mail account main windows */ /* 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"; "Read messages" = "Les meldinger";
"Write a new message" = "Skriv en ny melding"; "Write a new message" = "Skriv en ny melding";
@ -73,16 +73,16 @@
"Read mails from this folder" = "Les meldinger fra denne mappen"; "Read mails from this folder" = "Les meldinger fra denne mappen";
"Mark mails read and unread" = "Markere meldinger som leste og uleste"; "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"; "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"; "Post mails" = "Send e-postmeldinger";
"Add subfolders to this folder" = "Legg til undermapper til denne mappen"; "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"; "Erase mails from this folder" = "Slett meldinger fra mappen";
"Expunge this folder" = "Fjern mappen"; "Expunge this folder" = "Fjern mappen";
"Archive This Folder" = "Arkiver denne mappen"; "Archive This Folder" = "Arkiver denne mappen";
"Modify the acl of this folder" = "Endre adgangsrettigheter til 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"; "Update" = "Oppdater";
"Cancel" = "Avbryt"; "Cancel" = "Avbryt";
@ -113,7 +113,7 @@
"Return Receipt" = "Returkvittering"; "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?"; "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) - %@"; "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"; "Priority" = "Prioritet";
"highest" = "Høyest"; "highest" = "Høyest";
@ -130,7 +130,7 @@
/* Popup "show" */ /* Popup "show" */
"all" = "alle"; "all" = "alle";
"read" = "les"; "read" = "leste";
"unread" = "ulest"; "unread" = "ulest";
"deleted" = "slettet"; "deleted" = "slettet";
"flagged" = "flagget"; "flagged" = "flagget";
@ -192,13 +192,13 @@
"Mark Folder Read" = "Merk mappe som lest..."; "Mark Folder Read" = "Merk mappe som lest...";
"New Folder..." = "Ny mappe..."; "New Folder..." = "Ny mappe...";
"Compact This Folder" = "Komprimer mappen"; "Compact This Folder" = "Komprimer mappen";
"Search Messages..." = "Søk meldinger..."; "Search Messages..." = "Søk i meldinger...";
"Sharing..." = "Deling..."; "Sharing..." = "Deling...";
"New Subfolder..." = "Ny undermappe..."; "New Subfolder..." = "Ny undermappe...";
"Rename Folder..." = "Endre navn på mappe..."; "Rename Folder..." = "Endre navn på mappe...";
"Delete Folder" = "Slett mappe"; "Delete Folder" = "Slett mappe";
"Use This Folder For" = "Bruk mappen til"; "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..."; "Properties..." = "Egenskaper...";
"Delegation..." = "Delegasjon..."; "Delegation..." = "Delegasjon...";
@ -211,7 +211,7 @@
"Open Message In New Window" = "Åpne melding i nytt vindu"; "Open Message In New Window" = "Åpne melding i nytt vindu";
"Reply to Sender Only" = "Svar kun til avsender"; "Reply to Sender Only" = "Svar kun til avsender";
"Reply to All" = "Svar alle"; "Reply to All" = "Svar alle";
"Edit As New..." = "Redigere som nytt..."; "Edit As New..." = "Rediger som ny...";
"Move To" = "Flytt til"; "Move To" = "Flytt til";
"Copy To" = "Kopier til"; "Copy To" = "Kopier til";
"Label" = "Etikett"; "Label" = "Etikett";
@ -248,22 +248,21 @@
"Enter the new name of your folder :" "Enter the new name of your folder :"
= "Skriv navnet på mappen: "; = "Skriv navnet på mappen: ";
"Do you really want to move this folder into the trash ?" "Do you really want to move this folder into the trash ?"
= "Vil du virkelig flytte mappen till papirkurven?"; = "Vil du virkelig flytte mappen til papirkurven?";
"Operation failed" = "Operasjonen misslykkes"; "Operation failed" = "Operasjonen mislykkes";
"Quota" = "Disktildeling"; "Quota" = "Disktildeling";
"quotasFormat" = "%{0}% brukt av %{1} MB"; "quotasFormat" = "%{0}% brukt av %{1} MB";
"Please select a message." = "Marker en melding."; "Please select a message." = "Markér en melding.";
"Please select a message to print." = "Marker en melding som skal skrives ut."; "Please select a message to print." = "Markér en melding som skal skrives ut.";
"Please select only one message to print." = "Marker bare 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 som du markerte finnes ikke lengre."; "The message you have selected doesn't exist anymore." = "Meldingen du markerte finnes ikke lengre.";
"The folder with name \"%{0}\" could not be created." "The folder with name \"%{0}\" could not be created."
= "Mappen \"%{0}\" kunne ikke opprettes."; = "Mappen \"%{0}\" kunne ikke opprettes.";
"This folder could not be renamed to \"%{0}\"." "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." "The folder could not be deleted."
= "Mappen kunne ikke slettes."; = "Mappen kunne ikke slettes.";
"The trash could not be emptied." "The trash could not be emptied."
@ -271,7 +270,7 @@
"The folder functionality could not be changed." "The folder functionality could not be changed."
= "Mappens funksjon kunne ikke endres."; = "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!" "Moving a message into its own folder is impossible!"
= "Det er ikke mulig å flytte en e-postmelding til samme mappe!"; = "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?"; = "Meldingene kunne ikke flyttes til søppelmappen. Vil du slette dem umiddelbart?";
/* Message editing */ /* Message editing */
"error_validationfailed" = "Validering misslykket"; "error_missingsubject" = "Emnefelt mangler. Vil du likevel sende meldingen?";
"error_missingsubject" = "Emnefelt mangler"; "error_missingrecipients" = "Ingen mottakere er angitt";
"error_missingrecipients" = "Ingen mottagere er angitt"; "Send Anyway" = "Send likevel";
/* Message sending */ /* Message sending */
"cannot send message: (smtp) all recipients discarded" = "Kan ikke sende melding: alle mottakeradresser er ugyldige."; "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) - 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"; "Email" = "E-post";
"Name" = "Navn";

View file

@ -32,6 +32,7 @@
#import <NGObjWeb/WOResponse.h> #import <NGObjWeb/WOResponse.h>
#import <NGImap4/NGImap4Connection.h> #import <NGImap4/NGImap4Connection.h>
#import <NGImap4/NGImap4Client.h> #import <NGImap4/NGImap4Client.h>
#import <NGImap4/NSString+Imap4.h>
#import <NGExtensions/NSString+misc.h> #import <NGExtensions/NSString+misc.h>
#import <Mailer/SOGoMailAccount.h> #import <Mailer/SOGoMailAccount.h>
@ -123,7 +124,7 @@
- (NSArray *) _jsonFolders: (NSEnumerator *) rawFolders - (NSArray *) _jsonFolders: (NSEnumerator *) rawFolders
{ {
NSString *currentFolder, *currentDisplayName, *currentFolderType, *login, *fullName; NSString *currentFolder, *currentDecodedFolder, *currentDisplayName, *currentFolderType, *login, *fullName;
NSMutableArray *pathComponents; NSMutableArray *pathComponents;
SOGoUserManager *userManager; SOGoUserManager *userManager;
NSDictionary *folderData; NSDictionary *folderData;
@ -138,17 +139,19 @@
// are never reused and "autoreleased" at the end. This loop would consume // are never reused and "autoreleased" at the end. This loop would consume
// lots of LDAP connections during its execution. // lots of LDAP connections during its execution.
pool = [[NSAutoreleasePool alloc] init]; pool = [[NSAutoreleasePool alloc] init];
currentFolderType = [self _folderType: currentFolder];
currentDecodedFolder = [currentFolder stringByDecodingImap4FolderName];
currentFolderType = [self _folderType: currentDecodedFolder];
// We translate the "Other Users" and "Shared Folders" namespaces. // We translate the "Other Users" and "Shared Folders" namespaces.
// While we're at it, we also translate the user's mailbox names // While we're at it, we also translate the user's mailbox names
// to the full name of the person. // 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 // 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 // also have something like /shared under Dovecot. So we swap the username only
// if we have one, of course. // if we have one, of course.
pathComponents = [NSMutableArray arrayWithArray: [currentFolder pathComponents]]; pathComponents = [NSMutableArray arrayWithArray: [currentDecodedFolder pathComponents]];
if ([pathComponents count] > 2) if ([pathComponents count] > 2)
{ {
@ -166,14 +169,14 @@
else else
{ {
currentDisplayName = [NSString stringWithFormat: @"/%@%@", [self labelForKey: @"OtherUsersFolderName"], 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"], currentDisplayName = [NSString stringWithFormat: @"/%@%@", [self labelForKey: @"SharedFoldersName"],
[currentFolder substringFromIndex: [sharedFoldersName length]]]; [currentDecodedFolder substringFromIndex: [sharedFoldersName length]]];
else else
currentDisplayName = currentFolder; currentDisplayName = currentDecodedFolder;
folderData = [NSDictionary dictionaryWithObjectsAndKeys: folderData = [NSDictionary dictionaryWithObjectsAndKeys:
currentFolder, @"path", currentFolder, @"path",

View file

@ -567,8 +567,8 @@ static NSArray *infoKeys = nil;
{ {
info = [self storeInfo]; info = [self storeInfo];
[co setHeaders: info]; [co setHeaders: info];
[co setText: text];
[co setIsHTML: isHTML]; [co setIsHTML: isHTML];
[co setText: (isHTML ? [NSString stringWithFormat: @"<html>%@</html>", text] : text)];;
error = [co storeInfo]; error = [co storeInfo];
if (error) if (error)
{ {

View file

@ -7,12 +7,12 @@
"Domain:" = "Domene:"; "Domain:" = "Domene:";
"Remember username" = "Husk brukernavn"; "Remember username" = "Husk brukernavn";
"Connect" = "Logg inn"; "Connect" = "Koble til";
"Wrong username or password." = "Feil brukernavn eller passord."; "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"; "alternativeBrowsers" = "Alternativt kan du også forsøke følgende kompatible nettlesere";
"alternativeBrowserSafari" = "Alternativt kan du også bruke Safari."; "alternativeBrowserSafari" = "Alternativt kan du også bruke Safari.";
"Download" = "Last ned"; "Download" = "Last ned";
@ -44,19 +44,19 @@
"Welsh" = "Cymraeg"; "Welsh" = "Cymraeg";
"About" = "Om"; "About" = "Om";
"AboutBox" = "Utviklet av Inverse, SOGo er en komplett gruppevaretjener med foks på skalerbarhet og enkel bruk.<br/><br/>\nSOGo tilbyr ett rikt AJAX-basert webgrensesnitt, og støtter mange 3. parts klienter gjennom standardprotokoller som CalDAV og CardDAV.<br/><br/>\nSOGo er distribuert under <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> 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 <a href=\"http://www.sogo.nu/en/support/community.html\">denne siden</a> for support-muligheter."; "AboutBox" = "Utviklet av Inverse, SOGo er en komplett gruppevaretjener med fokus på skalerbarhet og enkel bruk.<br/><br/>\nSOGo tilbyr ett rikt AJAX-basert webgrensesnitt, og støtter mange 3. parts klienter gjennom standardprotokoller som CalDAV og CardDAV.<br/><br/>\nSOGo er distribuert under <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> 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 <a href=\"http://www.sogo.nu/en/support/community.html\">denne siden</a> 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."; "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"; "Change your Password" = "Endre ditt passord";
"The password was changed successfully." = "Passordet ble endret."; "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:"; "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."; "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."; "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."; "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}."; "Your password is going to expire in %{0} %{1}." = "Ditt passord vil utløpe om %{0} %{1}.";
"days" = "dager"; "days" = "dager";
"hours" = "timer"; "hours" = "timer";
@ -66,12 +66,12 @@
"Password change failed - Permission denied" = "Feil ved endring av passord - tillatelse nektet"; "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 - 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 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 too young" = "Feil ved endring av passord - Passordet er nylig brukt";
"Password change failed - Password is in history" = "Feil ved endring av passord - Password is in history"; "Password change failed - Password is in history" = "Feil ved endring av passord - Passordet har blitt brukt før";
"Unhandled policy error: %{0}" = ""; "Unhandled policy error: %{0}" = "Uhåndtert policyfeil: %{0}";
"Unhandled error response" = ""; "Unhandled error response" = "Uhåndtert feilmelding.";
"Password change is not supported." = "Passordendring er ikke støttet."; "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:"; "New password:" = "Nytt passord:";
"Confirmation:" = "Bekreftelse:"; "Confirmation:" = "Bekreftelse:";
"Cancel" = "Avbryt"; "Cancel" = "Avbryt";

View file

@ -19,6 +19,7 @@
"Language:" = "Jazyk:"; "Language:" = "Jazyk:";
"choose" = "Výber ..."; "choose" = "Výber ...";
"Arabic" = "العربية";
"Catalan" = "Katalánsky"; "Catalan" = "Katalánsky";
"Czech" = "Česky"; "Czech" = "Česky";
"Danish" = "Dansk (Danmark)"; "Danish" = "Dansk (Danmark)";

View file

@ -210,11 +210,11 @@
"Danish" = "Dansk (Danmark)"; "Danish" = "Dansk (Danmark)";
"Dutch" = "Nederlands"; "Dutch" = "Nederlands";
"English" = "English"; "English" = "English";
"Finnish" = "Finsk"; "Finnish" = "Suomi";
"French" = "Français"; "French" = "Français";
"German" = "Deutsch"; "German" = "Deutsch";
"Hungarian" = "Magyar"; "Hungarian" = "Magyar";
"Icelandic" = "Islandsk"; "Icelandic" = "Íslenska";
"Italian" = "Italiano"; "Italian" = "Italiano";
"NorwegianBokmal" = "Norsk"; "NorwegianBokmal" = "Norsk";
"NorwegianNynorsk" = "Nynorsk"; "NorwegianNynorsk" = "Nynorsk";

View file

@ -185,7 +185,6 @@
"German" = "Deutsch"; "German" = "Deutsch";
"Hungarian" = "Magyar"; "Hungarian" = "Magyar";
"Icelandic" = "Íslenska"; "Icelandic" = "Íslenska";
"Icelandic" = "Íslenska";
"Italian" = "Italiano"; "Italian" = "Italiano";
"NorwegianBokmal" = "Norsk bokmål"; "NorwegianBokmal" = "Norsk bokmål";
"NorwegianNynorsk" = "Norsk nynorsk"; "NorwegianNynorsk" = "Norsk nynorsk";

View file

@ -6,8 +6,8 @@
"General" = "Generelt"; "General" = "Generelt";
"Calendar Options" = "Kalenderinnstillinger"; "Calendar Options" = "Kalenderinnstillinger";
"Contacts Options" = "Kontaktinnstillinger"; "Contacts Options" = "Kontaktinnstillinger";
"Mail Options" = "E-post innstillinger"; "Mail Options" = "E-postinnstillinger";
"IMAP Accounts" = "IMAP kontoer"; "IMAP Accounts" = "IMAP-kontoer";
"Vacation" = "Fravær"; "Vacation" = "Fravær";
"Forward" = "Videresend"; "Forward" = "Videresend";
"Password" = "Passord"; "Password" = "Passord";
@ -18,7 +18,7 @@
"Delete" = "Fjern"; "Delete" = "Fjern";
/* contacts categories */ /* 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) */ /* vacation (auto-reply) */
"Enable vacation auto reply" = "Aktiver auto-svar ved fravær"; "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"; "Do not send responses to mailing lists" = "Ikke send svar til e-postlister";
"Disable auto reply on" = "Skru av auto-svar"; "Disable auto reply on" = "Skru av auto-svar";
"Please specify your message and your email addresses for which you want to enable auto reply." "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. "; "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." "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 messages */
"Forward incoming messages" = "Videresend innkommende e-post"; "Forward incoming messages" = "Videresend innkommende e-post";
@ -87,6 +87,7 @@
"timeFmt_1" = "%H:%M"; "timeFmt_1" = "%H:%M";
"timeFmt_2" = ""; "timeFmt_2" = "";
"timeFmt_3" = ""; "timeFmt_3" = "";
"timeFmt_4" = "";
/* calendar */ /* calendar */
"Week begins on :" = "Uken begynner med:"; "Week begins on :" = "Uken begynner med:";
@ -101,11 +102,11 @@
"Default reminder :" = "Standardpåminnelse:"; "Default reminder :" = "Standardpåminnelse:";
"firstWeekOfYear_January1" = "Begynner den 1. januar"; "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"; "firstWeekOfYear_FirstFullWeek" = "Første hele uken i året";
/* Default Calendar */ /* Default Calendar */
"Default calendar :" = "Standard kalender"; "Default calendar :" = "Standard kalender:";
"selectedCalendar" = "Valgte kalender"; "selectedCalendar" = "Valgte kalender";
"personalCalendar" = "Personlig kalender"; "personalCalendar" = "Personlig kalender";
"firstCalendar" = "Første aktiverte kalender"; "firstCalendar" = "Første aktiverte kalender";
@ -129,17 +130,18 @@
"Check for new mail:" = "Hent ny post:"; "Check for new mail:" = "Hent ny post:";
"messagecheck_manually" = "Manuelt"; "messagecheck_manually" = "Manuelt";
"messagecheck_every_minute" = "Hvert minutt"; "messagecheck_every_minute" = "Hvert minutt";
"messagecheck_every_2_minutes" = "Hvert 2 minutt"; "messagecheck_every_2_minutes" = "Hvert 2. minutt";
"messagecheck_every_5_minutes" = "Hvert 5 minutt"; "messagecheck_every_5_minutes" = "Hvert 5. minutt";
"messagecheck_every_10_minutes" = "Hvert 10 minutt"; "messagecheck_every_10_minutes" = "Hvert 10. minutt";
"messagecheck_every_20_minutes" = "Hvert 20 minutt"; "messagecheck_every_20_minutes" = "Hvert 20. minutt";
"messagecheck_every_30_minutes" = "Hvert 30 minutt"; "messagecheck_every_30_minutes" = "Hvert 30. minutt";
"messagecheck_once_per_hour" = "Hver time"; "messagecheck_once_per_hour" = "Hver time";
"Forward messages:" = "Videresend melding:"; "Forward messages:" = "Videresend meldinger:";
"messageforward_inline" = "Innsatt"; "messageforward_inline" = "Innsatt";
"messageforward_attached" = "Vedlegg"; "messageforward_attached" = "Vedlegg";
"When replying to a message:" = "Ved svar på melding: ";
"replyplacement_above" = "Start svaret ovenfor"; "replyplacement_above" = "Start svaret ovenfor";
"replyplacement_below" = "Start svaret under"; "replyplacement_below" = "Start svaret under";
"And place my signature" = "Legg til min signatur"; "And place my signature" = "Legg til min signatur";
@ -148,23 +150,32 @@
"Compose messages in" = "Opprett melding i"; "Compose messages in" = "Opprett melding i";
"composemessagestype_html" = "HTML"; "composemessagestype_html" = "HTML";
"composemessagestype_text" = "Ren text"; "composemessagestype_text" = "Ren text";
"Display remote inline images" = "Vis bilder lenket til fra andre nettsteder";
"displayremoteinlineimages_never" = "Aldri";
"displayremoteinlineimages_always" = "Alltid";
/* IMAP Accounts */ /* IMAP Accounts */
"New Mail Account" = "Ny epostkonto"; "New Mail Account" = "Ny e-postkonto";
"Server Name:" = "Servernavn:"; "Server Name:" = "Servernavn:";
"Port:" = "Port:"; "Port:" = "Port:";
"Encryption:" = "Kryptering:";
"None" = "Ingen";
"User Name:" = "Brukernavn:"; "User Name:" = "Brukernavn:";
"Password:" = "Passord:"; "Password:" = "Passord:";
"Full Name:" = "Fullt Navn:"; "Full Name:" = "Fullt navn:";
"Email:" = "E-post:"; "Email:" = "E-post:";
"Reply To Email:" = "Svar til e-post:";
"Signature:" = "Signatur:"; "Signature:" = "Signatur:";
"(Click to create)" = "(Klikk for å opprette)"; "(Click to create)" = "(Klikk for å opprette)";
"Signature" = "Signatur"; "Signature" = "Signatur";
"Please enter your signature below:" = "Vennligst fyll ut signatur under:"; "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 */
"Additional Parameters" = "Øvrige parametre"; "Additional Parameters" = "Øvrige parametre";
@ -174,11 +185,11 @@
"Change" = "Endre"; "Change" = "Endre";
/* Event+task classifications */ /* Event+task classifications */
"Default events classification :" = "Default events classification :"; "Default events classification :" = "Standard hendelsesklassifikasjon:";
"Default tasks classification :" = "Default tasks classification :"; "Default tasks classification :" = "Standard oppgaveklassifisering";
"PUBLIC_item" = "Public"; "PUBLIC_item" = "Offentlig";
"CONFIDENTIAL_item" = "Confidential"; "CONFIDENTIAL_item" = "Konfidensiell";
"PRIVATE_item" = "Private"; "PRIVATE_item" = "Privat";
/* Event+task categories */ /* Event+task categories */
"category_none" = "Ingen"; "category_none" = "Ingen";
@ -208,9 +219,9 @@
"NorwegianBokmal" = "Norsk bokmål"; "NorwegianBokmal" = "Norsk bokmål";
"NorwegianNynorsk" = "Norsk nynorsk"; "NorwegianNynorsk" = "Norsk nynorsk";
"BrazilianPortuguese" = "Português brasileiro"; "BrazilianPortuguese" = "Português brasileiro";
"Polish" = "Polski"; "Polish" = "Polsk";
"Russian" = "Русский"; "Russian" = "Русский";
"Slovak" = "Slovensky"; "Slovak" = "Slovensk";
"SpanishSpain" = "Español (España)"; "SpanishSpain" = "Español (España)";
"SpanishArgentina" = "Español (Argentina)"; "SpanishArgentina" = "Español (Argentina)";
"Swedish" = "Svenska"; "Swedish" = "Svenska";
@ -221,12 +232,12 @@
"When I receive a request for a return receipt:" = "Når jeg mottar anmodning om en returkvittering:"; "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"; "Never send a return receipt" = "Send aldri en returkvittering";
"Allow return receipts for some messages" = "Tillat returkvittering for noen meldinger"; "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:"; "If the sender is outside my domain:" = "Hvis senderen er utenfor mitt domene:";
"In all other cases:" = "I alle andre tilfeller:"; "In all other cases:" = "I alle andre tilfeller:";
"Never send" = "Send aldri"; "Never send" = "Aldri send";
"Always send" = "Send alltid"; "Always send" = "Alltid send";
"Ask me" = "Spør meg"; "Ask me" = "Spør meg";
/* Filters - UIxPreferences */ /* Filters - UIxPreferences */
@ -242,6 +253,7 @@
"match any of the following rules:" = "samsvarer med en av følgende regler:"; "match any of the following rules:" = "samsvarer med en av følgende regler:";
"match all messages" = "samsvarer med alle meldinger"; "match all messages" = "samsvarer med alle meldinger";
"Perform these actions:" = "Utfør disse handlingene:"; "Perform these actions:" = "Utfør disse handlingene:";
"Untitled Filter" = "Ikke navngitt filter";
"Subject" = "Emne"; "Subject" = "Emne";
"From" = "Fra"; "From" = "Fra";
@ -264,11 +276,11 @@
"is" = "er"; "is" = "er";
"is not" = "er ikke"; "is not" = "er ikke";
"contains" = "inneholder"; "contains" = "inneholder";
"does not contain" = "inneholder ikker"; "does not contain" = "inneholder ikke";
"matches" = "samsvarer"; "matches" = "samsvarer med";
"does not match" = "samsvarer ikke"; "does not match" = "samsvarer ikke med";
"matches regex" = "samsvarer regex"; "matches regex" = "samsvarer med regex";
"does not match regex" = "samvarer ikke regex"; "does not match regex" = "samvarer ikke med regex";
"Seen" = "Sett"; "Seen" = "Sett";
"Deleted" = "Slettet"; "Deleted" = "Slettet";
@ -282,15 +294,16 @@
"Label 4" = "Etikett 4"; "Label 4" = "Etikett 4";
"Label 5" = "Etikett 5"; "Label 5" = "Etikett 5";
"The password was changed successfully." = "Passordet ble endret.";
"Password must not be empty." = "Passord kan ikke være tomme."; "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."; "The passwords do not match. Please try again." = "Passordene er ikke like. Prøv igjen.";
"Password change failed" = "Passordendring feilet"; "Password change failed" = "Passordendring feilet";
"Password change failed - Permission denied" = "Passordendring feilet -- ikke tilgang"; "Password change failed - Permission denied" = "Passordendring feilet - ikke tilgang";
"Password change failed - Insufficient password quality" = "Passordendring feilet -- for dårlig passord"; "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 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 too young" = "Passordendring feilet - passordet er nylig brukt før";
"Password change failed - Password is in history" = "Passordendring feilet -- passordet er brukt før"; "Password change failed - Password is in history" = "Passordendring feilet - passordet er brukt før";
"Unhandled policy error: %{0}" = ""; "Unhandled policy error: %{0}" = "Uhåndtert policy-feil: %{0}";
"Unhandled error response" = ""; "Unhandled error response" = "Uhåndtert feilrespons";
"Password change is not supported." = "Passordendring er ikke støttet."; "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}";

View file

@ -141,6 +141,7 @@
"messageforward_inline" = "Incorporado"; "messageforward_inline" = "Incorporado";
"messageforward_attached" = "Como adjunto"; "messageforward_attached" = "Como adjunto";
"When replying to a message:" = "Cuando responda a un mensaje:";
"replyplacement_above" = "Empezar mi respuesta sobre el texto citado"; "replyplacement_above" = "Empezar mi respuesta sobre el texto citado";
"replyplacement_below" = "Empieza mi respuesta bajo el texto citado"; "replyplacement_below" = "Empieza mi respuesta bajo el texto citado";
"And place my signature" = "Y añadir mi firma"; "And place my signature" = "Y añadir mi firma";
@ -149,12 +150,17 @@
"Compose messages in" = "Redactar los mensajes en"; "Compose messages in" = "Redactar los mensajes en";
"composemessagestype_html" = "HTML"; "composemessagestype_html" = "HTML";
"composemessagestype_text" = "Texto plano"; "composemessagestype_text" = "Texto plano";
"Display remote inline images" = "Mostrar las imágenes remotas";
"displayremoteinlineimages_never" = "Nunca";
"displayremoteinlineimages_always" = "Siempre";
/* IMAP Accounts */ /* IMAP Accounts */
"New Mail Account" = "Nueva Cuenta de Correo"; "New Mail Account" = "Nueva Cuenta de Correo";
"Server Name:" = "Nombre del servidor:"; "Server Name:" = "Nombre del servidor:";
"Port:" = "Puerto:"; "Port:" = "Puerto:";
"Encryption:" = "Cifrado:";
"None" = "Sin cifrar";
"User Name:" = "Nombre de usuario:"; "User Name:" = "Nombre de usuario:";
"Password:" = "Contraseña:"; "Password:" = "Contraseña:";

View file

@ -376,7 +376,7 @@
"Show Time as Free" = "Čas zobrazit jako volný"; "Show Time as Free" = "Čas zobrazit jako volný";
/* email notifications */ /* email notifications */
"Send Appointment Notifications" = "Poslat připomenutí"; "Send Appointment Notifications" = "Poslat upozornění na schůzku";
/* validation errors */ /* validation errors */

View file

@ -179,6 +179,8 @@
"Reminder:" = "Muistuttaja:"; "Reminder:" = "Muistuttaja:";
"General:" = "Yleinen:"; "General:" = "Yleinen:";
"Reply:" = "Vastaus:"; "Reply:" = "Vastaus:";
"Created by:" = "Luonut:";
"Target:" = "Kohde:"; "Target:" = "Kohde:";
@ -373,6 +375,9 @@
"Show Time as Free" = "Näytä aika vapaana"; "Show Time as Free" = "Näytä aika vapaana";
/* email notifications */
"Send Appointment Notifications" = "Lähetä tapaamismuistutukset";
/* validation errors */ /* validation errors */
validate_notitle = "Otsikkoa ei ole asetettu, jatka?"; validate_notitle = "Otsikkoa ei ole asetettu, jatka?";

View file

@ -179,6 +179,8 @@
"Reminder:" = "Emlékeztető:"; "Reminder:" = "Emlékeztető:";
"General:" = "Általános:"; "General:" = "Általános:";
"Reply:" = "Válasz:"; "Reply:" = "Válasz:";
"Created by:" = "Létrehozta:";
"Target:" = "Cél:"; "Target:" = "Cél:";
@ -373,6 +375,9 @@
"Show Time as Free" = "Ne jelezzen foglaltságot"; "Show Time as Free" = "Ne jelezzen foglaltságot";
/* email notifications */
"Send Appointment Notifications" = "Találkozó értesítések küldése";
/* validation errors */ /* validation errors */
validate_notitle = "A cím nincs megadva, folytatja?"; validate_notitle = "A cím nincs megadva, folytatja?";

View file

@ -1,3 +1,4 @@
/* this file is in UTF-8 format! */
/* Tooltips */ /* Tooltips */
@ -51,15 +52,16 @@
"Contacts" = "Kontakter"; "Contacts" = "Kontakter";
"New Calendar..." = "Ny kalender..."; "New Calendar..." = "Ny kalender...";
"Delete Calendar" = "Slett kalender"; "Delete Calendar" = "Slett kalender...";
"Unsubscribe Calendar" = "Avslutt abonnement på kalender"; "Unsubscribe Calendar" = "Avslutt abonnement på kalender";
"Sharing..." = "Deling..."; "Sharing..." = "Deling...";
"Export Calendar..." = "Eksorter kalender..."; "Export Calendar..." = "Eksporter kalender...";
"Import Events..." = "Importer hendelser..."; "Import Events..." = "Importer hendelser...";
"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"; "Upload" = "Last opp";
"Publish Calendar..." = "Publiser Kalender..."; "Uploading" = "Laster opp";
"Publish Calendar..." = "Publiser kalender...";
"Reload Remote Calendars" = "Last på nytt fjernkalendre"; "Reload Remote Calendars" = "Last på nytt fjernkalendre";
"Properties" = "Egenskaper"; "Properties" = "Egenskaper";
"Done" = "Klar"; "Done" = "Klar";
@ -98,14 +100,14 @@
"View All" = "Vis alle"; "View All" = "Vis alle";
"View the Date & Time" = "Vis tid og dato"; "View the Date & Time" = "Vis tid og dato";
"Modify" = "Endra"; "Modify" = "Endre";
"Respond To" = "Svar"; "Respond To" = "Svar";
"None" = "Ingen"; "None" = "Ingen";
"This person can create objects in my calendar." "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." "This person can erase objects from my calendar."
= "Personen kan fjerne objekt i min kalender."; = "Personen kan fjerne objekter i min kalender.";
/* Button Titles */ /* Button Titles */
@ -159,7 +161,7 @@
"Email" = "E-post"; "Email" = "E-post";
"Status:" = "Status:"; "Status:" = "Status:";
"% complete" = "% utført"; "% complete" = "% utført";
"Location:" = "Plass:"; "Location:" = "Sted:";
"Priority:" = "Prioritet:"; "Priority:" = "Prioritet:";
"Privacy" = "Personvern"; "Privacy" = "Personvern";
"Cycle" = "Intervall"; "Cycle" = "Intervall";
@ -169,7 +171,7 @@
"Duration" = "Varighet"; "Duration" = "Varighet";
"Attendees:" = "Deltakere:"; "Attendees:" = "Deltakere:";
"Resources" = "Ressurser"; "Resources" = "Ressurser";
"Organizer:" = "Organisatør:"; "Organizer:" = "Organisator:";
"Description:" = "Beskrivelse:"; "Description:" = "Beskrivelse:";
"Document:" = "Dokument:"; "Document:" = "Dokument:";
"Category:" = "Kategori:"; "Category:" = "Kategori:";
@ -178,6 +180,7 @@
"General:" = "Generell:"; "General:" = "Generell:";
"Reply:" = "Svar:"; "Reply:" = "Svar:";
"Target:" = "Mål:"; "Target:" = "Mål:";
"attributes" = "attributter"; "attributes" = "attributter";
@ -193,22 +196,22 @@
"empty title" = "Ingen tittel"; "empty title" = "Ingen tittel";
"private appointment" = "Privat møte"; "private appointment" = "Privat møte";
"Change..." = "Endra..."; "Change..." = "Endre...";
/* Appointments (participation state) */ /* Appointments (participation state) */
"partStat_NEEDS-ACTION" = "Trenger handling"; "partStat_NEEDS-ACTION" = "Jeg vil bekrefte senere";
"partStat_ACCEPTED" = "Jeg kan delta"; "partStat_ACCEPTED" = "Jeg vil delta";
"partStat_DECLINED" = "Jeg kan ikke delta"; "partStat_DECLINED" = "Jeg kan ikke delta";
"partStat_TENTATIVE" = "Jeg kommer tilbake"; "partStat_TENTATIVE" = "Jeg kommer kanskje";
"partStat_DELEGATED" = "Jeg delegerer"; "partStat_DELEGATED" = "Jeg delegerer";
"partStat_OTHER" = "Annet"; "partStat_OTHER" = "Annet";
/* Appointments (error messages) */ /* Appointments (error messages) */
"Conflicts found!" = "Konflikter funnet!"; "Conflicts found!" = "Konflikter funnet!";
"Invalid iCal data!" = "Ugyldig iCal data!"; "Invalid iCal data!" = "Ugyldig iCal-data!";
"Could not create iCal data!" = "Kunne ikke opprette iCal data!"; "Could not create iCal data!" = "Kunne ikke opprette iCal-data!";
/* Searching */ /* Searching */
@ -301,12 +304,12 @@
"Week(s)" = "Uke(r)"; "Week(s)" = "Uke(r)";
"On" = "På"; "On" = "På";
"Month(s)" = "Måned(er)"; "Month(s)" = "Måned(er)";
"The" = ""; "The" = " Den";
"Recur on day(s)" = "Gjentas på dag(er)"; "Recur on day(s)" = "Gjentas på dag(er)";
"Year(s)" = "År"; "Year(s)" = "År";
"cycle_of" = "av"; "cycle_of" = "av";
"No end date" = "Ingen sluttdato"; "No end date" = "Ingen sluttdato";
"Create" = "Oprett"; "Create" = "Opprett";
"appointment(s)" = "avtale(r)"; "appointment(s)" = "avtale(r)";
"Repeat until" = "Gjenta til"; "Repeat until" = "Gjenta til";
@ -322,7 +325,7 @@
"category_none" = "Ingen"; "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"; "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_DAILY" = "Daglig";
"repeat_WEEKLY" = "Ukentlig"; "repeat_WEEKLY" = "Ukentlig";
"repeat_BI-WEEKLY" = "Annenhver uke"; "repeat_BI-WEEKLY" = "Annenhver uke";
@ -351,15 +354,15 @@
"reminder_DAYS" = "dager"; "reminder_DAYS" = "dager";
"reminder_BEFORE" = "før"; "reminder_BEFORE" = "før";
"reminder_AFTER" = "etter"; "reminder_AFTER" = "etter";
"reminder_START" = "hendelser starter"; "reminder_START" = "hendelsen starter";
"reminder_END" = "hendelser slutter"; "reminder_END" = "hendelsen slutter";
"Reminder Details" = "Påminnelsedetaljer"; "Reminder Details" = "Påminnelsedetaljer";
"Choose a Reminder Action" = "Velg en påminnelsesmåte"; "Choose a Reminder Action" = "Velg en påminnelsesmåte";
"Show an Alert" = "Vis en alarm"; "Show an Alert" = "Vis en alarm";
"Send an E-mail" = "Send en E-post"; "Send an E-mail" = "Send en E-post";
"Email Organizer" = "E-post organisator"; "Email Organizer" = "E-post-organisator";
"Email Attendees" = "E-post deltakere"; "Email Attendees" = "E-post-deltakere";
"zoom_400" = "400%"; "zoom_400" = "400%";
"zoom_200" = "200%"; "zoom_200" = "200%";
@ -371,6 +374,8 @@
"Show Time as Free" = "Vis tid som ledig"; "Show Time as Free" = "Vis tid som ledig";
/* email notifications */
/* validation errors */ /* validation errors */
validate_notitle = "Ingen tittel er angitt, fortsette?"; validate_notitle = "Ingen tittel er angitt, fortsette?";
@ -378,6 +383,7 @@ validate_invalid_startdate = "Feil startdato!";
validate_invalid_enddate = "Feil sluttdato!"; validate_invalid_enddate = "Feil sluttdato!";
validate_endbeforestart = "Angitt sluttdato inntreffer før angitt startdato."; validate_endbeforestart = "Angitt sluttdato inntreffer før angitt startdato.";
"Events" = "Hendelser";
"Tasks" = "Oppgaver"; "Tasks" = "Oppgaver";
"Show completed tasks" = "Vis utførte oppgave"; "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 Event..." = "Ny hendelse...";
"New Task..." = "Ny oppgave..."; "New Task..." = "Ny oppgave...";
"Edit Selected Event..." = "Endre hendelse..."; "Edit Selected Event..." = "Endre hendelse...";
"Delete Selected Event" = "Slett hendelse"; "Delete Selected Event" = "Slett valgt hendelse";
"Select All" = "Velg alle"; "Select All" = "Velg alle";
"Workweek days only" = "Bare arbeidsdager"; "Workweek days only" = "Bare arbeidsdager";
"Tasks in View" = "Oppgaver i visning"; "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?"; "taskDeleteConfirmation" = "Sletting av oppgaven er permanent.\nVil du fortsette?";
"You cannot remove nor unsubscribe from your personal calendar." "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}\"?" "Are you sure you want to delete the calendar \"%{0}\"?"
= "Er du sikker på at du vil slette kalenderen \"%{0}\"?"; = "Er du sikker på at du vil slette kalenderen \"%{0}\"?";
/* Legend */ /* Legend */
"Participant" = "Deltakelse kreves"; "Participant" = "Deltakelse kreves";
"Optional Participant" = "Deltakelse valgfritt"; "Optional Participant" = "Deltakelse valgfritt";
"Non Participant" = "Ingen deltaker"; "Non Participant" = "Ingen deltakelse";
"Chair" = "Stol"; "Chair" = "Stol";
"Needs action" = "Trenger handling"; "Needs action" = "Trenger handling";
@ -430,13 +436,13 @@ validate_endbeforestart = "Angitt sluttdato inntreffer før angitt startdato.
"Free" = "Ledig"; "Free" = "Ledig";
"Busy" = "Opptatt"; "Busy" = "Opptatt";
"Maybe busy" = "Kanskje 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 */ /* FreeBusy panel buttons and labels */
"Suggest time slot:" = "Foreslå tid:"; "Suggest time slot:" = "Foreslå tid:";
"Zoom:" = "Forstørr:"; "Zoom:" = "Forstørr:";
"Previous slot" = "Forrige spor"; "Previous slot" = "Forrige tidspunkt";
"Next slot" = "Neste spor"; "Next slot" = "Neste tidspunkt";
"Previous hour" = "Forrige time"; "Previous hour" = "Forrige time";
"Next hour" = "Neste time"; "Next hour" = "Neste time";
"Work days only" = "Bare arbeidsdager"; "Work days only" = "Bare arbeidsdager";
@ -445,28 +451,32 @@ validate_endbeforestart = "Angitt sluttdato inntreffer før angitt startdato.
"and" = "og"; "and" = "og";
"A time conflict exists with one or more attendees.\nWould you like to keep the current settings anyway?" "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 */ /* apt list */
"Title" = "Tittel"; "Title" = "Tittel";
"Start" = "Start"; "Start" = "Start";
"End" = "Slutt"; "End" = "Slutt";
"Due Date" = "Dato"; "Due Date" = "Forfallsdato";
"Location" = "Plass"; "Location" = "Sted";
"(Private Event)" = "(Privat hendelse)"; "(Private Event)" = "(Privat hendelse)";
vevent_class0 = "(Offentlig hendelse)"; vevent_class0 = "(Offentlig hendelse)";
vevent_class1 = "(Privat hendelse)"; vevent_class1 = "(Privat hendelse)";
vevent_class2 = "(Konfidensiell hendelse)"; vevent_class2 = "(Konfidensiell hendelse)";
"Priority" = "Prioritet";
"Category" = "Kategori";
vtodo_class0 = "(Offentlig oppgave)"; vtodo_class0 = "(Offentlig oppgave)";
vtodo_class1 = "(Privat oppgave)"; vtodo_class1 = "(Privat oppgave)";
vtodo_class2 = "(Konfidensiell oppgave)"; vtodo_class2 = "(Konfidensiell oppgave)";
"closeThisWindowMessage" = "Takk! Du kan lukke vinduet eller din visning"; "closeThisWindowMessage" = "Takk! Du kan lukke vinduet eller se din";
"Multicolumn Day View" = "Flerkolonne dagsvisning"; "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?"; "editRepeatingItem" = "Objektet du redigerer har gjentakelser. Vil du redigere alle forekomster eller bare denne forekomsten?";
"button_thisOccurrenceOnly" = "Bare denne forekomsten"; "button_thisOccurrenceOnly" = "Bare denne forekomsten";
@ -483,9 +493,14 @@ vtodo_class2 = "(Konfidensiell oppgave)";
"Tag:" = "Merkelapp:"; "Tag:" = "Merkelapp:";
"Display" = "Vis"; "Display" = "Vis";
"Show alarms" = "Vis alarm"; "Show alarms" = "Vis alarmer";
"Show tasks" = "Vis oppgaver"; "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"; "Links to this Calendar" = "Linker til denne kalenderen";
"Authenticated User Access" = "Autentisert brukertilgang"; "Authenticated User Access" = "Autentisert brukertilgang";
"CalDAV URL" = "CalDAV url"; "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."; "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."; "appointmentFieldInvalid" = "Angi en numerisk verdi i møtesfeltet større enn eller lik 1.";
"recurrenceUnsupported" = "Denne type gjentakelse støttes ikke i dag."; "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."; "tagNotDefined" = "Du må angi en merkelapp om du vil synkronisere kalenderen.";
"tagAlreadyExists" = "Merkelappen du spesifiserte er allerede knyttet til en annen kalender."; "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?"; "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."; "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."; "EventCopyError" = "Kopiering feilet. Vennligst prøv å kopiere til en annen kalender.";
@ -514,12 +529,11 @@ vtodo_class2 = "(Konfidensiell oppgave)";
"Delete Task" = "Slett oppgave"; "Delete Task" = "Slett oppgave";
"Delete Event" = "Slett hendelse"; "Delete Event" = "Slett hendelse";
"Copy event to my calendar" = "Kopier hendelse til min kalender"; "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..."; "Subscribe to a web calendar..." = "Abonnere på en internett-kalender...";
"URL of the Calendar" = "URL til kalenderen"; "URL of the Calendar" = "URL til kalenderen";
"Web Calendar" = "Internett-kalender"; "Web Calendar" = "Internett-kalender";
"Reload on login" = "Last på nytt ved innlogging"; "Reload on login" = "Last på nytt ved innlogging";
"Invalid number." = "Ugyldig tall."; "Invalid number." = "Ugyldig tall.";
"Please identify yourself to %{0}" = "Vennligst identifiser deg for %{0}";
"Category" = "Kategori";
"Priority" = "Prioritet";

View file

@ -90,7 +90,7 @@
"label_Public" = "Публичное событие"; "label_Public" = "Публичное событие";
"label_Private" = "Личное событие"; "label_Private" = "Личное событие";
"label_Confidential" = "Показывать только время и дату"; "label_Confidential" = "Конфиденциальное";
"label_Viewer" = "Показать все"; "label_Viewer" = "Показать все";
"label_DAndTViewer" = "Показать дату и время"; "label_DAndTViewer" = "Показать дату и время";

View file

@ -179,6 +179,8 @@
"Reminder:" = "Recordatorio:"; "Reminder:" = "Recordatorio:";
"General:" = "General:"; "General:" = "General:";
"Reply:" = "Responder:"; "Reply:" = "Responder:";
"Created by:" = "Creado por:";
"Target:" = "URL documento:"; "Target:" = "URL documento:";
@ -373,6 +375,9 @@
"Show Time as Free" = "Mostrar tiempo como disponible"; "Show Time as Free" = "Mostrar tiempo como disponible";
/* email notifications */
"Send Appointment Notifications" = "Enviar avisos de evento";
/* validation errors */ /* validation errors */
validate_notitle = "Sin título, ¿continuar?"; validate_notitle = "Sin título, ¿continuar?";

Some files were not shown because too many files have changed in this diff Show more