commit
e9eb8bdc86
10
.tx/config
10
.tx/config
|
@ -4,6 +4,7 @@ host = https://www.transifex.net
|
|||
[sogo.ui-mailerui]
|
||||
source_file = UI/MailerUI/English.lproj/Localizable.strings
|
||||
source_lang = en
|
||||
trans.ar = UI/MailerUI/Arabic.lproj/Localizable.strings
|
||||
trans.ca = UI/MailerUI/Catalan.lproj/Localizable.strings
|
||||
trans.cs = UI/MailerUI/Czech.lproj/Localizable.strings
|
||||
trans.cy = UI/MailerUI/Welsh.lproj/Localizable.strings
|
||||
|
@ -29,6 +30,7 @@ trans.uk = UI/MailerUI/Ukrainian.lproj/Localizable.strings
|
|||
[sogo.ui-preferencesui]
|
||||
source_file = UI/PreferencesUI/English.lproj/Localizable.strings
|
||||
source_lang = en
|
||||
trans.ar = UI/PreferencesUI/Arabic.lproj/Localizable.strings
|
||||
trans.ca = UI/PreferencesUI/Catalan.lproj/Localizable.strings
|
||||
trans.cs = UI/PreferencesUI/Czech.lproj/Localizable.strings
|
||||
trans.cy = UI/PreferencesUI/Welsh.lproj/Localizable.strings
|
||||
|
@ -54,6 +56,7 @@ trans.uk = UI/PreferencesUI/Ukrainian.lproj/Localizable.strings
|
|||
[sogo.ui-scheduler]
|
||||
source_file = UI/Scheduler/English.lproj/Localizable.strings
|
||||
source_lang = en
|
||||
trans.ar = UI/Scheduler/Arabic.lproj/Localizable.strings
|
||||
trans.ca = UI/Scheduler/Catalan.lproj/Localizable.strings
|
||||
trans.cs = UI/Scheduler/Czech.lproj/Localizable.strings
|
||||
trans.cy = UI/Scheduler/Welsh.lproj/Localizable.strings
|
||||
|
@ -79,6 +82,7 @@ trans.uk = UI/Scheduler/Ukrainian.lproj/Localizable.strings
|
|||
[sogo.ui-contacts]
|
||||
source_file = UI/Contacts/English.lproj/Localizable.strings
|
||||
source_lang = en
|
||||
trans.ar = UI/Contacts/Arabic.lproj/Localizable.strings
|
||||
trans.ca = UI/Contacts/Catalan.lproj/Localizable.strings
|
||||
trans.cs = UI/Contacts/Czech.lproj/Localizable.strings
|
||||
trans.cy = UI/Contacts/Welsh.lproj/Localizable.strings
|
||||
|
@ -104,6 +108,7 @@ trans.uk = UI/Contacts/Ukrainian.lproj/Localizable.strings
|
|||
[sogo.ui-mainui]
|
||||
source_file = UI/MainUI/English.lproj/Localizable.strings
|
||||
source_lang = en
|
||||
trans.ar = UI/MainUI/Arabic.lproj/Localizable.strings
|
||||
trans.ca = UI/MainUI/Catalan.lproj/Localizable.strings
|
||||
trans.cs = UI/MainUI/Czech.lproj/Localizable.strings
|
||||
trans.cy = UI/MainUI/Welsh.lproj/Localizable.strings
|
||||
|
@ -129,6 +134,7 @@ trans.uk = UI/MainUI/Ukrainian.lproj/Localizable.strings
|
|||
[sogo.ui-common]
|
||||
source_file = UI/Common/English.lproj/Localizable.strings
|
||||
source_lang = en
|
||||
trans.ar = UI/Common/Arabic.lproj/Localizable.strings
|
||||
trans.ca = UI/Common/Catalan.lproj/Localizable.strings
|
||||
trans.cs = UI/Common/Czech.lproj/Localizable.strings
|
||||
trans.cy = UI/Common/Welsh.lproj/Localizable.strings
|
||||
|
@ -154,6 +160,7 @@ trans.uk = UI/Common/Ukrainian.lproj/Localizable.strings
|
|||
[sogo.ui-administrationui]
|
||||
source_file = UI/AdministrationUI/English.lproj/Localizable.strings
|
||||
source_lang = en
|
||||
trans.ar = UI/AdministrationUI/Arabic.lproj/Localizable.strings
|
||||
trans.ca = UI/AdministrationUI/Catalan.lproj/Localizable.strings
|
||||
trans.cs = UI/AdministrationUI/Czech.lproj/Localizable.strings
|
||||
trans.cy = UI/AdministrationUI/Welsh.lproj/Localizable.strings
|
||||
|
@ -179,6 +186,7 @@ trans.uk = UI/AdministrationUI/Ukrainian.lproj/Localizable.strings
|
|||
[sogo.soobjects-appointments]
|
||||
source_file = SoObjects/Appointments/English.lproj/Localizable.strings
|
||||
source_lang = en
|
||||
trans.ar = SoObjects/Appointments/Arabic.lproj/Localizable.strings
|
||||
trans.ca = SoObjects/Appointments/Catalan.lproj/Localizable.strings
|
||||
trans.cs = SoObjects/Appointments/Czech.lproj/Localizable.strings
|
||||
trans.cy = SoObjects/Appointments/Welsh.lproj/Localizable.strings
|
||||
|
@ -204,6 +212,7 @@ trans.uk = SoObjects/Appointments/Ukrainian.lproj/Localizable.strings
|
|||
[sogo.soobjects-contacts]
|
||||
source_file = SoObjects/Contacts/English.lproj/Localizable.strings
|
||||
source_lang = en
|
||||
trans.ar = SoObjects/Contacts/Arabic.lproj/Localizable.strings
|
||||
trans.ca = SoObjects/Contacts/Catalan.lproj/Localizable.strings
|
||||
trans.cs = SoObjects/Contacts/Czech.lproj/Localizable.strings
|
||||
trans.cy = SoObjects/Contacts/Welsh.lproj/Localizable.strings
|
||||
|
@ -229,6 +238,7 @@ trans.uk = SoObjects/Contacts/Ukrainian.lproj/Localizable.strings
|
|||
[sogo.ui-mailpartviewers]
|
||||
source_file = UI/MailPartViewers/English.lproj/Localizable.strings
|
||||
source_lang = en
|
||||
trans.ar = UI/MailPartViewers/Arabic.lproj/Localizable.strings
|
||||
trans.ca = UI/MailPartViewers/Catalan.lproj/Localizable.strings
|
||||
trans.cs = UI/MailPartViewers/Czech.lproj/Localizable.strings
|
||||
trans.cy = UI/MailPartViewers/Welsh.lproj/Localizable.strings
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# use *:8843 for SSL
|
||||
<VirtualHost *:8800>
|
||||
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" "8800"
|
||||
RequestHeader set "x-webobjects-server-name" "changethis:8800"
|
||||
RequestHeader set "x-webobjects-server-url" "http://changethis:8800"
|
||||
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>
|
|
@ -59,7 +59,6 @@ ProxyPass /SOGo http://127.0.0.1:20000/SOGo retry=0
|
|||
# RequestHeader set "x-webobjects-remote-user" "%{REMOTE_USER}e"
|
||||
|
||||
RequestHeader set "x-webobjects-server-protocol" "HTTP/1.0"
|
||||
RequestHeader set "x-webobjects-remote-host" %{REMOTE_HOST}e env=REMOTE_HOST
|
||||
|
||||
AddDefaultCharset UTF-8
|
||||
|
||||
|
@ -67,8 +66,3 @@ ProxyPass /SOGo http://127.0.0.1:20000/SOGo retry=0
|
|||
Allow from all
|
||||
</Proxy>
|
||||
|
||||
## We use mod_rewrite to pass remote address to the SOGo proxy.
|
||||
# The remote address will appear in SOGo's log files and in the X-Forward
|
||||
# header of emails.
|
||||
RewriteEngine On
|
||||
RewriteRule ^/SOGo/(.*)$ /SOGo/$1 [env=REMOTE_HOST:%{REMOTE_ADDR},PT]
|
||||
|
|
936
ChangeLog
936
ChangeLog
|
@ -1,3 +1,912 @@
|
|||
commit 30f10ee8f06157b1222d68b0502c80162fcbb277
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Thu Apr 11 11:30:23 2013 -0400
|
||||
|
||||
Update translations
|
||||
|
||||
M SoObjects/Appointments/Russian.lproj/Localizable.strings
|
||||
M UI/Common/BrazilianPortuguese.lproj/Localizable.strings
|
||||
M UI/Common/Russian.lproj/Localizable.strings
|
||||
M UI/Contacts/Polish.lproj/Localizable.strings
|
||||
M UI/MailerUI/BrazilianPortuguese.lproj/Localizable.strings
|
||||
M UI/MailerUI/Czech.lproj/Localizable.strings
|
||||
M UI/MailerUI/Dutch.lproj/Localizable.strings
|
||||
M UI/MailerUI/French.lproj/Localizable.strings
|
||||
M UI/MailerUI/German.lproj/Localizable.strings
|
||||
M UI/MailerUI/Hungarian.lproj/Localizable.strings
|
||||
M UI/MailerUI/Polish.lproj/Localizable.strings
|
||||
M UI/MailerUI/Russian.lproj/Localizable.strings
|
||||
M UI/MailerUI/Slovak.lproj/Localizable.strings
|
||||
M UI/MailerUI/SpanishArgentina.lproj/Localizable.strings
|
||||
M UI/MailerUI/SpanishSpain.lproj/Localizable.strings
|
||||
M UI/Scheduler/BrazilianPortuguese.lproj/Localizable.strings
|
||||
M UI/Scheduler/Czech.lproj/Localizable.strings
|
||||
M UI/Scheduler/Dutch.lproj/Localizable.strings
|
||||
M UI/Scheduler/Finnish.lproj/Localizable.strings
|
||||
M UI/Scheduler/French.lproj/Localizable.strings
|
||||
M UI/Scheduler/German.lproj/Localizable.strings
|
||||
M UI/Scheduler/Hungarian.lproj/Localizable.strings
|
||||
M UI/Scheduler/Polish.lproj/Localizable.strings
|
||||
M UI/Scheduler/Russian.lproj/Localizable.strings
|
||||
M UI/Scheduler/Slovak.lproj/Localizable.strings
|
||||
M UI/Scheduler/SpanishArgentina.lproj/Localizable.strings
|
||||
M UI/Scheduler/SpanishSpain.lproj/Localizable.strings
|
||||
|
||||
commit dfb8788270ff3b30133417a52c9052fafea19ae2
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Thu Apr 11 10:37:34 2013 -0400
|
||||
|
||||
don't build SAML support on debian yet
|
||||
|
||||
M packaging/debian/control-squeeze
|
||||
M packaging/debian/rules
|
||||
|
||||
commit 3810833e1b5c1e02cdac731da15b68057e1176af
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Thu Apr 11 10:22:28 2013 -0400
|
||||
|
||||
remove unrtf leftovers
|
||||
|
||||
M OpenChange/GNUmakefile
|
||||
D OpenChange/GNUmakefile.unrtf
|
||||
M packaging/debian-multiarch/rules
|
||||
M packaging/debian/rules
|
||||
|
||||
commit 29e05c7c81b1a92d4b6bbc9be96d40f8ae3f2482
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Thu Apr 11 10:20:10 2013 -0400
|
||||
|
||||
Bump version to 2.0.5
|
||||
|
||||
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
|
||||
M NEWS
|
||||
M Version
|
||||
|
||||
commit 0a08285facce833fecba8319c4f0b2bdf641746e
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Thu Apr 11 10:09:02 2013 -0400
|
||||
|
||||
Add note regarding precedence of .GNUstepDefaults
|
||||
|
||||
M Scripts/sogo.conf
|
||||
|
||||
commit 01f20a42ad55356c772ca2a4a758d5421e986987
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Thu Apr 11 09:18:43 2013 -0400
|
||||
|
||||
packaging fixups
|
||||
|
||||
M packaging/debian/sogo.postinst
|
||||
M packaging/rhel/sogo.spec
|
||||
|
||||
commit 3a61a2566bf2c6e95b665f2474350c8e1c59328b
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Wed Apr 10 18:24:03 2013 -0400
|
||||
|
||||
Updated installation guide: version 2.0.5
|
||||
|
||||
M Documentation/SOGo Installation Guide.odt
|
||||
|
||||
commit d2dda86529b3fe6a1d383522640f4898c00b5f25
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Wed Apr 10 16:30:16 2013 -0400
|
||||
|
||||
... dir fixup again
|
||||
|
||||
M packaging/debian-multiarch/sogo.postinst
|
||||
|
||||
commit cc125d2192a8b1fb84c7d239c708735d18c33772
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Wed Apr 10 16:27:03 2013 -0400
|
||||
|
||||
directory fixup
|
||||
|
||||
M packaging/debian-multiarch/rules
|
||||
M packaging/debian/rules
|
||||
|
||||
commit 4da1e41d936fb0fc3bc24be5a104f0c4339fcd68
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Wed Apr 10 16:20:47 2013 -0400
|
||||
|
||||
deb: install a sample sogo.conf in /etc/sogo
|
||||
|
||||
While there, replace mkdir + cp combo with 'install'
|
||||
|
||||
M packaging/debian-multiarch/rules
|
||||
M packaging/debian-multiarch/sogo.install
|
||||
M packaging/debian-multiarch/sogo.postinst
|
||||
M packaging/debian-multiarch/sogo.preinst
|
||||
M packaging/debian/rules
|
||||
M packaging/debian/sogo.install
|
||||
M packaging/debian/sogo.postinst
|
||||
M packaging/debian/sogo.preinst
|
||||
|
||||
commit e24eb10c4fa9ce6b53021ef04a23254ad7fb7cab
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Wed Apr 10 16:20:16 2013 -0400
|
||||
|
||||
rpm: install a sample sogo.conf in /etc/sogo
|
||||
|
||||
M packaging/rhel/sogo.spec
|
||||
|
||||
commit dd9e51fd16822ac453b944b7e9a7efc3cd9caefa
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Wed Apr 10 16:16:30 2013 -0400
|
||||
|
||||
sogo.conf - new example configuration file
|
||||
|
||||
A Scripts/sogo.conf
|
||||
|
||||
commit 9932d1413b23a50bfb0665af24acb17b59f5f55f
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Wed Apr 10 12:29:48 2013 -0400
|
||||
|
||||
update NEWS
|
||||
|
||||
M NEWS
|
||||
|
||||
commit ff13c4954032566676b42a4cebd857de5644632a
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Wed Apr 10 12:16:26 2013 -0400
|
||||
|
||||
updated NEWS
|
||||
|
||||
M NEWS
|
||||
|
||||
commit 1e33b4bf269d660c77fbc891adb4776a83d0b601
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Wed Apr 10 12:05:44 2013 -0400
|
||||
|
||||
Add notes regarding UIDField: value must be unique
|
||||
|
||||
M Documentation/SOGo Installation Guide.odt
|
||||
|
||||
commit e23a7df125cd081c078f0baf5fd63acbe8b5f21a
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Wed Apr 10 11:33:41 2013 -0400
|
||||
|
||||
Update NEWS file
|
||||
|
||||
M NEWS
|
||||
|
||||
commit 4ca476db9e8a81b412a0b15525eeeaa76a78237a
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Apr 10 11:30:40 2013 -0400
|
||||
|
||||
Updated NEWS file
|
||||
|
||||
M NEWS
|
||||
|
||||
commit 33840c71cd38a22766f3e0463a17361e6fea8292
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Apr 10 10:48:25 2013 -0400
|
||||
|
||||
Changed noop by unselect/select.
|
||||
|
||||
M OpenChange/MAPIStoreMailVolatileMessage.m
|
||||
|
||||
commit 1b983ef691f55e3588cc9afcb9ba841ca472d3d7
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Apr 10 09:56:23 2013 -0400
|
||||
|
||||
Fixed a potential timing issue with Dovecot when getting the modseq
|
||||
|
||||
M OpenChange/MAPIStoreMailVolatileMessage.m
|
||||
|
||||
commit eec8c07d4f061a2006bd7ec9967a2b1c92e7618b
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Apr 9 11:35:53 2013 -0400
|
||||
|
||||
Avoid appending the domain if already present.
|
||||
|
||||
M SoObjects/SOGo/SOGoWebAuthenticator.m
|
||||
|
||||
commit 84ba93fc0a5c5a650482d1afdee6f93fdd9ea277
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Apr 8 13:58:55 2013 -0400
|
||||
|
||||
Now set ForceAuthn to false by default
|
||||
|
||||
M SoObjects/SOGo/SOGoSAML2Session.m
|
||||
|
||||
commit 37a6f8265978b2a2ec019527b16b68ed10051cf3
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Mon Apr 8 11:05:45 2013 -0400
|
||||
|
||||
Initial Arabic translation
|
||||
|
||||
M .tx/config
|
||||
A SoObjects/Appointments/Arabic.lproj/Localizable.strings
|
||||
M SoObjects/Appointments/GNUmakefile
|
||||
A SoObjects/Contacts/Arabic.lproj/Localizable.strings
|
||||
M SoObjects/Contacts/GNUmakefile
|
||||
M SoObjects/Mailer/GNUmakefile
|
||||
A SoObjects/Mailer/SOGoMailArabicForward.wo/SOGoMailArabicForward.html
|
||||
A SoObjects/Mailer/SOGoMailArabicForward.wo/SOGoMailArabicForward.wod
|
||||
A SoObjects/Mailer/SOGoMailArabicReply.wo/SOGoMailArabicReply.html
|
||||
A SoObjects/Mailer/SOGoMailArabicReply.wo/SOGoMailArabicReply.wod
|
||||
M SoObjects/Mailer/SOGoMailForward.h
|
||||
M SoObjects/Mailer/SOGoMailForward.m
|
||||
M SoObjects/Mailer/SOGoMailReply.h
|
||||
M SoObjects/Mailer/SOGoMailReply.m
|
||||
M SoObjects/SOGo/SOGoDefaults.plist
|
||||
M Tests/Integration/preferences.py
|
||||
A UI/AdministrationUI/Arabic.lproj/Localizable.strings
|
||||
M UI/AdministrationUI/GNUmakefile
|
||||
A UI/Common/Arabic.lproj/Localizable.strings
|
||||
M UI/Common/GNUmakefile
|
||||
A UI/Contacts/Arabic.lproj/Localizable.strings
|
||||
M UI/Contacts/GNUmakefile
|
||||
A UI/MailPartViewers/Arabic.lproj/Localizable.strings
|
||||
M UI/MailPartViewers/GNUmakefile
|
||||
A UI/MailerUI/Arabic.lproj/Localizable.strings
|
||||
M UI/MailerUI/GNUmakefile
|
||||
A UI/MainUI/Arabic.lproj/Locale
|
||||
A UI/MainUI/Arabic.lproj/Localizable.strings
|
||||
M UI/MainUI/BrazilianPortuguese.lproj/Localizable.strings
|
||||
M UI/MainUI/Catalan.lproj/Localizable.strings
|
||||
M UI/MainUI/Czech.lproj/Localizable.strings
|
||||
M UI/MainUI/Danish.lproj/Localizable.strings
|
||||
M UI/MainUI/Dutch.lproj/Localizable.strings
|
||||
M UI/MainUI/English.lproj/Localizable.strings
|
||||
M UI/MainUI/Finnish.lproj/Localizable.strings
|
||||
M UI/MainUI/French.lproj/Localizable.strings
|
||||
M UI/MainUI/GNUmakefile
|
||||
M UI/MainUI/German.lproj/Localizable.strings
|
||||
M UI/MainUI/Hungarian.lproj/Localizable.strings
|
||||
M UI/MainUI/Icelandic.lproj/Localizable.strings
|
||||
M UI/MainUI/Italian.lproj/Localizable.strings
|
||||
M UI/MainUI/NorwegianBokmal.lproj/Localizable.strings
|
||||
M UI/MainUI/NorwegianNynorsk.lproj/Localizable.strings
|
||||
M UI/MainUI/Polish.lproj/Localizable.strings
|
||||
M UI/MainUI/Russian.lproj/Localizable.strings
|
||||
M UI/MainUI/SpanishArgentina.lproj/Localizable.strings
|
||||
M UI/MainUI/SpanishSpain.lproj/Localizable.strings
|
||||
M UI/MainUI/Swedish.lproj/Localizable.strings
|
||||
M UI/MainUI/Ukrainian.lproj/Localizable.strings
|
||||
M UI/MainUI/Welsh.lproj/Localizable.strings
|
||||
A UI/PreferencesUI/Arabic.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/BrazilianPortuguese.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Catalan.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Czech.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Danish.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Dutch.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/English.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Finnish.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/French.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/GNUmakefile
|
||||
M UI/PreferencesUI/German.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Hungarian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Icelandic.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Italian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/NorwegianBokmal.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/NorwegianNynorsk.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Polish.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Russian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Slovak.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Swedish.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Ukrainian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Welsh.lproj/Localizable.strings
|
||||
A UI/Scheduler/Arabic.lproj/Localizable.strings
|
||||
M UI/Scheduler/GNUmakefile
|
||||
A UI/Templates/SOGoACLArabicAdditionAdvisory.wox
|
||||
A UI/Templates/SOGoACLArabicModificationAdvisory.wox
|
||||
A UI/Templates/SOGoACLArabicRemovalAdvisory.wox
|
||||
A UI/Templates/SOGoFolderArabicAdditionAdvisory.wox
|
||||
A UI/Templates/SOGoFolderArabicRemovalAdvisory.wox
|
||||
|
||||
commit b4aaa68d85edbaee9f555efef3f82f64598c050f
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Apr 5 10:26:17 2013 -0400
|
||||
|
||||
Also consider the "mail" attribute in order to get the user's login
|
||||
|
||||
M SoObjects/SOGo/SOGoSAML2Session.m
|
||||
|
||||
commit 5487f34b9ee9b9639e3f1d4a7abf4fad2d240d66
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Apr 5 08:57:47 2013 -0400
|
||||
|
||||
Disable hint verification for now.
|
||||
|
||||
M SoObjects/SOGo/SOGoSAML2Session.m
|
||||
|
||||
commit e07734fa5f57325a92ea70bcb4410b73340aa026
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Fri Mar 29 10:38:52 2013 -0400
|
||||
|
||||
Filter sql source entries based on the user domain
|
||||
|
||||
When using dynamic domains with SQL sources (DomainFieldName),
|
||||
let WebUI and dav lookups return entries from current domain
|
||||
and other domains visible from the originating domain.
|
||||
|
||||
Fixes #2269
|
||||
|
||||
SQLSource.m: _visibleDomainsQualifierFromDomain:
|
||||
returns a EOQualifier OR'ing all visible domains from specified domain
|
||||
(including specified domain)
|
||||
|
||||
SQLSource.m: allEntryIDsVisibleFromDomain
|
||||
Replacement for allEntryIDs.
|
||||
Instead of returning all entries from the sql source,
|
||||
only return the entries visible from the specified domain.
|
||||
|
||||
SoObjects/SOGo/SQLSource.m: allEntryIDs
|
||||
Changed to call allEntryIDsVisibleFromDomain with an empty domain.
|
||||
|
||||
SQLSource.m fetchContactsMatching:inDomain:
|
||||
Use _visibleDomainsQualifierFromDomain to filter entries
|
||||
|
||||
LDAPSource.m: allEntryIDsVisibleFromDomain
|
||||
Simply call allEntryIDs, discarding the domain.
|
||||
LDAP does need to do the extra domain filtering
|
||||
|
||||
SOGoContactSourceFolder.m: toOneRelationshipKeys
|
||||
Call new method: allEntryIDsVisibleFromDomain
|
||||
|
||||
M SoObjects/Contacts/SOGoContactSourceFolder.m
|
||||
M SoObjects/SOGo/LDAPSource.m
|
||||
M SoObjects/SOGo/SOGoSource.h
|
||||
M SoObjects/SOGo/SQLSource.m
|
||||
|
||||
commit 6a8e6cd762c51514224eb3cf24ae08c8a2a08d23
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Mar 28 08:32:00 2013 -0400
|
||||
|
||||
Fixed the GNUmakfile and const's for charset tables.
|
||||
|
||||
M OpenChange/GNUmakefile
|
||||
M OpenChange/RTFHandler.m
|
||||
|
||||
commit 663351029ac49e1c9802e07d1c874a872f147ca3
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Mar 26 19:32:08 2013 -0400
|
||||
|
||||
Replaced unrtf by our own RTF to HTML converter.
|
||||
|
||||
Faster, thread safe, a hell lot cleaner.
|
||||
|
||||
M OpenChange/GNUmakefile
|
||||
M OpenChange/MAPIStoreMessage.m
|
||||
A OpenChange/RTFHandler.h
|
||||
A OpenChange/RTFHandler.m
|
||||
D OpenChange/unrtf-0.21.2.diff
|
||||
D OpenChange/unrtf-0.21.2.tar.gz
|
||||
D OpenChange/unrtf_config_h
|
||||
|
||||
commit c26e5fa7fed83bae25529679fead923e8a8fe1f2
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Tue Mar 26 14:01:04 2013 -0400
|
||||
|
||||
semi-colon
|
||||
|
||||
M OpenChange/gen-charset-table.py
|
||||
|
||||
commit 74c01dc44841c696ed322c9b0bff542e7f2b4115
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Tue Mar 26 13:42:22 2013 -0400
|
||||
|
||||
gen-charset-table.py: script to import ms charmaps
|
||||
|
||||
For example: http://msdn.microsoft.com/en-us/goglobal/cc305147
|
||||
|
||||
A OpenChange/gen-charset-table.py
|
||||
|
||||
commit a009c71034826e3755a987a0f5730724dfc9f063
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Mar 25 15:58:36 2013 -0400
|
||||
|
||||
Fixed table initialization.
|
||||
|
||||
M SoObjects/SOGo/SOGoSAML2Session.m
|
||||
|
||||
commit b4ebc90dd0b452dfe134efc137de2f62b8ece59e
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Mon Mar 25 14:12:12 2013 -0400
|
||||
|
||||
replace subprocess.check_output with Popen magic
|
||||
|
||||
check_output isn't available in py 2.6...
|
||||
|
||||
M Scripts/openchange_cleanup.py
|
||||
|
||||
commit 95dc134ca618a47be6e2eafca71e6c7f9c9cbccc
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Fri Mar 22 15:13:39 2013 -0400
|
||||
|
||||
Revamped openchange_cleanup.py
|
||||
|
||||
This is now usable again.
|
||||
|
||||
- Don't delete password files in mapistoreCleanup()
|
||||
- reworked the ldb cleanup and enabled it
|
||||
- sql cleanup should now be able to figure out the db info from the config
|
||||
regardless of the format used (xml, plist, sogo.conf or GNUstepDefaults)
|
||||
(We really need a python plist parser.. the current solution is not elegant)
|
||||
- Inform user of missing python packages
|
||||
|
||||
M Scripts/openchange_cleanup.py
|
||||
|
||||
commit 9c4b7d848141166eb9742e080831b017d660ec78
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Thu Mar 21 15:39:02 2013 -0400
|
||||
|
||||
Add notes regarding html mails and mod_reqtimeout
|
||||
|
||||
M Documentation/SOGo Native Microsoft Outlook Configuration.odt
|
||||
|
||||
commit 9fb9f2cae667aa966e285216846a6b688418f753
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Wed Mar 20 11:51:37 2013 -0400
|
||||
|
||||
Enable saml2 support on squeeze (temporary fix)
|
||||
|
||||
M packaging/debian/control-squeeze
|
||||
M packaging/debian/rules
|
||||
|
||||
commit 15f9b7d22e6a5937224570b580dee31e391789dd
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Fri Mar 15 11:23:27 2013 -0400
|
||||
|
||||
Fix comments in UIxContactFolderActions.*
|
||||
|
||||
M UI/Contacts/UIxContactFolderActions.h
|
||||
M UI/Contacts/UIxContactFolderActions.m
|
||||
|
||||
commit 5f179ed6b0726504bbe7f300df3a8cbaa5d3c9a6
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Fri Mar 15 11:06:26 2013 -0400
|
||||
|
||||
Activate the menu option "Mark Folder Read"
|
||||
|
||||
Fixes #1473
|
||||
|
||||
M NEWS
|
||||
M UI/MailerUI/BrazilianPortuguese.lproj/Localizable.strings
|
||||
M UI/MailerUI/Catalan.lproj/Localizable.strings
|
||||
M UI/MailerUI/Czech.lproj/Localizable.strings
|
||||
M UI/MailerUI/Danish.lproj/Localizable.strings
|
||||
M UI/MailerUI/Dutch.lproj/Localizable.strings
|
||||
M UI/MailerUI/English.lproj/Localizable.strings
|
||||
M UI/MailerUI/Finnish.lproj/Localizable.strings
|
||||
M UI/MailerUI/French.lproj/Localizable.strings
|
||||
M UI/MailerUI/German.lproj/Localizable.strings
|
||||
M UI/MailerUI/Hungarian.lproj/Localizable.strings
|
||||
M UI/MailerUI/Icelandic.lproj/Localizable.strings
|
||||
M UI/MailerUI/Italian.lproj/Localizable.strings
|
||||
M UI/MailerUI/NorwegianBokmal.lproj/Localizable.strings
|
||||
M UI/MailerUI/NorwegianNynorsk.lproj/Localizable.strings
|
||||
M UI/MailerUI/Polish.lproj/Localizable.strings
|
||||
M UI/MailerUI/Russian.lproj/Localizable.strings
|
||||
M UI/MailerUI/Slovak.lproj/Localizable.strings
|
||||
M UI/MailerUI/SpanishArgentina.lproj/Localizable.strings
|
||||
M UI/MailerUI/SpanishSpain.lproj/Localizable.strings
|
||||
M UI/MailerUI/Swedish.lproj/Localizable.strings
|
||||
M UI/MailerUI/UIxMailFolderActions.m
|
||||
M UI/MailerUI/Ukrainian.lproj/Localizable.strings
|
||||
M UI/MailerUI/Welsh.lproj/Localizable.strings
|
||||
M UI/MailerUI/product.plist
|
||||
M UI/Templates/MailerUI/UIxMailMainFrame.wox
|
||||
M UI/WebServerResources/MailerUI.js
|
||||
|
||||
commit 93f9a7273e96970106259e4902cf378a425d1322
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Mar 13 15:04:11 2013 -0400
|
||||
|
||||
Now handle mem context when saving messages and removed useless debugging.
|
||||
|
||||
M OpenChange/EOQualifier+MAPI.m
|
||||
M OpenChange/MAPIStoreCalendarEmbeddedMessage.m
|
||||
M OpenChange/MAPIStoreCalendarFolder.m
|
||||
M OpenChange/MAPIStoreCalendarMessage.m
|
||||
M OpenChange/MAPIStoreContext.m
|
||||
M OpenChange/MAPIStoreDBFolder.m
|
||||
M OpenChange/MAPIStoreDBMessage.m
|
||||
M OpenChange/MAPIStoreDBMessageTable.m
|
||||
M OpenChange/MAPIStoreEmbeddedMessage.m
|
||||
M OpenChange/MAPIStoreFAIMessage.m
|
||||
M OpenChange/MAPIStoreFolder.m
|
||||
M OpenChange/MAPIStoreGCSMessageTable.m
|
||||
M OpenChange/MAPIStoreMailFolder.m
|
||||
M OpenChange/MAPIStoreMailMessage.m
|
||||
M OpenChange/MAPIStoreMailMessageTable.m
|
||||
M OpenChange/MAPIStoreMailVolatileMessage.m
|
||||
M OpenChange/MAPIStoreMessage.h
|
||||
M OpenChange/MAPIStoreMessage.m
|
||||
M OpenChange/MAPIStoreSOGo.m
|
||||
M OpenChange/MAPIStoreTable.m
|
||||
M OpenChange/MAPIStoreTypes.m
|
||||
M OpenChange/NSObject+MAPIStore.m
|
||||
M OpenChange/SOGoMAPIDBObject.m
|
||||
M OpenChange/iCalEvent+MAPIStore.h
|
||||
M OpenChange/iCalEvent+MAPIStore.m
|
||||
|
||||
commit 15e082896ce62665ca7b655521a1b43505fd9401
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Tue Mar 12 09:08:19 2013 -0400
|
||||
|
||||
Update sogo-tool expire-autoreply syntax in cron
|
||||
|
||||
M Scripts/sogo.cron
|
||||
|
||||
commit 63ff9751d78d271aba7a1148cf8c1f98003fa543
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Mon Mar 11 11:37:59 2013 -0400
|
||||
|
||||
Add ics_compare and use it in _testRespondTo()
|
||||
|
||||
This new class uses vobject.ics_diff() to compare 2 VCALENDAR components.
|
||||
We should use this instead of textually comparing events for equality
|
||||
in future tests.
|
||||
|
||||
M Tests/Integration/test-davacl.py
|
||||
M Tests/Integration/utilities.py
|
||||
|
||||
commit d12c651d59cb6891ce21e21aa8d56f349c75cc2d
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Mon Mar 11 09:34:36 2013 -0400
|
||||
|
||||
New system default SOGoEncryptionKey
|
||||
|
||||
To be used to encrypt the passwords of remote Web calendars when
|
||||
SOGoTrustProxyAuthentication is enabled.
|
||||
|
||||
M NEWS
|
||||
M SoObjects/Appointments/SOGoWebAppointmentFolder.m
|
||||
M SoObjects/SOGo/SOGoDefaults.plist
|
||||
M SoObjects/SOGo/SOGoSystemDefaults.h
|
||||
M SoObjects/SOGo/SOGoSystemDefaults.m
|
||||
|
||||
commit 41a6c02aa31b5bfb3b9ec0337eb31d22ef1d7e8e
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Fri Mar 8 16:20:27 2013 -0500
|
||||
|
||||
Rework web services section
|
||||
|
||||
State that HTTPS is mandatory for autodiscovery services.
|
||||
Add example named config for SRV record.
|
||||
|
||||
M Documentation/SOGo Native Microsoft Outlook Configuration.odt
|
||||
|
||||
commit a026e75c0e383db73c4096e23bb0370380e914be
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Fri Mar 8 15:57:10 2013 -0500
|
||||
|
||||
Removed note about linefeed in password files
|
||||
|
||||
This is handled by the code now
|
||||
|
||||
M Documentation/SOGo Native Microsoft Outlook Configuration.odt
|
||||
|
||||
commit 46815042c94dc79cbf93aafeaae91e382be79c1c
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Mar 7 09:29:56 2013 -0500
|
||||
|
||||
Fixed bug when modifying/deleting exceptions of recurring events.
|
||||
|
||||
M SoObjects/Appointments/SOGoAppointmentObject.m
|
||||
|
||||
commit c79af52b67cdfe76d250e5607e2243b446df26a8
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Wed Mar 6 11:03:19 2013 -0500
|
||||
|
||||
Fix BSONCodec.m includes
|
||||
|
||||
include objc.h instead of runtime.h so that it works on older gcc objc runtime
|
||||
|
||||
M OpenChange/BSONCodec.m
|
||||
|
||||
commit e882dedac9e25320c2190fbce0654697e19586ec
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Tue Mar 5 11:01:51 2013 -0500
|
||||
|
||||
Update News
|
||||
|
||||
M NEWS
|
||||
M Scripts/sql-update-2.0.4b_to_2.0.5-mysql.sh
|
||||
|
||||
commit 13277bbdb955a18200b26919c14171e7f391bc65
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Tue Mar 5 10:47:09 2013 -0500
|
||||
|
||||
c_content TEXT to LONGTEXT for OpenChange tables
|
||||
|
||||
Add an script to update existing tables.
|
||||
Note that if a row already have 65535 char in it,
|
||||
the data is most likely broken.
|
||||
|
||||
M OpenChange/GCSSpecialQueries+OpenChange.m
|
||||
A Scripts/sql-update-2.0.4b_to_2.0.5-mysql.sh
|
||||
|
||||
commit 7e8a83aefb5bd1e89225dd2bd6be847bcbb39470
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Tue Mar 5 10:22:20 2013 -0500
|
||||
|
||||
Fix Slovak templates for mail reply/forward
|
||||
|
||||
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 f1846191d5d47717e7c5dff710e265e21c8f0fe2
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Fri Mar 1 16:24:16 2013 -0500
|
||||
|
||||
Use an autorelease pool in member expansion
|
||||
|
||||
Otherwise, we would hold one ldap connection for each member of a group.
|
||||
And close them all later. With large groups, we could hit the open file limit
|
||||
(or the open file limit of the ldap server).
|
||||
|
||||
Fixes #2256
|
||||
|
||||
M SoObjects/SOGo/SOGoGroup.m
|
||||
|
||||
commit a7c3f33447a3e0c6902913013574052763c36eaa
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Fri Mar 1 01:26:15 2013 -0500
|
||||
|
||||
Whitespace
|
||||
|
||||
M SoObjects/SOGo/SOGoGroup.m
|
||||
|
||||
commit 89766b2e7e037be88d1460520c762c77d66f302e
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Feb 20 12:10:34 2013 -0500
|
||||
|
||||
Temporary fix for unsigned long long values.
|
||||
|
||||
M OpenChange/BSONCodec.m
|
||||
|
||||
commit 7d65d808f6ff80a2a5bac2a8c55ad218ba44aaa6
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Wed Feb 20 10:50:58 2013 -0500
|
||||
|
||||
Strip newline characters from user password files
|
||||
|
||||
Makes it easier to create those files with a regular editor.
|
||||
|
||||
M OpenChange/MAPIStoreUserContext.m
|
||||
|
||||
commit fa5e99d58dd9a70602e47481bd02e70c76e2727f
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Feb 19 15:54:52 2013 -0500
|
||||
|
||||
Much better fix over previous commit.
|
||||
|
||||
M OpenChange/BSONCodec.m
|
||||
M OpenChange/NSString+MAPIStore.m
|
||||
|
||||
commit 67c2d508ea2d0b6007d110d67383c7030711e0b9
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Feb 19 15:42:05 2013 -0500
|
||||
|
||||
Added rationale around previous commit.
|
||||
|
||||
M OpenChange/NSString+MAPIStore.m
|
||||
|
||||
commit 19923d10dbcba8598f4b2ed3aec86b2fe508a68f
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Feb 19 15:30:29 2013 -0500
|
||||
|
||||
Also handle date-strings as date objects.
|
||||
Dates are stored as string in BSON - might change in the future.
|
||||
|
||||
M OpenChange/NSString+MAPIStore.m
|
||||
|
||||
commit e57b6835e63f4a888edfdee4c382a6c9c1d6c872
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Feb 18 16:50:54 2013 -0500
|
||||
|
||||
Fix for objective-c runtimes.
|
||||
|
||||
M OpenChange/BSONCodec.m
|
||||
|
||||
commit bcab7e7dc9eb664ece3f4bf9301e5c2acd8036b1
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Feb 18 16:42:59 2013 -0500
|
||||
|
||||
C99 style fixes.
|
||||
|
||||
M OpenChange/BSONCodec.m
|
||||
|
||||
commit 2572eedd8988f8a3d3e3d819c27ad070aa250c0b
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Feb 18 16:28:06 2013 -0500
|
||||
|
||||
Added BSON encoder/decoder for Outlook cache files.
|
||||
|
||||
A OpenChange/BSONCodec.h
|
||||
A OpenChange/BSONCodec.m
|
||||
M OpenChange/GNUmakefile
|
||||
M OpenChange/MAPIStoreTypes.h
|
||||
M OpenChange/NSObject+PropertyList.m
|
||||
M OpenChange/SOGoMAPIDBObject.m
|
||||
|
||||
commit efb45bfba69ca5dac10f9de5cb59f353e2bd0a34
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Fri Feb 15 15:17:08 2013 -0500
|
||||
|
||||
Fix issue with exceptions in repeating events
|
||||
|
||||
Fixed the display of an exception when its recurrence id is outside the
|
||||
current view.
|
||||
|
||||
M NEWS
|
||||
M SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
|
||||
commit 4f38b5cf3f3118784125b495167923a9027d243a
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Feb 14 15:59:19 2013 -0500
|
||||
|
||||
Alse use hex-formatted keys for deleted mails.
|
||||
|
||||
M OpenChange/MAPIStoreMailFolder.m
|
||||
|
||||
commit 71b9772546b83df5bd671ad46a9d10155da596af
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Feb 14 15:22:48 2013 -0500
|
||||
|
||||
Ensure we hit the cache with hex-formatted keys.
|
||||
|
||||
M OpenChange/MAPIStoreMailMessageTable.m
|
||||
M OpenChange/MAPIStoreSOGo.m
|
||||
|
||||
commit c13c389ae5f55b89f78db4f114e7fb413eb1e201
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Tue Feb 12 08:42:47 2013 -0500
|
||||
|
||||
Update Danish translation
|
||||
|
||||
M SoObjects/Appointments/Danish.lproj/Localizable.strings
|
||||
M UI/Common/Danish.lproj/Localizable.strings
|
||||
M UI/Contacts/Danish.lproj/Localizable.strings
|
||||
M UI/MailerUI/Danish.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Danish.lproj/Localizable.strings
|
||||
M UI/Scheduler/Danish.lproj/Localizable.strings
|
||||
|
||||
commit caf6f0ec6cdc0a43a7026036b26b54ab944ceafc
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Mon Feb 11 10:41:50 2013 -0500
|
||||
|
||||
Add example apache configuration for apple AB
|
||||
|
||||
A Apache/SOGo-apple-ab.conf
|
||||
M packaging/debian-multiarch/sogo.docs
|
||||
M packaging/debian/sogo.docs
|
||||
M packaging/rhel/sogo.spec
|
||||
|
||||
commit 4952ff7914dd0f3aa5c9c2bf5e04e29bf4317836
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Fri Feb 8 16:22:14 2013 -0500
|
||||
|
||||
Use SOGoSystemDefaults in all tools
|
||||
|
||||
sogo-ealarms-notify and sogo-slapd-sockd will now be able to use sogo.conf
|
||||
Fixes #2226
|
||||
|
||||
M Tools/sogo-ealarms-notify.m
|
||||
M Tools/sogo-slapd-sockd.m
|
||||
|
||||
commit 8981dcd64503f1fa907e98593a76b6bff9cbb02d
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Fri Feb 8 09:42:31 2013 -0500
|
||||
|
||||
Fix segfault in SOGoSieveManager.m
|
||||
|
||||
M SoObjects/SOGo/SOGoSieveManager.m
|
||||
|
||||
commit 470a53a548c46af72d8956475fdacba045458d10
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Thu Feb 7 13:00:27 2013 -0500
|
||||
|
||||
Add example configuration for fail2ban
|
||||
|
||||
From Arnd Brandes. (#2229)
|
||||
|
||||
A Scripts/fail2ban/sogo-filter.conf
|
||||
A Scripts/fail2ban/sogo-jail.local
|
||||
|
||||
commit 7b65b7400e269bdc8d020d29bd8cf0b33aea09e1
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Thu Feb 7 09:00:16 2013 -0500
|
||||
|
||||
Update Finnish translation
|
||||
|
||||
M UI/MailerUI/Finnish.lproj/Localizable.strings
|
||||
|
||||
commit 90c61abdb654e00ad172ab88cc75059c3d45bd6d
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Wed Feb 6 15:16:09 2013 -0500
|
||||
|
||||
Update Polish translation
|
||||
|
||||
M SoObjects/Mailer/SOGoMailPolishReply.wo/SOGoMailPolishReply.html
|
||||
|
||||
commit f8387b90ffd3f016f4a4de88577b1280a84aefc8
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Wed Feb 6 09:23:47 2013 -0500
|
||||
|
||||
Log x-webobjects-remote-host in login process
|
||||
|
||||
Most of the time, the remote-host will contain data from the x-forwarded-for header.
|
||||
Which could have more than one ip in it if the request went through multiple proxies.
|
||||
eg. x-forwarded-for: real.client.ip, load.balancer.ip
|
||||
|
||||
M UI/MainUI/SOGoRootPage.m
|
||||
|
||||
commit feb02c54b918154919c224e257b79765c0770649
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Tue Feb 5 16:13:18 2013 -0500
|
||||
|
||||
Add missing localizable string
|
||||
|
||||
M UI/Scheduler/English.lproj/Localizable.strings
|
||||
M UI/WebServerResources/SchedulerUI.js
|
||||
|
||||
commit 49a22994148d25d0f22464f5de69d45112475c95
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Feb 5 16:11:37 2013 -0500
|
||||
|
||||
Avoid going out of bounds for special URL chars ending mail contents.
|
||||
|
||||
M SoObjects/SOGo/NSString+Utilities.m
|
||||
|
||||
commit 43044bf88fdbfe630572ad89a32ef9b2f155ea6d
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Tue Feb 5 15:09:55 2013 -0500
|
||||
|
||||
Plug sieve connection leak
|
||||
|
||||
Fixes #2228
|
||||
Fix from 'bofhus'
|
||||
|
||||
M SoObjects/SOGo/SOGoSieveManager.m
|
||||
|
||||
commit 0532d331a3497d97b91d59fdf3670dc4a21e8b0a
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Tue Feb 5 15:09:20 2013 -0500
|
||||
|
||||
whitespace (tabkill)
|
||||
|
||||
M SoObjects/SOGo/SOGoSieveManager.m
|
||||
|
||||
commit 70fc05091f2f3cdbac1c66291a940a8223e46876
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Tue Feb 5 14:27:16 2013 -0500
|
||||
|
||||
Remove x-webobjects-remote-host from apache conf
|
||||
|
||||
SOPE now handles this on its own by setting x-webobjects-remote-host
|
||||
to the content of the x-forward or x-forwarded-for headers if it wasn't defined
|
||||
|
||||
M Apache/SOGo.conf
|
||||
M NEWS
|
||||
|
||||
commit 469e5c647e74a53fc03d22c35b6da22fcbf1922d
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Tue Feb 5 11:52:26 2013 -0500
|
||||
|
||||
Updated NEWS
|
||||
|
||||
M NEWS
|
||||
|
||||
commit 3daa7e55b74890a1c03a37290826759f5d0ec05a
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Mon Feb 4 14:24:03 2013 -0500
|
||||
|
||||
Update ChangeLog
|
||||
|
||||
M ChangeLog
|
||||
|
||||
commit 6913502810ec21479889c4ecf0a393de5ede2635
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Mon Feb 4 14:22:37 2013 -0500
|
||||
|
@ -77,6 +986,33 @@ Date: Sun Feb 3 20:40:06 2013 -0500
|
|||
|
||||
M UI/WebServerResources/UIxPreferences.js
|
||||
|
||||
commit 7b5da8a2c9a30d36969fa6aa09b8e168f3e6e243
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Fri Feb 1 19:58:25 2013 -0500
|
||||
|
||||
don't use cache for login page
|
||||
|
||||
M UI/MainUI/SOGoRootPage.m
|
||||
|
||||
commit 451c82c8154b4e2bd4fb4cee5bded7109a1e1942
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Fri Feb 1 18:35:10 2013 -0500
|
||||
|
||||
Don't use user/password cache from the login page
|
||||
|
||||
The idea is to always use memcached for credentials to avoid hitting
|
||||
the authentication backend on every click but to check with the auth backend
|
||||
for every login requests.
|
||||
|
||||
This should fix #2169
|
||||
|
||||
While there, fix whitespace (killtab)
|
||||
|
||||
M SoObjects/SOGo/SOGoUserManager.h
|
||||
M SoObjects/SOGo/SOGoUserManager.m
|
||||
M SoObjects/SOGo/SOGoWebAuthenticator.h
|
||||
M SoObjects/SOGo/SOGoWebAuthenticator.m
|
||||
|
||||
commit a4bd966cc0c3429261747384dc746ec5f71423de
|
||||
Author: Jean Raby <jraby@inverse.ca>
|
||||
Date: Fri Feb 1 16:26:01 2013 -0500
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
33
NEWS
33
NEWS
|
@ -1,3 +1,36 @@
|
|||
2.0.5 (2013-04-11)
|
||||
------------------
|
||||
|
||||
New features
|
||||
- new system default SOGoEncryptionKey to be used to encrypt the passwords of
|
||||
remote Web calendars when SOGoTrustProxyAuthentication is enabled
|
||||
- activated the menu option "Mark Folder Read" in the Webmail (#1473)
|
||||
|
||||
Enhancements
|
||||
- added logging of the X-Forwarded-For HTTP header (#2229)
|
||||
- now use BSON instead of GNUstep's binary format for serializing
|
||||
Outlook related cache files
|
||||
- updated Danish, Finnish, Polish and Slovak translations
|
||||
- added Arabic translation - thanks to Anass Ahmed
|
||||
|
||||
Bug fixes
|
||||
- don't use the cache for password lookups from login page (#2169)
|
||||
- fixed issue with exceptions in repeating events
|
||||
- avoid data truncation issue in OpenChange with mysql backend
|
||||
run sql-update-2.0.4b_to_2.0.5-mysql.sh to update existing tables
|
||||
- avoid random crashes in OpenChange due to RTF conversion
|
||||
- fixed issue when modifying/deleting exceptions of recurring events
|
||||
- fixed major cache miss issue leading to slow Outlook resynchronizations
|
||||
- fixed major memory corruption issue when Outlook was saving "messages"
|
||||
- fixed filtering of sql contact entries when using dynamic domains (#2269)
|
||||
- sogo.conf can now be used by all tools (#2226)
|
||||
- SOPE: fixed handling of sieve capabilities after starttls (#2132)
|
||||
- OpenChange: fixed 'stuck email' problem when sending a mail
|
||||
- OpenChange NTLMAuthHandler: avoid tightloop when samba isn't available.
|
||||
- OpenChange NTLMAuthHandler: avoid crash while parsing cookies
|
||||
- OpenChange ocsmanager: a LOT of fixes, see git log
|
||||
|
||||
|
||||
2.0.4b (2013-02-04)
|
||||
------------------
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// BSONCodec.h
|
||||
// BSON Codec for Objective-C.
|
||||
//
|
||||
// Created by Martin Kou on 8/17/10.
|
||||
// MIT License, see LICENSE file for details.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <stdint.h>
|
||||
|
||||
@protocol BSONCoding
|
||||
- (uint8_t) BSONTypeID;
|
||||
- (NSData *) BSONEncode;
|
||||
- (NSData *) BSONRepresentation;
|
||||
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) typeID;
|
||||
@end
|
||||
|
||||
@protocol BSONObjectCoding
|
||||
- (id) initWithBSONDictionary: (NSDictionary *) data;
|
||||
- (NSDictionary *) BSONDictionary;
|
||||
@end
|
||||
|
||||
@interface NSObject (BSONObjectCoding)
|
||||
- (NSData *) BSONEncode;
|
||||
- (NSData *) BSONRepresentation;
|
||||
@end
|
||||
|
||||
|
||||
@interface NSDictionary (BSON) <BSONCoding>
|
||||
@end
|
||||
|
||||
@interface NSData (BSON) <BSONCoding>
|
||||
- (NSDictionary *) BSONValue;
|
||||
@end
|
||||
|
||||
@interface NSNumber (BSON) <BSONCoding>
|
||||
@end
|
||||
|
||||
@interface NSString (BSON) <BSONCoding>
|
||||
@end
|
||||
|
||||
@interface NSArray (BSON) <BSONCoding>
|
||||
@end
|
||||
|
||||
@interface NSNull (BSON) <BSONCoding>
|
||||
@end
|
||||
|
||||
@interface NSCalendarDate (BSON) <BSONCoding>
|
||||
@end
|
|
@ -0,0 +1,585 @@
|
|||
//
|
||||
// BSONCodec.m
|
||||
// BSON Codec for Objective-C.
|
||||
//
|
||||
// Created by Martin Kou on 8/17/10.
|
||||
// MIT License, see LICENSE file for details.
|
||||
//
|
||||
|
||||
#import "BSONCodec.h"
|
||||
#import <ctype.h>
|
||||
#import <string.h>
|
||||
#import <objc/objc.h>
|
||||
|
||||
#define BSONTYPE(tag,className) [className class], [NSNumber numberWithChar: (tag)]
|
||||
|
||||
#ifndef objc_msgSend
|
||||
#define objc_msgSend(obj, sel, ...) \
|
||||
objc_msg_lookup(obj, sel)(obj, sel, ## __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
static NSDictionary *BSONTypes()
|
||||
{
|
||||
static NSDictionary *retval = nil;
|
||||
|
||||
if (retval == nil)
|
||||
{
|
||||
retval = [[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
BSONTYPE(0x01, NSNumber),
|
||||
BSONTYPE(0x02, NSString),
|
||||
BSONTYPE(0x03, NSDictionary),
|
||||
BSONTYPE(0x04, NSArray),
|
||||
BSONTYPE(0x05, NSData),
|
||||
BSONTYPE(0x08, NSNumber),
|
||||
BSONTYPE(0x0A, NSNull),
|
||||
BSONTYPE(0x10, NSNumber),
|
||||
BSONTYPE(0x11, NSCalendarDate),
|
||||
BSONTYPE(0x12, NSNumber),
|
||||
nil] retain];
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define SWAP16(x) \
|
||||
((uint16_t)((((uint16_t)(x) & 0xff00) >> 8) | \
|
||||
(((uint16_t)(x) & 0x00ff) << 8)))
|
||||
|
||||
#define SWAP32(x) \
|
||||
((uint32_t)((((uint32_t)(x) & 0xff000000) >> 24) | \
|
||||
(((uint32_t)(x) & 0x00ff0000) >> 8) | \
|
||||
(((uint32_t)(x) & 0x0000ff00) << 8) | \
|
||||
(((uint32_t)(x) & 0x000000ff) << 24)))
|
||||
|
||||
#define SWAP64(x) \
|
||||
((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \
|
||||
(((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
|
||||
(((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
|
||||
(((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
|
||||
(((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
|
||||
(((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
|
||||
(((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
|
||||
(((uint64_t)(x) & 0x00000000000000ffULL) << 56)))
|
||||
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define BSONTOHOST16(x) (x)
|
||||
#define BSONTOHOST32(x) (x)
|
||||
#define BSONTOHOST64(x) (x)
|
||||
#define HOSTTOBSON16(x) (x)
|
||||
#define HOSTTOBSON32(x) (x)
|
||||
#define HOSTTOBSON64(x) (x)
|
||||
|
||||
#elif BYTE_ORDER == BIG_ENDIAN
|
||||
#define BSONTOHOST16(x) SWAP16(x)
|
||||
#define BSONTOHOST32(x) SWAP32(x)
|
||||
#define BSONTOHOST64(x) SWAP64(x)
|
||||
#define HOSTTOBSON16(x) SWAP16(x)
|
||||
#define HOSTTOBSON32(x) SWAP16(x)
|
||||
#define HOSTTOBSON64(x) SWAP16(x)
|
||||
|
||||
#endif
|
||||
|
||||
#define CLASS_NAME_MARKER @"$$__CLASS_NAME__$$"
|
||||
|
||||
@implementation NSObject (BSONObjectCoding)
|
||||
- (NSData *) BSONEncode
|
||||
{
|
||||
if (!class_conformsToProtocol([self class], @protocol(BSONObjectCoding)))
|
||||
[NSException raise: NSInvalidArgumentException format: @"BSON encoding is only valid on objects conforming to the BSONObjectEncoding protocol."];
|
||||
|
||||
id <BSONObjectCoding> myself = (id <BSONObjectCoding>) self;
|
||||
NSMutableDictionary *values = [[myself BSONDictionary] mutableCopy];
|
||||
|
||||
const char* className = class_getName([self class]);
|
||||
[values setObject: [NSData dataWithBytes: (void *)className length: strlen(className)] forKey: CLASS_NAME_MARKER];
|
||||
NSData *retval = [values BSONEncode];
|
||||
[values release];
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
- (NSData *) BSONRepresentation
|
||||
{
|
||||
return [self BSONEncode];
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSDictionary (BSON)
|
||||
|
||||
- (uint8_t) BSONTypeID
|
||||
{
|
||||
return 0x03;
|
||||
}
|
||||
|
||||
- (NSData *) BSONEncode
|
||||
{
|
||||
// Initialize the components structure.
|
||||
NSMutableArray *components = [[NSMutableArray alloc] init];
|
||||
|
||||
NSMutableData *lengthData = [[NSMutableData alloc] initWithLength: 4];
|
||||
[components addObject: lengthData];
|
||||
[lengthData release];
|
||||
|
||||
NSMutableData *contentsData = [[NSMutableData alloc] init];
|
||||
[components addObject: contentsData];
|
||||
[contentsData release];
|
||||
|
||||
[components addObject: [NSData dataWithBytes: "\x00" length: 1]];
|
||||
|
||||
// Ensure ordered keys. not in BSON spec, but ensures all BSONRepresentations
|
||||
// of the same dict will be the same.
|
||||
NSMutableArray *keys = [[NSMutableArray alloc] init];
|
||||
[keys addObjectsFromArray: [self allKeys]];
|
||||
//[keys sortUsingSelector: @selector(caseInsensitiveCompare:)];
|
||||
|
||||
// Encode data.- (NSData *) BSONEncode;
|
||||
uint8_t elementType = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < [keys count]; i++)
|
||||
{
|
||||
NSString *key = [keys objectAtIndex: i];
|
||||
NSObject *value = [self objectForKey: key];
|
||||
|
||||
if ([value respondsToSelector: @selector(BSONTypeID)])
|
||||
elementType = [(id <BSONCoding>) value BSONTypeID];
|
||||
else
|
||||
elementType = 3;
|
||||
|
||||
[contentsData appendBytes: &elementType length: 1];
|
||||
[contentsData appendData: [key dataUsingEncoding: NSUTF8StringEncoding]];
|
||||
[contentsData appendBytes: "\x00" length: 1];
|
||||
[contentsData appendData: [value BSONEncode]];
|
||||
}
|
||||
[keys release];
|
||||
|
||||
// Write length.
|
||||
uint32_t *length = (uint32_t *)[lengthData mutableBytes];
|
||||
*length = HOSTTOBSON32([contentsData length]) + 4 + 1;
|
||||
|
||||
// Assemble the output data.
|
||||
NSMutableData *retval = [NSMutableData data];
|
||||
for (i = 0; i < [components count]; i++)
|
||||
[retval appendData: [components objectAtIndex: i]];
|
||||
[components release];
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
- (NSData *) BSONRepresentation
|
||||
{
|
||||
return [self BSONEncode];
|
||||
}
|
||||
|
||||
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) t
|
||||
{
|
||||
const void *current = [data bytes];
|
||||
if ((id)base != nil)
|
||||
current = *base;
|
||||
else
|
||||
base = ¤t;
|
||||
|
||||
uint32_t length = BSONTOHOST32(*((uint32_t *)current));
|
||||
const void *endPoint = current + length;
|
||||
current += 4;
|
||||
|
||||
NSMutableDictionary *retval = [NSMutableDictionary dictionary];
|
||||
while (current < endPoint - 1)
|
||||
{
|
||||
uint8_t typeID = *((uint8_t *)current);
|
||||
current++;
|
||||
|
||||
char *utf8Key = (char *) current;
|
||||
while (*((char *)current) != 0 && current < endPoint - 1)
|
||||
current++;
|
||||
current++;
|
||||
NSString *key = [NSString stringWithUTF8String: utf8Key];
|
||||
|
||||
*base = current;
|
||||
Class typeClass = [BSONTypes() objectForKey: [NSNumber numberWithChar: typeID]];
|
||||
id value = objc_msgSend(typeClass, @selector(BSONFragment:at:ofType:), data, base, typeID);
|
||||
current = *base;
|
||||
|
||||
[retval setObject: value forKey: key];
|
||||
}
|
||||
|
||||
*base = current + 1;
|
||||
|
||||
// If the dictionary has a class name marker, then it is to be converted to an object.
|
||||
if ([retval objectForKey: CLASS_NAME_MARKER] != nil)
|
||||
{
|
||||
NSData *classNameData = [retval objectForKey: CLASS_NAME_MARKER];
|
||||
char *className = malloc([classNameData length] + 1);
|
||||
memcpy(className, [classNameData bytes], [classNameData length]);
|
||||
className[[classNameData length]] = 0;
|
||||
|
||||
Class targetClass = objc_getClass(className);
|
||||
if (targetClass == nil)
|
||||
[NSException raise: NSInvalidArgumentException format: @"Class %s found in incoming data is undefined.", className];
|
||||
|
||||
id obj = [[targetClass alloc] initWithBSONDictionary: retval];
|
||||
return obj;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSData (BSON)
|
||||
- (uint8_t) BSONTypeID
|
||||
{
|
||||
return 0x05;
|
||||
}
|
||||
|
||||
- (NSData *) BSONEncode
|
||||
{
|
||||
uint32_t length = HOSTTOBSON32([self length]);
|
||||
NSMutableData *retval = [NSMutableData data];
|
||||
[retval appendBytes: &length length: 4];
|
||||
[retval appendBytes: "\x00" length: 1];
|
||||
[retval appendData: self];
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
- (NSData *) BSONRepresentation
|
||||
{
|
||||
return [self BSONEncode];
|
||||
}
|
||||
|
||||
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) t
|
||||
{
|
||||
const void *current = [data bytes];
|
||||
if ((id)base != nil)
|
||||
current = *base;
|
||||
else
|
||||
base = ¤t;
|
||||
|
||||
uint32_t length = BSONTOHOST32(*((uint32_t *)current));
|
||||
current += 4 + 1;
|
||||
|
||||
NSData *retval = [NSData dataWithBytes: current length: length];
|
||||
current += length;
|
||||
*base = current;
|
||||
return retval;
|
||||
}
|
||||
|
||||
- (NSDictionary *) BSONValue
|
||||
{
|
||||
return [NSDictionary BSONFragment: self at: NULL ofType: 0x03];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSNumber (BSON)
|
||||
- (uint8_t) BSONTypeID
|
||||
{
|
||||
const char encoding = tolower(*([self objCType]));
|
||||
|
||||
switch (encoding) {
|
||||
case 'f':
|
||||
case 'd': return 0x01;
|
||||
case 'b': return 0x08;
|
||||
case 'c':
|
||||
case 's': return 0x10;
|
||||
case 'i':
|
||||
// Ok, if you're running Objective-C on 16-bit platforms...
|
||||
// Then YOU have issues.
|
||||
// So, yeah, we won't handle that case.
|
||||
if (sizeof(int) == 4)
|
||||
return 0x10;
|
||||
else if (sizeof(int) == 8)
|
||||
return 0x12;
|
||||
|
||||
case 'l':
|
||||
if (sizeof(long) == 4)
|
||||
return 0x10;
|
||||
else if (sizeof(long) == 8)
|
||||
return 0x12;
|
||||
|
||||
case 'q': return 0x12;
|
||||
default:
|
||||
[NSException raise: NSInvalidArgumentException format: @"%@::%s - invalid encoding type '%c'", [self class], _cmd, encoding];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (NSData *) BSONEncode
|
||||
{
|
||||
const char encoding = *([self objCType]);
|
||||
|
||||
if (encoding == 'd' || encoding == 'D')
|
||||
{
|
||||
double value = [self doubleValue];
|
||||
return [NSData dataWithBytes: &value length: 8];
|
||||
}
|
||||
|
||||
if (encoding == 'f' || encoding == 'F')
|
||||
{
|
||||
double value = [self floatValue];
|
||||
return [NSData dataWithBytes: &value length: 8];
|
||||
}
|
||||
|
||||
if (encoding == 'b' || encoding == 'B')
|
||||
{
|
||||
char value = [self boolValue];
|
||||
return [NSData dataWithBytes: &value length: 1];
|
||||
}
|
||||
|
||||
if (encoding == 'c' || encoding == 'C')
|
||||
{
|
||||
int32_t value = [self charValue];
|
||||
value = HOSTTOBSON32(value);
|
||||
return [NSData dataWithBytes: &value length: 4];
|
||||
}
|
||||
|
||||
if (encoding == 's' || encoding == 'S')
|
||||
{
|
||||
int32_t value = [self shortValue];
|
||||
value = HOSTTOBSON32(value);
|
||||
return [NSData dataWithBytes: &value length: 4];
|
||||
}
|
||||
|
||||
if (encoding == 'i' || encoding == 'I')
|
||||
{
|
||||
int value = [self intValue];
|
||||
if (sizeof(int) == 4)
|
||||
value = HOSTTOBSON32(value);
|
||||
else if (sizeof(int) == 8)
|
||||
value = HOSTTOBSON64(value);
|
||||
return [NSData dataWithBytes: &value length: sizeof(int)];
|
||||
}
|
||||
|
||||
if (encoding == 'l' || encoding == 'L')
|
||||
{
|
||||
long value = [self longValue];
|
||||
if (sizeof(long) == 4)
|
||||
value = HOSTTOBSON32(value);
|
||||
else if (sizeof(long) == 8)
|
||||
value = HOSTTOBSON64(value);
|
||||
|
||||
return [NSData dataWithBytes: &value length: sizeof(long)];
|
||||
}
|
||||
|
||||
if (encoding == 'q')
|
||||
{
|
||||
long long value = HOSTTOBSON64([self longLongValue]);
|
||||
return [NSData dataWithBytes: &value length: 8];
|
||||
}
|
||||
|
||||
if (encoding == 'Q')
|
||||
{
|
||||
long long value = HOSTTOBSON64([self unsignedLongLongValue]);
|
||||
return [NSData dataWithBytes: &value length: 8];
|
||||
}
|
||||
|
||||
|
||||
[NSException raise: NSInvalidArgumentException format: @"%@::%s - invalid encoding type '%c'", [self class], _cmd, encoding];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSData *) BSONRepresentation
|
||||
{
|
||||
return [self BSONEncode];
|
||||
}
|
||||
|
||||
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) t
|
||||
{
|
||||
if (t == 0x01)
|
||||
{
|
||||
// #5: LLVM GCC requires double pointers to have a certain alignment in ARM CPUs.
|
||||
// So we can't just read the double off directly from the data - need to copy it.
|
||||
double value;
|
||||
memcpy(&value, *base, sizeof(double));
|
||||
*base += 8;
|
||||
return [NSNumber numberWithDouble: value];
|
||||
}
|
||||
|
||||
if (t == 0x08)
|
||||
{
|
||||
char value = ((char *) *base)[0];
|
||||
*base += 1;
|
||||
return [NSNumber numberWithBool: value];
|
||||
}
|
||||
|
||||
if (t == 0x10)
|
||||
{
|
||||
int32_t value = BSONTOHOST32(((int32_t *) *base)[0]);
|
||||
*base += 4;
|
||||
|
||||
if (sizeof(int) == 4)
|
||||
return [NSNumber numberWithInt: value];
|
||||
|
||||
return [NSNumber numberWithLong: value];
|
||||
}
|
||||
|
||||
if (t == 0x12)
|
||||
{
|
||||
int64_t value = BSONTOHOST64(((int64_t *) *base)[0]);
|
||||
*base += 8;
|
||||
|
||||
return [NSNumber numberWithUnsignedLongLong: value];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSString (BSON)
|
||||
- (uint8_t) BSONTypeID
|
||||
{
|
||||
return 0x02;
|
||||
}
|
||||
|
||||
- (NSData *) BSONEncode
|
||||
{
|
||||
NSData *utf8Data = [self dataUsingEncoding: NSUTF8StringEncoding];
|
||||
uint32_t length = HOSTTOBSON32([utf8Data length] + 1);
|
||||
|
||||
NSMutableData *retval = [NSMutableData data];
|
||||
[retval appendBytes: &length length: 4];
|
||||
[retval appendData: utf8Data];
|
||||
[retval appendBytes: "\x00" length: 1];
|
||||
return retval;
|
||||
}
|
||||
|
||||
- (NSData *) BSONRepresentation
|
||||
{
|
||||
return [self BSONEncode];
|
||||
}
|
||||
|
||||
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) typeID
|
||||
{
|
||||
uint32_t length = BSONTOHOST32(((const uint32_t *) *base)[0]);
|
||||
*base += 4;
|
||||
|
||||
const char *utf8Str = (const char *) *base;
|
||||
*base += length;
|
||||
|
||||
return [NSString stringWithUTF8String: utf8Str];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSArray (BSON)
|
||||
- (uint8_t) BSONTypeID
|
||||
{
|
||||
return 0x04;
|
||||
}
|
||||
|
||||
- (NSData *) BSONEncode
|
||||
{
|
||||
// Initialize the components structure.
|
||||
NSMutableArray *components = [[NSMutableArray alloc] init];
|
||||
|
||||
NSMutableData *lengthData = [[NSMutableData alloc] initWithLength: 4];
|
||||
[components addObject: lengthData];
|
||||
[lengthData release];
|
||||
|
||||
NSMutableData *contentsData = [[NSMutableData alloc] init];
|
||||
[components addObject: contentsData];
|
||||
[contentsData release];
|
||||
|
||||
[components addObject: [NSData dataWithBytes: "\x00" length: 1]];
|
||||
|
||||
// Encode data.
|
||||
uint8_t elementType = 0;
|
||||
int i, count = [self count];
|
||||
for (i = 0 ; i < count ; i++)
|
||||
{
|
||||
NSObject *value = [self objectAtIndex: i];
|
||||
|
||||
if ([value respondsToSelector: @selector(BSONTypeID)])
|
||||
elementType = [(id <BSONCoding>) value BSONTypeID];
|
||||
else
|
||||
elementType = 3;
|
||||
|
||||
[contentsData appendBytes: &elementType length: 1];
|
||||
[contentsData appendData: [[NSString stringWithFormat: @"%d", i] dataUsingEncoding: NSUTF8StringEncoding]];
|
||||
[contentsData appendBytes: "\x00" length: 1];
|
||||
[contentsData appendData: [value BSONEncode]];
|
||||
}
|
||||
|
||||
// Write length.
|
||||
uint32_t *length = (uint32_t *)[lengthData mutableBytes];
|
||||
*length = HOSTTOBSON32([contentsData length]) + 4 + 1;
|
||||
|
||||
// Assemble the output data.
|
||||
NSMutableData *retval = [NSMutableData data];
|
||||
for (i = 0; i < [components count]; i++)
|
||||
[retval appendData: [components objectAtIndex: i]];
|
||||
[components release];
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
- (NSData *) BSONRepresentation
|
||||
{
|
||||
return [self BSONEncode];
|
||||
}
|
||||
|
||||
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) typeID
|
||||
{
|
||||
NSDictionary *tmp = [NSDictionary BSONFragment: data at: base ofType: 0x03];
|
||||
NSMutableArray *retval = [NSMutableArray arrayWithCapacity: [tmp count]];
|
||||
int i;
|
||||
for (i = 0; i < [tmp count]; i++)
|
||||
[retval addObject: [tmp objectForKey: [NSString stringWithFormat: @"%d", i]]];
|
||||
|
||||
return retval;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSNull (BSON)
|
||||
- (uint8_t) BSONTypeID
|
||||
{
|
||||
return 0x0a;
|
||||
}
|
||||
|
||||
- (NSData *) BSONEncode
|
||||
{
|
||||
return [NSData data];
|
||||
}
|
||||
|
||||
- (NSData *) BSONRepresentation
|
||||
{
|
||||
return [self BSONEncode];
|
||||
}
|
||||
|
||||
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) typeID
|
||||
{
|
||||
return [NSNull null];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSCalendarDate (BSON)
|
||||
- (uint8_t) BSONTypeID
|
||||
{
|
||||
return 0x11;
|
||||
}
|
||||
|
||||
- (NSData *) BSONEncode
|
||||
{
|
||||
NSString *v;
|
||||
|
||||
v = [self descriptionWithCalendarFormat: @"%Y-%m-%d %H:%M:%S %Z"
|
||||
locale: nil];
|
||||
|
||||
return [v BSONEncode];
|
||||
}
|
||||
|
||||
- (NSData *) BSONRepresentation
|
||||
{
|
||||
return [self BSONEncode];
|
||||
}
|
||||
|
||||
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) typeID
|
||||
{
|
||||
NSString *v;
|
||||
|
||||
v = [NSString BSONFragment: data at: base ofType: 0x02];
|
||||
|
||||
return [NSCalendarDate dateWithString: v
|
||||
calendarFormat: @"%Y-%m-%d %H:%M:%S %Z"];
|
||||
}
|
||||
@end
|
|
@ -46,12 +46,12 @@
|
|||
NSDictionary *properties;
|
||||
BOOL rc;
|
||||
|
||||
[self logWithFormat: @"evaluating object '%@'", object];
|
||||
//[self logWithFormat: @"evaluating object '%@'", object];
|
||||
|
||||
properties = [object properties];
|
||||
rc = [self _evaluateSOGoMAPIDBObject: properties];
|
||||
|
||||
[self logWithFormat: @" evaluation result: %d", rc];
|
||||
//[self logWithFormat: @" evaluation result: %d", rc];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -150,9 +150,9 @@ typedef BOOL (*EOComparator) (id, SEL, id);
|
|||
rc = ((isZero && (intValue & mask) == 0)
|
||||
|| (!isZero && (intValue & mask) != 0));
|
||||
|
||||
[self logWithFormat: @"evaluation of bitmask qualifier:"
|
||||
@" (%.8x & %.8x) %s 0: %d",
|
||||
intValue, mask, (isZero ? "==" : "!="), rc];
|
||||
//[self logWithFormat: @"evaluation of bitmask qualifier:"
|
||||
// @" (%.8x & %.8x) %s 0: %d",
|
||||
// intValue, mask, (isZero ? "==" : "!="), rc];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
@" c_lastmodified INT NOT NULL,"
|
||||
@" c_version INT NOT NULL DEFAULT 0,"
|
||||
@" c_deleted TINYINT NOT NULL DEFAULT 0,"
|
||||
@" c_content TEXT)");
|
||||
@" c_content LONGTEXT)");
|
||||
|
||||
return [NSString stringWithFormat: sqlFolderFormat, tableName];
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@ include ../Version
|
|||
|
||||
BACKEND_VERSION = 1.0.0
|
||||
|
||||
UNRTF_VERSION = 0.21.2
|
||||
|
||||
### bootstrap library
|
||||
MAPISTORESOGO = MAPIStoreSOGo
|
||||
LIBRARY_NAME = $(MAPISTORESOGO)
|
||||
|
@ -24,8 +22,6 @@ BUNDLE_NAME = $(SOGOBACKEND)
|
|||
BUNDLE_EXTENSION = .MAPIStore
|
||||
BUNDLE_INSTALL_DIR = $(SOGO_LIBDIR)
|
||||
|
||||
UNRTF_DIR = unrtf-$(UNRTF_VERSION)
|
||||
|
||||
PYTHON = /usr/bin/python
|
||||
PYTHON_IS_GOOD = $(shell $(PYTHON) -c 'from sys import version_info; a=version_info; print a[0] == 2 and a[1] >= 6')
|
||||
ifeq (${PYTHON_IS_GOOD},False)
|
||||
|
@ -37,8 +33,6 @@ all::
|
|||
|
||||
SAMBA_PRIVATE_DIR = $(shell $(PYTHON) ./samba-get-config.py "private dir")
|
||||
|
||||
$(SOGOBACKEND)_SUBPROJECTS += $(UNRTF_DIR)/src
|
||||
|
||||
$(SOGOBACKEND)_PRINCIPAL_CLASS = MAPIApplication
|
||||
|
||||
$(SOGOBACKEND)_OBJC_FILES += \
|
||||
|
@ -133,32 +127,14 @@ $(SOGOBACKEND)_OBJC_FILES += \
|
|||
\
|
||||
EOQualifier+MAPI.m \
|
||||
\
|
||||
EOBitmaskQualifier.m
|
||||
EOBitmaskQualifier.m \
|
||||
\
|
||||
BSONCodec.m \
|
||||
RTFHandler.m
|
||||
|
||||
|
||||
$(SOGOBACKEND)_RESOURCE_FILES += \
|
||||
product.plist \
|
||||
$(UNRTF_DIR)/charmaps/SYMBOL.charmap \
|
||||
$(UNRTF_DIR)/outputs/html.conf
|
||||
|
||||
### unrtf
|
||||
all:: $(UNRTF_DIR)/config.h $(UNRTF_DIR)/src/GNUmakefile
|
||||
|
||||
$(UNRTF_DIR): $(UNRTF_DIR).tar.gz $(UNRTF_DIR).diff
|
||||
@echo " Extracting and patching $(UNRTF_DIR)..."
|
||||
@rm -rf $(UNRTF_DIR)
|
||||
@$(TAR) -xvzf $< > /dev/null
|
||||
@(cd $(UNRTF_DIR) && patch -p1 < ../$(UNRTF_DIR).diff) > /dev/null
|
||||
@touch $(UNRTF_DIR)
|
||||
|
||||
$(UNRTF_DIR)-stamp: $(UNRTF_DIR)
|
||||
@touch $@
|
||||
|
||||
$(UNRTF_DIR)/config.h: $(UNRTF_DIR)-stamp unrtf_config_h
|
||||
@cp unrtf_config_h $(UNRTF_DIR)/config.h
|
||||
|
||||
$(UNRTF_DIR)/src/GNUmakefile: $(UNRTF_DIR)-stamp GNUmakefile.unrtf
|
||||
@cp GNUmakefile.unrtf $@
|
||||
product.plist
|
||||
|
||||
### pl reader
|
||||
PLREADER_TOOL = plreader
|
||||
|
@ -210,7 +186,6 @@ ADDITIONAL_INCLUDE_DIRS += \
|
|||
-DSAMBA_PRIVATE_DIR=@"\"$(SAMBA_PRIVATE_DIR)\"" \
|
||||
$(LIBMAPI_CFLAGS) \
|
||||
$(LIBMAPISTORE_CFLAGS) \
|
||||
-I$(UNRTF_DIR)/src \
|
||||
-I../SoObjects -I../SOPE \
|
||||
-DBACKEND_BUNDLE_NAME="@\"$(BUNDLE_NAME)$(BUNDLE_EXTENSION)\"" \
|
||||
-DSOGO_BUNDLES_DIR="@\"$(BUNDLE_INSTALL_DIR)\""
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
# -*-makefile-*-
|
||||
|
||||
# GNUstep makefile
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
UNRTF = unrtf
|
||||
|
||||
SUBPROJECT_NAME = $(UNRTF)
|
||||
|
||||
$(UNRTF)_C_FILES = \
|
||||
attr.c \
|
||||
convert.c \
|
||||
error.c \
|
||||
hash.c \
|
||||
malloc.c \
|
||||
my_iconv.c \
|
||||
output.c \
|
||||
parse.c \
|
||||
unicode.c \
|
||||
user.c \
|
||||
util.c \
|
||||
word.c
|
||||
|
||||
$(UNRTF)_CFLAGS = -DHAVE_CONFIG_H=1 -I. -I../
|
||||
|
||||
# Option include to set any additional variables
|
||||
-include GNUmakefile.preamble
|
||||
|
||||
# Include in the rules for making libraries
|
||||
include $(GNUSTEP_MAKEFILES)/subproject.make
|
||||
|
||||
# Option include to define any additional rules
|
||||
-include GNUmakefile.postamble
|
|
@ -161,7 +161,7 @@
|
|||
return [self getNo: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (void) save
|
||||
- (void) save: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
// (gdb) po embeddedMessage->properties
|
||||
// 2442592320 = "2012-07-11 22:30:00 +0000";
|
||||
|
@ -208,7 +208,8 @@
|
|||
|
||||
[[container event] updateFromMAPIProperties: properties
|
||||
inUserContext: [self userContext]
|
||||
withActiveUser: activeUser];
|
||||
withActiveUser: activeUser
|
||||
inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
SOGoAppointmentObject *newEntry;
|
||||
NSString *name;
|
||||
|
||||
[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__];
|
||||
//[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__];
|
||||
|
||||
name = [NSString stringWithFormat: @"%@.ics",
|
||||
[SOGoObject globallyUniqueObjectId]];
|
||||
|
|
|
@ -200,6 +200,7 @@ static Class NSArrayK;
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
//NSLog(@"MAPIStoreCalendarMessage: -dealloc (%p)", self);
|
||||
[calendar release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
@ -417,7 +418,7 @@ static Class NSArrayK;
|
|||
return [self getYes: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (NSString *) _uidFromGlobalObjectId
|
||||
- (NSString *) _uidFromGlobalObjectId: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSData *objectId;
|
||||
NSString *uid = nil;
|
||||
|
@ -431,7 +432,7 @@ static Class NSArrayK;
|
|||
if (objectId)
|
||||
{
|
||||
length = [objectId length];
|
||||
bytesDup = talloc_array (NULL, char, length + 1);
|
||||
bytesDup = talloc_array (memCtx, char, length + 1);
|
||||
memcpy (bytesDup, [objectId bytes], length);
|
||||
bytesDup[length] = 0;
|
||||
uidStart = bytesDup + length - 1;
|
||||
|
@ -596,7 +597,7 @@ static Class NSArrayK;
|
|||
}
|
||||
}
|
||||
|
||||
- (void) save
|
||||
- (void) save: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
// iCalCalendar *vCalendar;
|
||||
// NSCalendarDate *now;
|
||||
|
@ -608,7 +609,7 @@ static Class NSArrayK;
|
|||
|
||||
if (isNew)
|
||||
{
|
||||
uid = [self _uidFromGlobalObjectId];
|
||||
uid = [self _uidFromGlobalObjectId: memCtx];
|
||||
if (uid)
|
||||
{
|
||||
/* Hack required because of what's explained in oxocal 3.1.4.7.1:
|
||||
|
@ -650,12 +651,12 @@ static Class NSArrayK;
|
|||
activeUser = [[self context] activeUser];
|
||||
[masterEvent updateFromMAPIProperties: properties
|
||||
inUserContext: [self userContext]
|
||||
withActiveUser: activeUser];
|
||||
withActiveUser: activeUser
|
||||
inMemCtx: memCtx];
|
||||
[self _updateAttachedEvents];
|
||||
[[self userContext] activateWithUser: activeUser];
|
||||
[sogoObject updateContentWithCalendar: calendar
|
||||
fromRequest: nil];
|
||||
|
||||
[self updateVersions];
|
||||
}
|
||||
|
||||
|
|
|
@ -224,7 +224,7 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
|
|||
NSURL *baseURL;
|
||||
int rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
|
||||
NSLog (@"METHOD '%s' (%d) -- uri: '%s'", __FUNCTION__, __LINE__, newUri);
|
||||
//NSLog (@"METHOD '%s' (%d) -- uri: '%s'", __FUNCTION__, __LINE__, newUri);
|
||||
|
||||
context = nil;
|
||||
|
||||
|
@ -532,8 +532,8 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
|
|||
mappingId = [mapping idFromURL: childURL];
|
||||
if (mappingId == NSNotFound)
|
||||
{
|
||||
[self warnWithFormat: @"no id exist yet for '%@', requesting one...",
|
||||
childURL];
|
||||
//[self warnWithFormat: @"no id exist yet for '%@', requesting one...",
|
||||
// childURL];
|
||||
openchangedb_get_new_folderID (connInfo->oc_ctx, &mappingId);
|
||||
[mapping registerURL: childURL withID: mappingId];
|
||||
contextId = 0;
|
||||
|
|
|
@ -236,7 +236,7 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact";
|
|||
messageKeys = [self messageKeys];
|
||||
|
||||
date = [NSCalendarDate date];
|
||||
[self logWithFormat: @"current date: %@", date];
|
||||
//[self logWithFormat: @"current date: %@", date];
|
||||
|
||||
max = [messageKeys count];
|
||||
for (count = 0; count < max; count++)
|
||||
|
@ -245,7 +245,7 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact";
|
|||
fileDate = [msg lastModificationTime];
|
||||
if ([date laterDate: fileDate] == fileDate)
|
||||
{
|
||||
[self logWithFormat: @"current date: %@", date];
|
||||
//[self logWithFormat: @"current date: %@", date];
|
||||
|
||||
date = fileDate;
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@
|
|||
[super addProperties: newNewProperties];
|
||||
}
|
||||
|
||||
- (void) save
|
||||
- (void) save: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
uint64_t newVersion;
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ static Class MAPIStoreDBMessageK = Nil;
|
|||
cVersion = exchange_globcnt (([value unsignedLongLongValue] >> 16)
|
||||
& 0x0000ffffffffffffLL);
|
||||
version = [NSNumber numberWithUnsignedLongLong: cVersion];
|
||||
[self logWithFormat: @"change number from oxcfxics: %.16lx", [value unsignedLongLongValue]];
|
||||
//[self logWithFormat: @"change number from oxcfxics: %.16lx", [value unsignedLongLongValue]];
|
||||
[self logWithFormat: @" version: %.16lx", cVersion];
|
||||
*qualifier = [[EOKeyValueQualifier alloc] initWithKey: @"version"
|
||||
operatorSelector: EOQualifierOperatorGreaterThanOrEqualTo
|
||||
|
|
|
@ -146,7 +146,7 @@ static Class MAPIStoreAttachmentK;
|
|||
return ULLONG_MAX;
|
||||
}
|
||||
|
||||
- (void) save
|
||||
- (void) save: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
return [self getYes: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (enum mapistore_error) saveMessage
|
||||
- (enum mapistore_error) saveMessage: (TALLOC_CTX *) memCtx;
|
||||
{
|
||||
enum mapistore_error rc;
|
||||
MAPIStoreContext *context;
|
||||
|
@ -60,7 +60,7 @@
|
|||
context = [self context];
|
||||
ownerUser = [[self userContext] sogoUser];
|
||||
if ([[context activeUser] isEqual: ownerUser])
|
||||
rc = [super saveMessage];
|
||||
rc = [super saveMessage: memCtx];
|
||||
else
|
||||
rc = MAPISTORE_ERR_DENIED;
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__];
|
||||
//[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__];
|
||||
|
||||
// [messageKeys release];
|
||||
// [faiMessageKeys release];
|
||||
|
@ -366,7 +366,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
MAPIStoreMapping *mapping;
|
||||
NSString *childURL;
|
||||
|
||||
[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__];
|
||||
//[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__];
|
||||
|
||||
mapping = [self mapping];
|
||||
childURL = [mapping urlFromID: fid];
|
||||
|
@ -393,7 +393,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
MAPIStoreFolder *childFolder;
|
||||
SOGoUser *ownerUser;
|
||||
|
||||
[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__];
|
||||
//[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__];
|
||||
|
||||
ownerUser = [[self userContext] sogoUser];
|
||||
if ([[context activeUser] isEqual: ownerUser]
|
||||
|
@ -450,8 +450,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
NSArray *keys;
|
||||
int rc = MAPISTORE_SUCCESS;
|
||||
|
||||
[self logWithFormat: @"METHOD '%s' (%d) -- tableType: %d",
|
||||
__FUNCTION__, __LINE__, tableType];
|
||||
//[self logWithFormat: @"METHOD '%s' (%d) -- tableType: %d",
|
||||
//__FUNCTION__, __LINE__, tableType];
|
||||
|
||||
if (tableType == MAPISTORE_MESSAGE_TABLE)
|
||||
keys = [self messageKeys];
|
||||
|
@ -513,8 +513,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
MAPIStoreMapping *mapping;
|
||||
SOGoUser *ownerUser;
|
||||
|
||||
[self logWithFormat: @"METHOD '%s' -- mid: 0x%.16llx associated: %d",
|
||||
__FUNCTION__, mid, isAssociated];
|
||||
//[self logWithFormat: @"METHOD '%s' -- mid: 0x%.16llx associated: %d",
|
||||
// __FUNCTION__, mid, isAssociated];
|
||||
|
||||
context = [self context];
|
||||
ownerUser = [[self userContext] sogoUser];
|
||||
|
@ -699,7 +699,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
if (rc != MAPISTORE_SUCCESS)
|
||||
goto end;
|
||||
}
|
||||
[destMsg save];
|
||||
[destMsg save: memCtx];
|
||||
if (!wantCopy)
|
||||
rc = [sourceFolder deleteMessageWithMID: srcMid andFlags: 0];
|
||||
|
||||
|
@ -844,7 +844,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
[mapping registerURL: [targetMessage url]
|
||||
withID: fmid];
|
||||
}
|
||||
[targetMessage save];
|
||||
[targetMessage save: memCtx];
|
||||
}
|
||||
[pool release];
|
||||
|
||||
|
@ -865,7 +865,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
[mapping registerURL: [targetMessage url]
|
||||
withID: fmid];
|
||||
}
|
||||
[targetMessage save];
|
||||
[targetMessage save: memCtx];
|
||||
}
|
||||
[pool release];
|
||||
|
||||
|
|
|
@ -92,8 +92,8 @@
|
|||
value = NSObjectFromMAPISPropValue (&res->lpProp);
|
||||
lastModified = [(MAPIStoreGCSFolder *)
|
||||
container lastModifiedFromMessageChangeNumber: value];
|
||||
[self logWithFormat: @"change number from oxcfxics: %.16lx", [value unsignedLongLongValue]];
|
||||
[self logWithFormat: @" c_lastmodified: %@", lastModified];
|
||||
//[self logWithFormat: @"change number from oxcfxics: %.16lx", [value unsignedLongLongValue]];
|
||||
//[self logWithFormat: @" c_lastmodified: %@", lastModified];
|
||||
if (lastModified)
|
||||
{
|
||||
*qualifier = [[EOKeyValueQualifier alloc] initWithKey: @"c_lastmodified"
|
||||
|
|
|
@ -390,7 +390,7 @@ static Class SOGoMailFolderK, MAPIStoreMailFolderK, MAPIStoreOutboxFolderK;
|
|||
else
|
||||
value = [NSDate date];
|
||||
|
||||
[self logWithFormat: @"lastMessageModificationTime: %@", value];
|
||||
//[self logWithFormat: @"lastMessageModificationTime: %@", value];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@ -613,8 +613,8 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
|||
[messageEntry setObject: modseq forKey: @"modseq"];
|
||||
[messageEntry setObject: changeNumber forKey: @"version"];
|
||||
|
||||
[self logWithFormat: @"added message entry for uid %@, modseq %@,"
|
||||
@" version %@", uid, modseq, changeNumber];
|
||||
//[self logWithFormat: @"added message entry for uid %@, modseq %@,"
|
||||
// @" version %@", uid, modseq, changeNumber];
|
||||
|
||||
changeKey = [self getReplicaKeyFromGlobCnt: newChangeNum >> 16];
|
||||
[self _setChangeKey: changeKey forMessageEntry: messageEntry];
|
||||
|
@ -796,7 +796,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
|||
|
||||
if (tableType == MAPISTORE_MESSAGE_TABLE)
|
||||
{
|
||||
changeNumber = [NSString stringWithUnsignedLongLong: changeNum];
|
||||
changeNumber = [NSString stringWithFormat: @"0x%.16llx", changeNum];
|
||||
modseq = [[self modseqFromMessageChangeNumber: changeNumber]
|
||||
unsignedLongLongValue];
|
||||
if (modseq > 0)
|
||||
|
|
|
@ -1576,7 +1576,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
|||
bodySetup = YES;
|
||||
}
|
||||
|
||||
- (void) save
|
||||
- (void) save: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSNumber *value;
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ static Class MAPIStoreMailMessageK, NSDataK, NSStringK;
|
|||
case PidLidAppointmentStartWhole:
|
||||
case PidLidAppointmentEndWhole:
|
||||
case PidLidRecurring:
|
||||
[self logWithFormat: @"apt restriction on mail folder?"];
|
||||
//[self logWithFormat: @"apt restriction on mail folder?"];
|
||||
rc = MAPIRestrictionStateAlwaysFalse;
|
||||
break;
|
||||
|
||||
|
@ -155,10 +155,11 @@ static Class MAPIStoreMailMessageK, NSDataK, NSStringK;
|
|||
|
||||
case PidTagChangeNumber:
|
||||
{
|
||||
value = [NSString stringWithFormat: @"0x%.16llx", [value unsignedLongLongValue]];
|
||||
modseq = [(MAPIStoreMailFolder *)
|
||||
container modseqFromMessageChangeNumber: value];
|
||||
[self logWithFormat: @"change number from oxcfxics: %.16lx", [value unsignedLongLongValue]];
|
||||
[self logWithFormat: @" modseq: %.16lx", [modseq unsignedLongLongValue]];
|
||||
//[self logWithFormat: @"change number from oxcfxics: %.16lx", [value unsignedLongLongValue]];
|
||||
//[self logWithFormat: @" modseq: %.16lx", [modseq unsignedLongLongValue]];
|
||||
if (modseq)
|
||||
modseq = [NSNumber numberWithUnsignedLongLong:
|
||||
[modseq unsignedLongLongValue] + 1];
|
||||
|
@ -316,7 +317,7 @@ static Class MAPIStoreMailMessageK, NSDataK, NSStringK;
|
|||
ASSIGN (sortOrderings, newSortOrderings);
|
||||
else
|
||||
ASSIGN (sortOrderings, [NSArray arrayWithObject: @"ARRIVAL"]);
|
||||
[self logWithFormat: @"new sort orderings: '%@'", sortOrderings];
|
||||
//[self logWithFormat: @"new sort orderings: '%@'", sortOrderings];
|
||||
}
|
||||
else
|
||||
ASSIGN (sortOrderings, [NSArray arrayWithObject: @"ARRIVAL"]);
|
||||
|
|
|
@ -904,7 +904,7 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts, NS
|
|||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (void) save
|
||||
- (void) save: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSString *folderName, *flag, *newIdString, *messageKey;
|
||||
NSData *changeKey, *messageData;
|
||||
|
@ -943,7 +943,14 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts, NS
|
|||
[mapping registerURL: [self url] withID: mid];
|
||||
|
||||
/* synchronise the cache and update the change key with the one provided
|
||||
by the client */
|
||||
by the client. Before doing this, lets issue a unselect/select combo
|
||||
because of timing issues with Dovecot in obtaining the latest modseq.
|
||||
Sometimes, Dovecot doesn't return the newly appended UID if we do
|
||||
a "UID SORT (DATE) UTF-8 (MODSEQ XYZ) (NOT DELETED)" command (where
|
||||
XYZ is the HIGHESTMODSEQ+1) immediately after IMAP APPEND */
|
||||
[client unselect];
|
||||
[client select: folderName];
|
||||
|
||||
[(MAPIStoreMailFolder *) container synchroniseCache];
|
||||
changeKey = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)];
|
||||
if (changeKey)
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
- (int) getAttachmentTable: (MAPIStoreAttachmentTable **) tablePtr
|
||||
andRowCount: (uint32_t *) countPtr;
|
||||
- (int) setReadFlag: (uint8_t) flag;
|
||||
- (enum mapistore_error) saveMessage;
|
||||
- (enum mapistore_error) saveMessage: (TALLOC_CTX *) memCtx;
|
||||
|
||||
- (NSArray *) activeContainerMessageTables;
|
||||
|
||||
|
@ -74,7 +74,7 @@
|
|||
- (void) copyToMessage: (MAPIStoreMessage *) newMessage inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
|
||||
/* subclasses */
|
||||
- (void) save;
|
||||
- (void) save: (TALLOC_CTX *) memCtx;
|
||||
|
||||
/* attachments (subclasses) */
|
||||
- (MAPIStoreAttachment *) createAttachment;
|
||||
|
|
|
@ -45,11 +45,10 @@
|
|||
#import "NSData+MAPIStore.h"
|
||||
#import "NSObject+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
#import "RTFHandler.h"
|
||||
|
||||
#import "MAPIStoreMessage.h"
|
||||
|
||||
#include <unrtf.h>
|
||||
|
||||
#undef DEBUG
|
||||
#include <stdbool.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
|
@ -60,17 +59,6 @@ static Class MAPIStoreFolderK, MAPIStoreEmbeddedMessageK;
|
|||
|
||||
static NSString *resourcesDir = nil;
|
||||
|
||||
/* rtf conversion via unrtf */
|
||||
static int
|
||||
unrtf_data_output (void *data, const char *str, size_t str_len)
|
||||
{
|
||||
NSMutableData *rtfData = data;
|
||||
|
||||
[rtfData appendBytes: str length: str_len];
|
||||
|
||||
return str_len;
|
||||
}
|
||||
|
||||
static NSData *
|
||||
uncompressRTF (NSData *compressedRTF)
|
||||
{
|
||||
|
@ -97,22 +85,17 @@ rtf2html (NSData *compressedRTF)
|
|||
{
|
||||
NSData *rtf;
|
||||
NSMutableData *html = nil;
|
||||
int rc;
|
||||
struct unRTFOptions unrtfOptions;
|
||||
|
||||
rtf = uncompressRTF (compressedRTF);
|
||||
if (rtf)
|
||||
{
|
||||
html = [NSMutableData data];
|
||||
memset (&unrtfOptions, 0, sizeof (struct unRTFOptions));
|
||||
unrtf_set_output_device (&unrtfOptions, unrtf_data_output, html);
|
||||
unrtfOptions.config_directory = [resourcesDir UTF8String];
|
||||
unrtfOptions.output_format = "html";
|
||||
unrtfOptions.nopict_mode = YES;
|
||||
rc = unrtf_convert_from_string (&unrtfOptions,
|
||||
[rtf bytes], [rtf length]);
|
||||
if (!rc)
|
||||
html = nil;
|
||||
//html = [NSMutableData data];
|
||||
RTFHandler *handler;
|
||||
|
||||
handler = [[RTFHandler alloc] initWithData: rtf];
|
||||
AUTORELEASE(handler);
|
||||
|
||||
html = [handler parse];
|
||||
}
|
||||
|
||||
return html;
|
||||
|
@ -139,7 +122,7 @@ rtf2html (NSData *compressedRTF)
|
|||
|
||||
- (id) init
|
||||
{
|
||||
[self logWithFormat: @"METHOD '%s' (%d) (%d)", __FUNCTION__, __LINE__, self];
|
||||
//[self logWithFormat: @"METHOD '%s' (%d) (%d)", __FUNCTION__, __LINE__, self];
|
||||
|
||||
if ((self = [super init]))
|
||||
{
|
||||
|
@ -153,7 +136,7 @@ rtf2html (NSData *compressedRTF)
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
[self logWithFormat: @"METHOD '%s' (%d) (%d)", __FUNCTION__, __LINE__, self];
|
||||
//[self logWithFormat: @"METHOD '%s' (%d) (%d)", __FUNCTION__, __LINE__, self];
|
||||
[activeUserRoles release];
|
||||
[attachmentKeys release];
|
||||
[attachmentParts release];
|
||||
|
@ -260,7 +243,7 @@ rtf2html (NSData *compressedRTF)
|
|||
struct mapistore_message_recipient *recipient;
|
||||
NSUInteger count;
|
||||
|
||||
[self logWithFormat: @"METHOD '%s'", __FUNCTION__];
|
||||
//[self logWithFormat: @"METHOD '%s'", __FUNCTION__];
|
||||
|
||||
recipients = [NSMutableDictionary new];
|
||||
recipientProperties = [NSDictionary dictionaryWithObject: recipients
|
||||
|
@ -450,7 +433,7 @@ rtf2html (NSData *compressedRTF)
|
|||
NSString *key;
|
||||
MAPIStoreAttachment *attachment, *newAttachment;
|
||||
|
||||
[self logWithFormat: @"METHOD '%s' (%d) (%d)", __FUNCTION__, __LINE__, self];
|
||||
//[self logWithFormat: @"METHOD '%s' (%d) (%d)", __FUNCTION__, __LINE__, self];
|
||||
|
||||
//memCtx = talloc_zero (NULL, TALLOC_CTX);
|
||||
|
||||
|
@ -477,7 +460,7 @@ rtf2html (NSData *compressedRTF)
|
|||
//talloc_free (memCtx);
|
||||
}
|
||||
|
||||
- (enum mapistore_error) saveMessage
|
||||
- (enum mapistore_error) saveMessage: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
enum mapistore_error rc;
|
||||
NSArray *containerTables;
|
||||
|
@ -490,7 +473,7 @@ rtf2html (NSData *compressedRTF)
|
|||
BOOL userIsOwner;
|
||||
MAPIStoreMessage *mainMessage;
|
||||
|
||||
[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__];
|
||||
//[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__];
|
||||
|
||||
context = [self context];
|
||||
ownerUser = [[self userContext] sogoUser];
|
||||
|
@ -518,7 +501,7 @@ rtf2html (NSData *compressedRTF)
|
|||
|
||||
/* folder modified */
|
||||
notif_parameters
|
||||
= talloc_zero(NULL, struct mapistore_object_notification_parameters);
|
||||
= talloc_zero(memCtx, struct mapistore_object_notification_parameters);
|
||||
notif_parameters->object_id = folderId;
|
||||
if (isNew)
|
||||
{
|
||||
|
@ -542,7 +525,7 @@ rtf2html (NSData *compressedRTF)
|
|||
if (isNew)
|
||||
{
|
||||
notif_parameters
|
||||
= talloc_zero(NULL,
|
||||
= talloc_zero(memCtx,
|
||||
struct mapistore_object_notification_parameters);
|
||||
notif_parameters->object_id = [self objectId];
|
||||
notif_parameters->folder_id = folderId;
|
||||
|
@ -562,7 +545,7 @@ rtf2html (NSData *compressedRTF)
|
|||
[[containerTables objectAtIndex: count] restrictedChildKeys];
|
||||
}
|
||||
|
||||
[self save];
|
||||
[self save: memCtx];
|
||||
/* We make sure that any change-related properties are removes from the
|
||||
properties dictionary, to make sure that related methods will be
|
||||
invoked the next time they are requested. */
|
||||
|
@ -937,7 +920,7 @@ rtf2html (NSData *compressedRTF)
|
|||
return MAPISTORE_ERROR;
|
||||
}
|
||||
|
||||
- (void) save
|
||||
- (void) save: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ sogo_backend_atexit (void)
|
|||
|
||||
GSRegisterCurrentThread ();
|
||||
pool = [NSAutoreleasePool new];
|
||||
NSLog (@"allocated classes:\n%s", GSDebugAllocationList (YES));
|
||||
//NSLog (@"allocated classes:\n%s", GSDebugAllocationList (YES));
|
||||
[pool release];
|
||||
GSUnregisterCurrentThread ();
|
||||
}
|
||||
|
@ -1024,7 +1024,7 @@ sogo_message_set_read_flag (void *message_object, uint8_t flag)
|
|||
}
|
||||
|
||||
static enum mapistore_error
|
||||
sogo_message_save (void *message_object)
|
||||
sogo_message_save (void *message_object, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
struct MAPIStoreTallocWrapper *wrapper;
|
||||
NSAutoreleasePool *pool;
|
||||
|
@ -1039,7 +1039,7 @@ sogo_message_save (void *message_object)
|
|||
message = wrapper->instance;
|
||||
GSRegisterCurrentThread ();
|
||||
pool = [NSAutoreleasePool new];
|
||||
rc = [message saveMessage];
|
||||
rc = [message saveMessage: mem_ctx];
|
||||
// [context tearDownRequest];
|
||||
[pool release];
|
||||
GSUnregisterCurrentThread ();
|
||||
|
@ -1229,7 +1229,7 @@ sogo_table_set_restrictions (void *table_object, struct mapi_SRestriction *restr
|
|||
GSRegisterCurrentThread ();
|
||||
pool = [NSAutoreleasePool new];
|
||||
[table setRestrictions: restrictions];
|
||||
[table cleanupCaches];
|
||||
//[table cleanupCaches];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
*table_status = TBLSTAT_COMPLETE;
|
||||
[pool release];
|
||||
|
|
|
@ -375,12 +375,12 @@ static Class NSDataK, NSStringK;
|
|||
|
||||
- (void) setRestrictions: (const struct mapi_SRestriction *) res
|
||||
{
|
||||
EOQualifier *oldRestriction;
|
||||
//EOQualifier *oldRestriction;
|
||||
|
||||
// [self logWithFormat: @"set restriction to (table type: %d): %@",
|
||||
// type, MAPIStringForRestriction (res)];
|
||||
|
||||
oldRestriction = restriction;
|
||||
//oldRestriction = restriction;
|
||||
[restriction autorelease];
|
||||
if (res)
|
||||
restrictionState = [self evaluateRestriction: res
|
||||
|
@ -396,11 +396,11 @@ static Class NSDataK, NSStringK;
|
|||
// FIXME: we should not flush the caches if the restrictions matches
|
||||
[self cleanupCaches];
|
||||
|
||||
if (restriction)
|
||||
[self logWithFormat: @"restriction set to EOQualifier: %@",
|
||||
restriction];
|
||||
else if (oldRestriction)
|
||||
[self logWithFormat: @"restriction unset (was %@)", oldRestriction];
|
||||
//if (restriction)
|
||||
// [self logWithFormat: @"restriction set to EOQualifier: %@",
|
||||
// restriction];
|
||||
// else if (oldRestriction)
|
||||
// [self logWithFormat: @"restriction unset (was %@)", oldRestriction];
|
||||
}
|
||||
|
||||
- (MAPIRestrictionState) evaluateNotRestriction: (struct mapi_SNotRestriction *) res
|
||||
|
|
|
@ -52,9 +52,9 @@ static inline NSNumber *
|
|||
MAPIPropertyKey (enum MAPITAGS propTag)
|
||||
{
|
||||
#if (GS_SIZEOF_LONG == 4)
|
||||
return [NSNumber numberWithUnsignedLong: propTag];
|
||||
return [NSString stringWithFormat: @"%ul", propTag];
|
||||
#elif (GS_SIZEOF_INT == 4)
|
||||
return [NSNumber numberWithUnsignedInt: propTag];
|
||||
return [NSString stringWithFormat: @"%u", propTag];
|
||||
#else
|
||||
#error No suitable type for 4 bytes integers
|
||||
#endif
|
||||
|
|
|
@ -342,7 +342,8 @@ MAPIStoreDumpMessageProperties (NSDictionary *properties)
|
|||
{
|
||||
NSNumber *key;
|
||||
NSArray *allKeys;
|
||||
NSUInteger keyAsInt, count, max;
|
||||
NSUInteger count, max;
|
||||
NSUInteger keyAsInt;
|
||||
id value;
|
||||
|
||||
allKeys = [properties allKeys];
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSCharacterSet.h>
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSMapTable.h>
|
||||
|
@ -116,6 +117,8 @@ static NSMapTable *contextsTable = nil;
|
|||
password = [[NSString alloc] initWithData: content
|
||||
encoding: NSUTF8StringEncoding];
|
||||
[password autorelease];
|
||||
password = [password stringByTrimmingCharactersInSet:
|
||||
[NSCharacterSet characterSetWithCharactersInString: @"\r\n"]];
|
||||
}
|
||||
|
||||
return password;
|
||||
|
|
|
@ -50,8 +50,7 @@ MAPIStoreTallocWrapperDestroy (void *data)
|
|||
GSRegisterCurrentThread ();
|
||||
pool = [NSAutoreleasePool new];
|
||||
wrapper = data;
|
||||
//NSLog (@"destroying wrapped object (wrapper: %p; object: %p)...\n", wrapper, wrapper->MAPIStoreSOGoObject);
|
||||
NSLog (@"destroying wrapped object (wrapper: %p)", wrapper);
|
||||
//NSLog (@"destroying wrapped object (wrapper: %p; object: %p (%@))...\n", wrapper, wrapper->instance, NSStringFromClass([wrapper->instance class]));
|
||||
[wrapper->instance release];
|
||||
[pool release];
|
||||
GSUnregisterCurrentThread ();
|
||||
|
@ -67,8 +66,7 @@ MAPIStoreTallocWrapperDestroy (void *data)
|
|||
talloc_set_destructor ((void *) wrapper, MAPIStoreTallocWrapperDestroy);
|
||||
wrapper->instance = self;
|
||||
[self retain];
|
||||
NSLog (@"returning wrapper: %p; object: %p", wrapper, self);
|
||||
|
||||
//NSLog (@"returning wrapper: %p; object: %p (%@)", wrapper, self, NSStringFromClass([self class]));
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#import <Foundation/NSValue.h>
|
||||
#import <NGExtensions/NSNull+misc.h>
|
||||
|
||||
#import "BSONCodec.h"
|
||||
|
||||
const char *indentationStep = " ";
|
||||
|
||||
@interface NSObject (plext)
|
||||
|
@ -142,41 +144,43 @@ const char *indentationStep = " ";
|
|||
static void
|
||||
OCDumpPListData (NSData *content)
|
||||
{
|
||||
NSDictionary *d;
|
||||
NSPropertyListFormat format;
|
||||
NSString *error = nil;
|
||||
const char *formatName;
|
||||
//NSDictionary *d;
|
||||
//NSPropertyListFormat format;
|
||||
//NSString *error = nil;
|
||||
//const char *formatName;
|
||||
|
||||
d = [NSPropertyListSerialization propertyListFromData: content
|
||||
mutabilityOption: NSPropertyListImmutable
|
||||
format: &format
|
||||
errorDescription: &error];
|
||||
if (d)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case NSPropertyListOpenStepFormat:
|
||||
formatName = "OpenStep";
|
||||
break;
|
||||
case NSPropertyListXMLFormat_v1_0:
|
||||
formatName = "XML";
|
||||
break;
|
||||
case NSPropertyListBinaryFormat_v1_0:
|
||||
formatName = "Binary";
|
||||
break;
|
||||
case NSPropertyListGNUstepFormat:
|
||||
formatName = "GNUstep";
|
||||
break;
|
||||
case NSPropertyListGNUstepBinaryFormat:
|
||||
formatName = "GNUstep binary";
|
||||
break;
|
||||
default: formatName = "unknown";
|
||||
}
|
||||
//d = [NSPropertyListSerialization propertyListFromData: content
|
||||
// mutabilityOption: NSPropertyListImmutable
|
||||
// format: &format
|
||||
// errorDescription: &error];
|
||||
//d = [content BSONValue];
|
||||
|
||||
printf ("File format is: %s\n", formatName);
|
||||
[d displayWithIndentation: 0];
|
||||
printf ("\n");
|
||||
}
|
||||
else
|
||||
printf ("an error occurred: %s\n", [error UTF8String]);
|
||||
// if (d)
|
||||
// {
|
||||
// switch (format)
|
||||
// {
|
||||
// case NSPropertyListOpenStepFormat:
|
||||
// formatName = "OpenStep";
|
||||
// break;
|
||||
// case NSPropertyListXMLFormat_v1_0:
|
||||
// formatName = "XML";
|
||||
// break;
|
||||
// case NSPropertyListBinaryFormat_v1_0:
|
||||
// formatName = "Binary";
|
||||
// break;
|
||||
// case NSPropertyListGNUstepFormat:
|
||||
// formatName = "GNUstep";
|
||||
// break;
|
||||
// case NSPropertyListGNUstepBinaryFormat:
|
||||
// formatName = "GNUstep binary";
|
||||
// break;
|
||||
// default: formatName = "unknown";
|
||||
// }
|
||||
|
||||
// printf ("File format is: %s\n", formatName);
|
||||
// [d displayWithIndentation: 0];
|
||||
// printf ("\n");
|
||||
// }
|
||||
// else
|
||||
// printf ("an error occurred: %s\n", [error UTF8String]);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
Copyright (C) 2005-2012 Inverse inc.
|
||||
|
||||
This file is part of SOGo.
|
||||
|
||||
SOGo is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with OGo; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSData.h>
|
||||
#include <Foundation/NSMapTable.h>
|
||||
#include <Foundation/NSObject.h>
|
||||
#include <Foundation/NSString.h>
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@interface RTFHandler : NSObject
|
||||
{
|
||||
NSMapTable *_charsets;
|
||||
NSMutableData *_html;
|
||||
NSData *_data;
|
||||
|
||||
const char *_bytes;
|
||||
int _current_pos;
|
||||
int _len;
|
||||
}
|
||||
|
||||
- (id) initWithData: (NSData *) theData;
|
||||
- (NSMutableData *) parse;
|
||||
@end
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@interface RTFStack: NSObject
|
||||
{
|
||||
NSMutableArray *a;
|
||||
}
|
||||
- (void) push: (id) theObject;
|
||||
- (id) pop;
|
||||
@end
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@interface RTFFormattingOptions : NSObject
|
||||
{
|
||||
@public
|
||||
BOOL bold;
|
||||
BOOL italic;
|
||||
BOOL underline;
|
||||
BOOL strikethrough;
|
||||
int font_index;
|
||||
int color_index;
|
||||
int start_pos;
|
||||
}
|
||||
@end
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@interface RTFFontInfo : NSObject
|
||||
{
|
||||
@public
|
||||
NSString *family;
|
||||
NSString *charset;
|
||||
NSString *name;
|
||||
unsigned int pitch;
|
||||
unsigned int index;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//
|
||||
// \fX - font, index in font table
|
||||
//
|
||||
@interface RTFFontTable : NSObject
|
||||
{
|
||||
@public
|
||||
NSMapTable *fontInfos;
|
||||
}
|
||||
|
||||
- (void) addFontInfo: (RTFFontInfo *) theFontInfo
|
||||
atIndex: (unsigned int ) theIndex;
|
||||
|
||||
- (RTFFontInfo *) fontInfoAtIndex: (unsigned int ) theIndex;
|
||||
|
||||
@end
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@interface RTFColorDef : NSObject
|
||||
{
|
||||
@public
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//
|
||||
// {\colortbl\red0\green0\blue0;\red128\green0\blue0;\red255\green0\blue0;}
|
||||
//
|
||||
// \cfX - color/foreground - index
|
||||
// \cbX - color/background - index
|
||||
//
|
||||
//
|
||||
@interface RTFColorTable : NSObject
|
||||
{
|
||||
@public
|
||||
NSMutableArray *colorDefs;
|
||||
}
|
||||
|
||||
- (void) addColorDef: (RTFColorDef *) theColorDef;
|
||||
|
||||
@end
|
|
@ -0,0 +1,945 @@
|
|||
/*
|
||||
Copyright (C) 2005-2013 Inverse inc.
|
||||
|
||||
This file is part of SOGo.
|
||||
|
||||
SOGo is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with OGo; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "RTFHandler.h"
|
||||
#include <Foundation/NSValue.h>
|
||||
|
||||
//
|
||||
// Useful macros
|
||||
//
|
||||
#define ADVANCE _bytes++; _current_pos++;
|
||||
#define REWIND _bytes--; _current_pos--;
|
||||
|
||||
|
||||
//
|
||||
// Charset definitions. See http://msdn.microsoft.com/en-us/goglobal/bb964654 for all details.
|
||||
//
|
||||
const unsigned short ansicpg1250[256] = {
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
|
||||
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
|
||||
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
|
||||
0x20ac, 0x0000, 0x201a, 0x0000, 0x201e, 0x2026, 0x2020, 0x2021, 0x0000, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179,
|
||||
0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a,
|
||||
0x00a0, 0x02c7, 0x02d8, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b,
|
||||
0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c,
|
||||
0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
|
||||
0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
|
||||
0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
|
||||
0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 };
|
||||
|
||||
const unsigned short ansicpg1251[256] = {
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
|
||||
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
|
||||
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
|
||||
0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f,
|
||||
0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f,
|
||||
0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407,
|
||||
0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457,
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f };
|
||||
|
||||
const unsigned short ansicpg1252[256] = {
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
|
||||
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
|
||||
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
|
||||
0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178,
|
||||
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
|
||||
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
|
||||
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
|
||||
0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
|
||||
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
|
||||
0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff };
|
||||
|
||||
const unsigned short ansicpg1253[256] = {
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
|
||||
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
|
||||
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
|
||||
0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0000, 0x203a, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00a0, 0x0385, 0x0386, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x0000, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x2015,
|
||||
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x00b5, 0x00b6, 0x00b7, 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f,
|
||||
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
|
||||
0x03a0, 0x03a1, 0x0000, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af,
|
||||
0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
|
||||
0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000 };
|
||||
|
||||
const unsigned short ansicpg1254[256] = {
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
|
||||
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
|
||||
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
|
||||
0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x0000, 0x0178,
|
||||
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
|
||||
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
|
||||
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
|
||||
0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df,
|
||||
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
|
||||
0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff };
|
||||
|
||||
const unsigned short ansicpg1255[256] = {
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
|
||||
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
|
||||
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
|
||||
0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, 0x2122, 0x0000, 0x203a, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20aa, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
|
||||
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
|
||||
0x05b0, 0x05b1, 0x05b2, 0x05b3, 0x05b4, 0x05b5, 0x05b6, 0x05b7, 0x05b8, 0x05b9, 0x0000, 0x05bb, 0x05bc, 0x05bd, 0x05be, 0x05bf,
|
||||
0x05c0, 0x05c1, 0x05c2, 0x05c3, 0x05f0, 0x05f1, 0x05f2, 0x05f3, 0x05f4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df,
|
||||
0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x0000, 0x0000, 0x200e, 0x200f, 0x0000 };
|
||||
|
||||
const unsigned short ansicpg1256[256] = {
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
|
||||
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
|
||||
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
|
||||
0x20ac, 0x067e, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
|
||||
0x06af, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x06a9, 0x2122, 0x0691, 0x203a, 0x0153, 0x200c, 0x200d, 0x06ba,
|
||||
0x00a0, 0x060c, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x06be, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
|
||||
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x061b, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x061f,
|
||||
0x06c1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f,
|
||||
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00d7, 0x0637, 0x0638, 0x0639, 0x063a, 0x0640, 0x0641, 0x0642, 0x0643,
|
||||
0x00e0, 0x0644, 0x00e2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0649, 0x064a, 0x00ee, 0x00ef,
|
||||
0x064b, 0x064c, 0x064d, 0x064e, 0x00f4, 0x064f, 0x0650, 0x00f7, 0x0651, 0x00f9, 0x0652, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x06d2 };
|
||||
|
||||
const unsigned short ansicpg1257[256] = {
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
|
||||
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
|
||||
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
|
||||
0x20ac, 0x0000, 0x201a, 0x0000, 0x201e, 0x2026, 0x2020, 0x2021, 0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00a8, 0x02c7, 0x00b8,
|
||||
0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0000, 0x203a, 0x0000, 0x00af, 0x02db, 0x0000,
|
||||
0x00a0, 0x0000, 0x00a2, 0x00a3, 0x00a4, 0x0000, 0x00a6, 0x00a7, 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6,
|
||||
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6,
|
||||
0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b,
|
||||
0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df,
|
||||
0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c,
|
||||
0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x02d9 };
|
||||
|
||||
const unsigned short ansicpg1258[256] = {
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
|
||||
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
|
||||
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
|
||||
0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, 0x2122, 0x0000, 0x203a, 0x0153, 0x0000, 0x0000, 0x0178,
|
||||
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
|
||||
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
|
||||
0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x0300, 0x00cd, 0x00ce, 0x00cf,
|
||||
0x0110, 0x00d1, 0x0309, 0x00d3, 0x00d4, 0x01a0, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x01af, 0x0303, 0x00df,
|
||||
0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0301, 0x00ed, 0x00ee, 0x00ef,
|
||||
0x0111, 0x00f1, 0x0323, 0x00f3, 0x00f4, 0x01a1, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x01b0, 0x20ab, 0x00ff };
|
||||
|
||||
const unsigned short ansicpg874[256] = {
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
|
||||
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
|
||||
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
|
||||
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
|
||||
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
|
||||
0x20ac, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f,
|
||||
0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f,
|
||||
0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f,
|
||||
0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e3f,
|
||||
0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f,
|
||||
0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0x0000, 0x0000, 0x0000, 0x0000 };
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@implementation RTFStack
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
a = [[NSMutableArray alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(a);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) push: (id) theObject
|
||||
{
|
||||
[a addObject: theObject];
|
||||
}
|
||||
|
||||
- (id) pop
|
||||
{
|
||||
id o = nil;
|
||||
|
||||
if ([a count])
|
||||
{
|
||||
o = AUTORELEASE([[a lastObject] retain]);
|
||||
[a removeLastObject];
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
- (id) top
|
||||
{
|
||||
id o = nil;
|
||||
|
||||
if ([a count])
|
||||
{
|
||||
o = AUTORELEASE([[a lastObject] retain]);
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@implementation RTFFormattingOptions
|
||||
@end
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@implementation RTFFontInfo
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(family);
|
||||
RELEASE(charset);
|
||||
RELEASE(name);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@implementation RTFFontTable
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
fontInfos = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 128);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
NSFreeMapTable(fontInfos);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) addFontInfo: (RTFFontInfo *) theFontInfo
|
||||
atIndex: (unsigned int) theIndex
|
||||
{
|
||||
NSNumber *key;
|
||||
|
||||
key = [NSNumber numberWithInt: theIndex];
|
||||
NSMapInsert(fontInfos, key, (void*) theFontInfo);
|
||||
}
|
||||
|
||||
- (RTFFontInfo *) fontInfoAtIndex: (unsigned int) theIndex
|
||||
{
|
||||
NSNumber *key;
|
||||
|
||||
key = [NSNumber numberWithInt: theIndex];
|
||||
return NSMapGet(fontInfos, key);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@implementation RTFColorDef
|
||||
|
||||
@end
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@implementation RTFColorTable
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
colorDefs = [[NSMutableArray alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(colorDefs);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) addColorDef: (RTFColorDef *) theColorDef
|
||||
{
|
||||
[colorDefs addObject: theColorDef];
|
||||
}
|
||||
|
||||
- (RTFColorDef *) colorDefAtIndex: (unsigned int) theIndex
|
||||
{
|
||||
return [colorDefs objectAtIndex: theIndex];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@implementation RTFHandler
|
||||
|
||||
- (id) initWithData: (NSData *) theData
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
ASSIGN(_data, theData);
|
||||
_bytes = (char *)[_data bytes];
|
||||
_len = [_data length];
|
||||
_current_pos = 0;
|
||||
|
||||
_charsets = NSCreateMapTable(NSObjectMapKeyCallBacks, NSNonOwnedPointerMapValueCallBacks, 10);
|
||||
NSMapInsert(_charsets, @"ansicpg1250", ansicpg1250);
|
||||
NSMapInsert(_charsets, @"ansicpg1251", ansicpg1251);
|
||||
NSMapInsert(_charsets, @"ansicpg1252", ansicpg1252);
|
||||
NSMapInsert(_charsets, @"ansicpg1253", ansicpg1253);
|
||||
NSMapInsert(_charsets, @"ansicpg1254", ansicpg1254);
|
||||
NSMapInsert(_charsets, @"ansicpg1255", ansicpg1255);
|
||||
NSMapInsert(_charsets, @"ansicpg1256", ansicpg1256);
|
||||
NSMapInsert(_charsets, @"ansicpg1257", ansicpg1257);
|
||||
NSMapInsert(_charsets, @"ansicpg1258", ansicpg1258);
|
||||
NSMapInsert(_charsets, @"ansicpg874", ansicpg874);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
NSFreeMapTable(_charsets);
|
||||
RELEASE(_data);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (const char *) parseControlWord: (unsigned int *) len
|
||||
{
|
||||
const char *start, *end;
|
||||
|
||||
start = ADVANCE;
|
||||
|
||||
while (isalnum(*_bytes) || *_bytes == '-')
|
||||
{
|
||||
ADVANCE;
|
||||
}
|
||||
end = _bytes;
|
||||
|
||||
*len = end-start-1;
|
||||
return start+1;
|
||||
}
|
||||
|
||||
//
|
||||
// {\colortbl\red0\green0\blue0;\red128\green0\blue0;\red255\green0\blue0;}
|
||||
//
|
||||
- (RTFColorTable *) parseColorTable
|
||||
{
|
||||
RTFColorTable *colorTable;
|
||||
RTFColorDef *colorDef;
|
||||
|
||||
colorTable = [[[RTFColorTable alloc] init] autorelease];
|
||||
colorDef = [[[RTFColorDef alloc] init] autorelease];
|
||||
|
||||
while (*_bytes != '}')
|
||||
{
|
||||
if (*_bytes == ';')
|
||||
{
|
||||
[colorTable addColorDef: colorDef];
|
||||
colorDef = [[[RTFColorDef alloc] init] autorelease];
|
||||
ADVANCE;
|
||||
}
|
||||
else if (*_bytes == '\\')
|
||||
{
|
||||
const char *cw;
|
||||
unsigned int len;
|
||||
NSString *s;
|
||||
|
||||
cw = [self parseControlWord: &len];
|
||||
|
||||
// Skip our control word
|
||||
//if (strncmp(start+1, "colortbl", len) == 0)
|
||||
// continue;
|
||||
|
||||
s = [[NSString alloc] initWithBytesNoCopy: (void *)cw
|
||||
length: len
|
||||
encoding: NSASCIIStringEncoding
|
||||
freeWhenDone: NO];
|
||||
[s autorelease];
|
||||
|
||||
if ([s hasPrefix: @"red"])
|
||||
{
|
||||
colorDef->red = [[s substringFromIndex: 3] intValue];
|
||||
}
|
||||
else if ([s hasPrefix: @"green"])
|
||||
{
|
||||
colorDef->green = [[s substringFromIndex: 4] intValue];
|
||||
}
|
||||
else
|
||||
{
|
||||
colorDef->blue = [[s substringFromIndex: 4] intValue];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ADVANCE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return colorTable;
|
||||
}
|
||||
|
||||
//
|
||||
// Possible formats:
|
||||
//
|
||||
// {\fonttbl\f0\fswiss Helvetica;}
|
||||
// {\fonttbl{\f0\froman\fcharset0\fprq2 Arial;}{\f1\fswiss\fprq2\fcharset0 Arial;}}
|
||||
//
|
||||
// FIXME: Complex ones not handled right now:
|
||||
//
|
||||
// {\fonttbl{\f2\fnil\fcharset256\fprq2{\*\panose 00020703090202050204}Courier New;}{...
|
||||
// {\fonttbl{\f31\fnil\fcharset0\fprq0 Times New Roman Monotype{\*\falt Times New Roman};}{...
|
||||
//
|
||||
// We receive the full string.
|
||||
//
|
||||
- (RTFFontTable *) parseFontTable
|
||||
{
|
||||
NSMutableString *fontName;
|
||||
RTFFontTable *fontTable;
|
||||
RTFFontInfo *fontInfo;
|
||||
|
||||
unsigned int count;
|
||||
|
||||
fontTable = [[[RTFFontTable alloc] init] autorelease];
|
||||
fontName = nil;
|
||||
count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if (*_bytes == '{')
|
||||
{
|
||||
if (fontTable)
|
||||
{
|
||||
fontInfo = [[[RTFFontInfo alloc] init] autorelease];
|
||||
fontName = [[[NSMutableString alloc] init] autorelease];
|
||||
}
|
||||
ADVANCE;
|
||||
count++;
|
||||
}
|
||||
else if (*_bytes == '}')
|
||||
{
|
||||
if (fontTable) //&& ![NSAllMapTableValues(fontTable->fontInfos) containsObject: fontInfo])
|
||||
{
|
||||
ASSIGN(fontInfo->name, fontName);
|
||||
[fontTable addFontInfo: fontInfo atIndex: fontInfo->index];
|
||||
}
|
||||
ADVANCE;
|
||||
count--;
|
||||
}
|
||||
else if (*_bytes == '\\')
|
||||
{
|
||||
const char *cw;
|
||||
unsigned int len;
|
||||
NSString *s;
|
||||
|
||||
cw = [self parseControlWord: &len];
|
||||
|
||||
// Skip our control word
|
||||
if (strncmp((const char*)cw, "fonttbl", len) == 0)
|
||||
continue;
|
||||
|
||||
// We must at least parse <fontnum><fontfamily><fcharset>
|
||||
s = [[NSString alloc] initWithBytesNoCopy: (void *)cw+1
|
||||
length: len-1
|
||||
encoding: NSASCIIStringEncoding
|
||||
freeWhenDone: NO];
|
||||
[s autorelease];
|
||||
|
||||
// If we got a fontnum, let's parse all three fields at once)
|
||||
if (isdigit(*(cw+1)))
|
||||
{
|
||||
fontInfo->index = [s intValue];
|
||||
|
||||
// We now parse <fontfamily><fcharset>
|
||||
cw = [self parseControlWord: &len];
|
||||
fontInfo->family = [[NSString alloc] initWithBytesNoCopy: (void *)cw+1
|
||||
length: len-1
|
||||
encoding: NSASCIIStringEncoding
|
||||
freeWhenDone: NO];
|
||||
|
||||
cw = [self parseControlWord: &len];
|
||||
fontInfo->charset = [[NSString alloc] initWithBytesNoCopy: (void *)cw+1
|
||||
length: len-1
|
||||
encoding: NSASCIIStringEncoding
|
||||
freeWhenDone: NO];
|
||||
|
||||
// We now skip everything until we find our final group closer ('}')
|
||||
int cc = 1;
|
||||
|
||||
do
|
||||
{
|
||||
if (*_bytes == '{')
|
||||
cc++;
|
||||
if (*_bytes == '}')
|
||||
cc--;
|
||||
|
||||
ADVANCE;
|
||||
}
|
||||
while (cc != 0);
|
||||
|
||||
// move back our buffer;
|
||||
REWIND;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isalnum(*_bytes))
|
||||
[fontName appendFormat: @"%c", *_bytes];
|
||||
ADVANCE;
|
||||
}
|
||||
} while (count != 0);
|
||||
|
||||
return fontTable;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
- (void) parseStyleSheet
|
||||
{
|
||||
unsigned int count;
|
||||
|
||||
count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if (*_bytes == '{')
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else if (*_bytes == '}')
|
||||
{
|
||||
count--;
|
||||
}
|
||||
ADVANCE;
|
||||
|
||||
} while (count != 0);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
- (void) parsePicture
|
||||
{
|
||||
// Do the same as -parseStyleSheet for now, that is, ignore everything.
|
||||
[self parseStyleSheet];
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
- (NSMutableData *) parse
|
||||
{
|
||||
RTFFormattingOptions *formattingOptions;
|
||||
RTFColorTable *colorTable;
|
||||
RTFFontTable *fontTable;
|
||||
RTFStack *stack;
|
||||
|
||||
unsigned short *charset;
|
||||
char c;
|
||||
|
||||
stack = [[RTFStack alloc] init];
|
||||
fontTable = nil;
|
||||
colorTable = nil;
|
||||
charset = NULL;
|
||||
|
||||
_html = [[NSMutableData alloc] init];
|
||||
[_html appendBytes: "<html><meta charset='utf-8'><body>" length: 34];
|
||||
|
||||
|
||||
|
||||
// Check if we got RTF data
|
||||
if (_len > 4 && strncmp((const char*)_bytes, "{\\rtf", 4) != 0)
|
||||
return NO;
|
||||
|
||||
while (_current_pos < _len)
|
||||
{
|
||||
c = *_bytes;
|
||||
|
||||
// RTF control code
|
||||
if (c == '\\')
|
||||
{
|
||||
unsigned int len;
|
||||
const char *cw;
|
||||
NSString *s;
|
||||
|
||||
if (*(_bytes+1) == '\'' && charset)
|
||||
{
|
||||
// A hexadecimal value, based on the specified character set (may be used to identify 8-bit values).
|
||||
NSString *s;
|
||||
NSData *d;
|
||||
|
||||
const char *b1, *b2;
|
||||
unsigned short index;
|
||||
|
||||
ADVANCE;
|
||||
ADVANCE;
|
||||
|
||||
b1 = ADVANCE;
|
||||
b2 = ADVANCE;
|
||||
|
||||
index = (isdigit(*b1) ? *b1 - 48 : toupper(*b1) - 55) * 16;
|
||||
index += (isdigit(*b2) ? *b2 - 48 : toupper(*b2) - 55);
|
||||
|
||||
s = [NSString stringWithCharacters: &(charset[index]) length: 1];
|
||||
d = [s dataUsingEncoding: NSUTF8StringEncoding];
|
||||
[_html appendData: d];
|
||||
continue;
|
||||
}
|
||||
else if (*(_bytes+1) == '*')
|
||||
{
|
||||
while (*_bytes != '}')
|
||||
{
|
||||
ADVANCE;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
cw = [self parseControlWord: &len];
|
||||
|
||||
s = [[NSString alloc] initWithBytesNoCopy: (void *)cw
|
||||
length: len
|
||||
encoding: NSASCIIStringEncoding
|
||||
freeWhenDone: NO];
|
||||
[s autorelease];
|
||||
|
||||
if (strncmp(cw, "ansicpg", 7) == 0)
|
||||
{
|
||||
charset = NSMapGet(_charsets, s);
|
||||
}
|
||||
else if (strncmp(cw, "fonttbl", 7) == 0)
|
||||
{
|
||||
// We rewind our buffer so we start at the beginning of {\fonttbl...
|
||||
_bytes = cw-2;
|
||||
_current_pos -= 10;
|
||||
fontTable = [self parseFontTable];
|
||||
|
||||
// We go back 1 byte in order to end our section properly ('}' character
|
||||
REWIND;
|
||||
}
|
||||
else if (strncmp(cw, "stylesheet", 10) == 0)
|
||||
{
|
||||
_bytes = cw-2;
|
||||
_current_pos -= 13;
|
||||
[self parseStyleSheet];
|
||||
REWIND;
|
||||
}
|
||||
else if (strncmp(cw, "colortbl", 8) == 0)
|
||||
{
|
||||
colorTable = [self parseColorTable];
|
||||
}
|
||||
else if (strncmp(cw, "pict", 4) == 0)
|
||||
{
|
||||
_bytes = cw-2;
|
||||
_current_pos -= 7;
|
||||
[self parsePicture];
|
||||
REWIND;
|
||||
}
|
||||
else if ([s isEqualToString: @"b"] && formattingOptions)
|
||||
{
|
||||
[_html appendBytes: "<b>" length: 3];
|
||||
formattingOptions->bold = YES;
|
||||
}
|
||||
else if ([s isEqualToString: @"b0"] && formattingOptions)
|
||||
{
|
||||
[_html appendBytes: "</b>" length: 4];
|
||||
formattingOptions->bold = NO;
|
||||
}
|
||||
else if ([s hasPrefix: @"cf"] && [s length] > 2)
|
||||
{
|
||||
RTFColorDef *colorDef;
|
||||
int color_index;
|
||||
char *v;
|
||||
|
||||
color_index = [[s substringFromIndex: 2] intValue];
|
||||
|
||||
if (!formattingOptions)
|
||||
continue;
|
||||
|
||||
if (formattingOptions->color_index >= 0) // && color_index != formattingOptions->color_index)
|
||||
{
|
||||
[_html appendBytes: "</font>" length: 7];
|
||||
}
|
||||
|
||||
formattingOptions->color_index = color_index;
|
||||
colorDef = [colorTable colorDefAtIndex: color_index];
|
||||
|
||||
v = malloc(23*sizeof(char));
|
||||
memset(v, 0, 23);
|
||||
sprintf(v, "<font color=\"#%02x%02x%02x\">", colorDef->red, colorDef->green, colorDef->blue);
|
||||
[_html appendBytes: v length: strlen(v)];
|
||||
free(v);
|
||||
}
|
||||
else if ([s hasPrefix: @"fs"])
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
else if ([s hasPrefix: @"fbidis"])
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
else if ([s hasPrefix: @"fromhtml"])
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
else if ([s hasPrefix: @"f"] && [s length] > 1)
|
||||
{
|
||||
RTFFontInfo *fontInfo;
|
||||
int font_index;
|
||||
|
||||
font_index = [[s substringFromIndex: 1] intValue];
|
||||
|
||||
if (!formattingOptions)
|
||||
continue;
|
||||
|
||||
if (formattingOptions->font_index >= 0 &&
|
||||
font_index != formattingOptions->font_index)
|
||||
{
|
||||
[_html appendBytes: "</font>" length: 7];
|
||||
}
|
||||
|
||||
formattingOptions->font_index = font_index;
|
||||
|
||||
fontInfo = [fontTable fontInfoAtIndex: font_index];
|
||||
|
||||
char *v = malloc(128*sizeof(char));
|
||||
memset(v, 0, 128);
|
||||
sprintf(v, "<font face=\"%s\">", [fontInfo->name UTF8String]);
|
||||
[_html appendBytes: v length: strlen(v)];
|
||||
free(v);
|
||||
}
|
||||
else if ([s isEqualToString: @"i"] && formattingOptions)
|
||||
{
|
||||
[_html appendBytes: "<i>" length: 3];
|
||||
formattingOptions->italic = YES;
|
||||
}
|
||||
else if ([s isEqualToString: @"i0"] && formattingOptions)
|
||||
{
|
||||
[_html appendBytes: "</i>" length: 4];
|
||||
formattingOptions->italic = NO;
|
||||
}
|
||||
else if ([s isEqualToString: @"tab"])
|
||||
{
|
||||
[_html appendBytes: " " length: 12];
|
||||
}
|
||||
else if ([s isEqualToString: @"softline"] || [s isEqualToString: @"par"])
|
||||
{
|
||||
[_html appendBytes: "<br>" length: 4];
|
||||
}
|
||||
else if ([s isEqualToString: @"strike"] && formattingOptions)
|
||||
{
|
||||
[_html appendBytes: "<strike>" length: 8];
|
||||
formattingOptions->strikethrough = YES;
|
||||
}
|
||||
else if ([s isEqualToString: @"strike0"] && formattingOptions)
|
||||
{
|
||||
[_html appendBytes: "</strike>" length: 9];
|
||||
formattingOptions->strikethrough = NO;
|
||||
}
|
||||
else if ([s hasPrefix: @"u"] && [s length] > 1 && isdigit([s characterAtIndex: 1]))
|
||||
{
|
||||
NSData *d;
|
||||
unichar ch;
|
||||
|
||||
ch = (unichar)[[s substringFromIndex: 1] intValue];
|
||||
s = [NSString stringWithCharacters: &ch length: 1];
|
||||
d = [s dataUsingEncoding: NSUTF8StringEncoding];
|
||||
[_html appendData: d];
|
||||
}
|
||||
else if ([s isEqualToString: @"ul"] && formattingOptions)
|
||||
{
|
||||
[_html appendBytes: "<u>" length: 3];
|
||||
formattingOptions->underline = YES;
|
||||
}
|
||||
else if (([s isEqualToString: @"ul0"] || [s isEqualToString: @"ulnone"])
|
||||
&& formattingOptions)
|
||||
{
|
||||
[_html appendBytes: "</u>" length: 4];
|
||||
formattingOptions->underline = NO;
|
||||
}
|
||||
|
||||
// If a space delimits the control word, the space does not appear in the document.
|
||||
// Any characters following the delimiter, including spaces, will appear in the document.
|
||||
if (*_bytes == ' ')
|
||||
{
|
||||
ADVANCE;
|
||||
}
|
||||
}
|
||||
else if (c == '{')
|
||||
{
|
||||
formattingOptions = [[[RTFFormattingOptions alloc] init] autorelease];
|
||||
|
||||
formattingOptions->bold = NO;
|
||||
formattingOptions->italic = NO;
|
||||
formattingOptions->strikethrough = NO;
|
||||
formattingOptions->underline = NO;
|
||||
formattingOptions->font_index = -1;
|
||||
formattingOptions->color_index = -1;
|
||||
formattingOptions->start_pos = [_html length];
|
||||
[stack push: formattingOptions];
|
||||
ADVANCE;
|
||||
}
|
||||
else if (c == '}')
|
||||
{
|
||||
formattingOptions = [stack pop];
|
||||
|
||||
if (formattingOptions)
|
||||
{
|
||||
// Handle {\b bold} vs. \b bold \b0
|
||||
if (formattingOptions->bold)
|
||||
{
|
||||
[_html appendBytes: "</b>" length: 4];
|
||||
}
|
||||
|
||||
if (formattingOptions->italic)
|
||||
{
|
||||
[_html appendBytes: "</i>" length: 4];
|
||||
}
|
||||
|
||||
if (formattingOptions->strikethrough)
|
||||
{
|
||||
[_html appendBytes: "</strike>" length: 9];
|
||||
}
|
||||
|
||||
if (formattingOptions->underline)
|
||||
{
|
||||
[_html appendBytes: "</u>" length: 4];
|
||||
}
|
||||
|
||||
if (formattingOptions->font_index >= 0)
|
||||
{
|
||||
[_html appendBytes: "</font>" length: 7];
|
||||
}
|
||||
|
||||
if (formattingOptions->color_index >= 0)
|
||||
{
|
||||
[_html appendBytes: "</font>" length: 7];
|
||||
}
|
||||
}
|
||||
|
||||
formattingOptions = [stack top];
|
||||
ADVANCE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We avoid appending NULL bytes
|
||||
if (*_bytes)
|
||||
[_html appendBytes: _bytes length: 1];
|
||||
ADVANCE;
|
||||
}
|
||||
}
|
||||
|
||||
[_html appendBytes: "</body></html>" length: 14];
|
||||
|
||||
RELEASE(stack);
|
||||
return AUTORELEASE(_html);
|
||||
}
|
||||
|
||||
@end
|
|
@ -46,6 +46,7 @@
|
|||
#import "GCSSpecialQueries+OpenChange.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "SOGoMAPIDBFolder.h"
|
||||
#import "BSONCodec.h"
|
||||
|
||||
#import "SOGoMAPIDBObject.h"
|
||||
|
||||
|
@ -156,9 +157,9 @@ static EOAttribute *textColumn = nil;
|
|||
- (void) setupFromRecord: (NSDictionary *) record
|
||||
{
|
||||
NSInteger intValue;
|
||||
NSString *propsValue, *error;
|
||||
NSString *propsValue;//, *error;
|
||||
NSDictionary *newValues;
|
||||
NSPropertyListFormat format;
|
||||
//NSPropertyListFormat format;
|
||||
|
||||
objectType = [[record objectForKey: @"c_type"] intValue];
|
||||
intValue = [[record objectForKey: @"c_creationdate"] intValue];
|
||||
|
@ -174,13 +175,8 @@ static EOAttribute *textColumn = nil;
|
|||
propsValue = [record objectForKey: @"c_content"];
|
||||
if ([propsValue isNotNull])
|
||||
{
|
||||
newValues = [NSPropertyListSerialization propertyListFromData: [propsValue dataByDecodingBase64]
|
||||
mutabilityOption: NSPropertyListMutableContainers
|
||||
format: &format
|
||||
errorDescription: &error];
|
||||
newValues = [[propsValue dataByDecodingBase64] BSONValue];
|
||||
[properties addEntriesFromDictionary: newValues];
|
||||
// [properties addEntriesFromDictionary: [propsValue
|
||||
// objectFromJSONString]];
|
||||
}
|
||||
else
|
||||
[properties removeAllObjects];
|
||||
|
@ -255,13 +251,13 @@ static EOAttribute *textColumn = nil;
|
|||
className = @"MAPIStoreNotesMessage";
|
||||
else
|
||||
className = @"MAPIStoreDBMessage";
|
||||
[self logWithFormat: @"PidTagMessageClass = '%@', returning '%@'",
|
||||
mapiMsgClass, className];
|
||||
//[self logWithFormat: @"PidTagMessageClass = '%@', returning '%@'",
|
||||
// mapiMsgClass, className];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self warnWithFormat: @"PidTagMessageClass is not set, falling back"
|
||||
@" to 'MAPIStoreDBMessage'"];
|
||||
//[self warnWithFormat: @"PidTagMessageClass is not set, falling back"
|
||||
// @" to 'MAPIStoreDBMessage'"];
|
||||
className = @"MAPIStoreDBMessage";
|
||||
}
|
||||
break;
|
||||
|
@ -526,10 +522,7 @@ static EOAttribute *textColumn = nil;
|
|||
|
||||
if ([properties count] > 0)
|
||||
{
|
||||
content = [NSPropertyListSerialization
|
||||
dataFromPropertyList: properties
|
||||
format: plistFormat
|
||||
errorDescription: NULL];
|
||||
content = [properties BSONRepresentation];
|
||||
propsValue = [adaptor formatValue: [content stringByEncodingBase64]
|
||||
forAttribute: textColumn];
|
||||
}
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import getopt
|
||||
import os
|
||||
import re
|
||||
import string
|
||||
import sys
|
||||
|
||||
h_template = """unsigned short %(charsetName)s[%(len)d] = { %(values)s };"""
|
||||
CHAR_UNDEF = "0x0000"
|
||||
MAP_LEN = 256
|
||||
itemsPerLine = 16
|
||||
|
||||
def usage():
|
||||
usageMsg = """
|
||||
Usage: %s -f inputFile
|
||||
""" % (os.path.basename(sys.argv[0]))
|
||||
sys.stderr.write(usageMsg)
|
||||
|
||||
def parseCharsetFile(file = None):
|
||||
if file is None:
|
||||
return None
|
||||
|
||||
charmap = [CHAR_UNDEF] * MAP_LEN
|
||||
|
||||
# Sample line:
|
||||
# FD = U+200E : LEFT-TO-RIGHT MARK
|
||||
for line in file.xreadlines():
|
||||
m = re.search("(\w{2}) = U\+(\w{4}) :", line)
|
||||
if not m:
|
||||
sys.stderr.write("Skipping weird line: %s" % line)
|
||||
continue
|
||||
|
||||
ind = int(m.group(1), base=16)
|
||||
unicodeValue = str(m.group(2)).lower()
|
||||
|
||||
charmap[ind] = "0x%s" % (unicodeValue)
|
||||
|
||||
return charmap
|
||||
|
||||
|
||||
def formatCharacterMap(charmap = None):
|
||||
if not charmap:
|
||||
return None
|
||||
|
||||
value = ""
|
||||
for i in xrange(0,MAP_LEN-1):
|
||||
char = charmap[i]
|
||||
if i % itemsPerLine == 0:
|
||||
value += "\n "
|
||||
value += "%s, " % (char)
|
||||
i += 1
|
||||
value += charmap[MAP_LEN-1]
|
||||
|
||||
return value
|
||||
|
||||
if __name__ == '__main__':
|
||||
inputFile = None
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "f:")
|
||||
except getopt.GetoptError, err:
|
||||
sys.stderr.write(str(err))
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
for o, a in opts:
|
||||
if o == "-f":
|
||||
inputFile = a
|
||||
else:
|
||||
assert False, "unhandled option"
|
||||
|
||||
if not inputFile:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
f = open(inputFile, "r", 1)
|
||||
|
||||
charsetMap = parseCharsetFile(f)
|
||||
charsetValues = formatCharacterMap(charsetMap)
|
||||
print h_template % {"len": len(charsetMap),
|
||||
"charsetName": os.path.basename(inputFile),
|
||||
"values": charsetValues}
|
|
@ -23,6 +23,8 @@
|
|||
#ifndef ICALEVENT_MAPISTORE_H
|
||||
#define ICALEVENT_MAPISTORE_H
|
||||
|
||||
#include <talloc.h>
|
||||
|
||||
#import <NGCards/iCalEvent.h>
|
||||
|
||||
@class MAPIStoreUserContext;
|
||||
|
@ -34,8 +36,8 @@
|
|||
|
||||
- (void) updateFromMAPIProperties: (NSDictionary *) properties
|
||||
inUserContext: (MAPIStoreUserContext *) userContext
|
||||
withActiveUser: (SOGoUser *) activeUser;
|
||||
|
||||
withActiveUser: (SOGoUser *) activeUser
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
@end
|
||||
|
||||
#endif /* ICALEVENT_MAPISTORE_H */
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <talloc.h>
|
||||
#include <util/attr.h>
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
|
@ -75,16 +74,17 @@
|
|||
@implementation iCalEvent (MAPIStoreProperties)
|
||||
|
||||
- (void) _setupEventRecurrence: (NSData *) mapiRecurrenceData
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
struct Binary_r *blob;
|
||||
struct AppointmentRecurrencePattern *pattern;
|
||||
|
||||
blob = [mapiRecurrenceData asBinaryInMemCtx: NULL];
|
||||
pattern = get_AppointmentRecurrencePattern (blob, blob);
|
||||
blob = [mapiRecurrenceData asBinaryInMemCtx: memCtx];
|
||||
pattern = get_AppointmentRecurrencePattern (memCtx, blob);
|
||||
[(iCalCalendar *) parent
|
||||
setupRecurrenceWithMasterEntity: self
|
||||
fromRecurrencePattern: &pattern->RecurrencePattern];
|
||||
talloc_free (blob);
|
||||
//talloc_free (blob);
|
||||
}
|
||||
|
||||
- (void) _setupEventAlarmFromProperties: (NSDictionary *) properties
|
||||
|
@ -134,6 +134,7 @@
|
|||
- (void) updateFromMAPIProperties: (NSDictionary *) properties
|
||||
inUserContext: (MAPIStoreUserContext *) userContext
|
||||
withActiveUser: (SOGoUser *) activeUser
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
BOOL isAllDay;
|
||||
iCalDateTime *start, *end;
|
||||
|
@ -328,7 +329,7 @@
|
|||
value = [properties
|
||||
objectForKey: MAPIPropertyKey (PidLidAppointmentRecur)];
|
||||
if (value)
|
||||
[self _setupEventRecurrence: value];
|
||||
[self _setupEventRecurrence: value inMemCtx: memCtx];
|
||||
|
||||
/* alarm */
|
||||
[self _setupEventAlarmFromProperties: properties];
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -1,75 +0,0 @@
|
|||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <ctype.h> header file. */
|
||||
#define HAVE_CTYPE_H 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#define HAVE_MALLOC 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
#define HAVE_STDIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strstr' function. */
|
||||
#define HAVE_STRSTR 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "unrtf"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "bug-unrtf@gnu.org"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "unrtf"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "unrtf 0.21.2"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "unrtf"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "0.21.2"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "0.21.2"
|
||||
|
||||
/* Define to rpl_malloc if the replacement function should be used. */
|
||||
/* #undef malloc */
|
|
@ -0,0 +1,20 @@
|
|||
# /etc/fail2ban/filter.d/sogo.conf
|
||||
#
|
||||
# Fail2Ban configuration file
|
||||
# By Arnd Brandes
|
||||
# SOGo
|
||||
#
|
||||
|
||||
[Definition]
|
||||
# Option: failregex
|
||||
# Filter Ban in /var/log/sogo/sogo.log
|
||||
# Note: the error log may contain multiple hosts, whereas the first one
|
||||
# is the client and all others are poxys. We match the first one, only
|
||||
|
||||
failregex = Login from '<HOST>.*' for user '.*' might not have worked
|
||||
|
||||
# Option: ignoreregex
|
||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
||||
# Values: TEXT
|
||||
#
|
||||
ignoreregex =
|
|
@ -0,0 +1,9 @@
|
|||
[SOGo]
|
||||
enabled = true
|
||||
port = http,https
|
||||
# in proxy-free setup this would be:
|
||||
# port = 20000
|
||||
filter = sogo
|
||||
logpath = /var/log/sogo/sogo.log
|
||||
maxretry = 5
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import getopt
|
||||
import imaplib
|
||||
#import ldb
|
||||
import ldb
|
||||
import plistlib
|
||||
import os
|
||||
import re
|
||||
|
@ -16,7 +16,7 @@ imapport = 143
|
|||
sambaprivate = '/var/lib/samba/private'
|
||||
mapistorefolder = "%s/mapistore" % (sambaprivate)
|
||||
sogoSysDefaultsFile = "/etc/sogo/sogo.conf"
|
||||
sogoUserDefaultsFile = "/home/sogo/GNUstep/Defaults/.GNUstepDefaults"
|
||||
sogoUserDefaultsFile = os.path.expanduser("~sogo/GNUstep/Defaults/.GNUstepDefaults")
|
||||
|
||||
# - takes a username and optionally its password
|
||||
# - removes the entry in samba's ldap tree via ldbedit (NOTYET)
|
||||
|
@ -79,13 +79,15 @@ def main():
|
|||
except (shutil.Error, OSError) as e:
|
||||
print "Error during mapistoreCleanup, continuing: %s" % str(e)
|
||||
|
||||
# try:
|
||||
# pass
|
||||
# #ldbCleanup(sambaprivate, username)
|
||||
# except ldb.LdbError as e:
|
||||
# print "Error during ldbCleanup, continuing: %s" % str(e)
|
||||
try:
|
||||
ldbCleanup(sambaprivate, username)
|
||||
except ldb.LdbError as e:
|
||||
print "Error during ldbCleanup, continuing: %s" % str(e)
|
||||
|
||||
try:
|
||||
sqlCleanup(username)
|
||||
except Exception as e:
|
||||
print "Error during sqlCleanup, continuing: %s" % str(e)
|
||||
|
||||
def extractmb(si):
|
||||
inparen = False
|
||||
|
@ -135,6 +137,7 @@ def cleanupmb(mb, client):
|
|||
print "mailbox '%s' coult NOT be deleted (code = '%s')" % (mb, code)
|
||||
|
||||
def imapCleanup(imaphost, imapport, username, userpass):
|
||||
print "Starting IMAP cleanup"
|
||||
client = imaplib.IMAP4(imaphost, imapport)
|
||||
(code, data) = client.login(username, userpass)
|
||||
if code != "OK":
|
||||
|
@ -152,22 +155,41 @@ def imapCleanup(imaphost, imapport, username, userpass):
|
|||
client.logout()
|
||||
|
||||
def mapistoreCleanup(mapistorefolder, username):
|
||||
print "Starting MAPIstore cleanup"
|
||||
|
||||
# delete the user's folder under the mapistore and under mapistore/SOGo
|
||||
shutil.rmtree("%s/%s" % (mapistorefolder, username), ignore_errors=True)
|
||||
mapistoreUserDir = "%s/%s" % (mapistorefolder, username)
|
||||
for dirpath, dirnames, filenames in os.walk(mapistoreUserDir):
|
||||
for f in filenames:
|
||||
if f != "password":
|
||||
os.unlink("%s/%s" % (dirpath,f))
|
||||
break #one level only
|
||||
|
||||
shutil.rmtree("%s/SOGo/%s" % (mapistorefolder, username), ignore_errors=True)
|
||||
|
||||
# NOTYET
|
||||
#def ldbCleanup(sambaprivate, username):
|
||||
# conn = ldb.Ldb("%s/openchange.ldb" % (sambaprivate))
|
||||
#### entries = conn.search(None, expression="(|(cn=%s)(MAPIStoreURI=sogo://%s:*)(MAPIStoreURI=sogo://%s@*))" % (username,username,username),
|
||||
# entries = conn.search(None, expression="cn=%s" % (username),
|
||||
# scope=ldb.SCOPE_SUBTREE)
|
||||
# for entry in entries:
|
||||
# print "Deleting %s" % (entry.dn)
|
||||
# conn.delete(entry.dn)
|
||||
def ldbCleanup(sambaprivate, username):
|
||||
conn = ldb.Ldb("%s/openchange.ldb" % (sambaprivate))
|
||||
# find the DN of the user
|
||||
entries = conn.search(None, expression="(cn=%s)" % (username), scope=ldb.SCOPE_SUBTREE)
|
||||
if not entries:
|
||||
print "cn = %s not found in openchange.ldb" %(username)
|
||||
return
|
||||
|
||||
for entry in entries:
|
||||
# search again, but with the user's DN as a base
|
||||
subentries = conn.search(entry.dn.extended_str(), expression="(distinguishedName=*)", scope=ldb.SCOPE_SUBTREE)
|
||||
for subentry in subentries:
|
||||
print "Deleting %s" % (subentry.dn)
|
||||
conn.delete(subentry.dn)
|
||||
|
||||
def mysqlCleanup(dbhost, dbport, dbuser, dbpass, dbname, username):
|
||||
try:
|
||||
import MySQLdb
|
||||
except ImportError:
|
||||
msg ="""The python 'MySQLdb' module is not available
|
||||
On Debian based distro, install it using 'apt-get install python-mysqlbd'
|
||||
On RHEL, install it using 'yum install MySQL-python'"""
|
||||
raise Exception(msg)
|
||||
|
||||
conn = MySQLdb.connect(host=dbhost, port=int(dbport), user=dbuser, passwd=dbpass, db=dbname)
|
||||
c=conn.cursor()
|
||||
|
@ -177,28 +199,38 @@ def mysqlCleanup(dbhost, dbport, dbuser, dbpass, dbname, username):
|
|||
|
||||
|
||||
def postgresqlCleanup(dbhost, dbport, dbuser, dbpass, dbname, username):
|
||||
try:
|
||||
import pg
|
||||
except ImportError:
|
||||
msg ="""The python 'pg' module is not available
|
||||
On Debian based distro, install it using 'apt-get install python-pygresql'
|
||||
On RHEL, install it using 'yum install python-pgsql'"""
|
||||
raise Exception(msg)
|
||||
|
||||
conn = pg.connect(host=dbhost, port=int(dbport), user=dbuser, passwd=dbpass, dbname=dbname)
|
||||
tablename = "socfs_%s" % username
|
||||
conn.query("DELETE FROM %s" % tablename)
|
||||
print "table '%s' emptied" % tablename
|
||||
print "Table '%s' emptied" % tablename
|
||||
|
||||
def getOCSFolderInfoURL():
|
||||
global sogoSysDefaultsFile, sogoUserDefaultsFile
|
||||
|
||||
OCSFolderInfoURL = ""
|
||||
|
||||
# read defaults from /etc/sogo/sogo.conf
|
||||
if os.path.exists(sogoSysDefaultsFile):
|
||||
sogoDefaults = plistlib.readPlist(sogoSysDefaultsFile)
|
||||
if "OCSFolderInfoURL" in sogoDefaults:
|
||||
OCSFolderInfoURL = sogoDefaults["OCSFolderInfoURL"]
|
||||
# read defaults from defaults files
|
||||
# order is important, user defaults must have precedence
|
||||
for f in [sogoSysDefaultsFile, sogoUserDefaultsFile]:
|
||||
if os.path.exists(f):
|
||||
# FIXME: this is ugly, we should have a python plist parser
|
||||
# plistlib only supports XML plists.
|
||||
# the following magic replaces this shell pipeline:
|
||||
# sogo-tool dump-defaults -f %s | awk -F\\" '/ OCSFolderInfoURL =/ {print $2}'
|
||||
p1 = subprocess.Popen(["sogo-tool", "dump-defaults", "-f", f], stdout=subprocess.PIPE)
|
||||
p2 = subprocess.Popen(["awk", "-F\"", "/ OCSFolderInfoURL =/ {print $2}"], stdin=p1.stdout, stdout=subprocess.PIPE)
|
||||
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
|
||||
tmp = p2.communicate()[0]
|
||||
|
||||
# defaults from user directory must have precedence
|
||||
if os.path.exists(sogoUserDefaultsFile):
|
||||
sogoDefaults = plistlib.readPlist(sogoUserDefaultsFile)
|
||||
if "sogod" in sogoDefaults and "OCSFolderInfoURL" in sogoDefaults["sogod"]:
|
||||
OCSFolderInfoURL = sogoDefaults['sogod']['OCSFolderInfoURL']
|
||||
if tmp: OCSFolderInfoURL = tmp
|
||||
|
||||
return OCSFolderInfoURL
|
||||
|
||||
|
@ -226,6 +258,7 @@ def asCSSIdentifier(inputString):
|
|||
return "".join(newChars)
|
||||
|
||||
def sqlCleanup(username):
|
||||
print "Starting SQL cleanup"
|
||||
OCSFolderInfoURL = getOCSFolderInfoURL()
|
||||
if OCSFolderInfoURL is None:
|
||||
raise Exception("Couldn't fetch OCSFolderInfoURL or it is not set. the socfs_%s table should be truncated manually" % (username))
|
||||
|
@ -233,6 +266,9 @@ def sqlCleanup(username):
|
|||
# postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_folder_info
|
||||
m = re.search("(.+)://(.+):(.+)@(.+):(\d+)/(.+)/(.+)", OCSFolderInfoURL)
|
||||
|
||||
if not m:
|
||||
raise Exception("Unable to parse OCSFolderInfoURL: %s" % OCSFolderInfoURL)
|
||||
|
||||
proto = m.group(1)
|
||||
dbuser = m.group(2)
|
||||
dbpass = m.group(3)
|
||||
|
@ -248,7 +284,7 @@ def sqlCleanup(username):
|
|||
elif (proto == "mysql"):
|
||||
mysqlCleanup(dbhost, dbport, dbuser, dbpass, dbname, encodedUserName)
|
||||
else:
|
||||
raise Exception("Unknown sql proto: " % (proto))
|
||||
raise Exception("Unknown sql proto: %s" % (proto))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
{
|
||||
/* ********************* Main SOGo configuration file **********************
|
||||
* *
|
||||
* Since the content of this file is a dictionary in OpenStep plist format, *
|
||||
* the curly braces enclosing the body of the configuration are mandatory. *
|
||||
* See the Installation Guide for details on the format. *
|
||||
* *
|
||||
* C and C++ style comments are supported. *
|
||||
* *
|
||||
* This example configuration contains only a subset of all available *
|
||||
* configuration parameters. Please see the installation guide more details. *
|
||||
* *
|
||||
* ~sogo/GNUstep/Defaults/.GNUstepDefaults has precedence over this file, *
|
||||
* make sure to move it away to avoid unwanted parameter overrides. *
|
||||
* *
|
||||
* **************************************************************************/
|
||||
|
||||
/* Database configuration (mysql:// or postgresql://) */
|
||||
//SOGoProfileURL = "postgresql://sogo:sogo@localhost:5432/sogo/sogo_user_profile";
|
||||
//OCSFolderInfoURL = "postgresql://sogo:sogo@localhost:5432/sogo/sogo_folder_info";
|
||||
//OCSSessionsFolderURL = "postgresql://sogo:sogo@localhost:5432/sogo/sogo_sessions_folder";
|
||||
|
||||
/* Mail */
|
||||
//SOGoDraftsFolderName = Drafts;
|
||||
//SOGoSentFolderName = Sent;
|
||||
//SOGoTrashFolderName = Trash;
|
||||
//SOGoIMAPServer = localhost;
|
||||
//SOGoSieveServer = sieve://127.0.0.1:4190;
|
||||
//SOGoSMTPServer = 127.0.0.1;
|
||||
//SOGoMailDomain = acme.com;
|
||||
//SOGoMailingMechanism = smtp;
|
||||
//SOGoForceExternalLoginWithEmail = NO;
|
||||
//SOGoMailSpoolPath = /var/spool/sogo;
|
||||
//NGImap4ConnectionStringSeparator = "/";
|
||||
|
||||
//SOGoAppointmentSendEMailNotifications = NO;
|
||||
//SOGoACLsSendEMailNotifications = NO;
|
||||
|
||||
/* Authentication */
|
||||
//SOGoPasswordChangeEnabled = YES;
|
||||
|
||||
/* LDAP authentication example */
|
||||
//SOGoUserSources = (
|
||||
// {
|
||||
// type = ldap;
|
||||
// CNFieldName = cn;
|
||||
// IDFieldName = uid;
|
||||
// UIDFieldName = uid;
|
||||
// baseDN = "ou=users,dc=acme,dc=com";
|
||||
// bindDN = "uid=sogo,ou=users,dc=acme,dc=com";
|
||||
// bindPassword = qwerty;
|
||||
// canAuthenticate = YES;
|
||||
// displayName = "Shared Addresses";
|
||||
// hostname = ldap://127.0.0.1:389;
|
||||
// id = public;
|
||||
// isAddressBook = YES;
|
||||
// }
|
||||
//);
|
||||
|
||||
/* SQL authentication example */
|
||||
/* These database columns MUST be present in the view/table:
|
||||
* c_uid - will be used for authentication - it's the username or username@domain.tld)
|
||||
* c_name - which can be identical to c_uid - will be used to uniquely identify entries
|
||||
* c_password - password of the user, plain-text, md5 or sha encoded for now
|
||||
* c_cn - the user's common name - such as "John Doe"
|
||||
* mail - the user's mail address
|
||||
* See the installation guide for more details
|
||||
*/
|
||||
//SOGoUserSources =
|
||||
// (
|
||||
// {
|
||||
// type = sql;
|
||||
// id = directory;
|
||||
// viewURL = "postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_view";
|
||||
// canAuthenticate = YES;
|
||||
// isAddressBook = YES;
|
||||
// userPasswordAlgorithm = md5;
|
||||
// }
|
||||
// );
|
||||
|
||||
/* Web Interface */
|
||||
//SOGoPageTitle = SOGo;
|
||||
//SOGoVacationEnabled = YES;
|
||||
//SOGoForwardEnabled = YES;
|
||||
//SOGoSieveScriptsEnabled = YES;
|
||||
|
||||
/* General */
|
||||
//SOGoLanguage = English;
|
||||
//SOGoTimeZone = America/Montreal;
|
||||
//SOGoCalendarDefaultRoles = (
|
||||
// PublicDAndTViewer,
|
||||
// ConfidentialDAndTViewer
|
||||
//);
|
||||
//SOGoSuperUsernames = (sogo1, sogo2); //This is an array - keep the parens!
|
||||
|
||||
/* Debug */
|
||||
//SoDebugBaseURL = YES;
|
||||
//ImapDebugEnabled = YES;
|
||||
//LDAPDebugEnabled = YES;
|
||||
//SOGoDebugRequests = YES;
|
||||
//PGDebugEnabled = YES;
|
||||
//MySQL4DebugEnabled = YES;
|
||||
//SOGoUIxDebugEnabled = YES;
|
||||
//WODontZipResponse = YES;
|
||||
//WOLogFile = /var/log/sogo/sogo.log;
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
# Sogod cronjobs
|
||||
|
||||
# Vacation messages expiration
|
||||
# Make sure to set authname and authpassword with the credentials of a sieve admin
|
||||
#0 0 * * * sogo /usr/sbin/sogo-tool expire-autoreply authname:authpassword
|
||||
# The credentials file should contain the sieve admin credentials (username:passwd)
|
||||
#0 0 * * * sogo /usr/sbin/sogo-tool expire-autoreply -p /etc/sogo/sieve.creds
|
||||
|
||||
# Session cleanup - runs every minute
|
||||
# - Ajust the nbMinutes parameter to suit your needs
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# This script only works with mysql
|
||||
# updates c_content to longtext in SOGo/OpenChange cache tables
|
||||
# to avoid truncation of data at 64k
|
||||
|
||||
|
||||
defaultusername=$USER
|
||||
defaulthostname=127.0.0.1
|
||||
defaultdatabase=sogo
|
||||
|
||||
read -p "Username ($defaultusername): " username
|
||||
read -p "Hostname ($defaulthostname): " hostname
|
||||
read -p "Database ($defaultdatabase): " database
|
||||
|
||||
if [ -z "$username" ]
|
||||
then
|
||||
username=$defaultusername
|
||||
fi
|
||||
|
||||
if [ -z "$hostname" ]
|
||||
then
|
||||
hostname=$defaulthostname
|
||||
fi
|
||||
|
||||
if [ -z "$database" ]
|
||||
then
|
||||
database=$defaultdatabase
|
||||
fi
|
||||
|
||||
sqlscript=""
|
||||
|
||||
function growContent() {
|
||||
oldIFS="$IFS"
|
||||
IFS=" "
|
||||
part="`echo -e \"ALTER TABLE $table MODIFY c_content LONGTEXT;\\n\"`";
|
||||
sqlscript="$sqlscript$part"
|
||||
IFS="$oldIFS"
|
||||
}
|
||||
|
||||
echo "This script will ask for the sql password twice" >&2
|
||||
echo "Converting c_content from TEXT to LONGTEXT in SOGo/OpenChange cache tables" >&2
|
||||
tables=`mysql -p -s -u $username -h $hostname $database -e "show tables like 'socfs_%';"`
|
||||
|
||||
for table in $tables;
|
||||
do
|
||||
growContent
|
||||
done
|
||||
|
||||
echo "$sqlscript" | mysql -p -s -u $username -h $hostname $database
|
|
@ -0,0 +1,66 @@
|
|||
"Personal Calendar" = "التقويم الشخصي";
|
||||
vevent_class0 = "(حدث عام)";
|
||||
vevent_class1 = "(حدث خاص)";
|
||||
vevent_class2 = "(حدث سري)";
|
||||
|
||||
vtodo_class0 = "(مهمة عامة)";
|
||||
vtodo_class1 = "(مهمة خاصة)";
|
||||
vtodo_class2 = "(مهمة سرية)";
|
||||
|
||||
/* Receipts */
|
||||
"The event \"%{Summary}\" was created" = "أُنشِئ الحدث \"%{Summary}\"";
|
||||
"The event \"%{Summary}\" was deleted" = "حُذِفَ الحدث \"%{Summary}\"";
|
||||
"The event \"%{Summary}\" was updated" = "حُدِّث الحدث \"%{Summary}\"";
|
||||
"The following attendees(s) were notified:" = "تم ابلاغ المدعو (المدعويين) الأتي أسماءهم:";
|
||||
"The following attendees(s) were added:" = "تم أضافة المدعو (المدعويين) الأتي أسماءهم:";
|
||||
"The following attendees(s) were removed:" = "تم مسح المدعو (المدعويين) الأتي أسماءهم:";
|
||||
|
||||
/* IMIP messages */
|
||||
"calendar_label" = "التقويم:";
|
||||
"startDate_label" = "البداية:";
|
||||
"endDate_label" = "النهاية:";
|
||||
"due_label" = "تاريخ الاستحقاق:";
|
||||
"location_label" = "المكان:";
|
||||
"summary_label" = "الملخص:";
|
||||
"comment_label" = "التعليق:";
|
||||
|
||||
/* Invitation */
|
||||
"Event Invitation: \"%{Summary}\"" = "دعوة الحدث: \"%{Summary}\"";
|
||||
"(sent by %{SentBy}) " = "(أرسلت بواسطة٪ {SentBy})";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "وقد دعت%{Organizer} %{SentByText} الى %{Summary} . ⏎\n⏎\nبداية:٪ {StartDate} ⏎\nنهاية:%{EndDate}⏎\nالوصف:%{Description}\n";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}قام بدعوتك %{Summary}. ⏎\n⏎\nبداية:٪ {StartDate} في {٪ StartTime} ⏎\nالغاية: {٪ EndDate} في {٪ EndTime} ⏎\nالوصف:%{Description}\n";
|
||||
|
||||
/* Deletion */
|
||||
"Event Cancelled: \"%{Summary}\"" = "الحدث الغي : \"%{Summary}\"";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"
|
||||
= "ألغى%{Organizer} %{SentByText} هذا الحدث:.%{Summary} ⏎\n⏎\nبداية:٪ {StartDate} ⏎\nنهاية:%{EndDate} ⏎\nالوصف:%{Description}";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"
|
||||
= "%{Organizer} %{SentByText}قام بإلغاء هذا الحدث: %{Summary}.⏎\n⏎\nبداية:٪ {StartDate} في {٪ StartTime} ⏎\nالغاية: {٪ EndDate} في {٪ EndTime} ⏎\nالوصف:%{Description}";
|
||||
|
||||
/* Update */
|
||||
"The appointment \"%{Summary}\" for the %{OldStartDate} has changed"
|
||||
= "موعد \"%{Summary}\" بتاريخ %{OldStartDate} قد تغير";
|
||||
"The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed"
|
||||
= "تعيين \"%{Summary}\" ل٪ {OldStartDate} في {٪ OldStartTime} قد تغيرت";
|
||||
"The following parameters have changed in the \"%{Summary}\" meeting:"
|
||||
= " لقد تغيرت المحددات التالية في الاجتماع \"%{Summary}\":";
|
||||
"Please accept or decline those changes."
|
||||
= "يرجى قبول أو رفض تلك التغييرات.";
|
||||
|
||||
/* Reply */
|
||||
"Accepted invitation: \"%{Summary}\"" = "دعوةٌ مقبولة: \"%{Summary}\"";
|
||||
"Declined invitation: \"%{Summary}\"" = "دعوةٌ مرفوضة: \"%{Summary}\"";
|
||||
"Delegated invitation: \"%{Summary}\"" = "دعوة تفويض: \"%{Summary}\"";
|
||||
"Not yet decided on invitation: \"%{Summary}\"" = "دعوةٌ لم تقرر بشأنها: \"%{Summary}\"";
|
||||
"%{Attendee} %{SentByText}has accepted your event invitation."
|
||||
= "وقد قبلت%{Attendee} %{SentByText} دعوتك الحدث.";
|
||||
"%{Attendee} %{SentByText}has declined your event invitation."
|
||||
= "وقد رفض %{Attendee} %{SentByText} دعوتك للحدث";
|
||||
"%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}."
|
||||
= "وقد فوض%{Attendee} %{SentByText} الدعوة إلى %{Delegate}.";
|
||||
"%{Attendee} %{SentByText}has not yet decided upon your event invitation."
|
||||
= "%{Attendee} %{SentByText} لم يقرر حتى الآن حضورهذا الحدث الخاص بك.";
|
||||
|
||||
/* Resources */
|
||||
"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "لا يمكن الوصول إلى الموارد: \"%{Cn} %{SystemEmail}\"";
|
||||
"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "الحد الأقصى لعدد الحجوزات في وقت واحد (%{NumberOfSimultaneousBookings}) وصلت للموارد \"%{Cn} %{SystemEmail}\" . الحدث المتضارب في الموعد هو \"٪ {EventTitle}\"، ويبدأ فى٪ {StartDate}.";
|
|
@ -8,23 +8,15 @@ vtodo_class1 = "(Privat opgave)";
|
|||
vtodo_class2 = "(Hemmelig opgave)";
|
||||
|
||||
/* Receipts */
|
||||
"Title:" = "Titel:";
|
||||
"Start:" = "Start:";
|
||||
"End:" = "Slut:";
|
||||
|
||||
"Receipt: users invited to a meeting" = "Kvittering: brugere inviteret til et møde";
|
||||
"You have invited the following attendees(s):" = "Du har inviteret følgende deltager(e):";
|
||||
"... to attend the following event:" = "... til at deltage i følgende begivenhed:";
|
||||
|
||||
"Receipt: invitation updated" = "Kvittering: invitation opdateret";
|
||||
"The following attendees(s):" = "Følgende deltager(e):";
|
||||
"... have been notified of the changes to the following event:" = "... er blevet underrettet om ændringer i følgende begivenheder:";
|
||||
|
||||
"Receipt: attendees removed from an event" = "Kvittering: deltagere fjernet fra en begivenhed";
|
||||
"You have removed the following attendees(s):" = "Du har fjernet følgende deltager(e):";
|
||||
"... from the following event:" = "... fra følgende begivenhed:";
|
||||
"The event \"%{Summary}\" was created" = "Begivenheden \"%{Summary}\" blev oprettet";
|
||||
"The event \"%{Summary}\" was deleted" = "Begivenheden \"%{Summary}\" blev slettet";
|
||||
"The event \"%{Summary}\" was updated" = "Begivenheden \"%{Summary}\" blev opdateret";
|
||||
"The following attendees(s) were notified:" = "Følgende deltager(e) blev underrettet:";
|
||||
"The following attendees(s) were added:" = "Følgende deltager(e) blev tilføjet:";
|
||||
"The following attendees(s) were removed:" = "Følgende deltager(e) blev fjernet:";
|
||||
|
||||
/* IMIP messages */
|
||||
"calendar_label" = "Kalender:";
|
||||
"startDate_label" = "Start:";
|
||||
"endDate_label" = "Slut:";
|
||||
"due_label" = "Forfaldsdato:";
|
||||
|
@ -33,32 +25,33 @@ vtodo_class2 = "(Hemmelig opgave)";
|
|||
"comment_label" = "Kommentér:";
|
||||
|
||||
/* Invitation */
|
||||
"Event Invitation: \"%{Summary}\"" = "Begivenhed Invitation: \"%{Opsummering}\"";
|
||||
"Event Invitation: \"%{Summary}\"" = "Begivenhed Invitation: \"%{Summary}\"";
|
||||
"(sent by %{SentBy}) " = "(Sendt af%{SentBy})";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer}%{SentByText} har inviteret dig til%{Summary}.
|
||||
|
||||
Start:%{StartDate}ved%{StartTime}
|
||||
End:%{EndDate}ved%{endTime}
|
||||
Description:%{Description}";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText}har inviteret dig til %{Summary}.\n\nStart: %{StartDate}\nSlut: %{EndDate}\nBeskrivelse: %{Description}";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer}%{SentByText} har inviteret dig til%{Summary}.\n\nStart:%{StartDate}ved%{StartTime}\nEnd:%{EndDate}ved%{endTime}\nDescription:%{Description}";
|
||||
|
||||
/* Deletion */
|
||||
"Event Cancelled: \"%{Summary}\"" = "Begivenhed Annulleret: \"%{Opsummering}\"";
|
||||
"Event Cancelled: \"%{Summary}\"" = "Begivenhed Annulleret: \"%{Summary}\"";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"
|
||||
= "%{Organizer} %{SentByText}har aflyst denne begivenhed: %{Summary}.\n\nStart: %{StartDate}\nSlut: %{EndDate}\nBeskrivelse: %{Description}";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"
|
||||
= "%{Organizer} %{SentByText}har annulleret denne begivenhed: %{Summary}.
|
||||
|
||||
Start: %{StartDate} at %{StartTime}
|
||||
End: %{EndDate} at %{EndTime}
|
||||
Description: %{Description}";
|
||||
= "%{Organizer} %{SentByText}har annulleret denne begivenhed: %{Summary}.\n\nStart: %{StartDate} %{StartTime}\nSlut: %{EndDate} %{EndTime}\nBeskrivelse: %{Description}";
|
||||
|
||||
/* Update */
|
||||
"The appointment \"%{Summary}\" for the %{OldStartDate} has changed"
|
||||
= "Aftalen \"%{Summary}\" for %{OldStartDate} er ændret";
|
||||
"The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed"
|
||||
= "Aftalen \"%{Summary}\" den %{OldStartDate} kl. %{OldStartTime} er blevet ændret";
|
||||
"The following parameters have changed in the \"%{Summary}\" meeting:"
|
||||
= "Følgende parametre har ændret sig i \"% {Opsummering}\" møde:";
|
||||
= "Følgende parametre har ændret sig i \"%{Summary}\" møde:";
|
||||
"Please accept or decline those changes."
|
||||
= "Venligst acceptér eller afvis disse ændringer.";
|
||||
|
||||
/* Reply */
|
||||
"Accepted invitation: \"%{Summary}\"" = "Accepterede invitationen: \"%{Summary}\"";
|
||||
"Declined invitation: \"%{Summary}\"" = "Afslåede invitationen: \"%{Summary}\"";
|
||||
"Delegated invitation: \"%{Summary}\"" = "Delegerede invitationen: \"%{Summary}\"";
|
||||
"Not yet decided on invitation: \"%{Summary}\"" = "Ikke taget stilling til invitationen: \"%{Summary}\"";
|
||||
"%{Attendee} %{SentByText}has accepted your event invitation."
|
||||
= "%{Attendee} %{SentByText} har accepteret din begivenhedsinvitation.";
|
||||
"%{Attendee} %{SentByText}has declined your event invitation."
|
||||
|
@ -69,4 +62,5 @@ Description: %{Description}";
|
|||
= "%{Attendee} %{SentByText} har endnu ikke taget stilling til din begivenhedsinvitation.";
|
||||
|
||||
/* Resources */
|
||||
"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\"." = "Maximalt antal samtidige bookings (%{NumberOfSimultaneousBookings}) er nået for \"%{Cn} %{SystemEmail}\".";
|
||||
"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "Kan ikke tilgå ressourcen: \"%{Cn} %{SystemEmail}\"";
|
||||
"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Maksimalt antal tilladte indkaldelser (%{NumberOfSimultaneousBookings}) er nået for ressource \"%{Cn} %{SystemEmail}\". Konflikter med begivenheden \"%{EventTitle}\", som starter %{StartDate}.";
|
||||
|
|
|
@ -53,7 +53,7 @@ Appointments_RESOURCE_FILES += \
|
|||
\
|
||||
MSExchangeFreeBusySOAPRequest.wo
|
||||
|
||||
Appointments_LANGUAGES = BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
Appointments_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
|
||||
Appointments_LOCALIZED_RESOURCE_FILES = Localizable.strings
|
||||
|
||||
|
|
|
@ -48,6 +48,10 @@ vtodo_class2 = "(Конфиденциальная задача)";
|
|||
= "Пожалуйста подтвердите или отмените эти изменения.";
|
||||
|
||||
/* Reply */
|
||||
"Accepted invitation: \"%{Summary}\"" = "Принятое приглашение: \"%{Summary}\"";
|
||||
"Declined invitation: \"%{Summary}\"" = "Отклонённое приглашение: \"%{Summary}\"";
|
||||
"Delegated invitation: \"%{Summary}\"" = "Делегированное приглашение: \"%{Summary}\"";
|
||||
"Not yet decided on invitation: \"%{Summary}\"" = "Пока нет решения по приглашению: \"%{Summary}\"";
|
||||
"%{Attendee} %{SentByText}has accepted your event invitation."
|
||||
= "%{Attendee} %{SentByText}согласился участвовать в запланированном мероприятии.";
|
||||
"%{Attendee} %{SentByText}has declined your event invitation."
|
||||
|
|
|
@ -873,7 +873,9 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
|||
NSMutableDictionary *newRecord;
|
||||
NSDictionary *oldRecord;
|
||||
NGCalendarDateRange *newRecordRange;
|
||||
NSComparisonResult compare;
|
||||
int recordIndex, secondsOffsetFromGMT;
|
||||
NSNumber *dateSecs;
|
||||
|
||||
newRecord = nil;
|
||||
recurrenceId = [component recurrenceId];
|
||||
|
@ -895,30 +897,24 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
|||
[recurrenceId setTimeZone: tz];
|
||||
}
|
||||
|
||||
if ([dateRange containsDate: [component startDate]] ||
|
||||
[dateRange containsDate: [component endDate]])
|
||||
compare = [[dateRange startDate] compare: recurrenceId];
|
||||
if ((compare == NSOrderedAscending || compare == NSOrderedSame) &&
|
||||
[[dateRange endDate] compare: recurrenceId] == NSOrderedDescending)
|
||||
{
|
||||
recordIndex = [self _indexOfRecordMatchingDate: recurrenceId
|
||||
inArray: ma];
|
||||
// The recurrence exception intersects with the date range;
|
||||
// find the occurence and replace it with the new record
|
||||
recordIndex = [self _indexOfRecordMatchingDate: recurrenceId inArray: ma];
|
||||
if (recordIndex > -1)
|
||||
{
|
||||
if ([dateRange containsDate: [component startDate]])
|
||||
{
|
||||
newRecord = [self fixupRecord: [component quickRecord]];
|
||||
[newRecord setObject: [NSNumber numberWithInt: 1]
|
||||
forKey: @"c_iscycle"];
|
||||
oldRecord = [ma objectAtIndex: recordIndex];
|
||||
[newRecord setObject: [oldRecord objectForKey: @"c_recurrence_id"]
|
||||
forKey: @"c_recurrence_id"];
|
||||
|
||||
// The first instance date is added to the dictionary so it can
|
||||
// be used by UIxCalListingActions to compute the DST offset.
|
||||
[newRecord setObject: [fir startDate] forKey: @"cycleStartDate"];
|
||||
|
||||
// We identified the record as an exception.
|
||||
[newRecord setObject: [NSNumber numberWithInt: 1]
|
||||
forKey: @"isException"];
|
||||
|
||||
[ma replaceObjectAtIndex: recordIndex withObject: newRecord];
|
||||
}
|
||||
else
|
||||
// The range doesn't cover the exception; remove it from the records
|
||||
[ma removeObjectAtIndex: recordIndex];
|
||||
}
|
||||
else
|
||||
[self errorWithFormat:
|
||||
@"missing exception record for recurrence-id %@ (uid %@)",
|
||||
|
@ -926,17 +922,34 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
|||
}
|
||||
else
|
||||
{
|
||||
// The recurrence id of the exception is outside the date range;
|
||||
// simply add the exception to the records array
|
||||
newRecord = [self fixupRecord: [component quickRecord]];
|
||||
newRecordRange = [NGCalendarDateRange
|
||||
calendarDateRangeWithStartDate: [newRecord objectForKey: @"startDate"]
|
||||
endDate: [newRecord objectForKey: @"endDate"]];
|
||||
if ([dateRange doesIntersectWithDateRange: newRecordRange])
|
||||
[ma addObject: newRecord];
|
||||
else
|
||||
newRecord = nil;
|
||||
}
|
||||
|
||||
if (newRecord)
|
||||
{
|
||||
recurrenceId = [component recurrenceId];
|
||||
dateSecs = [NSNumber numberWithInt: [recurrenceId timeIntervalSince1970]];
|
||||
|
||||
[newRecord setObject: dateSecs forKey: @"c_recurrence_id"];
|
||||
[newRecord setObject: [NSNumber numberWithInt: 1] forKey: @"c_iscycle"];
|
||||
// The first instance date is added to the dictionary so it can
|
||||
// be used by UIxCalListingActions to compute the DST offset.
|
||||
[newRecord setObject: [fir startDate] forKey: @"cycleStartDate"];
|
||||
// We identified the record as an exception.
|
||||
[newRecord setObject: [NSNumber numberWithInt: 1] forKey: @"isException"];
|
||||
|
||||
[self _fixExceptionRecord: newRecord fromRow: row];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
|
@ -961,7 +974,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
|||
{
|
||||
components = [[elements objectAtIndex: 0] allObjects];
|
||||
max = [components count];
|
||||
for (count = 1; count < max; count++)
|
||||
for (count = 1; count < max; count++) // skip master event
|
||||
[self _appendCycleException: [components objectAtIndex: count]
|
||||
firstInstanceCalendarDateRange: fir
|
||||
fromRow: row
|
||||
|
|
|
@ -1798,20 +1798,18 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
|||
iCalCalendar *oldCalendar;
|
||||
iCalEvent *oldEvent, *newEvent;
|
||||
iCalEventChanges *changes;
|
||||
NSArray *oldEvents, *newEvents;
|
||||
NSMutableArray *oldEvents, *newEvents;
|
||||
NSCalendarDate *recurrenceId;
|
||||
BOOL master;
|
||||
int i;
|
||||
|
||||
//
|
||||
// We check what has changed in the event and react accordingly.
|
||||
//
|
||||
newEvents = [calendar events];
|
||||
newEvents = [NSMutableArray arrayWithArray: [calendar events]];
|
||||
|
||||
oldCalendar = [self calendar: NO secure: NO];
|
||||
oldEvents = [oldCalendar events];
|
||||
oldEvents = [NSMutableArray arrayWithArray: [oldCalendar events]];
|
||||
recurrenceId = nil;
|
||||
master = NO;
|
||||
|
||||
for (i = [newEvents count]-1; i >= 0; i--)
|
||||
{
|
||||
|
@ -1842,8 +1840,8 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
|||
}
|
||||
else
|
||||
{
|
||||
[calendar removeChild: oldEvent];
|
||||
[oldCalendar removeChild: newEvent];
|
||||
[newEvents removeObject: newEvent];
|
||||
[oldEvents removeObject: oldEvent];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1860,7 +1858,6 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
|||
{
|
||||
oldEvent = [oldEvents objectAtIndex: 0];
|
||||
newEvent = [newEvents objectAtIndex: 0];
|
||||
master = YES;
|
||||
}
|
||||
// A RECURRENCE-ID was added
|
||||
else if ([newEvents count] > [oldEvents count])
|
||||
|
@ -1893,24 +1890,37 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
|||
{
|
||||
NSString *uid;
|
||||
|
||||
// newEvent might be nil here, if we're deleting a RECURRENCE-ID with attendees
|
||||
// If that's the case, we use the oldEvent for now just to obtain the organizer
|
||||
// and we'll swap it back to nil once we're done.
|
||||
if (!newEvent)
|
||||
newEvent = oldEvent;
|
||||
|
||||
// We fetch the organizer's uid. Sometimes, the recurrence-id will
|
||||
// have it, sometimes not. If it doesn't, we fetch it from the master event.
|
||||
uid = [[newEvent organizer] uid];
|
||||
|
||||
if (!uid && !master)
|
||||
if (!uid && !recurrenceId)
|
||||
uid = [[[[[newEvent parent] events] objectAtIndex: 0] organizer] uid];
|
||||
|
||||
// With Thunderbird 10, if you create a recurring event with an exception
|
||||
// occurence, and invite someone, the PUT will have the organizer in the
|
||||
// recurrence-id and not in the master event. We must fix this, otherwise
|
||||
// SOGo will break.
|
||||
if (!master && ![[[[[newEvent parent] events] objectAtIndex: 0] organizer] uid])
|
||||
if (!recurrenceId && ![[[[[newEvent parent] events] objectAtIndex: 0] organizer] uid])
|
||||
[[[[newEvent parent] events] objectAtIndex: 0]
|
||||
setOrganizer: [newEvent organizer]];
|
||||
|
||||
if (newEvent == oldEvent)
|
||||
newEvent = nil;
|
||||
|
||||
if (uid && [uid caseInsensitiveCompare: owner] == NSOrderedSame)
|
||||
{
|
||||
if ((ex = [self _handleUpdatedEvent: newEvent fromOldEvent: oldEvent]))
|
||||
// A RECCURENCE-ID was removed
|
||||
if (!newEvent && oldEvent)
|
||||
[self prepareDeleteOccurence: oldEvent];
|
||||
// The master event was changed, A RECCURENCE-ID was added or modified
|
||||
else if ((ex = [self _handleUpdatedEvent: newEvent fromOldEvent: oldEvent]))
|
||||
return ex;
|
||||
}
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SOGoWebAppointmentFolder.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2009-2010 Inverse inc.
|
||||
* Copyright (C) 2009-2013 Inverse inc.
|
||||
*
|
||||
* Author: Cyril Robert <crobert@inverse.ca>
|
||||
* Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
@ -37,6 +37,7 @@
|
|||
#import <NGCards/iCalCalendar.h>
|
||||
#import <GDLContentStore/GCSFolder.h>
|
||||
#import <SOGo/SOGoAuthenticator.h>
|
||||
#import <SOGo/SOGoSystemDefaults.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserSettings.h>
|
||||
#import <SOGo/NSDictionary+Utilities.h>
|
||||
|
@ -69,14 +70,11 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
|
|||
NSString *authValue, *userPassword;
|
||||
NSArray *parts, *keys;
|
||||
|
||||
userPassword = [[self authenticatorInContext: context]
|
||||
passwordInContext: context];
|
||||
userPassword = [[self authenticatorInContext: context] passwordInContext: context];
|
||||
if ([userPassword length] == 0)
|
||||
{
|
||||
authData = nil;
|
||||
userPassword = [[SOGoSystemDefaults sharedSystemDefaults] encryptionKey];
|
||||
}
|
||||
else
|
||||
{
|
||||
authValue
|
||||
= [[self folderPropertyValueInCategory: @"WebCalendarsAuthentication"]
|
||||
decryptWithKey: userPassword];
|
||||
|
@ -89,7 +87,6 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
|
|||
}
|
||||
else
|
||||
authData = nil;
|
||||
}
|
||||
|
||||
return authData;
|
||||
}
|
||||
|
@ -99,10 +96,11 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
|
|||
{
|
||||
NSString *authValue, *userPassword;
|
||||
|
||||
userPassword = [[self authenticatorInContext: context]
|
||||
passwordInContext: context];
|
||||
if ([userPassword length] > 0)
|
||||
{
|
||||
userPassword = [[self authenticatorInContext: context] passwordInContext: context];
|
||||
if ([userPassword length] == 0) {
|
||||
userPassword = [[SOGoSystemDefaults sharedSystemDefaults] encryptionKey];
|
||||
}
|
||||
|
||||
if (!username)
|
||||
username = @"";
|
||||
if (!password)
|
||||
|
@ -111,7 +109,6 @@ size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
|
|||
[self setFolderPropertyValue: [authValue encryptWithKey: userPassword]
|
||||
inCategory: @"WebCalendarsAuthentication"];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDictionary *) loadWebCalendar
|
||||
{
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
"Personal Address Book" = "دفتر العناوين الشخصية";
|
|
@ -27,7 +27,7 @@ Contacts_OBJC_FILES = \
|
|||
Contacts_RESOURCE_FILES += \
|
||||
product.plist \
|
||||
|
||||
Contacts_LANGUAGES = BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
Contacts_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
|
||||
Contacts_LOCALIZED_RESOURCE_FILES = Localizable.strings
|
||||
|
||||
|
|
|
@ -200,7 +200,10 @@
|
|||
|
||||
- (NSArray *) toOneRelationshipKeys
|
||||
{
|
||||
return [source allEntryIDs];
|
||||
NSString *userDomain;
|
||||
|
||||
userDomain = [[context activeUser] domain];
|
||||
return [source allEntryIDsVisibleFromDomain: userDomain];
|
||||
}
|
||||
|
||||
- (NSException *) saveLDIFEntry: (SOGoContactLDIFEntry *) ldifEntry
|
||||
|
|
|
@ -42,6 +42,8 @@ Mailer_RESOURCE_FILES += \
|
|||
product.plist \
|
||||
|
||||
Mailer_RESOURCE_FILES += \
|
||||
SOGoMailArabicForward.wo \
|
||||
SOGoMailArabicReply.wo \
|
||||
SOGoMailBrazilianPortugueseForward.wo \
|
||||
SOGoMailBrazilianPortugueseReply.wo \
|
||||
SOGoMailCatalanForward.wo \
|
||||
|
@ -72,6 +74,8 @@ Mailer_RESOURCE_FILES += \
|
|||
SOGoMailPolishReply.wo \
|
||||
SOGoMailRussianForward.wo \
|
||||
SOGoMailRussianReply.wo \
|
||||
SOGoMailSlovakForward.wo \
|
||||
SOGoMailSlovakReply.wo \
|
||||
SOGoMailSpanishSpainForward.wo \
|
||||
SOGoMailSpanishSpainReply.wo \
|
||||
SOGoMailSpanishArgentinaForward.wo \
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<#newLine/>
|
||||
<#newLine/>
|
||||
<#newLine/>
|
||||
-------- الرسالة الاصلية --------<#newLine/>
|
||||
الموضوع: <#subject/><#newLine/>
|
||||
التاريخ: <#date/><#newLine/>
|
||||
من: <#from/><#newLine/>
|
||||
<#hasReplyTo>ردً على: <#replyTo/></#hasReplyTo><#hasOrganization>المنظمة: <#organization/></#hasOrganization>إلى: <#to/><#newLine/>
|
||||
<#hasCc>CC: <#cc/></#hasCc><#hasNewsGroups>مجموعات الأخبار: <#newsgroups/></#hasNewsGroups><#hasReferences>المراجع: <#references/></#hasReferences><#newLine/>
|
||||
<#newLine/>
|
||||
<#messageBody/><#newLine/>
|
||||
<#newLine/>
|
||||
<#signature/><#newLine/>
|
|
@ -0,0 +1,79 @@
|
|||
subject: WOString {
|
||||
value = subject;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
date: WOString {
|
||||
value = date;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
from: WOString {
|
||||
value = from;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
newLine: WOString {
|
||||
value = newLine;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasReplyTo: WOConditional {
|
||||
condition = hasReplyTo;
|
||||
}
|
||||
|
||||
replyTo: WOString {
|
||||
value = replyTo;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasOrganization: WOConditional {
|
||||
condition = hasOrganization;
|
||||
}
|
||||
|
||||
organization: WOString {
|
||||
value = organization;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
to: WOString {
|
||||
value = to;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasCc: WOConditional {
|
||||
condition = hasCc;
|
||||
}
|
||||
|
||||
cc: WOString {
|
||||
value = cc;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasNewsGroups: WOConditional {
|
||||
condition = hasNewsGroups;
|
||||
}
|
||||
|
||||
newsgroups: WOString {
|
||||
value = newsgroups;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasReferences: WOConditional {
|
||||
condition = hasReferences;
|
||||
}
|
||||
|
||||
references: WOString {
|
||||
value = references;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
messageBody: WOString {
|
||||
value = messageBody;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
signature: WOString {
|
||||
value = signature;
|
||||
escapeHTML = NO;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<#replyPlacementOnTop><#newLine/>
|
||||
<#newLine/>
|
||||
</#replyPlacementOnTop><#signaturePlacementOnTop><#newLine/>
|
||||
<#signature/><#newLine/>
|
||||
</#signaturePlacementOnTop><#outlookMode>-------- الرسالة الأصلية --------<#newLine/>
|
||||
الموضوع: <#subject/><#newLine/>
|
||||
التاريخ: <#date/><#newLine/>
|
||||
من: <#from/><#newLine/>
|
||||
<#hasReplyTo>ردً علي: <#replyTo/></#hasReplyTo><#hasOrganization>المنظمة: <#organization/></#hasOrganization>إلى: <#to/><#newLine/>
|
||||
<#hasCc>CC: <#cc/></#hasCc><#hasNewsGroups>مجموعات الأخبار: <#newsgroups/></#hasNewsGroups><#hasReferences>المراجع: <#references/></#hasReferences></#outlookMode><#newLine/>
|
||||
<#standardMode>في <#date/>, <#from/> كتب:</#standardMode><#newLine/>
|
||||
<#newLine/>
|
||||
<#messageBody/><#newLine/>
|
||||
<#replyPlacementOnBottom><#newLine/>
|
||||
<#newLine/>
|
||||
</#replyPlacementOnBottom><#signaturePlacementOnBottom><#signature/></#signaturePlacementOnBottom><#newLine/>
|
|
@ -0,0 +1,106 @@
|
|||
outlookMode: WOConditional {
|
||||
condition = outlookMode;
|
||||
}
|
||||
|
||||
standardMode: WOConditional {
|
||||
condition = outlookMode;
|
||||
negate = YES;
|
||||
}
|
||||
|
||||
subject: WOString {
|
||||
value = subject;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
date: WOString {
|
||||
value = date;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
from: WOString {
|
||||
value = from;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
newLine: WOString {
|
||||
value = newLine;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasReplyTo: WOConditional {
|
||||
condition = hasReplyTo;
|
||||
}
|
||||
|
||||
replyTo: WOString {
|
||||
value = replyTo;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasOrganization: WOConditional {
|
||||
condition = hasOrganization;
|
||||
}
|
||||
|
||||
organization: WOString {
|
||||
value = organization;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
to: WOString {
|
||||
value = to;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasCc: WOConditional {
|
||||
condition = hasCc;
|
||||
}
|
||||
|
||||
cc: WOString {
|
||||
value = cc;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasNewsGroups: WOConditional {
|
||||
condition = hasNewsGroups;
|
||||
}
|
||||
|
||||
newsgroups: WOString {
|
||||
value = newsgroups;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasReferences: WOConditional {
|
||||
condition = hasReferences;
|
||||
}
|
||||
|
||||
references: WOString {
|
||||
value = references;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
messageBody: WOString {
|
||||
value = messageBody;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
signature: WOString {
|
||||
value = signature;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
replyPlacementOnTop: WOConditional {
|
||||
condition = replyPlacementOnTop;
|
||||
}
|
||||
|
||||
replyPlacementOnBottom: WOConditional {
|
||||
condition = replyPlacementOnTop;
|
||||
negate = YES;
|
||||
}
|
||||
|
||||
signaturePlacementOnTop: WOConditional {
|
||||
condition = signaturePlacementOnTop;
|
||||
}
|
||||
|
||||
signaturePlacementOnBottom: WOConditional {
|
||||
condition = signaturePlacementOnTop;
|
||||
negate = YES;
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
/* SOGoMailForward.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2007-2013 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -39,6 +37,9 @@
|
|||
|
||||
@end
|
||||
|
||||
@interface SOGoMailArabicForward : SOGoMailForward
|
||||
@end
|
||||
|
||||
@interface SOGoMailBrazilianPortugueseForward : SOGoMailForward
|
||||
@end
|
||||
|
||||
|
@ -93,6 +94,9 @@
|
|||
@interface SOGoMailRussianForward : SOGoMailForward
|
||||
@end
|
||||
|
||||
@interface SOGoMailSlovakForward : SOGoMailForward
|
||||
@end
|
||||
|
||||
@interface SOGoMailUkrainianForward : SOGoMailForward
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/* SOGoMailForward.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2007-2013 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -243,6 +241,9 @@
|
|||
|
||||
@end
|
||||
|
||||
@implementation SOGoMailArabicForward
|
||||
@end
|
||||
|
||||
@implementation SOGoMailBrazilianPortugueseForward
|
||||
@end
|
||||
|
||||
|
@ -297,6 +298,9 @@
|
|||
@implementation SOGoMailRussianForward
|
||||
@end
|
||||
|
||||
@implementation SOGoMailSlovakForward
|
||||
@end
|
||||
|
||||
@implementation SOGoMailUkrainianForward
|
||||
@end
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ Data: <#date/><#newLine/>
|
|||
Od: <#from/><#newLine/>
|
||||
<#hasReplyTo>Odpowiedź do: <#replyTo/></#hasReplyTo><#hasOrganization>Organizacja: <#organization/></#hasOrganization>Do: <#to/><#newLine/>
|
||||
<#hasCc>DW: <#cc/></#hasCc><#hasNewsGroups>Grupy dyskusyjne: <#newsgroups/></#hasNewsGroups><#hasReferences>Odniesienia: <#references/></#hasReferences></#outlookMode><#newLine/>
|
||||
<#standardMode>Dnia <#date/>, <#from/> napisał(a):</#standardMode><#newLine/>
|
||||
<#standardMode>W dniu: <#date/>, <#from/> napisał(a):</#standardMode><#newLine/>
|
||||
<#newLine/>
|
||||
<#messageBody/><#newLine/>
|
||||
<#replyPlacementOnBottom><#newLine/>
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/* SOGoMailReply.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007-2010 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2007-2013 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -44,6 +42,9 @@
|
|||
|
||||
@end
|
||||
|
||||
@interface SOGoMailArabicReply : SOGoMailReply
|
||||
@end
|
||||
|
||||
@interface SOGoMailBrazilianPortugueseReply : SOGoMailReply
|
||||
@end
|
||||
|
||||
|
@ -98,6 +99,9 @@
|
|||
@interface SOGoMailRussianReply : SOGoMailReply
|
||||
@end
|
||||
|
||||
@interface SOGoMailSlovakReply : SOGoMailReply
|
||||
@end
|
||||
|
||||
@interface SOGoMailUkrainianReply : SOGoMailReply
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/* SOGoMailReply.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007-2009 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2007-2013 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -101,6 +99,9 @@
|
|||
|
||||
@end
|
||||
|
||||
@implementation SOGoMailArabicReply
|
||||
@end
|
||||
|
||||
@implementation SOGoMailBrazilianPortugueseReply
|
||||
@end
|
||||
|
||||
|
@ -155,6 +156,9 @@
|
|||
@implementation SOGoMailRussianReply
|
||||
@end
|
||||
|
||||
@implementation SOGoMailSlovakReply
|
||||
@end
|
||||
|
||||
@implementation SOGoMailUkrainianReply
|
||||
@end
|
||||
|
||||
|
|
|
@ -779,6 +779,13 @@ static Class NSStringK;
|
|||
return fields;
|
||||
}
|
||||
|
||||
/* This is required for SQL sources when DomainFieldName is enabled.
|
||||
* For LDAP, simply discard the domain and call the original method */
|
||||
- (NSArray *) allEntryIDsVisibleFromDomain: (NSString *) domain
|
||||
{
|
||||
return [self allEntryIDs];
|
||||
}
|
||||
|
||||
- (NSArray *) allEntryIDs
|
||||
{
|
||||
NSEnumerator *entries;
|
||||
|
|
|
@ -195,6 +195,10 @@ static int cssEscapingCount;
|
|||
startLocation--;
|
||||
matchRange.location = startLocation + 1;
|
||||
|
||||
// We avoid going out of bounds if the mail content actually finishes
|
||||
// with the @ (or something else) character
|
||||
if (matchRange.location < [selfCopy length])
|
||||
{
|
||||
currentUrlRange = [selfCopy _rangeOfURLInRange: matchRange];
|
||||
if (![ranges hasRangeIntersection: currentUrlRange])
|
||||
if (currentUrlRange.length > matchLength)
|
||||
|
@ -208,6 +212,11 @@ static int cssEscapingCount;
|
|||
matchRange = [selfCopy rangeOfString: match
|
||||
options: 0 range: rest];
|
||||
}
|
||||
else
|
||||
{
|
||||
matchRange.location = NSNotFound;
|
||||
}
|
||||
}
|
||||
|
||||
// Make the substitutions, keep track of the new offset
|
||||
offset = 0;
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
SOGoZipPath = "/usr/bin/zip";
|
||||
|
||||
SOGoEncryptionKey = "MySOGoEncryptionKey";
|
||||
|
||||
WOUseRelativeURLs = YES;
|
||||
WOMessageUseUTF8 = YES;
|
||||
WOParsersUseUTF8 = YES;
|
||||
|
@ -33,7 +35,7 @@
|
|||
|
||||
SOGoLoginModule = "Mail";
|
||||
SOGoLanguage = "English";
|
||||
SOGoSupportedLanguages = ( "Catalan", "Czech", "Dutch", "Danish", "Welsh", "English",
|
||||
SOGoSupportedLanguages = ( "Arabic", "Catalan", "Czech", "Dutch", "Danish", "Welsh", "English",
|
||||
"SpanishSpain", "SpanishArgentina", "Finnish", "French", "German",
|
||||
"Icelandic", "Italian", "Hungarian", "BrazilianPortuguese",
|
||||
"NorwegianBokmal", "NorwegianNynorsk", "Polish", "Russian", "Slovak",
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "SOGoGroup.h"
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSAutoreleasePool.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
|
@ -224,6 +225,7 @@
|
|||
NSDictionary *d;
|
||||
SOGoUser *user;
|
||||
NSArray *o;
|
||||
NSAutoreleasePool *pool;
|
||||
int i, c;
|
||||
|
||||
if (!_members)
|
||||
|
@ -260,6 +262,7 @@
|
|||
// We add members for whom we have their associated DN
|
||||
for (i = 0; i < [dns count]; i++)
|
||||
{
|
||||
pool = [NSAutoreleasePool new];
|
||||
dn = [dns objectAtIndex: i];
|
||||
login = [um getLoginForDN: [dn lowercaseString]];
|
||||
user = [SOGoUser userWithLogin: login roles: nil];
|
||||
|
@ -268,11 +271,13 @@
|
|||
[logins addObject: login];
|
||||
[_members addObject: user];
|
||||
}
|
||||
[pool release];
|
||||
}
|
||||
|
||||
// We add members for whom we have their associated login name
|
||||
for (i = 0; i < [uids count]; i++)
|
||||
{
|
||||
pool = [NSAutoreleasePool new];
|
||||
login = [uids objectAtIndex: i];
|
||||
user = [SOGoUser userWithLogin: login roles: nil];
|
||||
|
||||
|
@ -281,6 +286,7 @@
|
|||
[logins addObject: login];
|
||||
[_members addObject: user];
|
||||
}
|
||||
[pool release];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#import "SOGoCache.h"
|
||||
#import "SOGoSAML2Exceptions.h"
|
||||
#import "SOGoSystemDefaults.h"
|
||||
#import "SOGoUserManager.h"
|
||||
|
||||
|
||||
#import "SOGoSAML2Session.h"
|
||||
|
||||
|
@ -77,7 +79,7 @@ static NSMapTable *serverTable = nil;
|
|||
{
|
||||
if (!serverTable)
|
||||
{
|
||||
serverTable = [NSMapTable mapTableWithStrongToWeakObjects];
|
||||
serverTable = NSCreateMapTable(NSObjectMapKeyCallBacks, NSNonRetainedObjectMapValueCallBacks, 128);
|
||||
[serverTable retain];
|
||||
}
|
||||
lasso_init ();
|
||||
|
@ -160,7 +162,7 @@ LassoServerInContext (WOContext *context)
|
|||
}
|
||||
request->NameIDPolicy->Format = g_strdup(LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT);
|
||||
request->NameIDPolicy->AllowCreate = 1;
|
||||
request->ForceAuthn = TRUE;
|
||||
request->ForceAuthn = FALSE;
|
||||
request->IsPassive = FALSE;
|
||||
if (request->ProtocolBinding) {
|
||||
g_free (request->ProtocolBinding);
|
||||
|
@ -246,6 +248,13 @@ LassoServerInContext (WOContext *context)
|
|||
login = [NSString stringWithUTF8String: textNode->content];
|
||||
[login retain];
|
||||
}
|
||||
else if (strcmp (attribute->Name, "mail") == 0)
|
||||
{
|
||||
value = LASSO_SAML2_ATTRIBUTE_VALUE (attribute->AttributeValue->data);
|
||||
textNode = value->any->data;
|
||||
login = [[SOGoUserManager sharedUserManager] getUIDForEmail: [NSString stringWithUTF8String: textNode->content]];
|
||||
[login retain];
|
||||
}
|
||||
else
|
||||
attributeList = attributeList->next;
|
||||
}
|
||||
|
@ -381,6 +390,7 @@ LassoServerInContext (WOContext *context)
|
|||
|
||||
responseData = strdup ([authnResponse UTF8String]);
|
||||
|
||||
lasso_profile_set_signature_verify_hint(lassoLogin, LASSO_PROFILE_SIGNATURE_VERIFY_HINT_IGNORE);
|
||||
rc = lasso_login_process_authn_response_msg (lassoLogin, responseData);
|
||||
if (rc)
|
||||
[NSException raiseSAML2Exception: rc];
|
||||
|
|
|
@ -278,7 +278,7 @@ static NSString *sieveScriptName = @"sogo";
|
|||
else
|
||||
scriptError
|
||||
= [NSString stringWithFormat: @"Rule based on unknown field '%@'",
|
||||
*field];
|
||||
jsonField];
|
||||
}
|
||||
else
|
||||
scriptError = @"Rule without any specified field.";
|
||||
|
@ -867,6 +867,7 @@ static NSString *sieveScriptName = @"sogo";
|
|||
}
|
||||
}
|
||||
|
||||
[client closeConnection];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
inDomain: (NSString *) domain;
|
||||
|
||||
- (NSArray *) allEntryIDs;
|
||||
- (NSArray *) allEntryIDsVisibleFromDomain: (NSString *) domain;
|
||||
- (NSArray *) fetchContactsMatching: (NSString *) filter
|
||||
inDomain: (NSString *) domain;
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
- (BOOL) debugLeaks;
|
||||
- (int) vmemLimit;
|
||||
- (BOOL) trustProxyAuthentication;
|
||||
- (NSString *) encryptionKey;
|
||||
- (BOOL) useRelativeURLs;
|
||||
|
||||
- (BOOL) isWebAccessEnabled;
|
||||
|
|
|
@ -349,6 +349,11 @@ _injectConfigurationFromFile (NSMutableDictionary *defaultsDict,
|
|||
return [self boolForKey: @"SOGoTrustProxyAuthentication"];
|
||||
}
|
||||
|
||||
- (NSString *) encryptionKey;
|
||||
{
|
||||
return [self stringForKey: @"SOGoEncryptionKey"];
|
||||
}
|
||||
|
||||
- (BOOL) useRelativeURLs
|
||||
{
|
||||
return [self boolForKey: @"WOUseRelativeURLs"];
|
||||
|
|
|
@ -88,6 +88,14 @@
|
|||
expire: (int *) _expire
|
||||
grace: (int *) _grace;
|
||||
|
||||
- (BOOL) checkLogin: (NSString *) _login
|
||||
password: (NSString *) _pwd
|
||||
domain: (NSString **) _domain
|
||||
perr: (SOGoPasswordPolicyError *) _perr
|
||||
expire: (int *) _expire
|
||||
grace: (int *) _grace
|
||||
useCache: (BOOL) _useCache;
|
||||
|
||||
- (BOOL) changePasswordForLogin: (NSString *) login
|
||||
inDomain: (NSString *) domain
|
||||
oldPassword: (NSString *) oldPassword
|
||||
|
|
|
@ -453,6 +453,23 @@ static Class NSNullK;
|
|||
perr: (SOGoPasswordPolicyError *) _perr
|
||||
expire: (int *) _expire
|
||||
grace: (int *) _grace
|
||||
{
|
||||
return [self checkLogin: _login
|
||||
password: _pwd
|
||||
domain: _domain
|
||||
perr: _perr
|
||||
expire: _expire
|
||||
grace: _grace
|
||||
useCache: YES];
|
||||
}
|
||||
|
||||
- (BOOL) checkLogin: (NSString *) _login
|
||||
password: (NSString *) _pwd
|
||||
domain: (NSString **) _domain
|
||||
perr: (SOGoPasswordPolicyError *) _perr
|
||||
expire: (int *) _expire
|
||||
grace: (int *) _grace
|
||||
useCache: (BOOL) useCache
|
||||
{
|
||||
NSString *dictPassword, *username, *jsonUser;
|
||||
NSMutableDictionary *currentUser;
|
||||
|
@ -468,7 +485,7 @@ static Class NSNullK;
|
|||
jsonUser = [[SOGoCache sharedCache] userAttributesForLogin: username];
|
||||
currentUser = [jsonUser objectFromJSONString];
|
||||
dictPassword = [currentUser objectForKey: @"password"];
|
||||
if (currentUser && dictPassword)
|
||||
if (useCache && currentUser && dictPassword)
|
||||
{
|
||||
checkOK = ([dictPassword isEqualToString: [_pwd asSHA1String]]);
|
||||
//NSLog(@"Password cache hit for user %@", _login);
|
||||
|
|
|
@ -48,6 +48,14 @@
|
|||
expire: (int *) _expire
|
||||
grace: (int *) _grace;
|
||||
|
||||
- (BOOL) checkLogin: (NSString *) _login
|
||||
password: (NSString *) _pwd
|
||||
domain: (NSString **) _domain
|
||||
perr: (SOGoPasswordPolicyError *) _perr
|
||||
expire: (int *) _expire
|
||||
grace: (int *) _grace
|
||||
useCache: (BOOL) useCache;
|
||||
|
||||
- (WOCookie *) cookieWithUsername: (NSString *) username
|
||||
andPassword: (NSString *) password
|
||||
inContext: (WOContext *) context;
|
||||
|
|
|
@ -115,6 +115,23 @@
|
|||
perr: (SOGoPasswordPolicyError *) _perr
|
||||
expire: (int *) _expire
|
||||
grace: (int *) _grace
|
||||
{
|
||||
return [self checkLogin: _login
|
||||
password: _pwd
|
||||
domain: _domain
|
||||
perr: _perr
|
||||
expire: _expire
|
||||
grace: _grace
|
||||
useCache: YES];
|
||||
}
|
||||
|
||||
- (BOOL) checkLogin: (NSString *) _login
|
||||
password: (NSString *) _pwd
|
||||
domain: (NSString **) _domain
|
||||
perr: (SOGoPasswordPolicyError *) _perr
|
||||
expire: (int *) _expire
|
||||
grace: (int *) _grace
|
||||
useCache: (BOOL) _useCache
|
||||
{
|
||||
SOGoCASSession *session;
|
||||
SOGoSystemDefaults *sd;
|
||||
|
@ -150,7 +167,8 @@
|
|||
domain: _domain
|
||||
perr: _perr
|
||||
expire: _expire
|
||||
grace: _grace];
|
||||
grace: _grace
|
||||
useCache: _useCache];
|
||||
|
||||
//[self logWithFormat: @"Checked login with ppolicy enabled: %d %d %d", *_perr, *_expire, *_grace];
|
||||
|
||||
|
@ -239,7 +257,7 @@
|
|||
grace: &grace])
|
||||
return nil;
|
||||
|
||||
if (domain)
|
||||
if (domain && [login rangeOfString: @"@"].location == NSNotFound)
|
||||
login = [NSString stringWithFormat: @"%@@%@", login, domain];
|
||||
|
||||
return login;
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#import <GDLContentStore/EOQualifier+GCS.h>
|
||||
#import <GDLAccess/EOAdaptorChannel.h>
|
||||
|
||||
#import <SOGo/SOGoSystemDefaults.h>
|
||||
|
||||
#import "SOGoConstants.h"
|
||||
#import "NSString+Utilities.h"
|
||||
#import "NSString+Crypto.h"
|
||||
|
@ -626,13 +628,64 @@
|
|||
return [self _lookupContactEntry: entryID considerEmail: YES inDomain: domain];
|
||||
}
|
||||
|
||||
- (NSArray *) allEntryIDs
|
||||
/* Returns an EOQualifier of the following form:
|
||||
* (_domainField = domain OR _domainField = visibleDomain1 [...])
|
||||
* Should only be called on SQL sources using _domainField name.
|
||||
*/
|
||||
- (EOQualifier *) _visibleDomainsQualifierFromDomain: (NSString *) domain
|
||||
{
|
||||
int i;
|
||||
EOQualifier *qualifier, *domainQualifier;
|
||||
NSArray *visibleDomains;
|
||||
NSMutableArray *qualifiers;
|
||||
NSString *currentDomain;
|
||||
|
||||
SOGoSystemDefaults *sd;
|
||||
|
||||
/* Return early if no domain or if being called on a 'static' sql source */
|
||||
if (!domain || !_domainField)
|
||||
return nil;
|
||||
|
||||
sd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||
visibleDomains = [sd visibleDomainsForDomain: domain];
|
||||
qualifier = nil;
|
||||
|
||||
domainQualifier =
|
||||
[[EOKeyValueQualifier alloc] initWithKey: _domainField
|
||||
operatorSelector: EOQualifierOperatorEqual
|
||||
value: domain];
|
||||
[domainQualifier autorelease];
|
||||
|
||||
if ([visibleDomains count])
|
||||
{
|
||||
qualifiers = [NSMutableArray arrayWithCapacity: [visibleDomains count] + 1];
|
||||
[qualifiers addObject: domainQualifier];
|
||||
for(i = 0; i < [visibleDomains count]; i++)
|
||||
{
|
||||
currentDomain = [visibleDomains objectAtIndex: i];
|
||||
qualifier =
|
||||
[[EOKeyValueQualifier alloc] initWithKey: _domainField
|
||||
operatorSelector: EOQualifierOperatorEqual
|
||||
value: currentDomain];
|
||||
[qualifier autorelease];
|
||||
[qualifiers addObject: qualifier];
|
||||
}
|
||||
qualifier = [[EOOrQualifier alloc] initWithQualifierArray: qualifiers];
|
||||
[qualifier autorelease];
|
||||
}
|
||||
|
||||
return qualifier ? qualifier : domainQualifier;
|
||||
}
|
||||
|
||||
|
||||
- (NSArray *) allEntryIDsVisibleFromDomain: (NSString *) domain
|
||||
{
|
||||
EOAdaptorChannel *channel;
|
||||
NSMutableArray *results;
|
||||
EOQualifier *domainQualifier;
|
||||
GCSChannelManager *cm;
|
||||
NSException *ex;
|
||||
NSString *sql;
|
||||
NSMutableArray *results;
|
||||
NSMutableString *sql;
|
||||
|
||||
results = [NSMutableArray array];
|
||||
|
||||
|
@ -640,9 +693,29 @@
|
|||
channel = [cm acquireOpenChannelForURL: _viewURL];
|
||||
if (channel)
|
||||
{
|
||||
sql = [NSString stringWithFormat: @"SELECT c_uid FROM %@",
|
||||
sql = [NSMutableString stringWithFormat: @"SELECT c_uid FROM %@",
|
||||
[_viewURL gcsTableName]];
|
||||
|
||||
if (_domainField)
|
||||
{
|
||||
if ([domain length])
|
||||
{
|
||||
domainQualifier =
|
||||
[self _visibleDomainsQualifierFromDomain: domain];
|
||||
if (domainQualifier)
|
||||
{
|
||||
[sql appendString: @" WHERE "];
|
||||
[domainQualifier _gcsAppendToString: sql];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Should not happen but avoid returning the whole table
|
||||
* if a domain should have been defined */
|
||||
[sql appendFormat: @" WHERE %@ is NULL", _domainField];
|
||||
}
|
||||
}
|
||||
|
||||
ex = [channel evaluateExpressionX: sql];
|
||||
if (!ex)
|
||||
{
|
||||
|
@ -671,6 +744,11 @@
|
|||
return results;
|
||||
}
|
||||
|
||||
- (NSArray *) allEntryIDs
|
||||
{
|
||||
return [self allEntryIDsVisibleFromDomain: nil];
|
||||
}
|
||||
|
||||
- (NSArray *) fetchContactsMatching: (NSString *) filter
|
||||
inDomain: (NSString *) domain
|
||||
{
|
||||
|
@ -708,7 +786,17 @@
|
|||
if (_domainField)
|
||||
{
|
||||
if ([domain length])
|
||||
[sql appendFormat: @" AND %@ = '%@'", _domainField, domain];
|
||||
{
|
||||
EOQualifier *domainQualifier;
|
||||
domainQualifier =
|
||||
[self _visibleDomainsQualifierFromDomain: domain];
|
||||
if (domainQualifier)
|
||||
{
|
||||
[sql appendFormat: @" AND ("];
|
||||
[domainQualifier _gcsAppendToString: sql];
|
||||
[sql appendFormat: @")"];
|
||||
}
|
||||
}
|
||||
else
|
||||
[sql appendFormat: @" AND %@ IS NULL", _domainField];
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import sogoLogin
|
|||
|
||||
# must be kept in sync with SoObjects/SOGo/SOGoDefaults.plist
|
||||
# this should probably be fetched magically...
|
||||
SOGoSupportedLanguages = [ "Catalan", "Czech", "Dutch", "Danish", "Welsh", "English", "Finnish",
|
||||
SOGoSupportedLanguages = [ "Arabic", "Catalan", "Czech", "Dutch", "Danish", "Welsh", "English", "Finnish",
|
||||
"SpanishSpain", "SpanishArgentina", "French", "German",
|
||||
"Icelandic", "Italian", "Hungarian", "BrazilianPortuguese",
|
||||
"NorwegianBokmal", "NorwegianNynorsk", "Polish", "Russian", "Slovak",
|
||||
|
|
|
@ -681,9 +681,10 @@ class DAVCalendarAclTest(DAVAclTest):
|
|||
"organizer_line": "ORGANIZER:mailto:someone@nowhere.com\n",
|
||||
"attendee_line": att_line}
|
||||
event = self._getEvent(event_class, True)
|
||||
self.assertEquals(exp_event.strip(), event.strip(),
|
||||
"'respond to' event does not match:\nreceived:\n"
|
||||
"/%s/\nexpected:\n/%s/" % (event, exp_event))
|
||||
ics_diff = utilities.ics_compare(exp_event, event)
|
||||
self.assertTrue(ics_diff.areEqual(),
|
||||
"'respond to' event does not match:\n"
|
||||
"Diff(expected, got):\n %s" % ics_diff.textDiff())
|
||||
|
||||
class DAVAddressBookAclTest(DAVAclTest):
|
||||
resource = '/SOGo/dav/%s/Contacts/test-dav-acl/' % username
|
||||
|
|
|
@ -1,9 +1,60 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import StringIO
|
||||
import sys
|
||||
import unittest
|
||||
import vobject
|
||||
import vobject.ics_diff
|
||||
import webdavlib
|
||||
import xml.sax.saxutils
|
||||
|
||||
class ics_compare():
|
||||
|
||||
def __init__(self, event1, event2):
|
||||
self.event1 = event1
|
||||
self.event2 = event2
|
||||
self.diffs = None
|
||||
|
||||
def _vcalendarComponent(self, event):
|
||||
event_component = None
|
||||
for item in vobject.readComponents(event):
|
||||
if item.name == "VCALENDAR":
|
||||
event_component = item
|
||||
return event_component
|
||||
|
||||
def areEqual(self):
|
||||
s_event1 = StringIO.StringIO(self.event1)
|
||||
s_event2 = StringIO.StringIO(self.event2)
|
||||
|
||||
event1_vcalendar = self._vcalendarComponent(s_event1)
|
||||
if event1_vcalendar is None:
|
||||
raise Exception("No VCALENDAR component in event1")
|
||||
|
||||
event2_vcalendar = self._vcalendarComponent(s_event2)
|
||||
if event2_vcalendar is None:
|
||||
raise Exception("No VCALENDAR component in event2")
|
||||
|
||||
self.diffs = vobject.ics_diff.diff(event1_vcalendar, event2_vcalendar)
|
||||
if not self.diffs:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def textDiff(self):
|
||||
saved_stdout = sys.stdout
|
||||
out = StringIO.StringIO()
|
||||
sys.stdout = out
|
||||
try :
|
||||
if self.diffs is not None:
|
||||
for (left, right) in self.diffs:
|
||||
left.prettyPrint()
|
||||
right.prettyPrint()
|
||||
finally:
|
||||
sys.stdout = saved_stdout
|
||||
|
||||
return out.getvalue().strip()
|
||||
|
||||
|
||||
class TestUtility():
|
||||
def __init__(self, test, client, resource = None):
|
||||
self.test = test
|
||||
|
@ -144,3 +195,5 @@ class TestAddressBookACLUtility(TestACLUtility):
|
|||
sogoRights.append(sogoRightsTable[k])
|
||||
|
||||
return sogoRights
|
||||
|
||||
|
||||
|
|
|
@ -23,24 +23,25 @@
|
|||
#import <Foundation/NSAutoreleasePool.h>
|
||||
#import <Foundation/NSUserDefaults.h>
|
||||
|
||||
#import <SOGo/SOGoSystemDefaults.h>
|
||||
|
||||
#import "SOGoEAlarmsNotifier.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv, char **env)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
NSUserDefaults *ud;
|
||||
SOGoEAlarmsNotifier *notifier;
|
||||
SOGoSystemDefaults *sogoDefaults;
|
||||
int rc;
|
||||
|
||||
rc = 0;
|
||||
|
||||
pool = [NSAutoreleasePool new];
|
||||
|
||||
ud = [NSUserDefaults standardUserDefaults];
|
||||
[ud addSuiteNamed: @"sogod"];
|
||||
sogoDefaults = [SOGoSystemDefaults sharedSystemDefaults];
|
||||
|
||||
if ([ud objectForKey: @"SOGoEnableEMailAlarms"])
|
||||
if ([sogoDefaults objectForKey: @"SOGoEnableEMailAlarms"])
|
||||
{
|
||||
notifier = [SOGoEAlarmsNotifier new];
|
||||
if (![notifier run])
|
||||
|
|
|
@ -23,13 +23,14 @@
|
|||
#import <Foundation/NSAutoreleasePool.h>
|
||||
#import <Foundation/NSUserDefaults.h>
|
||||
|
||||
#import <SOGo/SOGoSystemDefaults.h>
|
||||
|
||||
#import "SOGoSockD.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv, char **env)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
NSUserDefaults *ud;
|
||||
SOGoSockD *sockd;
|
||||
int rc;
|
||||
|
||||
|
@ -37,8 +38,7 @@ main (int argc, char **argv, char **env)
|
|||
|
||||
pool = [NSAutoreleasePool new];
|
||||
|
||||
ud = [NSUserDefaults standardUserDefaults];
|
||||
[ud addSuiteNamed: @"sogod"];
|
||||
[SOGoSystemDefaults sharedSystemDefaults];
|
||||
|
||||
sockd = [SOGoSockD new];
|
||||
if ([sockd run])
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/* this file is in UTF-8 format! */
|
||||
|
||||
"Help" = "مساعدة";
|
||||
"Close" = "اغلاق";
|
||||
|
||||
"Modules" = "وحدات";
|
||||
|
||||
/* Modules short names */
|
||||
"ACLs" = "قوائم الصلاحيات";
|
||||
|
||||
/* Modules titles */
|
||||
"ACLs_title" = "إدارة صلاحيات مجلدات المستخدمين";
|
||||
|
||||
/* Modules descriptions */
|
||||
"ACLs_description" = "<p>وحدة إدارة قوائم الصلاحيات تسمح بتعديل صلاحيات تقويم ودفتر العناوين لكل مستخدم.</p><p>لتعديل قائمة صلاحيات خاصة بمجلد مستخدم, اكتب اسم المستخدم في حقل البحث في الجزء العلوي من النافذة واضغط مرتين على المجلد المطلوب.</p>";
|
|
@ -6,7 +6,7 @@ BUNDLE_NAME = AdministrationUI
|
|||
|
||||
AdministrationUI_PRINCIPAL_CLASS = AdministrationUIProduct
|
||||
|
||||
AdministrationUI_LANGUAGES = BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
AdministrationUI_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
|
||||
AdministrationUI_OBJC_FILES = \
|
||||
AdministrationUIProduct.m \
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/* this file is in UTF-8 format! */
|
||||
|
||||
/* toolbars */
|
||||
"Save" = "احفظ";
|
||||
"Close" = "أغلق";
|
||||
"Edit User Rights" = "حرِّر صلاحيات المستخدم";
|
||||
|
||||
"Home" = "الصفحة الرئيسية";
|
||||
"Calendar" = "التقويم";
|
||||
"Address Book" = "دفتر العناوين";
|
||||
"Mail" = "البريد";
|
||||
"Preferences" = "التفضيلات";
|
||||
"Administration" = "إدارة";
|
||||
"Disconnect" = "قطع الاتصال";
|
||||
"Right Administration" = "حق الإدارة";
|
||||
"Log Console (dev.)" = "سجل وحدة التحكم (برمجة)";
|
||||
|
||||
"User" = "مستخدم";
|
||||
"Vacation message is enabled" = "فُعِّلت رسالة العُطْلة";
|
||||
|
||||
"Help" = "المساعدة";
|
||||
|
||||
"noJavascriptError" = "سوجو يتطلب جافا سكريبت للتشغيل. يرجى التأكد من هذا الخيار متاح ضمن تفضيلات المتصفح.";
|
||||
"noJavascriptRetry" = "إعادة المحاولة";
|
||||
|
||||
"Owner:" = "المالك:";
|
||||
"Publish the Free/Busy information" = "نشر معلومات متوفر / مشغول";
|
||||
|
||||
"Add..." = "إضافة ...";
|
||||
"Remove" = "إزالة";
|
||||
|
||||
"Subscribe User" = "اشتراك المستخدم";
|
||||
|
||||
"Any Authenticated User" = "أي مستخدم مسجل";
|
||||
"Public Access" = "وصول الجمهور";
|
||||
"Any user not listed above" = "أي مستخدم غير مذكور أعلاه";
|
||||
"Anybody accessing this resource from the public area" = "أي شخص يدخل على هذه الموارد من منطقة عامة";
|
||||
|
||||
"Sorry, the user rights can not be configured for that object." = "آسف، لا يمكن أن يتم تكوين حقوق المستخدم لذلك الكائن.";
|
||||
|
||||
"Any user with an account on this system will be able to access your mailbox \"%{0}\". Are you certain you trust them all?"
|
||||
= "إن أي مستخدم لديه حساب على هذا النظام سيكون قادرا على الوصول إلى صندوق البريد الخاص بك \"٪ {0}\". هل أنت متأكد من أنك تثق بهم؟";
|
||||
"Any user with an account on this system will be able to access your calendar \"%{0}\". Are you certain you trust them all?"
|
||||
= "أي مستخدم لديه حساب على هذا النظام سيكون قادرا على الوصول إلى التقويم الخاص بك \"٪ {0}\". هل أنت متأكد من أنك تثق بهم؟";
|
||||
"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?"
|
||||
= "يحتمل أن يكون أي شخص على الإنترنت قادرا على الوصول إلى التقويم الخاص بك \"٪ {0}\"، حتى لو لم يكن لديهم حساب على هذا النظام. هل هذه المعلومات مناسبة لشبكة الانترنت العامة؟";
|
||||
"Any user with an account on this system will be able to access your address book \"%{0}\". Are you certain you trust them all?"
|
||||
= "إن أي مستخدم لديه حساب على هذا النظام سيكون قادرا على الوصول إلى دفترالعناوين الخاص بك \"٪ {0}\". هل أنت متأكد من أنك تثق بهم؟";
|
||||
"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?"
|
||||
= "يحتمل أن يتمكن أي شخص على الإنترنت من الوصول إلى دفنرالعناوين الخاص بك \"٪ {0}\"، حتى لو لم يكن لديه حساب على هذا النظام. هل هذه المعلومات مناسبة لشبكة الانترنت العامة؟";
|
||||
"Give Access" = "منح حق الوصول";
|
||||
"Keep Private" = "إبقاءه مخفي";
|
||||
|
||||
/* generic.js */
|
||||
"Unable to subscribe to that folder!"
|
||||
= "غير قادر على الاشتراك في هذا المجلد!";
|
||||
"You cannot subscribe to a folder that you own!"
|
||||
= "لا يمكنك الاشتراك في المجلد ملك لك!";
|
||||
"Unable to unsubscribe from that folder!"
|
||||
= "غير قادر على إلغاء الاشتراك من هذا المجلد!";
|
||||
"You cannot unsubscribe from a folder that you own!"
|
||||
= "لا يمكنك إلغاء الاشتراك من مجلد تمتلكه !";
|
||||
"Unable to rename that folder!" = "غير قادر على إعادة تسمية هذا المجلد!";
|
||||
"You have already subscribed to that folder!"
|
||||
= "أنت مشترك بالفعل في هذا المجلد!";
|
||||
"The user rights cannot be edited for this object!"
|
||||
= "لا يمكن تعديل حقوق المستخدم لهذا الكائن!";
|
||||
"A folder by that name already exists." = "مجلد بهذا الاسم موجود بالفعل.";
|
||||
"You cannot create a list in a shared address book."
|
||||
= "لا يمكنك إنشاء قائمة في دفتر العناوين المشترك.";
|
||||
"Warning" = "تحذير";
|
||||
|
||||
"You are not allowed to access this module or this system. Please contact your system administrator."
|
||||
= "لا يسمح لك بالوصول إلى هذه الوحدة أو هذا النظام. الرجاء الاتصال بمسؤول النظام.";
|
||||
"You don't have the required privileges to perform the operation."
|
||||
= "ليس لديك الصلاحيات المطلوبة لتنفيذ العملية.";
|
||||
|
||||
"noEmailForDelegation" = "يجب تحديد العنوان الذي تريد تفويضه بدعوتك.";
|
||||
"delegate is organizer" = "المفوض هو المنظم. يرجى تحديد مفوض مختلف.";
|
||||
"delegate is a participant" = "المفوض هو بالفعل أحد المشاركين.";
|
||||
"delegate is a group" = "العنوان المحدد يناظر مجموعة من العناوين. يمكنك فقط أن تفوض شخص معين.";
|
||||
|
||||
"Snooze for " = "تأجيل الى";
|
||||
"5 minutes" = "5 دقائق";
|
||||
"10 minutes" = "10 دقائق";
|
||||
"15 minutes" = "15 دقيقة";
|
||||
"30 minutes" = "30 دقيقة";
|
||||
"45 minutes" = "45 دقيقة";
|
||||
"1 hour" = "1 ساعة";
|
||||
|
||||
|
||||
/* common buttons */
|
||||
"OK" = "موافق";
|
||||
"Cancel" = "إلغاء";
|
||||
"Yes" = "نعم";
|
||||
"No" = "لا";
|
||||
|
||||
/* alarms */
|
||||
"Reminder:" = "تذكير:";
|
||||
"Start:" = "البداية:";
|
||||
"Due Date:" = "تاريخ الاستحقاق:";
|
||||
"Location:" = "الموقع:";
|
||||
|
||||
"a2_Sunday" = "ح";
|
||||
"a2_Monday" = "ن";
|
||||
"a2_Tuesday" = "ث";
|
||||
"a2_Wednesday" = "ر";
|
||||
"a2_Thursday" = "خ";
|
||||
"a2_Friday" = "ج";
|
||||
"a2_Saturday" = "س";
|
|
@ -16,6 +16,7 @@
|
|||
"Log Console (dev.)" = "Log Console (dev.)";
|
||||
|
||||
"User" = "Usuário";
|
||||
"Vacation message is enabled" = "Mensagem de ausência está ativa";
|
||||
|
||||
"Help" = "Ajuda";
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
"Log Console (dev.)" = "Log konsol (dev.)";
|
||||
|
||||
"User" = "Bruger";
|
||||
"Vacation message is enabled" = "Ferie meddelelse er aktiv";
|
||||
|
||||
"Help" = "Hjælp";
|
||||
|
||||
|
@ -37,6 +38,19 @@
|
|||
|
||||
"Sorry, the user rights can not be configured for that object." = "Beklager, brugerrettighederne kan ikke konfigureres for dette emne";
|
||||
|
||||
"Any user with an account on this system will be able to access your mailbox \"%{0}\". Are you certain you trust them all?"
|
||||
= "Alle brugere med en konto på dette system vil få adgang til din mail \"%{0}\". Er du sikker på at du har tillid til dem alle?";
|
||||
"Any user with an account on this system will be able to access your calendar \"%{0}\". Are you certain you trust them all?"
|
||||
= "Alle brugere med en konto på dette system vil få adgang til din kalender \"%{0}\". Er du sikker på at du har tillid til dem alle?";
|
||||
"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?"
|
||||
= "Potentielt alle på internettet vil være i stand til at få adgang til din kalender \"%{0}\", selv om de ikke har en konto på dette system. Er disse oplysninger egnet til det offentlige internet?";
|
||||
"Any user with an account on this system will be able to access your address book \"%{0}\". Are you certain you trust them all?"
|
||||
= "Alle brugere med en konto på dette system vil få adgang til din adressebog \"%{0}\". Er du sikker på at du har tillid til dem alle?";
|
||||
"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?"
|
||||
= "Potentielt alle på internettet vil være i stand til at få adgang til din adressebog \"%{0}\", selv om de ikke har en konto på dette system. Er disse oplysninger egnet til det offentlige internet?";
|
||||
"Give Access" = "Giv adgang";
|
||||
"Keep Private" = "Forbliv privat";
|
||||
|
||||
/* generic.js */
|
||||
"Unable to subscribe to that folder!"
|
||||
= "Det er ikke muligt at abonnere på denne mappe!";
|
||||
|
@ -66,6 +80,15 @@
|
|||
"delegate is a participant" = "Den inviterede er allerede en deltager.";
|
||||
"delegate is a group" = "Den angivne adresse svarer til en gruppe. Du kan kun invitere en enkelt person.";
|
||||
|
||||
"Snooze for " = "Udsæt i ";
|
||||
"5 minutes" = "5 minutter";
|
||||
"10 minutes" = "10 minutter";
|
||||
"15 minutes" = "15 minutter";
|
||||
"30 minutes" = "30 minutter";
|
||||
"45 minutes" = "45 minutter";
|
||||
"1 hour" = "1 time";
|
||||
|
||||
|
||||
/* common buttons */
|
||||
"OK" = "OK";
|
||||
"Cancel" = "Annullér";
|
||||
|
|
|
@ -6,7 +6,7 @@ BUNDLE_NAME = CommonUI
|
|||
|
||||
CommonUI_PRINCIPAL_CLASS = CommonUIProduct
|
||||
|
||||
CommonUI_LANGUAGES = BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
CommonUI_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
|
||||
CommonUI_OBJC_FILES += \
|
||||
CommonUIProduct.m \
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
"Log Console (dev.)" = "Вход Console (dev.)";
|
||||
|
||||
"User" = "Пользователь";
|
||||
"Vacation message is enabled" = "Сообщение об отпуске включено";
|
||||
|
||||
"Help" = "Помощь";
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue