diff --git a/.tx/config b/.tx/config index 1e7b39447..a782bec99 100644 --- a/.tx/config +++ b/.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 diff --git a/Apache/SOGo-apple-ab.conf b/Apache/SOGo-apple-ab.conf new file mode 100644 index 000000000..0f5516f6d --- /dev/null +++ b/Apache/SOGo-apple-ab.conf @@ -0,0 +1,26 @@ +# use *:8843 for SSL + + RewriteEngine Off + ProxyRequests Off + SetEnv proxy-nokeepalive 1 + ProxyPreserveHost On + ProxyPassInterpolateEnv On + ProxyPass /principals http://127.0.0.1:20000/SOGo/dav/ interpolate + ProxyPass /SOGo http://127.0.0.1:20000/SOGo interpolate + ProxyPass / http://127.0.0.1:20000/SOGo/dav/ interpolate + + Order allow,deny + Allow from all + + + + RequestHeader set "x-webobjects-server-port" "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 + + + ErrorLog /var/log/apache2/ab-error.log + CustomLog /var/log/apache2/ab-access.log combined + diff --git a/Apache/SOGo.conf b/Apache/SOGo.conf index 1762ebac3..853b5ae0e 100644 --- a/Apache/SOGo.conf +++ b/Apache/SOGo.conf @@ -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 -## 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] diff --git a/ChangeLog b/ChangeLog index 578da8c9d..fb2384ae9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,912 @@ +commit 30f10ee8f06157b1222d68b0502c80162fcbb277 +Author: Francis Lachapelle +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 +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 +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 +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 +Date: Thu Apr 11 10:09:02 2013 -0400 + + Add note regarding precedence of .GNUstepDefaults + +M Scripts/sogo.conf + +commit 01f20a42ad55356c772ca2a4a758d5421e986987 +Author: Jean Raby +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 +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 +Date: Wed Apr 10 16:30:16 2013 -0400 + + ... dir fixup again + +M packaging/debian-multiarch/sogo.postinst + +commit cc125d2192a8b1fb84c7d239c708735d18c33772 +Author: Jean Raby +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 +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 +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 +Date: Wed Apr 10 16:16:30 2013 -0400 + + sogo.conf - new example configuration file + +A Scripts/sogo.conf + +commit 9932d1413b23a50bfb0665af24acb17b59f5f55f +Author: Jean Raby +Date: Wed Apr 10 12:29:48 2013 -0400 + + update NEWS + +M NEWS + +commit ff13c4954032566676b42a4cebd857de5644632a +Author: Jean Raby +Date: Wed Apr 10 12:16:26 2013 -0400 + + updated NEWS + +M NEWS + +commit 1e33b4bf269d660c77fbc891adb4776a83d0b601 +Author: Jean Raby +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 +Date: Wed Apr 10 11:33:41 2013 -0400 + + Update NEWS file + +M NEWS + +commit 4ca476db9e8a81b412a0b15525eeeaa76a78237a +Author: Ludovic Marcotte +Date: Wed Apr 10 11:30:40 2013 -0400 + + Updated NEWS file + +M NEWS + +commit 33840c71cd38a22766f3e0463a17361e6fea8292 +Author: Ludovic Marcotte +Date: Wed Apr 10 10:48:25 2013 -0400 + + Changed noop by unselect/select. + +M OpenChange/MAPIStoreMailVolatileMessage.m + +commit 1b983ef691f55e3588cc9afcb9ba841ca472d3d7 +Author: Ludovic Marcotte +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 +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 +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 +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 +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 +Date: Fri Apr 5 08:57:47 2013 -0400 + + Disable hint verification for now. + +M SoObjects/SOGo/SOGoSAML2Session.m + +commit e07734fa5f57325a92ea70bcb4410b73340aa026 +Author: Jean Raby +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 +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 +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 +Date: Tue Mar 26 14:01:04 2013 -0400 + + semi-colon + +M OpenChange/gen-charset-table.py + +commit 74c01dc44841c696ed322c9b0bff542e7f2b4115 +Author: Jean Raby +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 +Date: Mon Mar 25 15:58:36 2013 -0400 + + Fixed table initialization. + +M SoObjects/SOGo/SOGoSAML2Session.m + +commit b4ebc90dd0b452dfe134efc137de2f62b8ece59e +Author: Jean Raby +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +Date: Fri Mar 1 01:26:15 2013 -0500 + + Whitespace + +M SoObjects/SOGo/SOGoGroup.m + +commit 89766b2e7e037be88d1460520c762c77d66f302e +Author: Ludovic Marcotte +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 +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 +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 +Date: Tue Feb 19 15:42:05 2013 -0500 + + Added rationale around previous commit. + +M OpenChange/NSString+MAPIStore.m + +commit 19923d10dbcba8598f4b2ed3aec86b2fe508a68f +Author: Ludovic Marcotte +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 +Date: Mon Feb 18 16:50:54 2013 -0500 + + Fix for objective-c runtimes. + +M OpenChange/BSONCodec.m + +commit bcab7e7dc9eb664ece3f4bf9301e5c2acd8036b1 +Author: Ludovic Marcotte +Date: Mon Feb 18 16:42:59 2013 -0500 + + C99 style fixes. + +M OpenChange/BSONCodec.m + +commit 2572eedd8988f8a3d3e3d819c27ad070aa250c0b +Author: Ludovic Marcotte +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 +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 +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 +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 +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 +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 +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 +Date: Fri Feb 8 09:42:31 2013 -0500 + + Fix segfault in SOGoSieveManager.m + +M SoObjects/SOGo/SOGoSieveManager.m + +commit 470a53a548c46af72d8956475fdacba045458d10 +Author: Jean Raby +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 +Date: Thu Feb 7 09:00:16 2013 -0500 + + Update Finnish translation + +M UI/MailerUI/Finnish.lproj/Localizable.strings + +commit 90c61abdb654e00ad172ab88cc75059c3d45bd6d +Author: Francis Lachapelle +Date: Wed Feb 6 15:16:09 2013 -0500 + + Update Polish translation + +M SoObjects/Mailer/SOGoMailPolishReply.wo/SOGoMailPolishReply.html + +commit f8387b90ffd3f016f4a4de88577b1280a84aefc8 +Author: Jean Raby +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 +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 +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 +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 +Date: Tue Feb 5 15:09:20 2013 -0500 + + whitespace (tabkill) + +M SoObjects/SOGo/SOGoSieveManager.m + +commit 70fc05091f2f3cdbac1c66291a940a8223e46876 +Author: Jean Raby +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 +Date: Tue Feb 5 11:52:26 2013 -0500 + + Updated NEWS + +M NEWS + +commit 3daa7e55b74890a1c03a37290826759f5d0ec05a +Author: Francis Lachapelle +Date: Mon Feb 4 14:24:03 2013 -0500 + + Update ChangeLog + +M ChangeLog + commit 6913502810ec21479889c4ecf0a393de5ede2635 Author: Francis Lachapelle 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 +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 +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 Date: Fri Feb 1 16:26:01 2013 -0500 diff --git a/Documentation/SOGo Installation Guide.odt b/Documentation/SOGo Installation Guide.odt index 21c7fa8bc..5b7093800 100644 Binary files a/Documentation/SOGo Installation Guide.odt and b/Documentation/SOGo Installation Guide.odt differ diff --git a/Documentation/SOGo Mobile Devices Configuration.odt b/Documentation/SOGo Mobile Devices Configuration.odt index 9949dbed0..8ae5ac6b9 100644 Binary files a/Documentation/SOGo Mobile Devices Configuration.odt and b/Documentation/SOGo Mobile Devices Configuration.odt differ diff --git a/Documentation/SOGo Mozilla Thunderbird Configuration.odt b/Documentation/SOGo Mozilla Thunderbird Configuration.odt index 2f8c2d101..5d4f5bdfa 100644 Binary files a/Documentation/SOGo Mozilla Thunderbird Configuration.odt and b/Documentation/SOGo Mozilla Thunderbird Configuration.odt differ diff --git a/Documentation/SOGo Native Microsoft Outlook Configuration.odt b/Documentation/SOGo Native Microsoft Outlook Configuration.odt index 5f648d913..4221333dc 100644 Binary files a/Documentation/SOGo Native Microsoft Outlook Configuration.odt and b/Documentation/SOGo Native Microsoft Outlook Configuration.odt differ diff --git a/NEWS b/NEWS index 4e8d5eb2f..73529d9bf 100644 --- a/NEWS +++ b/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) ------------------ diff --git a/OpenChange/BSONCodec.h b/OpenChange/BSONCodec.h new file mode 100644 index 000000000..f3a1b6a0c --- /dev/null +++ b/OpenChange/BSONCodec.h @@ -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 +#import + +@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) +@end + +@interface NSData (BSON) +- (NSDictionary *) BSONValue; +@end + +@interface NSNumber (BSON) +@end + +@interface NSString (BSON) +@end + +@interface NSArray (BSON) +@end + +@interface NSNull (BSON) +@end + +@interface NSCalendarDate (BSON) +@end diff --git a/OpenChange/BSONCodec.m b/OpenChange/BSONCodec.m new file mode 100644 index 000000000..518900ba2 --- /dev/null +++ b/OpenChange/BSONCodec.m @@ -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 +#import +#import + +#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 myself = (id ) 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 ) 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 ) 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 diff --git a/OpenChange/EOQualifier+MAPI.m b/OpenChange/EOQualifier+MAPI.m index 65e28c6fd..81e77d833 100644 --- a/OpenChange/EOQualifier+MAPI.m +++ b/OpenChange/EOQualifier+MAPI.m @@ -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; } diff --git a/OpenChange/GCSSpecialQueries+OpenChange.m b/OpenChange/GCSSpecialQueries+OpenChange.m index 914fe6227..2e6376b15 100644 --- a/OpenChange/GCSSpecialQueries+OpenChange.m +++ b/OpenChange/GCSSpecialQueries+OpenChange.m @@ -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]; } diff --git a/OpenChange/GNUmakefile b/OpenChange/GNUmakefile index 68f3e8dfb..3d9fa5b9f 100644 --- a/OpenChange/GNUmakefile +++ b/OpenChange/GNUmakefile @@ -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)\"" diff --git a/OpenChange/GNUmakefile.unrtf b/OpenChange/GNUmakefile.unrtf deleted file mode 100644 index eaac4764a..000000000 --- a/OpenChange/GNUmakefile.unrtf +++ /dev/null @@ -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 diff --git a/OpenChange/MAPIStoreCalendarEmbeddedMessage.m b/OpenChange/MAPIStoreCalendarEmbeddedMessage.m index 35246c113..ca3ba12d6 100644 --- a/OpenChange/MAPIStoreCalendarEmbeddedMessage.m +++ b/OpenChange/MAPIStoreCalendarEmbeddedMessage.m @@ -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 diff --git a/OpenChange/MAPIStoreCalendarFolder.m b/OpenChange/MAPIStoreCalendarFolder.m index 5cab28712..8c0830683 100644 --- a/OpenChange/MAPIStoreCalendarFolder.m +++ b/OpenChange/MAPIStoreCalendarFolder.m @@ -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]]; diff --git a/OpenChange/MAPIStoreCalendarMessage.m b/OpenChange/MAPIStoreCalendarMessage.m index bd6403f4c..de89eb487 100644 --- a/OpenChange/MAPIStoreCalendarMessage.m +++ b/OpenChange/MAPIStoreCalendarMessage.m @@ -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]; } diff --git a/OpenChange/MAPIStoreContext.m b/OpenChange/MAPIStoreContext.m index 658bea97d..4f1e67819 100644 --- a/OpenChange/MAPIStoreContext.m +++ b/OpenChange/MAPIStoreContext.m @@ -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; diff --git a/OpenChange/MAPIStoreDBFolder.m b/OpenChange/MAPIStoreDBFolder.m index d96b81faf..74bf12e2f 100644 --- a/OpenChange/MAPIStoreDBFolder.m +++ b/OpenChange/MAPIStoreDBFolder.m @@ -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; } diff --git a/OpenChange/MAPIStoreDBMessage.m b/OpenChange/MAPIStoreDBMessage.m index f794a381b..997f46570 100644 --- a/OpenChange/MAPIStoreDBMessage.m +++ b/OpenChange/MAPIStoreDBMessage.m @@ -135,7 +135,7 @@ [super addProperties: newNewProperties]; } -- (void) save +- (void) save: (TALLOC_CTX *) memCtx { uint64_t newVersion; diff --git a/OpenChange/MAPIStoreDBMessageTable.m b/OpenChange/MAPIStoreDBMessageTable.m index e457b5ac8..de22e238e 100644 --- a/OpenChange/MAPIStoreDBMessageTable.m +++ b/OpenChange/MAPIStoreDBMessageTable.m @@ -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 diff --git a/OpenChange/MAPIStoreEmbeddedMessage.m b/OpenChange/MAPIStoreEmbeddedMessage.m index 562d581de..f609726db 100644 --- a/OpenChange/MAPIStoreEmbeddedMessage.m +++ b/OpenChange/MAPIStoreEmbeddedMessage.m @@ -146,7 +146,7 @@ static Class MAPIStoreAttachmentK; return ULLONG_MAX; } -- (void) save +- (void) save: (TALLOC_CTX *) memCtx { [self subclassResponsibility: _cmd]; } diff --git a/OpenChange/MAPIStoreFAIMessage.m b/OpenChange/MAPIStoreFAIMessage.m index 99ab23c85..bfa093ff7 100644 --- a/OpenChange/MAPIStoreFAIMessage.m +++ b/OpenChange/MAPIStoreFAIMessage.m @@ -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; diff --git a/OpenChange/MAPIStoreFolder.m b/OpenChange/MAPIStoreFolder.m index ebb011013..2e54838b3 100644 --- a/OpenChange/MAPIStoreFolder.m +++ b/OpenChange/MAPIStoreFolder.m @@ -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]; diff --git a/OpenChange/MAPIStoreGCSMessageTable.m b/OpenChange/MAPIStoreGCSMessageTable.m index 74d9d3151..e6da41039 100644 --- a/OpenChange/MAPIStoreGCSMessageTable.m +++ b/OpenChange/MAPIStoreGCSMessageTable.m @@ -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" diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index a2a572938..f06508962 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -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) diff --git a/OpenChange/MAPIStoreMailMessage.m b/OpenChange/MAPIStoreMailMessage.m index d49cc0572..476ddbac6 100644 --- a/OpenChange/MAPIStoreMailMessage.m +++ b/OpenChange/MAPIStoreMailMessage.m @@ -1576,7 +1576,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) bodySetup = YES; } -- (void) save +- (void) save: (TALLOC_CTX *) memCtx { NSNumber *value; diff --git a/OpenChange/MAPIStoreMailMessageTable.m b/OpenChange/MAPIStoreMailMessageTable.m index 3933b62db..c13605829 100644 --- a/OpenChange/MAPIStoreMailMessageTable.m +++ b/OpenChange/MAPIStoreMailMessageTable.m @@ -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"]); diff --git a/OpenChange/MAPIStoreMailVolatileMessage.m b/OpenChange/MAPIStoreMailVolatileMessage.m index 9193794dd..513b94f26 100644 --- a/OpenChange/MAPIStoreMailVolatileMessage.m +++ b/OpenChange/MAPIStoreMailVolatileMessage.m @@ -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) diff --git a/OpenChange/MAPIStoreMessage.h b/OpenChange/MAPIStoreMessage.h index 06ca45436..6fa42218c 100644 --- a/OpenChange/MAPIStoreMessage.h +++ b/OpenChange/MAPIStoreMessage.h @@ -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; diff --git a/OpenChange/MAPIStoreMessage.m b/OpenChange/MAPIStoreMessage.m index 0751c993d..444ecd0fb 100644 --- a/OpenChange/MAPIStoreMessage.m +++ b/OpenChange/MAPIStoreMessage.m @@ -45,11 +45,10 @@ #import "NSData+MAPIStore.h" #import "NSObject+MAPIStore.h" #import "NSString+MAPIStore.h" +#import "RTFHandler.h" #import "MAPIStoreMessage.h" -#include - #undef DEBUG #include #include @@ -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]; } diff --git a/OpenChange/MAPIStoreSOGo.m b/OpenChange/MAPIStoreSOGo.m index c9e24b715..720635975 100644 --- a/OpenChange/MAPIStoreSOGo.m +++ b/OpenChange/MAPIStoreSOGo.m @@ -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]; diff --git a/OpenChange/MAPIStoreTable.m b/OpenChange/MAPIStoreTable.m index cf34f1fe9..842fa3afc 100644 --- a/OpenChange/MAPIStoreTable.m +++ b/OpenChange/MAPIStoreTable.m @@ -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 diff --git a/OpenChange/MAPIStoreTypes.h b/OpenChange/MAPIStoreTypes.h index a556bb26f..b12cab6a1 100644 --- a/OpenChange/MAPIStoreTypes.h +++ b/OpenChange/MAPIStoreTypes.h @@ -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 diff --git a/OpenChange/MAPIStoreTypes.m b/OpenChange/MAPIStoreTypes.m index 8903eba73..f8e32c824 100644 --- a/OpenChange/MAPIStoreTypes.m +++ b/OpenChange/MAPIStoreTypes.m @@ -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]; @@ -351,7 +352,7 @@ MAPIStoreDumpMessageProperties (NSDictionary *properties) NSLog (@"message properties (%d):", max); value = [properties objectForKey: @"recipients"]; - if (value) + if (value) NSLog (@" recipients: %@", value); for (count = 0; count < max; count++) @@ -363,7 +364,7 @@ MAPIStoreDumpMessageProperties (NSDictionary *properties) value = [properties objectForKey: key]; NSLog (@" 0x%.4x: %@ (%@)", keyAsInt, value, - NSStringFromClass ([value class])); + NSStringFromClass ([value class])); } } } diff --git a/OpenChange/MAPIStoreUserContext.m b/OpenChange/MAPIStoreUserContext.m index 4f398fe26..7432f91fd 100644 --- a/OpenChange/MAPIStoreUserContext.m +++ b/OpenChange/MAPIStoreUserContext.m @@ -20,6 +20,7 @@ * Boston, MA 02111-1307, USA. */ +#import #import #import #import @@ -107,15 +108,17 @@ static NSMapTable *contextsTable = nil; password = nil; path = [NSString stringWithFormat: SAMBA_PRIVATE_DIR - @"/mapistore/%@/password", newUsername]; + @"/mapistore/%@/password", newUsername]; content = [NSData dataWithContentsOfFile: path]; if (content) { password = [[NSString alloc] initWithData: content - encoding: NSUTF8StringEncoding]; + encoding: NSUTF8StringEncoding]; [password autorelease]; + password = [password stringByTrimmingCharactersInSet: + [NSCharacterSet characterSetWithCharactersInString: @"\r\n"]]; } return password; diff --git a/OpenChange/NSObject+MAPIStore.m b/OpenChange/NSObject+MAPIStore.m index 958fb9208..e02f29f07 100644 --- a/OpenChange/NSObject+MAPIStore.m +++ b/OpenChange/NSObject+MAPIStore.m @@ -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; } diff --git a/OpenChange/NSObject+PropertyList.m b/OpenChange/NSObject+PropertyList.m index 37861ed0f..ce01bd227 100644 --- a/OpenChange/NSObject+PropertyList.m +++ b/OpenChange/NSObject+PropertyList.m @@ -33,6 +33,8 @@ #import #import +#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]); } diff --git a/OpenChange/RTFHandler.h b/OpenChange/RTFHandler.h new file mode 100644 index 000000000..52567cc29 --- /dev/null +++ b/OpenChange/RTFHandler.h @@ -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 +#include +#include +#include +#include + +// +// +// +@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 diff --git a/OpenChange/RTFHandler.m b/OpenChange/RTFHandler.m new file mode 100644 index 000000000..99ddd48b1 --- /dev/null +++ b/OpenChange/RTFHandler.m @@ -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 + +// +// 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 + 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 + 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: "" 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: "" length: 3]; + formattingOptions->bold = YES; + } + else if ([s isEqualToString: @"b0"] && formattingOptions) + { + [_html appendBytes: "" 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: "" length: 7]; + } + + formattingOptions->color_index = color_index; + colorDef = [colorTable colorDefAtIndex: color_index]; + + v = malloc(23*sizeof(char)); + memset(v, 0, 23); + sprintf(v, "", 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: "" length: 7]; + } + + formattingOptions->font_index = font_index; + + fontInfo = [fontTable fontInfoAtIndex: font_index]; + + char *v = malloc(128*sizeof(char)); + memset(v, 0, 128); + sprintf(v, "", [fontInfo->name UTF8String]); + [_html appendBytes: v length: strlen(v)]; + free(v); + } + else if ([s isEqualToString: @"i"] && formattingOptions) + { + [_html appendBytes: "" length: 3]; + formattingOptions->italic = YES; + } + else if ([s isEqualToString: @"i0"] && formattingOptions) + { + [_html appendBytes: "" length: 4]; + formattingOptions->italic = NO; + } + else if ([s isEqualToString: @"tab"]) + { + [_html appendBytes: "  " length: 12]; + } + else if ([s isEqualToString: @"softline"] || [s isEqualToString: @"par"]) + { + [_html appendBytes: "
" length: 4]; + } + else if ([s isEqualToString: @"strike"] && formattingOptions) + { + [_html appendBytes: "" length: 8]; + formattingOptions->strikethrough = YES; + } + else if ([s isEqualToString: @"strike0"] && formattingOptions) + { + [_html appendBytes: "" 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: "" length: 3]; + formattingOptions->underline = YES; + } + else if (([s isEqualToString: @"ul0"] || [s isEqualToString: @"ulnone"]) + && formattingOptions) + { + [_html appendBytes: "" 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: "" length: 4]; + } + + if (formattingOptions->italic) + { + [_html appendBytes: "" length: 4]; + } + + if (formattingOptions->strikethrough) + { + [_html appendBytes: "" length: 9]; + } + + if (formattingOptions->underline) + { + [_html appendBytes: "" length: 4]; + } + + if (formattingOptions->font_index >= 0) + { + [_html appendBytes: "
" length: 7]; + } + + if (formattingOptions->color_index >= 0) + { + [_html appendBytes: "" length: 7]; + } + } + + formattingOptions = [stack top]; + ADVANCE; + } + else + { + // We avoid appending NULL bytes + if (*_bytes) + [_html appendBytes: _bytes length: 1]; + ADVANCE; + } + } + + [_html appendBytes: "" length: 14]; + + RELEASE(stack); + return AUTORELEASE(_html); +} + +@end diff --git a/OpenChange/SOGoMAPIDBObject.m b/OpenChange/SOGoMAPIDBObject.m index 7f24c8dd6..6407fbda3 100644 --- a/OpenChange/SOGoMAPIDBObject.m +++ b/OpenChange/SOGoMAPIDBObject.m @@ -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]; } diff --git a/OpenChange/gen-charset-table.py b/OpenChange/gen-charset-table.py new file mode 100755 index 000000000..1bcc1aa17 --- /dev/null +++ b/OpenChange/gen-charset-table.py @@ -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} diff --git a/OpenChange/iCalEvent+MAPIStore.h b/OpenChange/iCalEvent+MAPIStore.h index 171813e2b..198526687 100644 --- a/OpenChange/iCalEvent+MAPIStore.h +++ b/OpenChange/iCalEvent+MAPIStore.h @@ -23,6 +23,8 @@ #ifndef ICALEVENT_MAPISTORE_H #define ICALEVENT_MAPISTORE_H +#include + #import @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 */ diff --git a/OpenChange/iCalEvent+MAPIStore.m b/OpenChange/iCalEvent+MAPIStore.m index 84ddddd7d..4d64a7ac7 100644 --- a/OpenChange/iCalEvent+MAPIStore.m +++ b/OpenChange/iCalEvent+MAPIStore.m @@ -20,7 +20,6 @@ * Boston, MA 02111-1307, USA. */ -#include #include #import @@ -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]; diff --git a/OpenChange/unrtf-0.21.2.diff b/OpenChange/unrtf-0.21.2.diff deleted file mode 100644 index c49b9cda9..000000000 --- a/OpenChange/unrtf-0.21.2.diff +++ /dev/null @@ -1,12505 +0,0 @@ -diff -durpN unrtf-0.21.2.old/configure.ac unrtf-0.21.2/configure.ac ---- unrtf-0.21.2.old/configure.ac 2010-08-15 03:59:52.000000000 +0200 -+++ unrtf-0.21.2/configure.ac 2013-01-17 02:42:10.681861561 +0100 -@@ -33,7 +33,7 @@ AC_HEADER_STDC - - # following is not really necessary, since it is already done by preceding - # macro, but it shows how to extend HAVE_ macros to other headers. --AC_CHECK_HEADERS([stdlib.h stdio.h ctype.h string.h]) -+AC_CHECK_HEADERS([stdlib.h stdio.h ctype.h string.h stdint.h]) - - # Checks for typedefs, structures, and compiler characteristics. - -diff -durpN unrtf-0.21.2.old/outputs/html.conf unrtf-0.21.2/outputs/html.conf ---- unrtf-0.21.2.old/outputs/html.conf 2010-08-15 14:44:09.000000000 +0200 -+++ unrtf-0.21.2/outputs/html.conf 2013-01-17 02:41:09.681864239 +0100 -@@ -5,7 +5,7 @@ comment_end - --> - - document_begin -- -+ - #Second test of comments - - -@@ -67,7 +67,7 @@ align_right_end - - - forced_space --   -+   - line_break -
- -diff -durpN unrtf-0.21.2.old/src/attr.c unrtf-0.21.2/src/attr.c ---- unrtf-0.21.2.old/src/attr.c 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/attr.c 2013-01-17 02:41:09.681864239 +0100 -@@ -1,23 +1,23 @@ - /*============================================================================= -- GNU UnRTF, a command-line program to convert RTF documents to other formats. -- Copyright (C) 2000,2001,2004 by Zachary Smith -+ GNU UnRTF, a command-line program to convert RTF documents to other formats. -+ Copyright (C) 2000,2001,2004 by Zachary Smith - -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. - -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. - -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -- The maintainer is reachable by electronic mail at daved@physiol.usyd.edu.au --=============================================================================*/ -+ The maintainer is reachable by electronic mail at daved@physiol.usyd.edu.au -+ =============================================================================*/ - - - /*---------------------------------------------------------------------- -@@ -57,47 +57,20 @@ - #include - #endif - -+#include "attr.h" -+#include "convert.h" - #include "malloc.h" - #include "defs.h" - #include "error.h" -+#include "output.h" -+#include "unrtf.h" - - #ifndef HAVE_ATTR_H --#include "attr.h" - #define HAVE_ATTR_H - #endif - - #include "main.h" - --extern void starting_body(); --extern void starting_text(); -- --extern int simulate_allcaps; --extern int simulate_smallcaps; -- -- --#define MAX_ATTRS (10000) -- -- --/* For each RTF text block (the text within braces) we must keep -- * an AttrStack which is a stack of attributes and their optional -- * parameter. Since RTF text blocks are nested, these make up a -- * stack of stacks. And, since RTF text blocks inherit attributes -- * from parent blocks, all new AttrStacks do the same from -- * their parent AttrStack. -- */ --typedef struct _stack { -- unsigned char attr_stack[MAX_ATTRS]; -- char *attr_stack_params[MAX_ATTRS]; -- int tos; -- struct _stack *next; --} AttrStack; -- --/*@null@*/ static AttrStack *stack_of_stacks = NULL; --/*@null@*/ static AttrStack *stack_of_stacks_top = NULL; -- -- -- -- - /*======================================================================== - * Name: attr_express_begin - * Purpose: Print the HTML for beginning an attribute. -@@ -106,95 +79,96 @@ typedef struct _stack { - *=======================================================================*/ - - void --attr_express_begin (int attr, char* param) { -- switch(attr) -- { -- case ATTR_BOLD: -- if (safe_printf(0, op->bold_begin)) fprintf(stderr, TOO_MANY_ARGS, "bold_begin");; -- break; -- case ATTR_ITALIC: -- if (safe_printf(0, op->italic_begin)) fprintf(stderr, TOO_MANY_ARGS, "italic_begin");; -- break; -+attr_express_begin (int attr, char* param, const struct OutputContext *oc) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ switch(attr) -+ { -+ case ATTR_BOLD: -+ if (safe_printf(device, 0, oc->personality->bold_begin)) fprintf(stderr, TOO_MANY_ARGS, "bold_begin");; -+ break; -+ case ATTR_ITALIC: -+ if (safe_printf(device, 0, oc->personality->italic_begin)) fprintf(stderr, TOO_MANY_ARGS, "italic_begin");; -+ break; - -- /* Various underlines, they all resolve to HTML's */ -- case ATTR_THICK_UL: -- case ATTR_WAVE_UL: -- case ATTR_DASH_UL: -- case ATTR_DOT_UL: -- case ATTR_DOT_DASH_UL: -- case ATTR_2DOT_DASH_UL: -- case ATTR_WORD_UL: -- case ATTR_UNDERLINE: -- if (safe_printf(0, op->underline_begin)) fprintf(stderr, TOO_MANY_ARGS, "underline_begin");; -- break; -+ /* Various underlines, they all resolve to HTML's */ -+ case ATTR_THICK_UL: -+ case ATTR_WAVE_UL: -+ case ATTR_DASH_UL: -+ case ATTR_DOT_UL: -+ case ATTR_DOT_DASH_UL: -+ case ATTR_2DOT_DASH_UL: -+ case ATTR_WORD_UL: -+ case ATTR_UNDERLINE: -+ if (safe_printf(device, 0, oc->personality->underline_begin)) fprintf(stderr, TOO_MANY_ARGS, "underline_begin");; -+ break; - -- case ATTR_DOUBLE_UL: -- if (safe_printf(0, op->dbl_underline_begin)) fprintf(stderr, TOO_MANY_ARGS, "dbl_underline_begin");; -- break; -+ case ATTR_DOUBLE_UL: -+ if (safe_printf(device, 0, oc->personality->dbl_underline_begin)) fprintf(stderr, TOO_MANY_ARGS, "dbl_underline_begin");; -+ break; - -- case ATTR_FONTSIZE: -- op_begin_std_fontsize (op, atoi (param)); -- break; -+ case ATTR_FONTSIZE: -+ op_begin_std_fontsize (oc, atoi (param)); -+ break; - -- case ATTR_FONTFACE: -- if (safe_printf(1, op->font_begin,param)) fprintf(stderr, TOO_MANY_ARGS, "font_begin");; -- break; -+ case ATTR_FONTFACE: -+ if (safe_printf(device, 1, oc->personality->font_begin,param)) fprintf(stderr, TOO_MANY_ARGS, "font_begin");; -+ break; - -- case ATTR_FOREGROUND: -- if (safe_printf(1, op->foreground_begin, param)) fprintf(stderr, TOO_MANY_ARGS, "foreground_begin");; -- break; -+ case ATTR_FOREGROUND: -+ if (safe_printf(device, 1, oc->personality->foreground_begin, param)) fprintf(stderr, TOO_MANY_ARGS, "foreground_begin");; -+ break; - -- case ATTR_BACKGROUND: -- if (!simple_mode) -- if (safe_printf(1, op->background_begin,param)) fprintf(stderr, TOO_MANY_ARGS, "background_begin");; -- break; -+ case ATTR_BACKGROUND: -+ if (!oc->conversion->options->simple_mode) -+ if (safe_printf(device, 1, oc->personality->background_begin,param)) fprintf(stderr, TOO_MANY_ARGS, "background_begin");; -+ break; - -- case ATTR_SUPER: -- if (safe_printf(0, op->superscript_begin)) fprintf(stderr, TOO_MANY_ARGS, "superscript_begin");; -- break; -- case ATTR_SUB: -- if (safe_printf(0, op->subscript_begin)) fprintf(stderr, TOO_MANY_ARGS, "subscript_begin");; -- break; -+ case ATTR_SUPER: -+ if (safe_printf(device, 0, oc->personality->superscript_begin)) fprintf(stderr, TOO_MANY_ARGS, "superscript_begin");; -+ break; -+ case ATTR_SUB: -+ if (safe_printf(device, 0, oc->personality->subscript_begin)) fprintf(stderr, TOO_MANY_ARGS, "subscript_begin");; -+ break; - -- case ATTR_STRIKE: -- if (safe_printf(0, op->strikethru_begin)) fprintf(stderr, TOO_MANY_ARGS, "strikethru_begin");; -- break; -+ case ATTR_STRIKE: -+ if (safe_printf(device, 0, oc->personality->strikethru_begin)) fprintf(stderr, TOO_MANY_ARGS, "strikethru_begin");; -+ break; - -- case ATTR_DBL_STRIKE: -- if (safe_printf(0, op->dbl_strikethru_begin)) fprintf(stderr, TOO_MANY_ARGS, "dbl_strikethru_begin");; -- break; -+ case ATTR_DBL_STRIKE: -+ if (safe_printf(device, 0, oc->personality->dbl_strikethru_begin)) fprintf(stderr, TOO_MANY_ARGS, "dbl_strikethru_begin");; -+ break; - -- case ATTR_EXPAND: -- if (safe_printf(1, op->expand_begin, param)) fprintf(stderr, TOO_MANY_ARGS, "expand_begin");; -- break; -+ case ATTR_EXPAND: -+ if (safe_printf(device, 1, oc->personality->expand_begin, param)) fprintf(stderr, TOO_MANY_ARGS, "expand_begin");; -+ break; - -- case ATTR_OUTLINE: -- if (safe_printf(0, op->outline_begin)) fprintf(stderr, TOO_MANY_ARGS, "outline_begin");; -- break; -- case ATTR_SHADOW: -- if (safe_printf(0, op->shadow_begin)) fprintf(stderr, TOO_MANY_ARGS, "shadow_begin");; -- break; -- case ATTR_EMBOSS: -- if (safe_printf(0, op->emboss_begin)) fprintf(stderr, TOO_MANY_ARGS, "emboss_begin");; -- break; -- case ATTR_ENGRAVE: -- if (safe_printf(0, op->engrave_begin)) fprintf(stderr, TOO_MANY_ARGS, "engrave_begin");; -- break; -+ case ATTR_OUTLINE: -+ if (safe_printf(device, 0, oc->personality->outline_begin)) fprintf(stderr, TOO_MANY_ARGS, "outline_begin");; -+ break; -+ case ATTR_SHADOW: -+ if (safe_printf(device, 0, oc->personality->shadow_begin)) fprintf(stderr, TOO_MANY_ARGS, "shadow_begin");; -+ break; -+ case ATTR_EMBOSS: -+ if (safe_printf(device, 0, oc->personality->emboss_begin)) fprintf(stderr, TOO_MANY_ARGS, "emboss_begin");; -+ break; -+ case ATTR_ENGRAVE: -+ if (safe_printf(device, 0, oc->personality->engrave_begin)) fprintf(stderr, TOO_MANY_ARGS, "engrave_begin");; -+ break; - -- case ATTR_CAPS: -- if (op->simulate_all_caps) -- simulate_allcaps = TRUE; -- break; -+ case ATTR_CAPS: -+ if (oc->personality->simulate_all_caps) -+ oc->conversion->simulate_allcaps = TRUE; -+ break; - -- case ATTR_SMALLCAPS: -- if (op->simulate_small_caps) -- simulate_smallcaps = TRUE; -- else { -- if (op->small_caps_begin) -- if (safe_printf(0, op->small_caps_begin)) fprintf(stderr, TOO_MANY_ARGS, "small_caps_begin");; -- } -- break; -- } -+ case ATTR_SMALLCAPS: -+ if (oc->personality->simulate_small_caps) -+ oc->conversion->simulate_smallcaps = TRUE; -+ else { -+ if (oc->personality->small_caps_begin) -+ if (safe_printf(device, 0, oc->personality->small_caps_begin)) fprintf(stderr, TOO_MANY_ARGS, "small_caps_begin");; -+ } -+ break; -+ } - } - - -@@ -206,95 +180,96 @@ attr_express_begin (int attr, char* para - *=======================================================================*/ - - void --attr_express_end (int attr, char *param) -+attr_express_end (int attr, char *param, const struct OutputContext *oc) - { -- switch(attr) -- { -- case ATTR_BOLD: -- if (safe_printf(0, op->bold_end)) fprintf(stderr, TOO_MANY_ARGS, "bold_end");; -- break; -- case ATTR_ITALIC: -- if (safe_printf(0, op->italic_end)) fprintf(stderr, TOO_MANY_ARGS, "italic_end");; -- break; -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ switch(attr) -+ { -+ case ATTR_BOLD: -+ if (safe_printf(device, 0, oc->personality->bold_end)) fprintf(stderr, TOO_MANY_ARGS, "bold_end");; -+ break; -+ case ATTR_ITALIC: -+ if (safe_printf(device, 0, oc->personality->italic_end)) fprintf(stderr, TOO_MANY_ARGS, "italic_end");; -+ break; - -- /* Various underlines, they all resolve to HTML's */ -- case ATTR_THICK_UL: -- case ATTR_WAVE_UL: -- case ATTR_DASH_UL: -- case ATTR_DOT_UL: -- case ATTR_DOT_DASH_UL: -- case ATTR_2DOT_DASH_UL: -- case ATTR_WORD_UL: -- case ATTR_UNDERLINE: -- if (safe_printf(0, op->underline_end)) fprintf(stderr, TOO_MANY_ARGS, "underline_end");; -- break; -+ /* Various underlines, they all resolve to HTML's */ -+ case ATTR_THICK_UL: -+ case ATTR_WAVE_UL: -+ case ATTR_DASH_UL: -+ case ATTR_DOT_UL: -+ case ATTR_DOT_DASH_UL: -+ case ATTR_2DOT_DASH_UL: -+ case ATTR_WORD_UL: -+ case ATTR_UNDERLINE: -+ if (safe_printf(device, 0, oc->personality->underline_end)) fprintf(stderr, TOO_MANY_ARGS, "underline_end");; -+ break; - -- case ATTR_DOUBLE_UL: -- if (safe_printf(0, op->dbl_underline_end)) fprintf(stderr, TOO_MANY_ARGS, "dbl_underline_end");; -- break; -+ case ATTR_DOUBLE_UL: -+ if (safe_printf(device, 0, oc->personality->dbl_underline_end)) fprintf(stderr, TOO_MANY_ARGS, "dbl_underline_end");; -+ break; - -- case ATTR_FONTSIZE: -- op_end_std_fontsize (op, atoi (param)); -- break; -+ case ATTR_FONTSIZE: -+ op_end_std_fontsize (oc, atoi (param)); -+ break; - -- case ATTR_FONTFACE: -- if (safe_printf(0, op->font_end)) fprintf(stderr, TOO_MANY_ARGS, "font_end");; -- break; -+ case ATTR_FONTFACE: -+ if (safe_printf(device, 0, oc->personality->font_end)) fprintf(stderr, TOO_MANY_ARGS, "font_end");; -+ break; - -- case ATTR_FOREGROUND: -- if (safe_printf(0, op->foreground_end)) fprintf(stderr, TOO_MANY_ARGS, "foreground_end");; -- break; -- case ATTR_BACKGROUND: -- if (!simple_mode) -- if (safe_printf(0, op->background_end)) fprintf(stderr, TOO_MANY_ARGS, "background_end");; -- break; -+ case ATTR_FOREGROUND: -+ if (safe_printf(device, 0, oc->personality->foreground_end)) fprintf(stderr, TOO_MANY_ARGS, "foreground_end");; -+ break; -+ case ATTR_BACKGROUND: -+ if (!oc->conversion->options->simple_mode) -+ if (safe_printf(device, 0, oc->personality->background_end)) fprintf(stderr, TOO_MANY_ARGS, "background_end");; -+ break; - -- case ATTR_SUPER: -- if (safe_printf(0, op->superscript_end)) fprintf(stderr, TOO_MANY_ARGS, "superscript_end");; -- break; -- case ATTR_SUB: -- if (safe_printf(0, op->subscript_end)) fprintf(stderr, TOO_MANY_ARGS, "subscript_end");; -- break; -+ case ATTR_SUPER: -+ if (safe_printf(device, 0, oc->personality->superscript_end)) fprintf(stderr, TOO_MANY_ARGS, "superscript_end");; -+ break; -+ case ATTR_SUB: -+ if (safe_printf(device, 0, oc->personality->subscript_end)) fprintf(stderr, TOO_MANY_ARGS, "subscript_end");; -+ break; - -- case ATTR_STRIKE: -- if (safe_printf(0, op->strikethru_end)) fprintf(stderr, TOO_MANY_ARGS, "strikethru_end");; -- break; -+ case ATTR_STRIKE: -+ if (safe_printf(device, 0, oc->personality->strikethru_end)) fprintf(stderr, TOO_MANY_ARGS, "strikethru_end");; -+ break; - -- case ATTR_DBL_STRIKE: -- if (safe_printf(0, op->dbl_strikethru_end)) fprintf(stderr, TOO_MANY_ARGS, "dbl_strikethru_end");; -- break; -+ case ATTR_DBL_STRIKE: -+ if (safe_printf(device, 0, oc->personality->dbl_strikethru_end)) fprintf(stderr, TOO_MANY_ARGS, "dbl_strikethru_end");; -+ break; - -- case ATTR_OUTLINE: -- if (safe_printf(0, op->outline_end)) fprintf(stderr, TOO_MANY_ARGS, "outline_end");; -- break; -- case ATTR_SHADOW: -- if (safe_printf(0, op->shadow_end)) fprintf(stderr, TOO_MANY_ARGS, "shadow_end");; -- break; -- case ATTR_EMBOSS: -- if (safe_printf(0, op->emboss_end)) fprintf(stderr, TOO_MANY_ARGS, "emboss_end");; -- break; -- case ATTR_ENGRAVE: -- if (safe_printf(0, op->engrave_end)) fprintf(stderr, TOO_MANY_ARGS, "engrave_end");; -- break; -+ case ATTR_OUTLINE: -+ if (safe_printf(device, 0, oc->personality->outline_end)) fprintf(stderr, TOO_MANY_ARGS, "outline_end");; -+ break; -+ case ATTR_SHADOW: -+ if (safe_printf(device, 0, oc->personality->shadow_end)) fprintf(stderr, TOO_MANY_ARGS, "shadow_end");; -+ break; -+ case ATTR_EMBOSS: -+ if (safe_printf(device, 0, oc->personality->emboss_end)) fprintf(stderr, TOO_MANY_ARGS, "emboss_end");; -+ break; -+ case ATTR_ENGRAVE: -+ if (safe_printf(device, 0, oc->personality->engrave_end)) fprintf(stderr, TOO_MANY_ARGS, "engrave_end");; -+ break; - -- case ATTR_EXPAND: -- if (safe_printf(0, op->expand_end)) fprintf(stderr, TOO_MANY_ARGS, "expand_end");; -- break; -+ case ATTR_EXPAND: -+ if (safe_printf(device, 0, oc->personality->expand_end)) fprintf(stderr, TOO_MANY_ARGS, "expand_end");; -+ break; - -- case ATTR_CAPS: -- if (op->simulate_all_caps) -- simulate_allcaps = FALSE; -- break; -+ case ATTR_CAPS: -+ if (oc->personality->simulate_all_caps) -+ oc->conversion->simulate_allcaps = FALSE; -+ break; - -- case ATTR_SMALLCAPS: -- if (op->simulate_small_caps) -- simulate_smallcaps = FALSE; -- else { -- if (op->small_caps_end) -- if (safe_printf(0, op->small_caps_end)) fprintf(stderr, TOO_MANY_ARGS, "small_caps_end");; -- } -- break; -- } -+ case ATTR_SMALLCAPS: -+ if (oc->personality->simulate_small_caps) -+ oc->conversion->simulate_smallcaps = FALSE; -+ else { -+ if (oc->personality->small_caps_end) -+ if (safe_printf(device, 0, oc->personality->small_caps_end)) fprintf(stderr, TOO_MANY_ARGS, "small_caps_end");; -+ } -+ break; -+ } - } - - -@@ -307,32 +282,32 @@ attr_express_end (int attr, char *param) - *=======================================================================*/ - - void --attr_push(int attr, char* param) -+attr_push(int attr, char* param, const struct OutputContext *oc) - { -- AttrStack *stack = stack_of_stacks_top; -- if (!stack) { -- warning_handler("No stack to push attribute onto"); -- return; -- } -+ AttrStack *stack = oc->conversion->stack_of_stacks_top; -+ if (!stack) { -+ warning_handler("No stack to push attribute onto"); -+ return; -+ } - -- if (stack->tos >= MAX_ATTRS) { -- fprintf(stderr, "Too many attributes!\n"); -- return; -- } -+ if (stack->tos >= MAX_ATTRS) { -+ fprintf(stderr, "Too many attributes!\n"); -+ return; -+ } - -- /* Make sure it's understood we're in the section. */ -- /* KLUDGE */ -- starting_body(); -- starting_text(); -+ /* Make sure it's understood we're in the section. */ -+ /* KLUDGE */ -+ starting_body(oc); -+ starting_text(oc); - -- ++stack->tos; -- stack->attr_stack[stack->tos] = attr; -- if (param) -- stack->attr_stack_params[stack->tos] = my_strdup(param); -- else -- stack->attr_stack_params[stack->tos] = NULL; -+ ++stack->tos; -+ stack->attr_stack[stack->tos] = attr; -+ if (param) -+ stack->attr_stack_params[stack->tos] = unrtf_strdup(oc->conversion, param); -+ else -+ stack->attr_stack_params[stack->tos] = NULL; - -- attr_express_begin(attr, param); -+ attr_express_begin(attr, param, oc); - } - - -@@ -344,62 +319,25 @@ attr_push(int attr, char* param) - *=======================================================================*/ - - char * --attr_get_param(int attr) --{ -- int i; -- AttrStack *stack = stack_of_stacks_top; -- if (!stack) { -- warning_handler("No stack to get attribute from"); -- return; -- } -- -- i=stack->tos; -- while (i>=0) -- { -- if(stack->attr_stack [i] == attr) -- { -- if(stack->attr_stack_params [i] != NULL) -- return stack->attr_stack_params [i]; -- else -- return NULL; -- } -- i--; -- } -- return NULL; --} -- -- --/*======================================================================== -- * Name: attrstack_copy_all -- * Purpose: Routine to copy all attributes from one stack to another. -- * Args: Two stacks. -- * Returns: None. -- *=======================================================================*/ -- --void --attrstack_copy_all (AttrStack *src, AttrStack *dest) -+attr_get_param(const struct ConversionContext *cc, int attr) - { -- int i; -- int total; -- -- CHECK_PARAM_NOT_NULL(src); -- CHECK_PARAM_NOT_NULL(dest); -- -- total = src->tos + 1; -- -- for (i=0; iattr_stack [i]; -- char *param=src->attr_stack_params [i]; -- -- dest->attr_stack[i] = attr; -- if (param) -- dest->attr_stack_params[i] = my_strdup (param); -- else -- dest->attr_stack_params[i] = NULL; -- } -+ int i; -+ AttrStack *stack = cc->stack_of_stacks_top; -+ if (!stack) { -+ warning_handler("No stack to get attribute from"); -+ return NULL; -+ } - -- dest->tos = src->tos; -+ i=stack->tos; -+ while (i>=0) -+ { -+ if(stack->attr_stack[i] == attr) -+ { -+ return stack->attr_stack_params[i]; -+ } -+ i--; -+ } -+ return NULL; - } - - /*======================================================================== -@@ -414,21 +352,21 @@ attrstack_copy_all (AttrStack *src, Attr - *=======================================================================*/ - - void --attrstack_unexpress_all (AttrStack *stack) -+attrstack_unexpress_all (AttrStack *stack, const struct OutputContext *oc) - { -- int i; -+ int i; - -- CHECK_PARAM_NOT_NULL(stack); -+ CHECK_PARAM_NOT_NULL(stack); - -- i=stack->tos; -- while (i>=0) -- { -- int attr=stack->attr_stack [i]; -- char *param=stack->attr_stack_params [i]; -+ i=stack->tos; -+ while (i>=0) -+ { -+ int attr=stack->attr_stack[i]; -+ char *param=stack->attr_stack_params[i]; - -- attr_express_end (attr, param); -- i--; -- } -+ attr_express_end (attr, param, oc); -+ i--; -+ } - } - - -@@ -440,23 +378,20 @@ attrstack_unexpress_all (AttrStack *stac - * Returns: None. - *=======================================================================*/ - void --attrstack_push () -+attrstack_push (struct ConversionContext *cc) - { -- AttrStack *new_stack; -- AttrStack *prev_stack; -- -- new_stack = (AttrStack*) my_malloc (sizeof (AttrStack)); -- memset ((void*) new_stack, 0, sizeof (AttrStack)); -+ AttrStack *new_stack; - -- prev_stack = stack_of_stacks_top; -+ new_stack = (AttrStack*) unrtf_malloc (sizeof (AttrStack)); -+ memset ((void*) new_stack, 0, sizeof (AttrStack)); -+ new_stack->tos = -1; - -- if (!stack_of_stacks) { -- stack_of_stacks = new_stack; -- } else { -- stack_of_stacks_top->next = new_stack; -- } -- stack_of_stacks_top = new_stack; -- new_stack->tos = -1; -+ if (!cc->stack_of_stacks) { -+ cc->stack_of_stacks = new_stack; -+ } else { -+ cc->stack_of_stacks_top->next = new_stack; -+ } -+ cc->stack_of_stacks_top = new_stack; - } - - -@@ -470,29 +405,30 @@ attrstack_push () - *=======================================================================*/ - - int --attr_pop (int attr) -+attr_pop (int attr, const struct OutputContext *oc) - { -- AttrStack *stack = stack_of_stacks_top; -+ AttrStack *stack = oc->conversion->stack_of_stacks_top; - -- if (!stack) { -- warning_handler ("no stack to pop attribute from"); -- return FALSE; -- } -+ if (!stack) { -+ warning_handler ("no stack to pop attribute from"); -+ return FALSE; -+ } - -- if(stack->tos>=0 && stack->attr_stack[stack->tos]==attr) -- { -- char *param = stack->attr_stack_params [stack->tos]; -+ if(stack->tos>=0 && stack->attr_stack[stack->tos]==attr) -+ { -+ char *param = stack->attr_stack_params[stack->tos]; - -- attr_express_end (attr, param); -+ attr_express_end (attr, param, oc); - -- if (param) my_free(param); -+ if (param) unrtf_free(param); -+ stack->attr_stack_params[stack->tos] = NULL; - -- stack->tos--; -+ stack->tos--; - -- return TRUE; -- } -- else -- return FALSE; -+ return TRUE; -+ } -+ else -+ return FALSE; - } - - -@@ -506,20 +442,20 @@ attr_pop (int attr) - *=======================================================================*/ - - int --attr_read() { -- AttrStack *stack = stack_of_stacks_top; -- if (!stack) { -- warning_handler ("no stack to read attribute from"); -- return FALSE; -- } -+attr_read(const struct ConversionContext *cc) { -+ AttrStack *stack = cc->stack_of_stacks_top; -+ if (!stack) { -+ warning_handler ("no stack to read attribute from"); -+ return FALSE; -+ } - -- if(stack->tos>=0) -- { -- int attr = stack->attr_stack [stack->tos]; -- return attr; -- } -- else -- return ATTR_NONE; -+ if(stack->tos>=0) -+ { -+ int attr = stack->attr_stack[stack->tos]; -+ return attr; -+ } -+ else -+ return ATTR_NONE; - } - - -@@ -531,20 +467,21 @@ attr_read() { - *=======================================================================*/ - - void --attr_drop_all () -+attr_drop_all (const struct ConversionContext *cc) - { -- AttrStack *stack = stack_of_stacks_top; -- if (!stack) { -- warning_handler ("no stack to drop all attributes from"); -- return; -- } -+ AttrStack *stack = cc->stack_of_stacks_top; -+ if (!stack) { -+ warning_handler ("no stack to drop all attributes from"); -+ return; -+ } - -- while (stack->tos>=0) -- { -- char *param=stack->attr_stack_params [stack->tos]; -- if (param) my_free(param); -- stack->tos--; -- } -+ while (stack->tos>=0) -+ { -+ char *param=stack->attr_stack_params[stack->tos]; -+ if (param) unrtf_free(param); -+ stack->attr_stack_params[stack->tos] = NULL; -+ stack->tos--; -+ } - } - - -@@ -557,30 +494,34 @@ attr_drop_all () - *=======================================================================*/ - - void --attrstack_drop () -+attrstack_drop (const struct OutputContext *oc) - { -- AttrStack *stack = stack_of_stacks_top; -- AttrStack *prev_stack; -- if (!stack) { -- warning_handler ("no attr-stack to drop"); -- return; -- } -+ AttrStack *stack = oc->conversion->stack_of_stacks_top; -+ AttrStack *prev_stack; -+ if (!stack) { -+ warning_handler ("no attr-stack to drop"); -+ return; -+ } - -- attr_pop_all (); -- prev_stack = stack_of_stacks; -+ attr_pop_all (oc); - -- while(prev_stack && prev_stack->next && prev_stack->next != stack) -- prev_stack = prev_stack->next; -+ if (stack == oc->conversion->stack_of_stacks) { -+ oc->conversion->stack_of_stacks_top = NULL; -+ oc->conversion->stack_of_stacks = NULL; -+ } -+ else { -+ prev_stack = oc->conversion->stack_of_stacks; - -- if (prev_stack) { -- stack_of_stacks_top = prev_stack; -- prev_stack->next = NULL; -- } else { -- stack_of_stacks_top = NULL; -- stack_of_stacks = NULL; -- } -+ while (prev_stack->next && prev_stack->next != stack) -+ prev_stack = prev_stack->next; - -- my_free ((void*) stack); -+ if (prev_stack) { -+ oc->conversion->stack_of_stacks_top = prev_stack; -+ prev_stack->next = NULL; -+ } -+ } -+ -+ unrtf_free ((void*) stack); - } - - /*======================================================================== -@@ -592,21 +533,22 @@ attrstack_drop () - *=======================================================================*/ - - void --attr_pop_all() -+attr_pop_all(const struct OutputContext *oc) - { -- AttrStack *stack = stack_of_stacks_top; -- if (!stack) { -- warning_handler ("no stack to pop from"); -- return; -- } -+ AttrStack *stack = oc->conversion->stack_of_stacks_top; -+ if (!stack) { -+ warning_handler ("no stack to pop from"); -+ return; -+ } - -- while (stack->tos>=0) { -- int attr=stack->attr_stack [stack->tos]; -- char *param=stack->attr_stack_params [stack->tos]; -- attr_express_end (attr,param); -- if (param) my_free(param); -- stack->tos--; -- } -+ while (stack->tos>=0) { -+ int attr=stack->attr_stack[stack->tos]; -+ char *param=stack->attr_stack_params[stack->tos]; -+ attr_express_end (attr,param, oc); -+ if (param) unrtf_free(param); -+ stack->attr_stack_params[stack->tos] = NULL; -+ stack->tos--; -+ } - } - - -@@ -621,23 +563,23 @@ attr_pop_all() - *=======================================================================*/ - - void --attrstack_express_all() { -- AttrStack *stack = stack_of_stacks_top; -- int i; -+attrstack_express_all(const struct OutputContext *oc) { -+ AttrStack *stack = oc->conversion->stack_of_stacks_top; -+ int i; - -- if (!stack) { -- warning_handler ("no stack to pop from"); -- return; -- } -+ if (!stack) { -+ warning_handler ("no stack to pop from"); -+ return; -+ } - -- i=0; -- while (i<=stack->tos) -- { -- int attr=stack->attr_stack [i]; -- char *param=stack->attr_stack_params [i]; -- attr_express_begin (attr, param); -- i++; -- } -+ i=0; -+ while (i<=stack->tos) -+ { -+ int attr=stack->attr_stack[i]; -+ char *param=stack->attr_stack_params[i]; -+ attr_express_begin (attr, param, oc); -+ i++; -+ } - } - - -@@ -652,78 +594,112 @@ attrstack_express_all() { - *=======================================================================*/ - - void --attr_pop_dump() { -- AttrStack *stack = stack_of_stacks_top; -- int i; -+attr_pop_dump(const struct OutputContext *oc) { -+ AttrStack *stack = oc->conversion->stack_of_stacks_top; -+ int i; - -- if (!stack) return; -+ if (!stack) return; - -- i=stack->tos; -- while (i>=0) -- { -- int attr=stack->attr_stack [i]; -- attr_pop (attr); -- i--; -- } -+ i=stack->tos; -+ while (i>=0) -+ { -+ int attr=stack->attr_stack[i]; -+ attr_pop (attr, oc); -+ i--; -+ } - } - - /*======================================================================== - * Name: safe_printf - * Purpose: Prevents format string attack and writes empty string -- instead of NULL. -+ instead of NULL. - * Args: Number of parameters (without a string), string to write, -- additional parameters to print (have to be strings). -+ additional parameters to print (have to be strings). - * Returns: Returns 0 if number of not escaped '%' in string -- is not greater than nr, else returns -1 -+ is not greater than nr, else returns -1 - *=======================================================================*/ - -- - int --safe_printf(int nr, char *string, ...) -+safe_printf(const struct unRTFOutputDevice *od, int nr, char *string, ...) - { -+ char *s, *output; -+ int i = 0, ret_code = 0, written; -+ size_t output_len = 0, output_max = 0, size_max; -+ va_list arguments; - -- char *s; -- int i = 0, ret_code = 0; -- va_list arguments; -+ if (string != NULL) -+ { -+ output_max = 1024; -+ output = malloc(output_max * sizeof (char)); -+ *output = 0; -+ va_start(arguments, string); - -- if (string == NULL) -- printf(""); -- else -- { -- va_start(arguments, string); -+ for (; nr > 0; nr--) -+ { -+ while (string[i] != '\0' && (string[i] != '%' || (string[i] == '%' && (i != 0 && string[i-1] == '\\')))) -+ { -+ if (string[i] != '\\' || string[i+1] != '%') -+ { -+ if (output_len + 1 > output_max) -+ { -+ output_max += 1024; -+ output = realloc(output, output_max * sizeof (char)); -+ } -+ output[output_len] = string[i]; -+ output_len++; -+ } -+ i++; -+ } - -- for (; nr > 0; nr--) -- { -- while (string[i] != '\0' && (string[i] != '%' || (string[i] == '%' && (i != 0 && string[i-1] == '\\')))) -- { -- if (string[i] != '\\' || string[i+1] != '%') -- printf("%c", string[i]); -- i++; -- } -+ if (string[i] != '\0') -+ { -+ s = va_arg(arguments, char *); -+ size_max = output_max - output_len; -+ written = snprintf(output + output_len, size_max, "%s", s); -+ if (written > size_max) -+ { -+ output_max += 1024 + written; -+ output = realloc(output, (output_max + 1) * sizeof (char)); -+ sprintf(output + output_len, "%s", s); -+ } -+ output_len += written; -+ i++; -+ } -+ } -+ va_end(arguments); - -- if (string[i] != '\0') -- { -- s = va_arg(arguments, char *); -- printf("%s", s); -- i++; -- } -- } -- va_end(arguments); -+ while (string[i] != '\0') -+ { -+ if (string[i] != '\\' || (string[i] == '\\' && string[i+1] != '%')) -+ { -+ if (string[i] != '%' || (string[i] == '%' && (i != 0 && string[i-1] == '\\'))) -+ { -+ if (output_len + 1 > output_max) -+ { -+ output_max += 1024; -+ output = realloc(output, output_max * sizeof (char)); -+ } -+ output[output_len] = string[i]; -+ output_len++; -+ } -+ else -+ ret_code = -1; -+ } -+ i++; -+ } - -- while (string[i] != '\0') -- { -- if (string[i] != '\\' || (string[i] == '\\' && string[i+1] != '%')) -- { -- if (string[i] != '%' || (string[i] == '%' && (i != 0 && string[i-1] == '\\'))) -- printf("%c", string[i]); -- else -- ret_code = -1; -- } -- i++; -- } -- } -+ if (output_len + 1 > output_max) -+ { -+ output_max += 1; -+ output = realloc(output, output_max * sizeof (char)); -+ } -+ output[output_len] = 0; - -- return ret_code; -+ od->print(od->data, output, output_len); -+ free(output); -+ } -+ -+ return ret_code; - } - - /*======================================================================== -@@ -731,51 +707,51 @@ safe_printf(int nr, char *string, ...) - * Purpose: See Returns - * Args: String to return and int to put into first parameter. - * Returns: Returns first parameter where first not escaped -- character % is substituted with second parameter. -+ character % is substituted with second parameter. - *=======================================================================*/ - - char * - assemble_string(char *string, int nr) - { - -- char *s, tmp[12];/* Number of characters that can be in int type (including '\0') - AF */ -- int i = 0, j = 0; -+ char *s, tmp[12];/* Number of characters that can be in int type (including '\0') - AF */ -+ int i = 0, j = 0; - -- if (string == NULL) -- return NULL; -- else { -- s = my_malloc(strlen(string) + 1 + 12/* Number of characters that can be in int type (including '\0') - AF */); -- while(string[i] != '\0' && (string[i] != '%' || (string[i] == '%' && (i != 0 && string[i-1] == '\\')))) { -- if (string[i] != '\\' || string[i+1] != '%') { -- s[j] = string[i]; -- j++; -- } -- i++; -- } -+ if (string == NULL) -+ return NULL; -+ else { -+ s = unrtf_malloc(strlen(string) + 1 + 12/* Number of characters that can be in int type (including '\0') - AF */); -+ while(string[i] != '\0' && (string[i] != '%' || (string[i] == '%' && (i != 0 && string[i-1] == '\\')))) { -+ if (string[i] != '\\' || string[i+1] != '%') { -+ s[j] = string[i]; -+ j++; -+ } -+ i++; -+ } - -- if (string[i] != '\0') { -- sprintf(tmp, "%d", nr); -- strcpy(&s[j], tmp); -- j = j + strlen(tmp); -- } -+ if (string[i] != '\0') { -+ sprintf(tmp, "%d", nr); -+ strcpy(&s[j], tmp); -+ j = j + strlen(tmp); -+ } - -- while (string[i] != '\0') { -- if (string[i] != '\\' || (string[i] == '\\' && string[i+1] != '%')) { -- if (string[i] != '%' || (string[i] == '%' && (i != 0 && string[i-1] == '\\'))) { -- s[j] = string[i]; -- j++; -- } -- else { -- /* More than one char % occured */ -- } -- } -- i++; -- } -- } -+ while (string[i] != '\0') { -+ if (string[i] != '\\' || (string[i] == '\\' && string[i+1] != '%')) { -+ if (string[i] != '%' || (string[i] == '%' && (i != 0 && string[i-1] == '\\'))) { -+ s[j] = string[i]; -+ j++; -+ } -+ else { -+ /* More than one char % occured */ -+ } -+ } -+ i++; -+ } -+ } - -- s[j] = '\0'; -+ s[j] = '\0'; - -- return s; -+ return s; - } - - -@@ -789,39 +765,39 @@ assemble_string(char *string, int nr) - Collection * - add_to_collection(Collection *col, int nr, char *text) - { -- Collection *c = col; -+ Collection *c = col; - -- if (col == NULL) -- { -- col = (Collection *)my_malloc(sizeof(Collection)); -- col->nr = nr; -- col->text = text; -- col->next = NULL; -- } -- else -- { -- while (c->next != NULL) -- { -- if (c->nr == nr) -- { --/* Here is a memory leak but not heavy. Do we need to care about this? -- my_free(a->alias.text); --*/ -- c->text = text; -+ if (col == NULL) -+ { -+ col = (Collection *)unrtf_malloc(sizeof(Collection)); -+ col->nr = nr; -+ col->text = strdup(text); -+ col->next = NULL; -+ } -+ else -+ { -+ while (c->next != NULL) -+ { -+ if (c->nr == nr) -+ { -+ /* Here is a memory leak but not heavy. Do we need to care about this? -+ unrtf_free(a->alias.text); -+ */ -+ c->text = strdup(text); - -- return col; -- } -+ return col; -+ } - -- c = c->next; -- } -+ c = c->next; -+ } - -- c->next = (Collection *)my_malloc(sizeof(Collection)); -- c->next->nr = nr; -- c->next->text = text; -- c->next->next = NULL; -- } -+ c->next = (Collection *)unrtf_malloc(sizeof(Collection)); -+ c->next->nr = nr; -+ c->next->text = strdup(text); -+ c->next->next = NULL; -+ } - -- return col; -+ return col; - } - - /*======================================================================== -@@ -834,15 +810,15 @@ add_to_collection(Collection *col, int n - char * - get_from_collection(Collection *c, int nr) - { -- while (c != NULL) -- { -- if (c->nr == nr) -- return c->text; -+ while (c != NULL) -+ { -+ if (c->nr == nr) -+ return c->text; - -- c = c->next; -- } -+ c = c->next; -+ } - -- return NULL; -+ return NULL; - } - - /*======================================================================== -@@ -855,13 +831,15 @@ get_from_collection(Collection *c, int n - void - free_collection(Collection *c) - { -- Collection *c2; -+ Collection *c2; - -- while (c != NULL) -- { -- c2 = c->next; -- my_free((void *)c); -- c = c2; -- } -+ while (c != NULL) -+ { -+ c2 = c->next; -+ if (c->text) { -+ unrtf_free((void *)c->text); -+ } -+ unrtf_free((void *)c); -+ c = c2; -+ } - } -- -diff -durpN unrtf-0.21.2.old/src/attr.h unrtf-0.21.2/src/attr.h ---- unrtf-0.21.2.old/src/attr.h 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/attr.h 2013-01-17 02:41:09.681864239 +0100 -@@ -1,23 +1,23 @@ - /*============================================================================= -- GNU UnRTF, a command-line program to convert RTF documents to other formats. -- Copyright (C) 2000,2001,2004 by Zachary Smith -+ GNU UnRTF, a command-line program to convert RTF documents to other formats. -+ Copyright (C) 2000,2001,2004 by Zachary Smith - -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. - -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. - -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -- The maintainer is reachable by electronic mail at daved@physiol.usyd.edu.au --=============================================================================*/ -+ The maintainer is reachable by electronic mail at daved@physiol.usyd.edu.au -+ =============================================================================*/ - - - /*---------------------------------------------------------------------- -@@ -35,69 +35,77 @@ - * 09 Nov 08, arkadiusz.firus@gmail.com: adopt safe_printf & collection funcs - *--------------------------------------------------------------------*/ - -+#ifndef ATTR_H -+#define ATTR_H -+ - enum { -- ATTR_NONE=0, -- ATTR_BOLD, ATTR_ITALIC, -+ ATTR_NONE=0, -+ ATTR_BOLD, ATTR_ITALIC, - -- ATTR_UNDERLINE, ATTR_DOUBLE_UL, ATTR_WORD_UL, -+ ATTR_UNDERLINE, ATTR_DOUBLE_UL, ATTR_WORD_UL, - -- ATTR_THICK_UL, ATTR_WAVE_UL, -+ ATTR_THICK_UL, ATTR_WAVE_UL, - -- ATTR_DOT_UL, ATTR_DASH_UL, ATTR_DOT_DASH_UL, ATTR_2DOT_DASH_UL, -+ ATTR_DOT_UL, ATTR_DASH_UL, ATTR_DOT_DASH_UL, ATTR_2DOT_DASH_UL, - -- ATTR_FONTSIZE, ATTR_STD_FONTSIZE, -- ATTR_FONTFACE, -- ATTR_FOREGROUND, ATTR_BACKGROUND, -- ATTR_CAPS, -- ATTR_SMALLCAPS, -+ ATTR_FONTSIZE, ATTR_STD_FONTSIZE, -+ ATTR_FONTFACE, -+ ATTR_FOREGROUND, ATTR_BACKGROUND, -+ ATTR_CAPS, -+ ATTR_SMALLCAPS, - -- ATTR_SHADOW, -- ATTR_OUTLINE, -- ATTR_EMBOSS, -- ATTR_ENGRAVE, -+ ATTR_SHADOW, -+ ATTR_OUTLINE, -+ ATTR_EMBOSS, -+ ATTR_ENGRAVE, - -- ATTR_SUPER, ATTR_SUB, -- ATTR_STRIKE, -- ATTR_DBL_STRIKE, -+ ATTR_SUPER, ATTR_SUB, -+ ATTR_STRIKE, -+ ATTR_DBL_STRIKE, - -- ATTR_EXPAND, -- /* ATTR_CONDENSE */ -+ ATTR_EXPAND, -+ /* ATTR_CONDENSE */ - }; - - typedef struct _c - { -- int nr; -- char *text; -- struct _c *next; -+ int nr; -+ char *text; -+ struct _c *next; - } Collection; - - Collection *add_to_collection(Collection *col, int nr, char *text); - char *get_from_collection(Collection *c, int nr); - void free_collection(Collection *c); - -+struct ConversionContext; -+struct OutputContext; -+struct unRTFOutputDevice; -+ - extern void attr_push_core (int attr, char* param); - - extern void attr_pop_core (int attr); - --extern void attr_push(int attr, char* param); -+extern void attr_push(int attr, char* param, const struct OutputContext *oc); - --extern void attrstack_push(); --extern void attrstack_drop(); -+extern void attrstack_push(struct ConversionContext *cc); -+extern void attrstack_drop(const struct OutputContext *oc); - extern void attrstack_express_all(); - --extern int attr_pop(int attr); -+extern int attr_pop(int attr, const struct OutputContext *oc); - --extern int attr_read(); -+extern int attr_read(const struct ConversionContext *cc); - - extern void attr_drop_all (); - --extern void attr_pop_all(); -+extern void attr_pop_all(const struct OutputContext *oc); - - extern void attr_pop_dump(); - --char * attr_get_param(int attr); -+char * attr_get_param(const struct ConversionContext *cc, int attr); - --int safe_printf(int nr, char *string, ...); -+int safe_printf(const struct unRTFOutputDevice *device, int nr, char *string, ...); - char *assemble_string(char *string, int nr); - #define TOO_MANY_ARGS "Tag name \"%s\" do not take so many arguments" - -+#endif /* ATTR_H */ -diff -durpN unrtf-0.21.2.old/src/convert.c unrtf-0.21.2/src/convert.c ---- unrtf-0.21.2.old/src/convert.c 2011-06-07 14:00:23.000000000 +0200 -+++ unrtf-0.21.2/src/convert.c 2013-01-17 02:41:09.685864239 +0100 -@@ -1,24 +1,24 @@ - - /*=========================================================================== -- GNU UnRTF, a command-line program to convert RTF documents to other formats. -- Copyright (C) 2000,2001,2004 Zachary Thayer Smith -+ GNU UnRTF, a command-line program to convert RTF documents to other formats. -+ Copyright (C) 2000,2001,2004 Zachary Thayer Smith - -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. - -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. - -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -- The maintainer is reachable by electronic mail at daved@physiol.usyd.edu.au --===========================================================================*/ -+ The maintainer is reachable by electronic mail at daved@physiol.usyd.edu.au -+ ===========================================================================*/ - - - /*---------------------------------------------------------------------- -@@ -56,8 +56,8 @@ - * 31 Mar 05, daved@physiol.usyd.edu.au: strcat security bug fixed - * 06 Jan 06, marcossamaral@terra.com.br: patch from debian 0.19.3-1.1 - * 03 Mar 06, daved@physiol.usyd.edu.au: fixed creation date spelling -- and added support for accented characters in titles from -- Laurent Monin -+ and added support for accented characters in titles from -+ Laurent Monin - * 09 Mar 06, daved@physiol.usyd.edu.au: don't print null post_trans - * 18 Jun 06, daved@physiol.usyd.edu.au: fixed some incorrect comment_end - * 18 Jun 06, frolovs@internet2.ru: codepage support -@@ -68,7 +68,7 @@ - * 04 Jan 10, arkadiusz.firus@gmail.com: deal with (faulty) negative unicodes - * 04 Jan 10, daved@physiol.usyd.edu.au: suppress - * 21 Aug 10, daved@physiol.usyd.edu.au: add support for hex char doublet -- representation of special characters output by some rtf writers -+ representation of special characters output by some rtf writers - *--------------------------------------------------------------------*/ - - #ifdef HAVE_CONFIG_H -@@ -91,15 +91,21 @@ - #include - #endif - -+#ifdef HAVE_UNISTD_H -+#include -+#endif -+ - #include "defs.h" - #include "parse.h" - #include "util.h" - #include "malloc.h" --#include "main.h" - #include "error.h" - #include "word.h" - #include "hash.h" -+#include "output.h" - #include "convert.h" -+#include "user.h" -+#include "unrtf.h" - - #ifndef HAVE_ATTR_H - #include "attr.h" -@@ -107,506 +113,460 @@ - #endif - - static CodepageInfo codepages[14] = --{ --/*-- cp850 --*/ --{ -- 850, -- { -- /* 0x80 */ -- 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, -- 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, -- /* 0x90 */ -- 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, -- 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192, -- /* 0xa0 */ -- 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, -- 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, -- /* 0xb0 */ -- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, -- 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, -- /* 0xc0 */ -- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, -- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, -- /* 0xd0 */ -- 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce, -- 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, -- /* 0xe0 */ -- 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe, -- 0x00de, 0x00da, 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4, -- /* 0xf0 */ -- 0x00ad, 0x00b1, 0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, -- 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0, -- } --}, --/*-- cp866 --*/ --{ -- 866, -- { -- /* 0x80 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0x90 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xa0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xb0 */ -- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, -- 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, -- /* 0xc0 */ -- 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, -- 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, -- /* 0xd0 */ -- 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, -- 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, -- /* 0xe0 */ -- 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, -- 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, -- /* 0xf0 */ -- 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040e, 0x045e, -- 0x00b0, 0x2219, 0x00b7, 0x221a, 0x2116, 0x00a4, 0x25a0, 0x00a0, -- } --}, --/*-- cp874 --*/ --{ -- 874, -- { -- /* 0x80 */ -- 0x20ac, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2026, 0xfffd, 0xfffd, -- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -- /* 0x90 */ -- 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -- 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -- /* 0xa0 */ -- 0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, -- 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, -- /* 0xb0 */ -- 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, -- 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, -- /* 0xc0 */ -- 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, -- 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, -- /* 0xd0 */ -- 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, -- 0x0e38, 0x0e39, 0x0e3a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x0e3f, -- /* 0xe0 */ -- 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, -- 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f, -- /* 0xf0 */ -- 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, -- 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -- } --}, --/*-- cp1133 --*/ --{ -- 1133, -- { -- /* 0x80 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0x90 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xa0 */ -- 0x00a0, 0x0e81, 0x0e82, 0x0e84, 0x0e87, 0x0e88, 0x0eaa, 0x0e8a, -- 0x0e8d, 0x0e94, 0x0e95, 0x0e96, 0x0e97, 0x0e99, 0x0e9a, 0x0e9b, -- /* 0xb0 */ -- 0x0e9c, 0x0e9d, 0x0e9e, 0x0e9f, 0x0ea1, 0x0ea2, 0x0ea3, 0x0ea5, -- 0x0ea7, 0x0eab, 0x0ead, 0x0eae, 0xfffd, 0xfffd, 0xfffd, 0x0eaf, -- /* 0xc0 */ -- 0x0eb0, 0x0eb2, 0x0eb3, 0x0eb4, 0x0eb5, 0x0eb6, 0x0eb7, 0x0eb8, -- 0x0eb9, 0x0ebc, 0x0eb1, 0x0ebb, 0x0ebd, 0xfffd, 0xfffd, 0xfffd, -- /* 0xd0 */ -- 0x0ec0, 0x0ec1, 0x0ec2, 0x0ec3, 0x0ec4, 0x0ec8, 0x0ec9, 0x0eca, -- 0x0ecb, 0x0ecc, 0x0ecd, 0x0ec6, 0xfffd, 0x0edc, 0x0edd, 0x20ad, -- /* 0xe0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xf0 */ -- 0x0ed0, 0x0ed1, 0x0ed2, 0x0ed3, 0x0ed4, 0x0ed5, 0x0ed6, 0x0ed7, -- 0x0ed8, 0x0ed9, 0xfffd, 0xfffd, 0x00a2, 0x00ac, 0x00a6, 0xfffd, -- } --}, --/*-- cp1250 --*/ --{ -- 1250, - { -- /* 0x80 */ -- 0x20ac, 0xfffd, 0x201a, 0xfffd, 0x201e, 0x2026, 0x2020, 0x2021, -- 0xfffd, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179, -- /* 0x90 */ -- 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -- 0xfffd, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a, -- /* 0xa0 */ -- 0x00a0, 0x02c7, 0x02d8, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, -- 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b, -- /* 0xb0 */ -- 0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, -- 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c, -- /* 0xc0 */ -- 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, -- 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, -- /* 0xd0 */ -- 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, -- 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, -- /* 0xe0 */ -- 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, -- 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, -- /* 0xf0 */ -- 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, -- 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9, -- } --}, --/*-- cp1251 --*/ --{ -- 1251, -- { -- /* 0x80 */ -- 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, -- 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f, -- /* 0x90 */ -- 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -- 0xfffd, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, -- /* 0xa0 */ -- 0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, -- 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, -- /* 0xb0 */ -- 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, -- 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457, -- /* 0xc0 */ -- 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, -- 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, -- /* 0xd0 */ -- 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, -- 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, -- /* 0xe0 */ -- 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, -- 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, -- /* 0xf0 */ -- 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, -- 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, -- } --}, --/*-- cp1252 --*/ --{ -- 1252, -- { -- /* 0x80 */ -- 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, -- 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0xfffd, 0x017d, 0xfffd, -- /* 0x90 */ --/* daved - don't process 93 & 94 as we want entities */ -- 0xfffd, 0x2018, 0x2019, 0, 0, 0x2022, 0x2013, 0x2014, -- 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0xfffd, 0x017e, 0x0178, -- /* 0xa0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xb0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xc0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xd0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xe0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xf0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- } --}, --/*-- cp1253 --*/ --{ -- 1253, -- { -- /* 0x80 */ -- 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, -- 0xfffd, 0x2030, 0xfffd, 0x2039, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -- /* 0x90 */ -- 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -- 0xfffd, 0x2122, 0xfffd, 0x203a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -- /* 0xa0 */ -- 0x00a0, 0x0385, 0x0386, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, -- 0x00a8, 0x00a9, 0xfffd, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x2015, -- /* 0xb0 */ -- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x00b5, 0x00b6, 0x00b7, -- 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, -- /* 0xc0 */ -- 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, -- 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, -- /* 0xd0 */ -- 0x03a0, 0x03a1, 0xfffd, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, -- 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, -- /* 0xe0 */ -- 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, -- 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, -- /* 0xf0 */ -- 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, -- 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0xfffd, -- } --}, --/*-- 1254 --*/ --{ -- 1254, -- { -- /* 0x80 */ -- 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, -- 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0xfffd, 0xfffd, 0xfffd, -- /* 0x90 */ -- 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -- 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0xfffd, 0xfffd, 0x0178, -- /* 0xa0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xb0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xc0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xd0 */ -- 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, -- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, -- /* 0xe0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xf0 */ -- 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, -- 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff, -- } --}, --/*-- cp1255 --*/ --{ -- 1255, -- { -- /* 0x80 */ -- 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, -- 0x02c6, 0x2030, 0xfffd, 0x2039, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -- /* 0x90 */ -- 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -- 0x02dc, 0x2122, 0xfffd, 0x203a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -- /* 0xa0 */ -- 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20aa, 0x00a5, 0x00a6, 0x00a7, -- 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, -- /* 0xb0 */ -- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, -- 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, -- /* 0xc0 */ -- 0x05b0, 0x05b1, 0x05b2, 0x05b3, 0x05b4, 0x05b5, 0x05b6, 0x05b7, -- 0x05b8, 0x05b9, 0xfffd, 0x05bb, 0x05bc, 0x05bd, 0x05be, 0x05bf, -- /* 0xd0 */ -- 0x05c0, 0x05c1, 0x05c2, 0x05c3, 0x05f0, 0x05f1, 0x05f2, 0x05f3, -- 0x05f4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -- /* 0xe0 */ -- 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, -- 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, -- /* 0xf0 */ -- 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, -- 0x05e8, 0x05e9, 0x05ea, 0xfffd, 0xfffd, 0x200e, 0x200f, 0xfffd, -- } --}, --/*-- cp1256 --*/ --{ -- 1256, -- { -- /* 0x80 */ -- 0x20ac, 0x067e, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, -- 0x02c6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, -- /* 0x90 */ -- 0x06af, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -- 0x06a9, 0x2122, 0x0691, 0x203a, 0x0153, 0x200c, 0x200d, 0x06ba, -- /* 0xa0 */ -- 0x00a0, 0x060c, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, -- 0x00a8, 0x00a9, 0x06be, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, -- /* 0xb0 */ -- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, -- 0x00b8, 0x00b9, 0x061b, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x061f, -- /* 0xc0 */ -- 0x06c1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, -- 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, -- /* 0xd0 */ -- 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00d7, -- 0x0637, 0x0638, 0x0639, 0x063a, 0x0640, 0x0641, 0x0642, 0x0643, -- /* 0xe0 */ -- 0x00e0, 0x0644, 0x00e2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00e7, -- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0649, 0x064a, 0x00ee, 0x00ef, -- /* 0xf0 */ -- 0x064b, 0x064c, 0x064d, 0x064e, 0x00f4, 0x064f, 0x0650, 0x00f7, -- 0x0651, 0x00f9, 0x0652, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x06d2, -- } --}, --{ -- 1257, -- { -- /* 0x80 */ -- 0x20ac, 0xfffd, 0x201a, 0xfffd, 0x201e, 0x2026, 0x2020, 0x2021, -- 0xfffd, 0x2030, 0xfffd, 0x2039, 0xfffd, 0x00a8, 0x02c7, 0x00b8, -- /* 0x90 */ -- 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -- 0xfffd, 0x2122, 0xfffd, 0x203a, 0xfffd, 0x00af, 0x02db, 0xfffd, -- /* 0xa0 */ -- 0x00a0, 0xfffd, 0x00a2, 0x00a3, 0x00a4, 0xfffd, 0x00a6, 0x00a7, -- 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, -- /* 0xb0 */ -- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, -- 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, -- /* 0xc0 */ -- 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, -- 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b, -- /* 0xd0 */ -- 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, -- 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df, -- /* 0xe0 */ -- 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, -- 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, -- /* 0xf0 */ -- 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, -- 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x02d9, -- } --}, --{ -- 1258, -- { -- /* 0x80 */ -- 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, -- 0x02c6, 0x2030, 0xfffd, 0x2039, 0x0152, 0xfffd, 0xfffd, 0xfffd, -- /* 0x90 */ -- 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -- 0x02dc, 0x2122, 0xfffd, 0x203a, 0x0153, 0xfffd, 0xfffd, 0x0178, -- /* 0xa0 */ -- 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, -- 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, -- /* 0xb0 */ -- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, -- 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, -- /* 0xc0 */ -- 0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x00c5, 0x00c6, 0x00c7, -- 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x0300, 0x00cd, 0x00ce, 0x00cf, -- /* 0xd0 */ -- 0x0110, 0x00d1, 0x0309, 0x00d3, 0x00d4, 0x01a0, 0x00d6, 0x00d7, -- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x01af, 0x0303, 0x00df, -- /* 0xe0 */ -- 0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x00e5, 0x00e6, 0x00e7, -- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0301, 0x00ed, 0x00ee, 0x00ef, -- /* 0xf0 */ -- 0x0111, 0x00f1, 0x0323, 0x00f3, 0x00f4, 0x01a1, 0x00f6, 0x00f7, -- 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x01b0, 0x20ab, 0x00ff, -- } --}, --/*-- null --*/ --{ -- 0, -- { -- /* 0x80 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0x90 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xa0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xb0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xc0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xd0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xe0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- /* 0xf0 */ -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- } --}, --}; -- -+ /*-- cp850 --*/ -+ { -+ 850, -+ { -+ /* 0x80 */ -+ 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, -+ 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, -+ /* 0x90 */ -+ 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, -+ 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192, -+ /* 0xa0 */ -+ 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, -+ 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, -+ /* 0xb0 */ -+ 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, -+ 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, -+ /* 0xc0 */ -+ 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, -+ 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, -+ /* 0xd0 */ -+ 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce, -+ 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, -+ /* 0xe0 */ -+ 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe, -+ 0x00de, 0x00da, 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4, -+ /* 0xf0 */ -+ 0x00ad, 0x00b1, 0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, -+ 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0, -+ } -+ }, -+ /*-- cp866 --*/ -+ { -+ 866, -+ { -+ /* 0x80 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0x90 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xa0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xb0 */ -+ 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, -+ 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, -+ /* 0xc0 */ -+ 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, -+ 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, -+ /* 0xd0 */ -+ 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, -+ 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, -+ /* 0xe0 */ -+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, -+ 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, -+ /* 0xf0 */ -+ 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040e, 0x045e, -+ 0x00b0, 0x2219, 0x00b7, 0x221a, 0x2116, 0x00a4, 0x25a0, 0x00a0, -+ } -+ }, -+ /*-- cp874 --*/ -+ { -+ 874, -+ { -+ /* 0x80 */ -+ 0x20ac, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2026, 0xfffd, 0xfffd, -+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -+ /* 0x90 */ -+ 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -+ /* 0xa0 */ -+ 0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, -+ 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, -+ /* 0xb0 */ -+ 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, -+ 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, -+ /* 0xc0 */ -+ 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, -+ 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, -+ /* 0xd0 */ -+ 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, -+ 0x0e38, 0x0e39, 0x0e3a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x0e3f, -+ /* 0xe0 */ -+ 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, -+ 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f, -+ /* 0xf0 */ -+ 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, -+ 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -+ } -+ }, -+ /*-- cp1133 --*/ -+ { -+ 1133, -+ { -+ /* 0x80 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0x90 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xa0 */ -+ 0x00a0, 0x0e81, 0x0e82, 0x0e84, 0x0e87, 0x0e88, 0x0eaa, 0x0e8a, -+ 0x0e8d, 0x0e94, 0x0e95, 0x0e96, 0x0e97, 0x0e99, 0x0e9a, 0x0e9b, -+ /* 0xb0 */ -+ 0x0e9c, 0x0e9d, 0x0e9e, 0x0e9f, 0x0ea1, 0x0ea2, 0x0ea3, 0x0ea5, -+ 0x0ea7, 0x0eab, 0x0ead, 0x0eae, 0xfffd, 0xfffd, 0xfffd, 0x0eaf, -+ /* 0xc0 */ -+ 0x0eb0, 0x0eb2, 0x0eb3, 0x0eb4, 0x0eb5, 0x0eb6, 0x0eb7, 0x0eb8, -+ 0x0eb9, 0x0ebc, 0x0eb1, 0x0ebb, 0x0ebd, 0xfffd, 0xfffd, 0xfffd, -+ /* 0xd0 */ -+ 0x0ec0, 0x0ec1, 0x0ec2, 0x0ec3, 0x0ec4, 0x0ec8, 0x0ec9, 0x0eca, -+ 0x0ecb, 0x0ecc, 0x0ecd, 0x0ec6, 0xfffd, 0x0edc, 0x0edd, 0x20ad, -+ /* 0xe0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xf0 */ -+ 0x0ed0, 0x0ed1, 0x0ed2, 0x0ed3, 0x0ed4, 0x0ed5, 0x0ed6, 0x0ed7, -+ 0x0ed8, 0x0ed9, 0xfffd, 0xfffd, 0x00a2, 0x00ac, 0x00a6, 0xfffd, -+ } -+ }, -+ /*-- cp1250 --*/ -+ { -+ 1250, -+ { -+ /* 0x80 */ -+ 0x20ac, 0xfffd, 0x201a, 0xfffd, 0x201e, 0x2026, 0x2020, 0x2021, -+ 0xfffd, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179, -+ /* 0x90 */ -+ 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -+ 0xfffd, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a, -+ /* 0xa0 */ -+ 0x00a0, 0x02c7, 0x02d8, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, -+ 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b, -+ /* 0xb0 */ -+ 0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, -+ 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c, -+ /* 0xc0 */ -+ 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, -+ 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, -+ /* 0xd0 */ -+ 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, -+ 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, -+ /* 0xe0 */ -+ 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, -+ 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, -+ /* 0xf0 */ -+ 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, -+ 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9, -+ } -+ }, -+ /*-- cp1251 --*/ -+ { -+ 1251, -+ { -+ /* 0x80 */ -+ 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, -+ 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f, -+ /* 0x90 */ -+ 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -+ 0xfffd, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, -+ /* 0xa0 */ -+ 0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, -+ 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, -+ /* 0xb0 */ -+ 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, -+ 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457, -+ /* 0xc0 */ -+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, -+ 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, -+ /* 0xd0 */ -+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, -+ 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, -+ /* 0xe0 */ -+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, -+ 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, -+ /* 0xf0 */ -+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, -+ 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, -+ } -+ }, -+ /*-- cp1252 --*/ -+ { -+ 1252, -+ { -+ /* 0x80 */ -+ 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, -+ 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0xfffd, 0x017d, 0xfffd, -+ /* 0x90 */ -+ /* daved - don't process 93 & 94 as we want entities */ -+ 0xfffd, 0x2018, 0x2019, 0, 0, 0x2022, 0x2013, 0x2014, -+ 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0xfffd, 0x017e, 0x0178, -+ /* 0xa0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xb0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xc0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xd0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xe0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xf0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ } -+ }, -+ /*-- cp1253 --*/ -+ { -+ 1253, -+ { -+ /* 0x80 */ -+ 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, -+ 0xfffd, 0x2030, 0xfffd, 0x2039, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -+ /* 0x90 */ -+ 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -+ 0xfffd, 0x2122, 0xfffd, 0x203a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -+ /* 0xa0 */ -+ 0x00a0, 0x0385, 0x0386, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, -+ 0x00a8, 0x00a9, 0xfffd, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x2015, -+ /* 0xb0 */ -+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x00b5, 0x00b6, 0x00b7, -+ 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, -+ /* 0xc0 */ -+ 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, -+ 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, -+ /* 0xd0 */ -+ 0x03a0, 0x03a1, 0xfffd, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, -+ 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, -+ /* 0xe0 */ -+ 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, -+ 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, -+ /* 0xf0 */ -+ 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, -+ 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0xfffd, -+ } -+ }, -+ /*-- 1254 --*/ -+ { -+ 1254, -+ { -+ /* 0x80 */ -+ 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, -+ 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0xfffd, 0xfffd, 0xfffd, -+ /* 0x90 */ -+ 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -+ 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0xfffd, 0xfffd, 0x0178, -+ /* 0xa0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xb0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xc0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xd0 */ -+ 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, -+ 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, -+ /* 0xe0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xf0 */ -+ 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, -+ 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff, -+ } -+ }, -+ /*-- cp1255 --*/ -+ { -+ 1255, -+ { -+ /* 0x80 */ -+ 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, -+ 0x02c6, 0x2030, 0xfffd, 0x2039, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -+ /* 0x90 */ -+ 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -+ 0x02dc, 0x2122, 0xfffd, 0x203a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -+ /* 0xa0 */ -+ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20aa, 0x00a5, 0x00a6, 0x00a7, -+ 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, -+ /* 0xb0 */ -+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, -+ 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, -+ /* 0xc0 */ -+ 0x05b0, 0x05b1, 0x05b2, 0x05b3, 0x05b4, 0x05b5, 0x05b6, 0x05b7, -+ 0x05b8, 0x05b9, 0xfffd, 0x05bb, 0x05bc, 0x05bd, 0x05be, 0x05bf, -+ /* 0xd0 */ -+ 0x05c0, 0x05c1, 0x05c2, 0x05c3, 0x05f0, 0x05f1, 0x05f2, 0x05f3, -+ 0x05f4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, -+ /* 0xe0 */ -+ 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, -+ 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, -+ /* 0xf0 */ -+ 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, -+ 0x05e8, 0x05e9, 0x05ea, 0xfffd, 0xfffd, 0x200e, 0x200f, 0xfffd, -+ } -+ }, -+ /*-- cp1256 --*/ -+ { -+ 1256, -+ { -+ /* 0x80 */ -+ 0x20ac, 0x067e, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, -+ 0x02c6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, -+ /* 0x90 */ -+ 0x06af, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -+ 0x06a9, 0x2122, 0x0691, 0x203a, 0x0153, 0x200c, 0x200d, 0x06ba, -+ /* 0xa0 */ -+ 0x00a0, 0x060c, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, -+ 0x00a8, 0x00a9, 0x06be, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, -+ /* 0xb0 */ -+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, -+ 0x00b8, 0x00b9, 0x061b, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x061f, -+ /* 0xc0 */ -+ 0x06c1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, -+ 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, -+ /* 0xd0 */ -+ 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00d7, -+ 0x0637, 0x0638, 0x0639, 0x063a, 0x0640, 0x0641, 0x0642, 0x0643, -+ /* 0xe0 */ -+ 0x00e0, 0x0644, 0x00e2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00e7, -+ 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0649, 0x064a, 0x00ee, 0x00ef, -+ /* 0xf0 */ -+ 0x064b, 0x064c, 0x064d, 0x064e, 0x00f4, 0x064f, 0x0650, 0x00f7, -+ 0x0651, 0x00f9, 0x0652, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x06d2, -+ } -+ }, -+ { -+ 1257, -+ { -+ /* 0x80 */ -+ 0x20ac, 0xfffd, 0x201a, 0xfffd, 0x201e, 0x2026, 0x2020, 0x2021, -+ 0xfffd, 0x2030, 0xfffd, 0x2039, 0xfffd, 0x00a8, 0x02c7, 0x00b8, -+ /* 0x90 */ -+ 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -+ 0xfffd, 0x2122, 0xfffd, 0x203a, 0xfffd, 0x00af, 0x02db, 0xfffd, -+ /* 0xa0 */ -+ 0x00a0, 0xfffd, 0x00a2, 0x00a3, 0x00a4, 0xfffd, 0x00a6, 0x00a7, -+ 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, -+ /* 0xb0 */ -+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, -+ 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, -+ /* 0xc0 */ -+ 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, -+ 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b, -+ /* 0xd0 */ -+ 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, -+ 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df, -+ /* 0xe0 */ -+ 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, -+ 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, -+ /* 0xf0 */ -+ 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, -+ 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x02d9, -+ } -+ }, -+ { -+ 1258, -+ { -+ /* 0x80 */ -+ 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, -+ 0x02c6, 0x2030, 0xfffd, 0x2039, 0x0152, 0xfffd, 0xfffd, 0xfffd, -+ /* 0x90 */ -+ 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, -+ 0x02dc, 0x2122, 0xfffd, 0x203a, 0x0153, 0xfffd, 0xfffd, 0x0178, -+ /* 0xa0 */ -+ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, -+ 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, -+ /* 0xb0 */ -+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, -+ 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, -+ /* 0xc0 */ -+ 0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x00c5, 0x00c6, 0x00c7, -+ 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x0300, 0x00cd, 0x00ce, 0x00cf, -+ /* 0xd0 */ -+ 0x0110, 0x00d1, 0x0309, 0x00d3, 0x00d4, 0x01a0, 0x00d6, 0x00d7, -+ 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x01af, 0x0303, 0x00df, -+ /* 0xe0 */ -+ 0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x00e5, 0x00e6, 0x00e7, -+ 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0301, 0x00ed, 0x00ee, 0x00ef, -+ /* 0xf0 */ -+ 0x0111, 0x00f1, 0x0323, 0x00f3, 0x00f4, 0x01a1, 0x00f6, 0x00f7, -+ 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x01b0, 0x20ab, 0x00ff, -+ } -+ }, -+ /*-- null --*/ -+ { -+ 0, -+ { -+ /* 0x80 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0x90 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xa0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xb0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xc0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xd0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xe0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ /* 0xf0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ } -+ }, -+ }; - --extern int nopict_mode; - - /* --#define BINARY_ATTRS -+ #define BINARY_ATTRS - */ - --my_iconv_t desc = MY_ICONV_T_CLEAR, desc2 = MY_ICONV_T_CLEAR; -- - /* Nested tables aren't supported. - */ --static int coming_pars_that_are_tabular = 0; --static int within_table = FALSE; --static int have_printed_row_begin=FALSE; --static int have_printed_cell_begin=FALSE; --static int have_printed_row_end=FALSE; --static int have_printed_cell_end=FALSE; -- -- --/* Previously in word_print_core function -- */ --static int total_chars_this_line=0; /* for simulating \tab */ -- - - /* Paragraph alignment (kludge) - */ - enum { -- ALIGN_LEFT=0, -- ALIGN_RIGHT, -- ALIGN_CENTER, -- ALIGN_JUSTIFY -+ ALIGN_LEFT=0, -+ ALIGN_RIGHT, -+ ALIGN_CENTER, -+ ALIGN_JUSTIFY - }; - -- -- --/* This value is set by attr_push and attr_pop -- */ --int simulate_smallcaps; --int simulate_allcaps; -- -- - /* Most pictures must be written to files. */ - enum { -- PICT_UNKNOWN=0, -- PICT_WM, -- PICT_MAC, -- PICT_PM, -- PICT_DI, -- PICT_WB, -- PICT_JPEG, -- PICT_PNG, -+ PICT_UNKNOWN=0, -+ PICT_WM, -+ PICT_MAC, -+ PICT_PM, -+ PICT_DI, -+ PICT_WB, -+ PICT_JPEG, -+ PICT_PNG, - }; --static int within_picture=FALSE; --static int picture_file_number=1; --static char picture_path[255]; --static int picture_width; --static int picture_height; --static int picture_bits_per_pixel=1; --static int picture_type=PICT_UNKNOWN; --static int picture_wmetafile_type; --static char *picture_wmetafile_type_str; -- -- --static int have_printed_body=FALSE; --static int within_header=TRUE; -- -- -- --static char *hyperlink_base = NULL; -- -- -- --void starting_body(); --void starting_text(); --void print_with_special_exprs (char *s); -- --static int banner_printed=FALSE; - -+void starting_body(const struct OutputContext *oc); -+void starting_text(const struct OutputContext *oc); -+void print_with_special_exprs (const struct OutputContext *oc, char *s); - - /*======================================================================== - * Name: print_banner -@@ -616,15 +576,17 @@ static int banner_printed=FALSE; - *=======================================================================*/ - - void --print_banner () { -- if (!banner_printed) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf(" Translation from RTF performed by "); -- printf("UnRTF, version "); -- printf("%s ", PACKAGE_VERSION); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- banner_printed=TRUE; -+print_banner (const struct OutputContext *oc) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (!oc->conversion->banner_printed) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf(" Translation from RTF performed by "); -+ printf("UnRTF, version "); -+ printf("%s ", PACKAGE_VERSION); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ oc->conversion->banner_printed=TRUE; - } - - -@@ -636,16 +598,18 @@ print_banner () { - *=======================================================================*/ - - void --starting_body () -+starting_body (const struct OutputContext *oc) - { -- if (!have_printed_body) { -- if (!inline_mode) { -- if (safe_printf(0, op->header_end)) fprintf(stderr, TOO_MANY_ARGS, "header_end"); -- if (safe_printf(0, op->body_begin)) fprintf(stderr, TOO_MANY_ARGS, "body_begin"); -- } -- within_header = FALSE; -- have_printed_body = TRUE; -- } -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (!oc->conversion->have_printed_body) { -+ if (!oc->conversion->options->inline_mode) { -+ if (safe_printf(device, 0, oc->personality->header_end)) fprintf(stderr, TOO_MANY_ARGS, "header_end"); -+ if (safe_printf(device, 0, oc->personality->body_begin)) fprintf(stderr, TOO_MANY_ARGS, "body_begin"); -+ } -+ oc->conversion->within_header = FALSE; -+ oc->conversion->have_printed_body = TRUE; -+ } - } - - -@@ -691,55 +655,44 @@ static char *month_strings[12]= { - *=======================================================================*/ - - void --word_dump_date (Word *w) -+word_dump_date (const struct ConversionContext *cc, Word *w) - { -- int year=0, month=0, day=0, hour=0, minute=0; -- CHECK_PARAM_NOT_NULL(w); -- while (w) { -- char *s = word_string (w); -- if (*s == '\\') { -- ++s; -- if (!strncmp (s, "yr", 2) && isdigit(s[2])) { -- year = atoi (&s[2]); -- } -- else if (!strncmp (s, "mo", 2) && isdigit(s[2])) { -- month= atoi (&s[2]); -- } -- else if (!strncmp (s, "dy", 2) && isdigit(s[2])) { -- day= atoi (&s[2]); -- } -- else if (!strncmp (s, "min", 3) && isdigit(s[3])) { -- minute= atoi (&s[3]); -- } -- else if (!strncmp (s, "hr", 2) && isdigit(s[2])) { -- hour= atoi (&s[2]); -- } -- } -- w=w->next; -- } -- if (year && month && day) { -- printf("%d %s %d ", day, month_strings[month-1], year); -- } -- if (hour && minute) { -- printf("%02d:%02d ", hour, minute); -- } -+ int year=0, month=0, day=0, hour=0, minute=0; -+ CHECK_PARAM_NOT_NULL(w); -+ while (w) { -+ char *s = word_string (cc, w); -+ if (*s == '\\') { -+ ++s; -+ if (!strncmp (s, "yr", 2) && isdigit(s[2])) { -+ year = atoi (&s[2]); -+ } -+ else if (!strncmp (s, "mo", 2) && isdigit(s[2])) { -+ month= atoi (&s[2]); -+ } -+ else if (!strncmp (s, "dy", 2) && isdigit(s[2])) { -+ day= atoi (&s[2]); -+ } -+ else if (!strncmp (s, "min", 3) && isdigit(s[3])) { -+ minute= atoi (&s[3]); -+ } -+ else if (!strncmp (s, "hr", 2) && isdigit(s[2])) { -+ hour= atoi (&s[2]); -+ } -+ } -+ w=w->next; -+ } -+ if (year && month && day) { -+ printf("%d %s %d ", day, month_strings[month-1], year); -+ } -+ if (hour && minute) { -+ printf("%02d:%02d ", hour, minute); -+ } - } - - - - /*-------------------------------------------------------------------*/ - --typedef struct { -- int num; -- char *name; --} FontEntry; -- --#define MAX_FONTS (8192) --static FontEntry font_table[MAX_FONTS]; --static int total_fonts=0; -- -- -- - /*======================================================================== - * Name: lookup_fontname - * Purpose: Fetches the name of a font from the already-read font table. -@@ -748,14 +701,14 @@ static int total_fonts=0; - *=======================================================================*/ - - char* --lookup_fontname (int num) { -- int i; -- if (total_fonts) -- for(i=0;itotal_fonts) -+ for(i=0;itotal_fonts;i++) { -+ if (cc->font_table[i].num==num) -+ return cc->font_table[i].name; -+ } -+ return NULL; - } - - -@@ -767,73 +720,87 @@ lookup_fontname (int num) { - *=======================================================================*/ - - void --process_font_table (Word *w) -+process_font_table (const struct OutputContext *oc, Word *w) - { -- Word *w2; -+ Word *w2; -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; - -- CHECK_PARAM_NOT_NULL(w); -+ CHECK_PARAM_NOT_NULL(w); - -- if (safe_printf(0, op->fonttable_begin)) fprintf(stderr, TOO_MANY_ARGS, "fonttable_begin"); -+ if (safe_printf(device, 0, oc->personality->fonttable_begin)) fprintf(stderr, TOO_MANY_ARGS, "fonttable_begin"); - -- while (w) { -- int num; -- char name[BUFSIZ]; -- char *tmp; -+ while (w) { -+ int num; -+ char name[BUFSIZ]; -+ char *tmp; - -- if ((w2 = w->child)) { -- tmp = word_string(w2); -- if (!strncmp("\\f", tmp, 2)) { -- num = atoi(&tmp[2]); -- name[0] = 0; -+ if ((w2 = w->child)) { -+ tmp = word_string (oc->conversion, w2); -+ if (!strncmp("\\f", tmp, 2)) { -+ num = atoi(&tmp[2]); -+ name[0] = 0; - -- w2 = w2->next; -- while (w2) { -- tmp = word_string (w2); -- if (tmp && tmp[0] != '\\') { -- if (strlen(tmp) + strlen(name) > BUFSIZ - 1) { -- printf("Invalid font table entry\n"); -- name[0] = 0; -- } -- else -- strncat(name,tmp,sizeof(name) - strlen(name) - 1); -- } -- w2 = w2->next; -- } -+ w2 = w2->next; -+ while (w2) { -+ tmp = word_string (oc->conversion, w2); -+ if (tmp && tmp[0] != '\\') { -+ if (strlen(tmp) + strlen(name) > BUFSIZ - 1) { -+ printf("Invalid font table entry\n"); -+ name[0] = 0; -+ } -+ else -+ strncat(name,tmp,sizeof(name) - strlen(name) - 1); -+ } -+ w2 = w2->next; -+ } - -- /* Chop the gall-derned semicolon. */ -- if ((tmp = strchr(name, ';'))) -- *tmp = 0; -+ /* Chop the gall-derned semicolon. */ -+ if ((tmp = strchr(name, ';'))) -+ *tmp = 0; - -- font_table[total_fonts].num=num; -- font_table[total_fonts].name=my_strdup(name); -- if (safe_printf(0, assemble_string(op->fonttable_fontnr, num))) fprintf(stderr, TOO_MANY_ARGS, "fonttable_fontnr"); -- if (safe_printf(1, op->fonttable_fontname, name)) fprintf(stderr, TOO_MANY_ARGS, "fonttable_fontname"); -- total_fonts++; -- } -- } -- w=w->next; -- } -+ oc->conversion->font_table[oc->conversion->total_fonts].num=num; -+ oc->conversion->font_table[oc->conversion->total_fonts].name=unrtf_strdup(oc->conversion, name); -+ if (safe_printf(device, 0, assemble_string(oc->personality->fonttable_fontnr, num))) fprintf(stderr, TOO_MANY_ARGS, "fonttable_fontnr"); -+ if (safe_printf(device, 1, oc->personality->fonttable_fontname, name)) fprintf(stderr, TOO_MANY_ARGS, "fonttable_fontname"); -+ oc->conversion->total_fonts++; -+ } -+ } -+ w=w->next; -+ } - -- if (safe_printf(0, op->fonttable_end)) fprintf(stderr, TOO_MANY_ARGS, "fonttable_end"); -+ if (safe_printf(device, 0, oc->personality->fonttable_end)) fprintf(stderr, TOO_MANY_ARGS, "fonttable_end"); - -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("font table contains %d fonts total",total_fonts); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("font table contains %d fonts total", oc->conversion->total_fonts); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); - -- if (debug_mode) { -- int i; -+ if (oc->conversion->options->debug_mode) { -+ int i; - -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("font table dump: \n"); -- for (i=0; ipersonality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("font table dump: \n"); -+ for (i=0; i< oc->conversion->total_fonts; i++) { -+ printf(" font %d = %s\n", oc->conversion->font_table[i].num, -+ oc->conversion->font_table[i].name); -+ } - -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } - } - -+static void -+fonttable_free(struct ConversionContext *cc) -+{ -+ int i; -+ -+ for (i = 0; i < cc->total_fonts; i++) { -+ if (cc->font_table[i].name) { -+ unrtf_free(cc->font_table[i].name); -+ cc->font_table[i].name = NULL; -+ } -+ } -+ cc->total_fonts = 0; -+} - - /*======================================================================== - * Name: process_index_entry -@@ -843,24 +810,25 @@ process_font_table (Word *w) - *=======================================================================*/ - - void --process_index_entry (Word *w) -+process_index_entry (const struct OutputContext *oc, Word *w) - { -- Word *w2; -+ Word *w2; -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; - -- CHECK_PARAM_NOT_NULL(w); -+ CHECK_PARAM_NOT_NULL(w); - -- while(w) { -- if ((w2=w->child)) { -- char *str = word_string (w2); -+ while(w) { -+ if ((w2=w->child)) { -+ char *str = word_string (oc->conversion, w2); - -- if (debug_mode && str) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("index entry word: %s ", str); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- } -- w=w->next; -- } -+ if (oc->conversion->options->debug_mode && str) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("index entry word: %s ", str); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ } -+ w=w->next; -+ } - } - - -@@ -872,27 +840,28 @@ process_index_entry (Word *w) - *=======================================================================*/ - - void --process_toc_entry (Word *w, int include_page_num) -+process_toc_entry (const struct OutputContext *oc, Word *w, int include_page_num) - { -- Word *w2; -+ Word *w2; -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; - -- CHECK_PARAM_NOT_NULL(w); -+ CHECK_PARAM_NOT_NULL(w); - -- while(w) { -- if ((w2=w->child)) { -- char *str = word_string (w2); -+ while(w) { -+ if ((w2=w->child)) { -+ char *str = word_string (oc->conversion, w2); - -- if (debug_mode && str) { -+ if (oc->conversion->options->debug_mode && str) { - -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("toc %s entry word: %s ", -- include_page_num ? "page#":"no page#", -- str); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- } -- w=w->next; -- } -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("toc %s entry word: %s ", -+ include_page_num ? "page#":"no page#", -+ str); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ } -+ w=w->next; -+ } - } - - -@@ -904,183 +873,173 @@ process_toc_entry (Word *w, int include_ - *=======================================================================*/ - - void --process_info_group (Word *w) -+process_info_group (const struct OutputContext *oc, Word *w) - { -- Word *child; -+ Word *child; -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; - -- /* amaral - 0.19.2 */ -- /* CHECK_PARAM_NOT_NULL(w); */ -- if (!w) printf("AUTHOR'S COMMENT: \\info command is null!\n"); -+ /* amaral - 0.19.2 */ -+ /* CHECK_PARAM_NOT_NULL(w); */ -+ if (!w) printf("AUTHOR'S COMMENT: \\info command is null!\n"); - -- while(w) { -- child = w->child; -- if (child) { -- Word *w2; -- char *s; -+ while(w) { -+ child = w->child; -+ if (child) { -+ Word *w2; -+ char *s; - -- s = word_string(child); -+ s = word_string (oc->conversion, child); - -- if (!inline_mode) { -- if (!strcmp("\\title", s)) { -+ if (!oc->conversion->options->inline_mode) { -+ if (!strcmp("\\title", s)) { - -- if (safe_printf(0, op->document_title_begin)) fprintf(stderr, TOO_MANY_ARGS, "document_title_begin"); -- w2=child->next; -- while (w2) { -- char *s2 = word_string(w2); -- if (s2[0] != '\\') -- { -- print_with_special_exprs (s2); -- } -- else -- { -- if (s2[1] == '\'') -- { -- int ch = h2toi (&s2[2]); -+ if (safe_printf(device, 0, oc->personality->document_title_begin)) fprintf(stderr, TOO_MANY_ARGS, "document_title_begin"); -+ w2=child->next; -+ while (w2) { -+ char *s2 = word_string (oc->conversion, w2); -+ if (s2[0] != '\\') -+ { -+ print_with_special_exprs (oc, s2); -+ } -+ else -+ { -+ if (s2[1] == '\'') -+ { -+ int ch = h2toi (&s2[2]); - -- char *s3; -- s3 = op_translate_char (op, desc, ch); -- if (!s3 || !*s3) -- { -- if (safe_printf(0, op->comment_begin)) -- fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("char 0x%02x",ch); -- if (safe_printf(0, op->comment_end)) -- fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- } -- else -- { -- if (op->word_begin) -- if (safe_printf(0, op->word_begin)) -- fprintf(stderr, TOO_MANY_ARGS, "word_begin"); -- printf("%s", s3); -- if (op->word_end) -- if (safe_printf(0, op->word_end)) -- fprintf(stderr, TOO_MANY_ARGS, "word_end"); -- } -- } -- } -+ char *s3; -+ s3 = op_translate_char (oc->conversion, oc->personality, ch); -+ if (!s3 || !*s3) -+ { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) -+ fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("char 0x%02x",ch); -+ if (safe_printf(device, 0, oc->personality->comment_end)) -+ fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ } -+ else -+ { -+ if (oc->personality->word_begin) -+ if (safe_printf(device, 0, oc->personality->word_begin)) -+ fprintf(stderr, TOO_MANY_ARGS, "word_begin"); -+ printf("%s", s3); -+ if (oc->personality->word_end) -+ if (safe_printf(device, 0, oc->personality->word_end)) -+ fprintf(stderr, TOO_MANY_ARGS, "word_end"); -+ } -+ } -+ } - -- w2 = w2->next; -- } -- if (safe_printf(0, op->document_title_end)) fprintf(stderr, TOO_MANY_ARGS, "document_title_end"); -- } -- else if (!strcmp("\\keywords", s)) { -- if (safe_printf(0, op->document_keywords_begin)) fprintf(stderr, TOO_MANY_ARGS, "document_keywords_begin"); -- w2=child->next; -- while (w2) { -- char *s2 = word_string(w2); -- if (s2[0] != '\\') -- printf("%s,", s2); -- w2 = w2->next; -- } -- if (safe_printf(0, op->document_keywords_end)) fprintf(stderr, TOO_MANY_ARGS, "document_keywords_end"); -- } -- else if (!strcmp("\\author", s)) { -- if (safe_printf(0, op->document_author_begin)) fprintf(stderr, TOO_MANY_ARGS, "document_author_begin"); -- w2=child->next; -- while (w2) { -- char *s2 = word_string(w2); -- if (s2[0] != '\\') -- printf("%s", s2); -- w2 = w2->next; -- } -- if (safe_printf(0, op->document_author_end)) fprintf(stderr, TOO_MANY_ARGS, "document_author_end"); -- } -- else if (!strcmp("\\comment", s)) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("comments: "); -- w2=child->next; -- while (w2) { -- char *s2 = word_string(w2); -- if (s2[0] != '\\') -- printf("%s", s2); -- w2 = w2->next; -- } -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- else if (!strncmp("\\nofpages", s, 9)) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("total pages: %s",&s[9]); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- else if (!strncmp("\\nofwords", s, 9)) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("total words: %s",&s[9]); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- else if (!strncmp("\\nofchars", s, 9) && isdigit(s[9])) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("total chars: %s",&s[9]); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- else if (!strcmp("\\creatim", s)) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("creation date: "); -- if (child->next) word_dump_date (child->next); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- else if (!strcmp("\\printim", s)) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("last printed: "); -- if (child->next) word_dump_date (child->next); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- else if (!strcmp("\\buptim", s)) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("last backup: "); -- if (child->next) word_dump_date (child->next); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- else if (!strcmp("\\revtim", s)) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("revision date: "); -- if (child->next) word_dump_date (child->next); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- } -+ w2 = w2->next; -+ } -+ if (safe_printf(device, 0, oc->personality->document_title_end)) fprintf(stderr, TOO_MANY_ARGS, "document_title_end"); -+ } -+ else if (!strcmp("\\keywords", s)) { -+ if (safe_printf(device, 0, oc->personality->document_keywords_begin)) fprintf(stderr, TOO_MANY_ARGS, "document_keywords_begin"); -+ w2=child->next; -+ while (w2) { -+ char *s2 = word_string (oc->conversion, w2); -+ if (s2[0] != '\\') -+ printf("%s,", s2); -+ w2 = w2->next; -+ } -+ if (safe_printf(device, 0, oc->personality->document_keywords_end)) fprintf(stderr, TOO_MANY_ARGS, "document_keywords_end"); -+ } -+ else if (!strcmp("\\author", s)) { -+ if (safe_printf(device, 0, oc->personality->document_author_begin)) fprintf(stderr, TOO_MANY_ARGS, "document_author_begin"); -+ w2=child->next; -+ while (w2) { -+ char *s2 = word_string (oc->conversion, w2); -+ if (s2[0] != '\\') -+ printf("%s", s2); -+ w2 = w2->next; -+ } -+ if (safe_printf(device, 0, oc->personality->document_author_end)) fprintf(stderr, TOO_MANY_ARGS, "document_author_end"); -+ } -+ else if (!strcmp("\\comment", s)) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("comments: "); -+ w2=child->next; -+ while (w2) { -+ char *s2 = word_string (oc->conversion, w2); -+ if (s2[0] != '\\') -+ printf("%s", s2); -+ w2 = w2->next; -+ } -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ else if (!strncmp("\\nofpages", s, 9)) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("total pages: %s",&s[9]); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ else if (!strncmp("\\nofwords", s, 9)) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("total words: %s",&s[9]); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ else if (!strncmp("\\nofchars", s, 9) && isdigit(s[9])) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("total chars: %s",&s[9]); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ else if (!strcmp("\\creatim", s)) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("creation date: "); -+ if (child->next) word_dump_date (oc->conversion, child->next); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ else if (!strcmp("\\printim", s)) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("last printed: "); -+ if (child->next) word_dump_date (oc->conversion, child->next); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ else if (!strcmp("\\buptim", s)) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("last backup: "); -+ if (child->next) word_dump_date (oc->conversion, child->next); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ else if (!strcmp("\\revtim", s)) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("revision date: "); -+ if (child->next) word_dump_date (oc->conversion, child->next); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ } - -- /* Irregardless of whether we're in inline mode, -- * we want to process the following. -- */ -- if (!strcmp("\\hlinkbase", s)) { -- char *linkstr = NULL; -+ /* Irregardless of whether we're in inline mode, -+ * we want to process the following. -+ */ -+ if (!strcmp("\\hlinkbase", s)) { -+ char *linkstr = NULL; - -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("hyperlink base: "); -- if (child->next) { -- Word *nextword = child->next; -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("hyperlink base: "); -+ if (child->next) { -+ Word *nextword = child->next; - -- if (nextword) -- linkstr=word_string (nextword); -- } -+ if (nextword) -+ linkstr=word_string (oc->conversion, nextword); -+ } - -- if (linkstr) -- printf("%s", linkstr); -- else -- printf("(none)"); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ if (linkstr) -+ printf("%s", linkstr); -+ else -+ printf("(none)"); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); - -- /* Store the pointer, it will remain good. */ -- hyperlink_base = linkstr; -- } -- } -- w = w->next; -- } -+ /* Store the pointer, it will remain good. */ -+ oc->conversion->hyperlink_base = linkstr; -+ } -+ } -+ w = w->next; -+ } - } - - /*-------------------------------------------------------------------*/ - --/* RTF color table colors are RGB */ -- --typedef struct { -- unsigned char r,g,b; --} Color; -- --#define MAX_COLORS (1024) --static Color color_table[MAX_COLORS]; --static int total_colors=0; -- -- - /*======================================================================== - * Name: process_color_table - * Purpose: Processes the color table of an RTF file. -@@ -1089,59 +1048,60 @@ static int total_colors=0; - *=======================================================================*/ - - void --process_color_table (Word *w) -+process_color_table (const struct OutputContext *oc, Word *w) - { -- int r,g,b; -+ int r,g,b; -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; - -- CHECK_PARAM_NOT_NULL(w); -+ CHECK_PARAM_NOT_NULL(w); - -- /* Sometimes, RTF color tables begin with a semicolon, -- * i.e. an empty color entry. This seems to indicate that color 0 -- * will not be used, so here I set it to black. -- */ -- r=g=b=0; -+ /* Sometimes, RTF color tables begin with a semicolon, -+ * i.e. an empty color entry. This seems to indicate that color 0 -+ * will not be used, so here I set it to black. -+ */ -+ r=g=b=0; - -- while(w) { -- char *s = word_string (w); -+ while(w) { -+ char *s = word_string (oc->conversion, w); - -- if (!strncmp("\\red",s,4)) { -- r = atoi(&s[4]); -- while(r>255) r>>=8; -- } -- else if (!strncmp("\\green",s,6)) { -- g = atoi(&s[6]); -- while(g>255) g>>=8; -- } -- else if (!strncmp("\\blue",s,5)) { -- b = atoi(&s[5]); -- while(b>255) b>>=8; -- } -- else -- /* If we find the semicolon which denotes the end of -- * a color entry then store the color, even if we don't -- * have all of it. -- */ -- if (!strcmp (";", s)) { -- color_table[total_colors].r = r; -- color_table[total_colors].g = g; -- color_table[total_colors++].b = b; -- if (debug_mode) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("storing color entry %d: %02x%02x%02x", -- total_colors-1, r,g,b); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- r=g=b=0; -- } -+ if (!strncmp("\\red",s,4)) { -+ r = atoi(&s[4]); -+ while(r>255) r>>=8; -+ } -+ else if (!strncmp("\\green",s,6)) { -+ g = atoi(&s[6]); -+ while(g>255) g>>=8; -+ } -+ else if (!strncmp("\\blue",s,5)) { -+ b = atoi(&s[5]); -+ while(b>255) b>>=8; -+ } -+ else -+ /* If we find the semicolon which denotes the end of -+ * a color entry then store the color, even if we don't -+ * have all of it. -+ */ -+ if (!strcmp (";", s)) { -+ oc->conversion->color_table[oc->conversion->total_colors].r = r; -+ oc->conversion->color_table[oc->conversion->total_colors].g = g; -+ oc->conversion->color_table[oc->conversion->total_colors++].b = b; -+ if (oc->conversion->options->debug_mode) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("storing color entry %d: %02x%02x%02x", -+ oc->conversion->total_colors-1, r,g,b); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ r=g=b=0; -+ } - -- w=w->next; -- } -+ w=w->next; -+ } - -- if (debug_mode) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("color table had %d entries -->\n", total_colors); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -+ if (oc->conversion->options->debug_mode) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("color table had %d entries -->\n", oc->conversion->total_colors); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } - } - - /*======================================================================== -@@ -1152,21 +1112,21 @@ process_color_table (Word *w) - *=======================================================================*/ - - static int --cmd_cf (Word *w, int align, char has_param, int num) { -- char str[40]; -+cmd_cf (const struct OutputContext *oc, Word *w, int align, char has_param, int num) { -+ char str[40]; - -- if (!has_param || num>=total_colors) { -- warning_handler ("font color change attempted is invalid"); -- } -- else -- { -- sprintf(str,"#%02x%02x%02x", -- color_table[num].r, -- color_table[num].g, -- color_table[num].b); -- attr_push(ATTR_FOREGROUND,str); -- } -- return FALSE; -+ if (!has_param || num>=oc->conversion->total_colors) { -+ warning_handler ("font color change attempted is invalid"); -+ } -+ else -+ { -+ sprintf(str,"#%02x%02x%02x", -+ oc->conversion->color_table[num].r, -+ oc->conversion->color_table[num].g, -+ oc->conversion->color_table[num].b); -+ attr_push(ATTR_FOREGROUND,str, oc); -+ } -+ return FALSE; - } - - -@@ -1179,21 +1139,21 @@ cmd_cf (Word *w, int align, char has_par - *=======================================================================*/ - - static int --cmd_cb (Word *w, int align, char has_param, int num) { -- char str[40]; -+cmd_cb (const struct OutputContext *oc, Word *w, int align, char has_param, int num) { -+ char str[40]; - -- if (!has_param || num>=total_colors) { -- warning_handler ("font color change attempted is invalid"); -- } -- else -- { -- sprintf(str,"#%02x%02x%02x", -- color_table[num].r, -- color_table[num].g, -- color_table[num].b); -- attr_push(ATTR_BACKGROUND,str); -- } -- return FALSE; -+ if (!has_param || num>=oc->conversion->total_colors) { -+ warning_handler ("font color change attempted is invalid"); -+ } -+ else -+ { -+ sprintf(str,"#%02x%02x%02x", -+ oc->conversion->color_table[num].r, -+ oc->conversion->color_table[num].g, -+ oc->conversion->color_table[num].b); -+ attr_push(ATTR_BACKGROUND,str, oc); -+ } -+ return FALSE; - } - - -@@ -1204,18 +1164,18 @@ cmd_cb (Word *w, int align, char has_par - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - static int --cmd_fs (Word *w, int align, char has_param, int points) { -- char str[20]; -+cmd_fs (const struct OutputContext *oc, Word *w, int align, char has_param, int points) { -+ char str[20]; - -- if (!has_param) return FALSE; -+ if (!has_param) return FALSE; - -- /* Note, fs20 means 10pt */ -- points /= 2; -+ /* Note, fs20 means 10pt */ -+ points /= 2; - -- sprintf(str,"%d",points); -- attr_push(ATTR_FONTSIZE,str); -+ sprintf(str,"%d",points); -+ attr_push(ATTR_FONTSIZE,str, oc); - -- return FALSE; -+ return FALSE; - } - - -@@ -1229,95 +1189,99 @@ cmd_fs (Word *w, int align, char has_par - *=======================================================================*/ - - static int --cmd_field (Word *w, int align, char has_param, int num) { -- Word *child; -+cmd_field (const struct OutputContext *oc, Word *w, int align, char has_param, int num) { -+ Word *child; -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; - -- CHECK_PARAM_NOT_NULL(w); -+ CHECK_PARAM_NOT_NULL(w); - -- while(w) { -- child = w->child; -- if (child) { -- Word *w2; -- char *s; -+ while(w) { -+ child = w->child; -+ if (child) { -+ Word *w2; -+ char *s; - -- s = word_string(child); -+ s = word_string (oc->conversion, child); - #if 1 /* daved experimenting with fldrslt */ -- if(!strcmp("\\fldrslt", s)) -- return FALSE; -+ if(!strcmp("\\fldrslt", s)) -+ return FALSE; - #endif - - -- if (!strcmp("\\*", s)) -- { -- w2=child->next; -- while (w2) -- { -- char *s2 = word_string(w2); -- if (s2 && !strcmp("\\fldinst", s2)) -- { -- Word *w3; -- char *s; -- char *s4; -- Word *w4; -- w3=w2->next; -- s = word_string(w3); -- if (s && !strcmp(s, "SYMBOL") ) -- { -- w4=w3->next; -- while(w4 && !strcmp(word_string(w4), " ")) -- w4 = w4->next; -- s4 = word_string(w4); -- if (s4) -- { -- int char_num; -- char *string; -- my_iconv_t d; -- char_num = atoi(s4); -+ if (!strcmp("\\*", s)) -+ { -+ w2=child->next; -+ while (w2) -+ { -+ char *s2 = word_string (oc->conversion, w2); -+ if (s2 && !strcmp("\\fldinst", s2)) -+ { -+ Word *w3; -+ char *s; -+ char *s4; -+ Word *w4; -+ w3=w2->next; -+ s = word_string (oc->conversion, w3); -+ if (s && !strcmp(s, "SYMBOL") ) -+ { -+ w4=w3->next; -+ while(w4 && !strcmp(word_string (oc->conversion, w4), " ")) -+ w4 = w4->next; -+ s4 = word_string (oc->conversion, w4); -+ if (s4) -+ { -+ int char_num; -+ char *string; -+ my_iconv_t d, olddesc; -+ char_num = atoi(s4); - -- if (my_iconv_is_valid((d = my_iconv_open("utf8", FONT_SYMBOL)))) -- { -- string = op_translate_char (op, d, char_num); -- if (string != NULL) -- printf("%s", string); -- my_iconv_close(d); -- } -- else -- fprintf(stderr, "unrtf: Error in translation SYMBOL character\n"); -- } -- } -- while (w3 && !w3->child) { -- w3=w3->next; -- } -- if (w3) w3=w3->child; -- while (w3) -- { -- char *s3=word_string(w3); -- if (s3 && !strcmp("HYPERLINK",s3)) { -- Word *w4; -- char *s4; -- w4=w3->next; -- while (w4 && !strcmp(" ", word_string(w4))) -- w4=w4->next; -- if (w4) { -- s4=word_string(w4); -- if (safe_printf(0, op->hyperlink_begin)) fprintf(stderr, TOO_MANY_ARGS, "hyperlink_begin"); -- printf("%s", s4); -- if (safe_printf(0, op->hyperlink_end)) fprintf(stderr, TOO_MANY_ARGS, "hyperlink_end"); -- return TRUE; -- } -+ if (my_iconv_is_valid((d = my_iconv_open(oc->conversion, "utf8", FONT_SYMBOL)))) -+ { -+ olddesc = oc->conversion->desc; -+ oc->conversion->desc = d; -+ string = op_translate_char (oc->conversion, oc->personality/* , d */, char_num); -+ if (string != NULL) -+ printf("%s", string); -+ my_iconv_close(d); -+ oc->conversion->desc = olddesc; -+ } -+ else -+ fprintf(stderr, "unrtf: Error in translation SYMBOL character\n"); -+ } -+ } -+ while (w3 && !w3->child) { -+ w3=w3->next; -+ } -+ if (w3) w3=w3->child; -+ while (w3) -+ { -+ char *s3=word_string (oc->conversion, w3); -+ if (s3 && !strcmp("HYPERLINK",s3)) { -+ Word *w4; -+ char *s4; -+ w4=w3->next; -+ while (w4 && !strcmp(" ", word_string (oc->conversion, w4))) -+ w4=w4->next; -+ if (w4) { -+ s4=word_string (oc->conversion, w4); -+ if (safe_printf(device, 0, oc->personality->hyperlink_begin)) fprintf(stderr, TOO_MANY_ARGS, "hyperlink_begin"); -+ printf("%s", s4); -+ if (safe_printf(device, 0, oc->personality->hyperlink_end)) fprintf(stderr, TOO_MANY_ARGS, "hyperlink_end"); -+ return TRUE; -+ } - -- } -- w3=w3->next; -- } -- } -- w2 = w2->next; -- } -+ } -+ w3=w3->next; -+ } -+ } -+ w2 = w2->next; -+ } - -- } -- } -- w=w->next; -- } -- return TRUE; -+ } -+ } -+ w=w->next; -+ } -+ return TRUE; - } - - /*======================================================================== -@@ -1327,59 +1291,60 @@ cmd_field (Word *w, int align, char has_ - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - static int --cmd_f (Word *w, int align, char has_param, int num) { -- char *name; -+cmd_f (const struct OutputContext *oc, Word *w, int align, char has_param, int num) { -+ char *name; -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; - -- /* no param exit early XX */ -- if (!has_param) -- return FALSE; -+ /* no param exit early XX */ -+ if (!has_param) -+ return FALSE; - -- name = lookup_fontname(num); -- if (!name) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("invalid font number %d",num); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } else { -- if (op->fonttable_begin != NULL) -- { -- name = my_malloc(12); -- sprintf(name, "%d", num); -- } -+ name = lookup_fontname(oc->conversion, num); -+ if (!name) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("invalid font number %d",num); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } else { -+ if (oc->personality->fonttable_begin != NULL) -+ { -+ name = unrtf_malloc(12); -+ sprintf(name, "%d", num); -+ } - #if 1 /* daved 0.21.1 */ -- /* we are going to output entities, so should not output font */ -- if(strstr(name,"Symbol") == NULL) -+ /* we are going to output entities, so should not output font */ -+ if(strstr(name,"Symbol") == NULL) - #endif -- attr_push(ATTR_FONTFACE,name); -- if (strstr(name,"Symbol") != NULL) -- { -- if (!my_iconv_is_valid(desc2)) -- desc2 = desc; -- else -- my_iconv_close(desc); -+ attr_push(ATTR_FONTFACE,name, oc); -+ if (strstr(name,"Symbol") != NULL) -+ { -+ if (!my_iconv_is_valid(oc->conversion->desc2)) -+ oc->conversion->desc2 = oc->conversion->desc; -+ else -+ my_iconv_close(oc->conversion->desc); - -- desc = my_iconv_open("UTF-8", FONT_SYMBOL); -- } -- else if (strstr(name,"Greek") != NULL) -- { -- if (!my_iconv_is_valid(desc2)) -- desc2 = desc; -- else -- my_iconv_close(desc); -+ oc->conversion->desc = my_iconv_open(oc->conversion, "UTF-8", FONT_SYMBOL); -+ } -+ else if (strstr(name,"Greek") != NULL) -+ { -+ if (!my_iconv_is_valid(oc->conversion->desc2)) -+ oc->conversion->desc2 = oc->conversion->desc; -+ else -+ my_iconv_close(oc->conversion->desc); - -- desc = my_iconv_open("UTF-8", FONT_GREEK); -- } -- else -- { -- if (my_iconv_is_valid(desc2)) -- { -- desc = my_iconv_close(desc); -- desc = desc2; -- my_iconv_t_make_invalid(&desc2); -- } -- } -- } -+ oc->conversion->desc = my_iconv_open(oc->conversion, "UTF-8", FONT_GREEK); -+ } -+ else -+ { -+ if (my_iconv_is_valid(oc->conversion->desc2)) -+ { -+ oc->conversion->desc = my_iconv_close(oc->conversion->desc); -+ oc->conversion->desc = oc->conversion->desc2; -+ my_iconv_t_make_invalid(&oc->conversion->desc2); -+ } -+ } -+ } - -- return FALSE; -+ return FALSE; - } - - -@@ -1391,22 +1356,22 @@ cmd_f (Word *w, int align, char has_para - *=======================================================================*/ - - static int --cmd_highlight (Word *w, int align, char has_param, int num) -+cmd_highlight (const struct OutputContext *oc, Word *w, int align, char has_param, int num) - { -- char str[40]; -+ char str[40]; - -- if (!has_param || num>=total_colors) { -- warning_handler ("font background color change attempted is invalid"); -- } -- else -- { -- sprintf(str,"#%02x%02x%02x", -- color_table[num].r, -- color_table[num].g, -- color_table[num].b); -- attr_push(ATTR_BACKGROUND,str); -- } -- return FALSE; -+ if (!has_param || num>=oc->conversion->total_colors) { -+ warning_handler ("font background color change attempted is invalid"); -+ } -+ else -+ { -+ sprintf(str,"#%02x%02x%02x", -+ oc->conversion->color_table[num].r, -+ oc->conversion->color_table[num].g, -+ oc->conversion->color_table[num].b); -+ attr_push(ATTR_BACKGROUND,str, oc); -+ } -+ return FALSE; - } - - -@@ -1419,22 +1384,24 @@ cmd_highlight (Word *w, int align, char - *=======================================================================*/ - - static int --cmd_tab (Word *w, int align, char has_param, int param) -+cmd_tab (const struct OutputContext *oc, Word *w, int align, char has_param, int param) - { -- /* Tab presents a genuine problem -- * since some output formats don't have -- * an equivalent. As a kludge fix, I shall -- * assume the font is fixed width and that -- * the tabstops are 8 characters apart. -- */ -- int need= 8-(total_chars_this_line%8); -- total_chars_this_line += need; -- while(need>0) { -- if (safe_printf(0, op->forced_space)) fprintf(stderr, TOO_MANY_ARGS, "forced_space"); -- need--; -- } -- printf("\n"); -- return FALSE; -+ /* Tab presents a genuine problem -+ * since some output formats don't have -+ * an equivalent. As a kludge fix, I shall -+ * assume the font is fixed width and that -+ * the tabstops are 8 characters apart. -+ */ -+ int need= 8-(oc->conversion->total_chars_this_line%8); -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ oc->conversion->total_chars_this_line += need; -+ while(need>0) { -+ if (safe_printf(device, 0, oc->personality->forced_space)) fprintf(stderr, TOO_MANY_ARGS, "forced_space"); -+ need--; -+ } -+ printf("\n"); -+ return FALSE; - } - - -@@ -1446,9 +1413,9 @@ cmd_tab (Word *w, int align, char has_pa - *=======================================================================*/ - - static int --cmd_plain (Word *w, int align, char has_param, int param) { -- attr_pop_all(); -- return FALSE; -+cmd_plain (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_pop_all(oc); -+ return FALSE; - } - - -@@ -1459,9 +1426,9 @@ cmd_plain (Word *w, int align, char has_ - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - static int --cmd_fnil (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_FONTFACE,FONTNIL_STR); -- return FALSE; -+cmd_fnil (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_FONTFACE,FONTNIL_STR, oc); -+ return FALSE; - } - - -@@ -1473,9 +1440,9 @@ cmd_fnil (Word *w, int align, char has_p - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - static int --cmd_froman (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_FONTFACE,FONTROMAN_STR); -- return FALSE; -+cmd_froman (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_FONTFACE,FONTROMAN_STR, oc); -+ return FALSE; - } - - -@@ -1487,9 +1454,9 @@ cmd_froman (Word *w, int align, char has - *=======================================================================*/ - - static int --cmd_fswiss (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_FONTFACE,FONTSWISS_STR); -- return FALSE; -+cmd_fswiss (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_FONTFACE,FONTSWISS_STR, oc); -+ return FALSE; - } - - -@@ -1501,9 +1468,9 @@ cmd_fswiss (Word *w, int align, char has - *=======================================================================*/ - - static int --cmd_fmodern (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_FONTFACE,FONTMODERN_STR); -- return FALSE; -+cmd_fmodern (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_FONTFACE,FONTMODERN_STR, oc); -+ return FALSE; - } - - -@@ -1515,9 +1482,9 @@ cmd_fmodern (Word *w, int align, char ha - *=======================================================================*/ - - static int --cmd_fscript (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_FONTFACE,FONTSCRIPT_STR); -- return FALSE; -+cmd_fscript (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_FONTFACE,FONTSCRIPT_STR, oc); -+ return FALSE; - } - - /*======================================================================== -@@ -1528,9 +1495,9 @@ cmd_fscript (Word *w, int align, char ha - *=======================================================================*/ - - static int --cmd_fdecor (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_FONTFACE,FONTDECOR_STR); -- return FALSE; -+cmd_fdecor (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_FONTFACE,FONTDECOR_STR, oc); -+ return FALSE; - } - - /*======================================================================== -@@ -1541,9 +1508,9 @@ cmd_fdecor (Word *w, int align, char has - *=======================================================================*/ - - static int --cmd_ftech (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_FONTFACE,FONTTECH_STR); -- return FALSE; -+cmd_ftech (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_FONTFACE,FONTTECH_STR, oc); -+ return FALSE; - } - - /*======================================================================== -@@ -1554,16 +1521,16 @@ cmd_ftech (Word *w, int align, char has_ - *=======================================================================*/ - - static int --cmd_expand (Word *w, int align, char has_param, int param) { -- char str[10]; -- if (has_param) { -- sprintf(str, "%d", param/4); -- if (!param) -- attr_pop(ATTR_EXPAND); -- else -- attr_push(ATTR_EXPAND, str); -- } -- return FALSE; -+cmd_expand (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ char str[10]; -+ if (has_param) { -+ sprintf(str, "%d", param/4); -+ if (!param) -+ attr_pop(ATTR_EXPAND, oc); -+ else -+ attr_push(ATTR_EXPAND, str, oc); -+ } -+ return FALSE; - } - - -@@ -1575,16 +1542,16 @@ cmd_expand (Word *w, int align, char has - *=======================================================================*/ - - static int --cmd_emboss (Word *w, int align, char has_param, int param) { -- char str[10]; -- if (has_param && !param) -- attr_pop(ATTR_EMBOSS); -- else -- { -- sprintf(str, "%d", param); -- attr_push(ATTR_EMBOSS, str); -- } -- return FALSE; -+cmd_emboss (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ char str[10]; -+ if (has_param && !param) -+ attr_pop(ATTR_EMBOSS, oc); -+ else -+ { -+ sprintf(str, "%d", param); -+ attr_push(ATTR_EMBOSS, str, oc); -+ } -+ return FALSE; - } - - -@@ -1596,16 +1563,16 @@ cmd_emboss (Word *w, int align, char has - *=======================================================================*/ - - static int --cmd_engrave (Word *w, int align, char has_param, int param) { -- char str[10]; -- if (has_param && !param) -- attr_pop(ATTR_ENGRAVE); -- else -- { -- sprintf(str, "%d", param); -- attr_push(ATTR_ENGRAVE, str); -- } -- return FALSE; -+cmd_engrave (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ char str[10]; -+ if (has_param && !param) -+ attr_pop(ATTR_ENGRAVE, oc); -+ else -+ { -+ sprintf(str, "%d", param); -+ attr_push(ATTR_ENGRAVE, str, oc); -+ } -+ return FALSE; - } - - /*======================================================================== -@@ -1616,12 +1583,12 @@ cmd_engrave (Word *w, int align, char ha - *=======================================================================*/ - - static int --cmd_caps (Word *w, int align, char has_param, int param) { -- if (has_param && !param) -- attr_pop(ATTR_CAPS); -- else -- attr_push(ATTR_CAPS,NULL); -- return FALSE; -+cmd_caps (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (has_param && !param) -+ attr_pop(ATTR_CAPS, oc); -+ else -+ attr_push(ATTR_CAPS,NULL, oc); -+ return FALSE; - } - - -@@ -1632,12 +1599,12 @@ cmd_caps (Word *w, int align, char has_p - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - static int --cmd_scaps (Word *w, int align, char has_param, int param) { -- if (has_param && !param) -- attr_pop(ATTR_SMALLCAPS); -- else -- attr_push(ATTR_SMALLCAPS,NULL); -- return FALSE; -+cmd_scaps (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (has_param && !param) -+ attr_pop(ATTR_SMALLCAPS, oc); -+ else -+ attr_push(ATTR_SMALLCAPS,NULL, oc); -+ return FALSE; - } - - -@@ -1648,12 +1615,14 @@ cmd_scaps (Word *w, int align, char has_ - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - static int --cmd_bullet (Word *w, int align, char has_param, int param) { -- if (op->chars.bullet) { -- if (safe_printf(0, op->chars.bullet)) fprintf(stderr, TOO_MANY_ARGS, "chars.bullet"); -- ++total_chars_this_line; /* \tab */ -- } -- return FALSE; -+cmd_bullet (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->personality->chars.bullet) { -+ if (safe_printf(device, 0, oc->personality->chars.bullet)) fprintf(stderr, TOO_MANY_ARGS, "chars.bullet"); -+ ++oc->conversion->total_chars_this_line; /* \tab */ -+ } -+ return FALSE; - } - - /*======================================================================== -@@ -1663,12 +1632,14 @@ cmd_bullet (Word *w, int align, char has - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - static int --cmd_ldblquote (Word *w, int align, char has_param, int param) { -- if (op->chars.left_dbl_quote) { -- if (safe_printf(0, op->chars.left_dbl_quote)) fprintf(stderr, TOO_MANY_ARGS, "chars.left_dbl_quote"); -- ++total_chars_this_line; /* \tab */ -- } -- return FALSE; -+cmd_ldblquote (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->personality->chars.left_dbl_quote) { -+ if (safe_printf(device, 0, oc->personality->chars.left_dbl_quote)) fprintf(stderr, TOO_MANY_ARGS, "chars.left_dbl_quote"); -+ ++oc->conversion->total_chars_this_line; /* \tab */ -+ } -+ return FALSE; - } - - -@@ -1680,12 +1651,14 @@ cmd_ldblquote (Word *w, int align, char - *=======================================================================*/ - - static int --cmd_rdblquote (Word *w, int align, char has_param, int param) { -- if (op->chars.right_dbl_quote) { -- if (safe_printf(0, op->chars.right_dbl_quote)) fprintf(stderr, TOO_MANY_ARGS, "chars.right_dbl_quote"); -- ++total_chars_this_line; /* \tab */ -- } -- return FALSE; -+cmd_rdblquote (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->personality->chars.right_dbl_quote) { -+ if (safe_printf(device, 0, oc->personality->chars.right_dbl_quote)) fprintf(stderr, TOO_MANY_ARGS, "chars.right_dbl_quote"); -+ ++oc->conversion->total_chars_this_line; /* \tab */ -+ } -+ return FALSE; - } - - -@@ -1696,12 +1669,14 @@ cmd_rdblquote (Word *w, int align, char - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - static int --cmd_lquote (Word *w, int align, char has_param, int param) { -- if (op->chars.left_quote) { -- if (safe_printf(0, op->chars.left_quote)) fprintf(stderr, TOO_MANY_ARGS, "chars.left_quote"); -- ++total_chars_this_line; /* \tab */ -- } -- return FALSE; -+cmd_lquote (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->personality->chars.left_quote) { -+ if (safe_printf(device, 0, oc->personality->chars.left_quote)) fprintf(stderr, TOO_MANY_ARGS, "chars.left_quote"); -+ ++oc->conversion->total_chars_this_line; /* \tab */ -+ } -+ return FALSE; - } - - -@@ -1713,12 +1688,14 @@ cmd_lquote (Word *w, int align, char has - *=======================================================================*/ - - static int --cmd_nonbreaking_space (Word *w, int align, char has_param, int param) { -- if (op->chars.nonbreaking_space) { -- if (safe_printf(0, op->chars.nonbreaking_space)) fprintf(stderr, TOO_MANY_ARGS, "chars.nonbreaking_space"); -- ++total_chars_this_line; /* \tab */ -- } -- return FALSE; -+cmd_nonbreaking_space (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->personality->chars.nonbreaking_space) { -+ if (safe_printf(device, 0, oc->personality->chars.nonbreaking_space)) fprintf(stderr, TOO_MANY_ARGS, "chars.nonbreaking_space"); -+ ++oc->conversion->total_chars_this_line; /* \tab */ -+ } -+ return FALSE; - } - - -@@ -1730,12 +1707,14 @@ cmd_nonbreaking_space (Word *w, int alig - *=======================================================================*/ - - static int --cmd_nonbreaking_hyphen (Word *w, int align, char has_param, int param) { -- if (op->chars.nonbreaking_hyphen) { -- if (safe_printf(0, op->chars.nonbreaking_hyphen)) fprintf(stderr, TOO_MANY_ARGS, "chars.nonbreaking_hyphen"); -- ++total_chars_this_line; /* \tab */ -- } -- return FALSE; -+cmd_nonbreaking_hyphen (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->personality->chars.nonbreaking_hyphen) { -+ if (safe_printf(device, 0, oc->personality->chars.nonbreaking_hyphen)) fprintf(stderr, TOO_MANY_ARGS, "chars.nonbreaking_hyphen"); -+ ++oc->conversion->total_chars_this_line; /* \tab */ -+ } -+ return FALSE; - } - - -@@ -1747,12 +1726,14 @@ cmd_nonbreaking_hyphen (Word *w, int ali - *=======================================================================*/ - - static int --cmd_optional_hyphen (Word *w, int align, char has_param, int param) { -- if (op->chars.optional_hyphen) { -- if (safe_printf(0, op->chars.optional_hyphen)) fprintf(stderr, TOO_MANY_ARGS, "chars.optional_hyphen"); -- ++total_chars_this_line; /* \tab */ -- } -- return FALSE; -+cmd_optional_hyphen (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->personality->chars.optional_hyphen) { -+ if (safe_printf(device, 0, oc->personality->chars.optional_hyphen)) fprintf(stderr, TOO_MANY_ARGS, "chars.optional_hyphen"); -+ ++oc->conversion->total_chars_this_line; /* \tab */ -+ } -+ return FALSE; - } - - -@@ -1763,12 +1744,14 @@ cmd_optional_hyphen (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - static int --cmd_emdash (Word *w, int align, char has_param, int param) { -- if (op->chars.emdash) { -- if (safe_printf(0, op->chars.emdash)) fprintf(stderr, TOO_MANY_ARGS, "chars.emdash"); -- ++total_chars_this_line; /* \tab */ -- } -- return FALSE; -+cmd_emdash (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->personality->chars.emdash) { -+ if (safe_printf(device, 0, oc->personality->chars.emdash)) fprintf(stderr, TOO_MANY_ARGS, "chars.emdash"); -+ ++oc->conversion->total_chars_this_line; /* \tab */ -+ } -+ return FALSE; - } - - -@@ -1780,12 +1763,14 @@ cmd_emdash (Word *w, int align, char has - *=======================================================================*/ - - static int --cmd_endash (Word *w, int align, char has_param, int param) { -- if (op->chars.endash) { -- if (safe_printf(0, op->chars.endash)) fprintf(stderr, TOO_MANY_ARGS, "chars.endash"); -- ++total_chars_this_line; /* \tab */ -- } -- return FALSE; -+cmd_endash (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->personality->chars.endash) { -+ if (safe_printf(device, 0, oc->personality->chars.endash)) fprintf(stderr, TOO_MANY_ARGS, "chars.endash"); -+ ++oc->conversion->total_chars_this_line; /* \tab */ -+ } -+ return FALSE; - } - - -@@ -1797,12 +1782,14 @@ cmd_endash (Word *w, int align, char has - *=======================================================================*/ - - static int --cmd_rquote (Word *w, int align, char has_param, int param) { -- if (op->chars.right_quote) { -- if (safe_printf(0, op->chars.right_quote)) fprintf(stderr, TOO_MANY_ARGS, "chars.right_quote"); -- ++total_chars_this_line; /* \tab */ -- } -- return FALSE; -+cmd_rquote (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->personality->chars.right_quote) { -+ if (safe_printf(device, 0, oc->personality->chars.right_quote)) fprintf(stderr, TOO_MANY_ARGS, "chars.right_quote"); -+ ++oc->conversion->total_chars_this_line; /* \tab */ -+ } -+ return FALSE; - } - - -@@ -1813,12 +1800,14 @@ cmd_rquote (Word *w, int align, char has - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - static int --cmd_par (Word *w, int align, char has_param, int param) { -- if (op->line_break) { -- if (safe_printf(0, op->line_break)) fprintf(stderr, TOO_MANY_ARGS, "line_break"); -- total_chars_this_line = 0; /* \tab */ -- } -- return FALSE; -+cmd_par (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->personality->line_break) { -+ if (safe_printf(device, 0, oc->personality->line_break)) fprintf(stderr, TOO_MANY_ARGS, "line_break"); -+ oc->conversion->total_chars_this_line = 0; /* \tab */ -+ } -+ return FALSE; - } - - -@@ -1830,12 +1819,14 @@ cmd_par (Word *w, int align, char has_pa - *=======================================================================*/ - - static int --cmd_line (Word *w, int align, char has_param, int param) { -- if (op->line_break) { -- if (safe_printf(0, op->line_break)) fprintf(stderr, TOO_MANY_ARGS, "line_break"); -- total_chars_this_line = 0; /* \tab */ -- } -- return FALSE; -+cmd_line (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->personality->line_break) { -+ if (safe_printf(device, 0, oc->personality->line_break)) fprintf(stderr, TOO_MANY_ARGS, "line_break"); -+ oc->conversion->total_chars_this_line = 0; /* \tab */ -+ } -+ return FALSE; - } - - -@@ -1846,12 +1837,14 @@ cmd_line (Word *w, int align, char has_p - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_page (Word *w, int align, char has_param, int param) { -- if (op->page_break) { -- if (safe_printf(0, op->page_break)) fprintf(stderr, TOO_MANY_ARGS, "page_break"); -- total_chars_this_line = 0; /* \tab */ -- } -- return FALSE; -+static int cmd_page (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->personality->page_break) { -+ if (safe_printf(device, 0, oc->personality->page_break)) fprintf(stderr, TOO_MANY_ARGS, "page_break"); -+ oc->conversion->total_chars_this_line = 0; /* \tab */ -+ } -+ return FALSE; - } - - -@@ -1862,9 +1855,9 @@ static int cmd_page (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_intbl (Word *w, int align, char has_param, int param) { -- ++coming_pars_that_are_tabular; -- return FALSE; -+static int cmd_intbl (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ ++oc->conversion->coming_pars_that_are_tabular; -+ return FALSE; - } - - -@@ -1875,31 +1868,31 @@ static int cmd_intbl (Word *w, int align - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_ulnone (Word *w, int align, char has_param, int param) { -- int attr, more=TRUE; -- -+static int cmd_ulnone (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ int attr, more=TRUE; -+ - #ifdef BINARY_ATTRS -- attr_remove_underlining()) fprintf(stderr, TOO_MANY_ARGS, ); -+ attr_remove_underlining() fprintf(stderr, TOO_MANY_ARGS, ); - #else -- do { -- attr = attr_read(); -- if (attr==ATTR_UNDERLINE || -- attr==ATTR_DOT_UL || -- attr==ATTR_DASH_UL || -- attr==ATTR_DOT_DASH_UL || -- attr==ATTR_2DOT_DASH_UL || -- attr==ATTR_WORD_UL || -- attr==ATTR_WAVE_UL || -- attr==ATTR_THICK_UL || -- attr==ATTR_DOUBLE_UL) -- { -- if (!attr_pop(ATTR_UNDERLINE)) -- ; -- } else -- more=FALSE; -- } while(more); -+ do { -+ attr = attr_read(oc->conversion); -+ if (attr==ATTR_UNDERLINE || -+ attr==ATTR_DOT_UL || -+ attr==ATTR_DASH_UL || -+ attr==ATTR_DOT_DASH_UL || -+ attr==ATTR_2DOT_DASH_UL || -+ attr==ATTR_WORD_UL || -+ attr==ATTR_WAVE_UL || -+ attr==ATTR_THICK_UL || -+ attr==ATTR_DOUBLE_UL) -+ { -+ if (!attr_pop(ATTR_UNDERLINE, oc)) -+ ; -+ } else -+ more=FALSE; -+ } while(more); - #endif -- return FALSE; -+ return FALSE; - } - - /*======================================================================== -@@ -1909,13 +1902,13 @@ static int cmd_ulnone (Word *w, int alig - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_ul (Word *w, int align, char has_param, int param) { -- if (has_param && param == 0) { -- cmd_ulnone(w, align, has_param, param); -- } else { -- attr_push(ATTR_UNDERLINE, NULL); -- } -- return FALSE; -+static int cmd_ul (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (has_param && param == 0) { -+ cmd_ulnone(oc, w, align, has_param, param); -+ } else { -+ attr_push(ATTR_UNDERLINE, NULL, oc); -+ } -+ return FALSE; - } - - /*======================================================================== -@@ -1925,9 +1918,9 @@ static int cmd_ul (Word *w, int align, c - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_uld (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_DOUBLE_UL, NULL); -- return FALSE; -+static int cmd_uld (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_DOUBLE_UL, NULL, oc); -+ return FALSE; - } - - /*======================================================================== -@@ -1937,9 +1930,9 @@ static int cmd_uld (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_uldb (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_DOT_UL, NULL); -- return FALSE; -+static int cmd_uldb (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_DOT_UL, NULL, oc); -+ return FALSE; - } - - -@@ -1950,9 +1943,9 @@ static int cmd_uldb (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_uldash (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_DASH_UL, NULL); -- return FALSE; -+static int cmd_uldash (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_DASH_UL, NULL, oc); -+ return FALSE; - } - - -@@ -1963,9 +1956,9 @@ static int cmd_uldash (Word *w, int alig - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_uldashd (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_DOT_DASH_UL,NULL); -- return FALSE; -+static int cmd_uldashd (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_DOT_DASH_UL,NULL, oc); -+ return FALSE; - } - - -@@ -1976,9 +1969,9 @@ static int cmd_uldashd (Word *w, int ali - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_uldashdd (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_2DOT_DASH_UL,NULL); -- return FALSE; -+static int cmd_uldashdd (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_2DOT_DASH_UL,NULL, oc); -+ return FALSE; - } - - -@@ -1989,9 +1982,9 @@ static int cmd_uldashdd (Word *w, int al - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_ulw (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_WORD_UL,NULL); -- return FALSE; -+static int cmd_ulw (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_WORD_UL,NULL, oc); -+ return FALSE; - } - - -@@ -2002,9 +1995,9 @@ static int cmd_ulw (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_ulth (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_THICK_UL,NULL); -- return FALSE; -+static int cmd_ulth (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_THICK_UL,NULL, oc); -+ return FALSE; - } - - -@@ -2015,9 +2008,9 @@ static int cmd_ulth (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_ulthd (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_THICK_UL, NULL); -- return FALSE; -+static int cmd_ulthd (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_THICK_UL, NULL, oc); -+ return FALSE; - } - - -@@ -2028,9 +2021,9 @@ static int cmd_ulthd (Word *w, int align - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_ulthdash (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_THICK_UL, NULL); -- return FALSE; -+static int cmd_ulthdash (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_THICK_UL, NULL, oc); -+ return FALSE; - } - - -@@ -2041,9 +2034,9 @@ static int cmd_ulthdash (Word *w, int al - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_ulwave (Word *w, int align, char has_param, int param) { -- attr_push(ATTR_WAVE_UL,NULL); -- return FALSE; -+static int cmd_ulwave (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_push(ATTR_WAVE_UL,NULL, oc); -+ return FALSE; - } - - -@@ -2054,12 +2047,12 @@ static int cmd_ulwave (Word *w, int alig - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_strike (Word *w, int align, char has_param, int param) { -- if (has_param && param==0) -- attr_pop(ATTR_STRIKE); -- else -- attr_push(ATTR_STRIKE,NULL); -- return FALSE; -+static int cmd_strike (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (has_param && param==0) -+ attr_pop(ATTR_STRIKE, oc); -+ else -+ attr_push(ATTR_STRIKE,NULL, oc); -+ return FALSE; - } - - /*======================================================================== -@@ -2069,12 +2062,12 @@ static int cmd_strike (Word *w, int alig - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_strikedl (Word *w, int align, char has_param, int param) { -- if (has_param && param==0) -- attr_pop(ATTR_DBL_STRIKE); -- else -- attr_push(ATTR_DBL_STRIKE,NULL); -- return FALSE; -+static int cmd_strikedl (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (has_param && param==0) -+ attr_pop(ATTR_DBL_STRIKE, oc); -+ else -+ attr_push(ATTR_DBL_STRIKE,NULL, oc); -+ return FALSE; - } - - -@@ -2085,12 +2078,12 @@ static int cmd_strikedl (Word *w, int al - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_striked (Word *w, int align, char has_param, int param) { -- if (has_param && param==0) -- attr_pop(ATTR_DBL_STRIKE); -- else -- attr_push(ATTR_DBL_STRIKE,NULL); -- return FALSE; -+static int cmd_striked (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (has_param && param==0) -+ attr_pop(ATTR_DBL_STRIKE, oc); -+ else -+ attr_push(ATTR_DBL_STRIKE,NULL, oc); -+ return FALSE; - } - - -@@ -2101,8 +2094,8 @@ static int cmd_striked (Word *w, int ali - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_rtf (Word *w, int align, char has_param, int param) { -- return FALSE; -+static int cmd_rtf (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ return FALSE; - } - - -@@ -2113,12 +2106,12 @@ static int cmd_rtf (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_up (Word *w, int align, char has_param, int param) { -- if (has_param && param==0) -- attr_pop(ATTR_SUPER); -- else -- attr_push(ATTR_SUPER,NULL); -- return FALSE; -+static int cmd_up (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (has_param && param==0) -+ attr_pop(ATTR_SUPER, oc); -+ else -+ attr_push(ATTR_SUPER,NULL, oc); -+ return FALSE; - } - - /*======================================================================== -@@ -2128,61 +2121,63 @@ static int cmd_up (Word *w, int align, c - * Returns: Flag, always false - *=======================================================================*/ - --static int cmd_u (Word *w, int align, char has_param, int param) { --/* TODO: Unicode characters won't be correctly preprocessed if sizeof(int) < 4 -- * and document have unicode character which value is greater than 65536 -- */ -+static int cmd_u (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ /* TODO: Unicode characters won't be correctly preprocessed if sizeof(int) < 4 -+ * and document have unicode character which value is greater than 65536 -+ */ - -- short done=0; -- long unicode_number = (long) param; /* On 16bit architectures int is too small to store unicode characters. - AF */ -- char tmp[12]; /* Number of characters that can be in int type (including '\0'). If int size is greater than 4 bytes change this value. - AF */ -- char *alias; -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ short done=0; -+ long unicode_number = (long) param; /* On 16bit architectures int is too small to store unicode characters. - AF */ -+ char tmp[12]; /* Number of characters that can be in int type (including '\0'). If int size is greater than 4 bytes change this value. - AF */ -+ char *alias; - #if DEBUG -- char *str; -- if (has_param == TRUE) -- { -- fprintf(stderr,"param is %d (x%x) (0%o)\n", param, -- param, param); -- } -- if (w->hash_index) -- { -- str=hash_get_string (w->hash_index); -- fprintf(stderr,"string is %s\n", str); -- } -+ char *str; -+ -+ if (has_param == TRUE) -+ { -+ fprintf(stderr,"param is %d (x%x) (0%o)\n", param, -+ param, param); -+ } -+ if (w->hash_index) -+ { -+ str=hash_get_string (oc->conversion, w->hash_index); -+ fprintf(stderr,"string is %s\n", str); -+ } - #endif -- /* 0.20.3 - daved added missing function call for unprocessed chars */ -- if ((alias = get_alias(op, param)) != NULL) -- { -- printf("%s", alias); -- done++; -- } -- else -- if(!done && op->unisymbol_print) -- { -- if (unicode_number < 0) -- { -+ /* 0.20.3 - daved added missing function call for unprocessed chars */ -+ if ((alias = get_alias(oc->personality, param)) != NULL) -+ { -+ printf("%s", alias); -+ done++; -+ } -+ else -+ if(!done && oc->personality->unisymbol_print) -+ { -+ if (unicode_number < 0) -+ { - #if DEBUG -- fprintf(stderr, "Invalid unicode character number accured: %ld\n", unicode_number); -+ fprintf(stderr, "Invalid unicode character number accured: %ld\n", unicode_number); - #endif -- unicode_number += 65536; -+ unicode_number += 65536; - #if DEBUG -- fprintf(stderr, "Assumes it should be: %ld\n", unicode_number); -+ fprintf(stderr, "Assumes it should be: %ld\n", unicode_number); - #endif -- } -- sprintf(tmp, "%ld", unicode_number); -- -- if (safe_printf(1, op->unisymbol_print, tmp)) fprintf(stderr, TOO_MANY_ARGS, "unisymbol_print"); -- done++; -- } -- -- /* -- ** if we know how to represent the unicode character in the -- ** output language, we need to skip the next word, otherwise -- ** we will output that alternative. -- */ -- if (done) -- return(SKIP_ONE_WORD); -- return(FALSE); -+ } -+ sprintf(tmp, "%ld", unicode_number); -+ -+ if (safe_printf(device, 1, oc->personality->unisymbol_print, tmp)) fprintf(stderr, TOO_MANY_ARGS, "unisymbol_print"); -+ done++; -+ } -+ -+ /* -+ ** if we know how to represent the unicode character in the -+ ** output language, we need to skip the next word, otherwise -+ ** we will output that alternative. -+ */ -+ if (done) -+ return(SKIP_ONE_WORD); -+ return(FALSE); - } - - /*======================================================================== -@@ -2192,12 +2187,12 @@ static int cmd_u (Word *w, int align, ch - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_dn (Word *w, int align, char has_param, int param) { -- if (has_param && param==0) -- attr_pop(ATTR_SUB); -- else -- attr_push(ATTR_SUB,NULL); -- return FALSE; -+static int cmd_dn (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (has_param && param==0) -+ attr_pop(ATTR_SUB, oc); -+ else -+ attr_push(ATTR_SUB,NULL, oc); -+ return FALSE; - } - - /*======================================================================== -@@ -2207,10 +2202,10 @@ static int cmd_dn (Word *w, int align, c - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_nosupersub (Word *w, int align, char has_param, int param) { -- attr_pop(ATTR_SUPER); -- attr_pop(ATTR_SUB); -- return FALSE; -+static int cmd_nosupersub (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ attr_pop(ATTR_SUPER, oc); -+ attr_pop(ATTR_SUB, oc); -+ return FALSE; - } - - /*======================================================================== -@@ -2220,12 +2215,12 @@ static int cmd_nosupersub (Word *w, int - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_super (Word *w, int align, char has_param, int param) { -- if (has_param && param==0) -- attr_pop(ATTR_SUPER); -- else -- attr_push(ATTR_SUPER,NULL); -- return FALSE; -+static int cmd_super (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (has_param && param==0) -+ attr_pop(ATTR_SUPER, oc); -+ else -+ attr_push(ATTR_SUPER,NULL, oc); -+ return FALSE; - } - - /*======================================================================== -@@ -2235,12 +2230,12 @@ static int cmd_super (Word *w, int align - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_sub (Word *w, int align, char has_param, int param) { -- if (has_param && param==0) -- attr_pop(ATTR_SUB); -- else -- attr_push(ATTR_SUB,NULL); -- return FALSE; -+static int cmd_sub (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (has_param && param==0) -+ attr_pop(ATTR_SUB, oc); -+ else -+ attr_push(ATTR_SUB,NULL, oc); -+ return FALSE; - } - - /*======================================================================== -@@ -2250,12 +2245,12 @@ static int cmd_sub (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_shad (Word *w, int align, char has_param, int param) { -- if (has_param && param==0) -- attr_pop(ATTR_SHADOW); -- else -- attr_push(ATTR_SHADOW,NULL); -- return FALSE; -+static int cmd_shad (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (has_param && param==0) -+ attr_pop(ATTR_SHADOW, oc); -+ else -+ attr_push(ATTR_SHADOW,NULL, oc); -+ return FALSE; - } - - /*======================================================================== -@@ -2266,13 +2261,13 @@ static int cmd_shad (Word *w, int align, - *=======================================================================*/ - - static int --cmd_b (Word *w, int align, char has_param, int param) { -- if (has_param && param==0) { -- attr_pop(ATTR_BOLD); -- } -- else -- attr_push(ATTR_BOLD,NULL); -- return FALSE; -+cmd_b (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (has_param && param==0) { -+ attr_pop(ATTR_BOLD, oc); -+ } -+ else -+ attr_push(ATTR_BOLD,NULL, oc); -+ return FALSE; - } - - /*======================================================================== -@@ -2282,12 +2277,12 @@ cmd_b (Word *w, int align, char has_para - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_i (Word *w, int align, char has_param, int param) { -- if (has_param && param==0) -- attr_pop(ATTR_ITALIC); -- else -- attr_push(ATTR_ITALIC,NULL); -- return FALSE; -+static int cmd_i (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (has_param && param==0) -+ attr_pop(ATTR_ITALIC, oc); -+ else -+ attr_push(ATTR_ITALIC,NULL, oc); -+ return FALSE; - } - - /*======================================================================== -@@ -2296,8 +2291,8 @@ static int cmd_i (Word *w, int align, ch - * Args: Word, paragraph align info, and numeric param if any. - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ --static int cmd_s (Word *w, int align, char has_param, int param) { -- return FALSE; -+static int cmd_s (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ return FALSE; - } - - /*======================================================================== -@@ -2307,12 +2302,14 @@ static int cmd_s (Word *w, int align, ch - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_sect (Word *w, int align, char has_param, int param) { -- /* XX kludge */ -- if (op->paragraph_begin) { -- if (safe_printf(0, op->paragraph_begin)) fprintf(stderr, TOO_MANY_ARGS, "paragraph_begin"); -- } -- return FALSE; -+static int cmd_sect (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ /* XX kludge */ -+ if (oc->personality->paragraph_begin) { -+ if (safe_printf(device, 0, oc->personality->paragraph_begin)) fprintf(stderr, TOO_MANY_ARGS, "paragraph_begin"); -+ } -+ return FALSE; - } - - /*======================================================================== -@@ -2322,14 +2319,16 @@ static int cmd_sect (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_shp (Word *w, int align, char has_param, int param) { -- if (op->comment_begin) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("Drawn Shape (ignored--not implemented yet)"); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -+static int cmd_shp (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; - -- return FALSE; -+ if (oc->personality->comment_begin) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("Drawn Shape (ignored--not implemented yet)"); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ -+ return FALSE; - } - - /*======================================================================== -@@ -2339,12 +2338,12 @@ static int cmd_shp (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_outl (Word *w, int align, char has_param, int param) { -- if (has_param && param==0) -- attr_pop(ATTR_OUTLINE); -- else -- attr_push(ATTR_OUTLINE,NULL); -- return FALSE; -+static int cmd_outl (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (has_param && param==0) -+ attr_pop(ATTR_OUTLINE, oc); -+ else -+ attr_push(ATTR_OUTLINE,NULL, oc); -+ return FALSE; - } - - /*======================================================================== -@@ -2354,12 +2353,12 @@ static int cmd_outl (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_ansi (Word *w, int align, char has_param, int param) { -- if (my_iconv_is_valid(desc)) -- desc = my_iconv_close(desc); -+static int cmd_ansi (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (my_iconv_is_valid(oc->conversion->desc)) -+ oc->conversion->desc = my_iconv_close(oc->conversion->desc); - -- desc = my_iconv_open("UTF-8", "cp1252"); -- return FALSE; -+ oc->conversion->desc = my_iconv_open(oc->conversion, "UTF-8", "cp1252"); -+ return FALSE; - } - - /*======================================================================== -@@ -2369,18 +2368,18 @@ static int cmd_ansi (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_ansicpg (Word *w, int align, char has_param, int param) -+static int cmd_ansicpg (const struct OutputContext *oc, Word *w, int align, char has_param, int param) - { -- char tmp[8]; -+ char tmp[8]; - -- snprintf(tmp, 8, "cp%d", param); -+ snprintf(tmp, 8, "cp%d", param); - -- if (my_iconv_is_valid(desc)) -- desc = my_iconv_close(desc); -+ if (my_iconv_is_valid(oc->conversion->desc)) -+ oc->conversion->desc = my_iconv_close(oc->conversion->desc); - -- desc = my_iconv_open("UTF-8", tmp); -+ oc->conversion->desc = my_iconv_open(oc->conversion, "UTF-8", tmp); - -- return FALSE; -+ return FALSE; - } - - /*======================================================================== -@@ -2390,13 +2389,13 @@ static int cmd_ansicpg (Word *w, int ali - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_pc (Word *w, int align, char has_param, int param) { -- if (my_iconv_is_valid(desc)) -- desc = my_iconv_close(desc); -+static int cmd_pc (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (my_iconv_is_valid(oc->conversion->desc)) -+ oc->conversion->desc = my_iconv_close(oc->conversion->desc); - -- desc = my_iconv_open("UTF-8", "cp437"); -+ oc->conversion->desc = my_iconv_open(oc->conversion, "UTF-8", "cp437"); - -- return FALSE; -+ return FALSE; - } - - /*======================================================================== -@@ -2406,14 +2405,14 @@ static int cmd_pc (Word *w, int align, c - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_pca (Word *w, int align, char has_param, int param) { -+static int cmd_pca (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { - -- if (my_iconv_is_valid(desc)) -- my_iconv_close(desc); -+ if (my_iconv_is_valid(oc->conversion->desc)) -+ my_iconv_close(oc->conversion->desc); - -- desc = my_iconv_open("UTF-8", "cp850"); -+ oc->conversion->desc = my_iconv_open(oc->conversion, "UTF-8", "cp850"); - -- return FALSE; -+ return FALSE; - } - - /*======================================================================== -@@ -2423,13 +2422,13 @@ static int cmd_pca (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_mac (Word *w, int align, char has_param, int param) { -+static int cmd_mac (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { - -- if (my_iconv_is_valid(desc)) -- my_iconv_close(desc); -+ if (my_iconv_is_valid(oc->conversion->desc)) -+ my_iconv_close(oc->conversion->desc); - -- desc = my_iconv_open("UTF-8", "mac"); -- return FALSE; -+ oc->conversion->desc = my_iconv_open(oc->conversion, "UTF-8", "mac"); -+ return FALSE; - } - - /*======================================================================== -@@ -2439,11 +2438,11 @@ static int cmd_mac (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_colortbl (Word *w, int align, char has_param, int param) { -- if (w->next) { -- process_color_table(w->next); -- } -- return TRUE; -+static int cmd_colortbl (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (w->next) { -+ process_color_table (oc, w->next); -+ } -+ return TRUE; - } - - /*======================================================================== -@@ -2453,11 +2452,11 @@ static int cmd_colortbl (Word *w, int al - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_fonttbl (Word *w, int align, char has_param, int param) { -- if (w->next) { -- process_font_table(w->next); -- } -- return TRUE; -+static int cmd_fonttbl (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (w->next) { -+ process_font_table (oc, w->next); -+ } -+ return TRUE; - } - - /*======================================================================== -@@ -2467,8 +2466,8 @@ static int cmd_fonttbl (Word *w, int ali - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_header (Word *w, int align, char has_param, int param) { -- return TRUE; -+static int cmd_header (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ return TRUE; - } - - /*======================================================================== -@@ -2478,8 +2477,8 @@ static int cmd_header (Word *w, int alig - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_headerl (Word *w, int align, char has_param, int param) { -- return TRUE; -+static int cmd_headerl (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ return TRUE; - } - - /*======================================================================== -@@ -2489,8 +2488,8 @@ static int cmd_headerl (Word *w, int ali - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_headerr (Word *w, int align, char has_param, int param) { -- return TRUE; -+static int cmd_headerr (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ return TRUE; - } - - /*======================================================================== -@@ -2500,8 +2499,8 @@ static int cmd_headerr (Word *w, int ali - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_headerf (Word *w, int align, char has_param, int param) { -- return TRUE; -+static int cmd_headerf (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ return TRUE; - } - - /*======================================================================== -@@ -2511,8 +2510,8 @@ static int cmd_headerf (Word *w, int ali - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_footer (Word *w, int align, char has_param, int param) { -- return TRUE; -+static int cmd_footer (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ return TRUE; - } - - /*======================================================================== -@@ -2522,8 +2521,8 @@ static int cmd_footer (Word *w, int alig - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_footerl (Word *w, int align, char has_param, int param) { -- return TRUE; -+static int cmd_footerl (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ return TRUE; - } - - /*======================================================================== -@@ -2533,8 +2532,8 @@ static int cmd_footerl (Word *w, int ali - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_footerr (Word *w, int align, char has_param, int param) { -- return TRUE; -+static int cmd_footerr (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ return TRUE; - } - - /*======================================================================== -@@ -2544,8 +2543,8 @@ static int cmd_footerr (Word *w, int ali - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_footerf (Word *w, int align, char has_param, int param) { -- return TRUE; -+static int cmd_footerf (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ return TRUE; - } - - /*======================================================================== -@@ -2555,8 +2554,8 @@ static int cmd_footerf (Word *w, int ali - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_ignore (Word *w, int align, char has_param, int param) { -- return TRUE; -+static int cmd_ignore (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ return TRUE; - } - - /*======================================================================== -@@ -2566,9 +2565,9 @@ static int cmd_ignore (Word *w, int alig - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_info (Word *w, int align, char has_param, int param) { -- process_info_group (w->next); -- return TRUE; -+static int cmd_info (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ process_info_group (oc, w->next); -+ return TRUE; - } - - /*======================================================================== -@@ -2578,11 +2577,11 @@ static int cmd_info (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_pict (Word *w, int align, char has_param, int param) { -- within_picture=TRUE; -- picture_width = picture_height = 0; -- picture_type = PICT_WB; -- return FALSE; -+static int cmd_pict (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ oc->conversion->within_picture=TRUE; -+ oc->conversion->picture_width = oc->conversion->picture_height = 0; -+ oc->conversion->picture_type = PICT_WB; -+ return FALSE; - } - - /*======================================================================== -@@ -2592,8 +2591,8 @@ static int cmd_pict (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_bin (Word *w, int align, char has_param, int param) { -- return FALSE; -+static int cmd_bin (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ return FALSE; - } - - -@@ -2604,9 +2603,9 @@ static int cmd_bin (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_macpict (Word *w, int align, char has_param, int param) { -- picture_type = PICT_MAC; -- return FALSE; -+static int cmd_macpict (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ oc->conversion->picture_type = PICT_MAC; -+ return FALSE; - } - - /*======================================================================== -@@ -2616,9 +2615,9 @@ static int cmd_macpict (Word *w, int ali - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_jpegblip (Word *w, int align, char has_param, int param) { -- picture_type = PICT_JPEG; -- return FALSE; -+static int cmd_jpegblip (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ oc->conversion->picture_type = PICT_JPEG; -+ return FALSE; - } - - /*======================================================================== -@@ -2628,9 +2627,9 @@ static int cmd_jpegblip (Word *w, int al - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_pngblip (Word *w, int align, char has_param, int param) { -- picture_type = PICT_PNG; -- return FALSE; -+static int cmd_pngblip (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ oc->conversion->picture_type = PICT_PNG; -+ return FALSE; - } - - /*======================================================================== -@@ -2640,9 +2639,9 @@ static int cmd_pngblip (Word *w, int ali - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_pnmetafile (Word *w, int align, char has_param, int param) { -- picture_type = PICT_PM; -- return FALSE; -+static int cmd_pnmetafile (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ oc->conversion->picture_type = PICT_PM; -+ return FALSE; - } - - /*======================================================================== -@@ -2652,23 +2651,23 @@ static int cmd_pnmetafile (Word *w, int - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_wmetafile (Word *w, int align, char has_param, int param) { -- picture_type = PICT_WM; -- if (within_picture && has_param) { -- picture_wmetafile_type=param; -- switch(param) { -- case 1: picture_wmetafile_type_str="MM_TEXT"; break; -- case 2: picture_wmetafile_type_str="MM_LOMETRIC"; break; -- case 3: picture_wmetafile_type_str="MM_HIMETRIC"; break; -- case 4: picture_wmetafile_type_str="MM_LOENGLISH"; break; -- case 5: picture_wmetafile_type_str="MM_HIENGLISH"; break; -- case 6: picture_wmetafile_type_str="MM_TWIPS"; break; -- case 7: picture_wmetafile_type_str="MM_ISOTROPIC"; break; -- case 8: picture_wmetafile_type_str="MM_ANISOTROPIC"; break; -- default: picture_wmetafile_type_str="default:MM_TEXT"; break; -- } -- } -- return FALSE; -+static int cmd_wmetafile (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ oc->conversion->picture_type = PICT_WM; -+ if (oc->conversion->within_picture && has_param) { -+ oc->conversion->picture_wmetafile_type=param; -+ switch(param) { -+ case 1: oc->conversion->picture_wmetafile_type_str="MM_TEXT"; break; -+ case 2: oc->conversion->picture_wmetafile_type_str="MM_LOMETRIC"; break; -+ case 3: oc->conversion->picture_wmetafile_type_str="MM_HIMETRIC"; break; -+ case 4: oc->conversion->picture_wmetafile_type_str="MM_LOENGLISH"; break; -+ case 5: oc->conversion->picture_wmetafile_type_str="MM_HIENGLISH"; break; -+ case 6: oc->conversion->picture_wmetafile_type_str="MM_TWIPS"; break; -+ case 7: oc->conversion->picture_wmetafile_type_str="MM_ISOTROPIC"; break; -+ case 8: oc->conversion->picture_wmetafile_type_str="MM_ANISOTROPIC"; break; -+ default: oc->conversion->picture_wmetafile_type_str="default:MM_TEXT"; break; -+ } -+ } -+ return FALSE; - } - - /*======================================================================== -@@ -2678,10 +2677,10 @@ static int cmd_wmetafile (Word *w, int a - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_wbmbitspixel (Word *w, int align, char has_param, int param) { -- if (within_picture && has_param) -- picture_bits_per_pixel = param; -- return FALSE; -+static int cmd_wbmbitspixel (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (oc->conversion->within_picture && has_param) -+ oc->conversion->picture_bits_per_pixel = param; -+ return FALSE; - } - - /*======================================================================== -@@ -2691,10 +2690,10 @@ static int cmd_wbmbitspixel (Word *w, in - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_picw (Word *w, int align, char has_param, int param) { -- if (within_picture && has_param) -- picture_width = param; -- return FALSE; -+static int cmd_picw (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (oc->conversion->within_picture && has_param) -+ oc->conversion->picture_width = param; -+ return FALSE; - } - - /*======================================================================== -@@ -2704,10 +2703,10 @@ static int cmd_picw (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_pich (Word *w, int align, char has_param, int param) { -- if (within_picture && has_param) -- picture_height = param; -- return FALSE; -+static int cmd_pich (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ if (oc->conversion->within_picture && has_param) -+ oc->conversion->picture_height = param; -+ return FALSE; - } - - -@@ -2718,9 +2717,9 @@ static int cmd_pich (Word *w, int align, - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_xe (Word *w, int align, char has_param, int param) { -- process_index_entry (w); -- return TRUE; -+static int cmd_xe (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ process_index_entry (oc, w); -+ return TRUE; - } - - /*======================================================================== -@@ -2730,9 +2729,9 @@ static int cmd_xe (Word *w, int align, c - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_tc (Word *w, int align, char has_param, int param) { -- process_toc_entry (w, TRUE); -- return TRUE; -+static int cmd_tc (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ process_toc_entry (oc, w, TRUE); -+ return TRUE; - } - - /*======================================================================== -@@ -2742,282 +2741,282 @@ static int cmd_tc (Word *w, int align, c - * Returns: Flag, true only if rest of Words on line should be ignored. - *=======================================================================*/ - --static int cmd_tcn (Word *w, int align, char has_param, int param) { -- process_toc_entry (w, FALSE); -- return TRUE; -+static int cmd_tcn (const struct OutputContext *oc, Word *w, int align, char has_param, int param) { -+ process_toc_entry (oc, w, FALSE); -+ return TRUE; - } - - - typedef struct { -- char *name; -- int (*func)(Word*, int, char, int); -- char *debug_print; --} HashItem; -+ char *name; -+ int (*func)(const struct OutputContext *, Word*, int, char, int); -+ char *debug_print; -+} CmdHashItem; - - - /* All of the possible commands that RTF might recognize. */ --static HashItem hashArray_other [] = { -- { "*", cmd_ignore, NULL }, -- { "-", cmd_optional_hyphen, "optional hyphen" }, -- { "_", cmd_nonbreaking_hyphen, "nonbreaking hyphen" }, -- { "~", cmd_nonbreaking_space, NULL }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_other [] = { -+ { "*", cmd_ignore, NULL }, -+ { "-", cmd_optional_hyphen, "optional hyphen" }, -+ { "_", cmd_nonbreaking_hyphen, "nonbreaking hyphen" }, -+ { "~", cmd_nonbreaking_space, NULL }, -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_a [] = { -- { "ansi", &cmd_ansi , NULL }, -- { "ansicpg", &cmd_ansicpg , NULL }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_a [] = { -+ { "ansi", &cmd_ansi , NULL }, -+ { "ansicpg", &cmd_ansicpg , NULL }, -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_b [] = { -- { "b", &cmd_b, NULL }, -- { "bullet", &cmd_bullet, NULL }, -- { "bin", &cmd_bin, "picture is binary" }, -+static CmdHashItem hashArray_b [] = { -+ { "b", &cmd_b, NULL }, -+ { "bullet", &cmd_bullet, NULL }, -+ { "bin", &cmd_bin, "picture is binary" }, - #if 0 -- { "bgbdiag", NULL, NULL }, -- { "bgcross", NULL, NULL }, -- { "bgdcross", NULL, NULL }, -- { "bgfdiag", NULL, NULL }, -- { "bghoriz", NULL, NULL }, -- { "bgkbdiag", NULL, NULL }, -- { "bgkcross", NULL, NULL }, -- { "bgkdcross", NULL, NULL }, -- { "bgkfdiag", NULL, NULL }, -- { "bgkhoriz", NULL, NULL }, -- { "bgkvert", NULL, NULL }, -- { "bgvert", NULL, NULL }, -- { "brdrcf", NULL, NULL }, -- { "brdrdb", NULL, NULL }, -- { "brdrdot", NULL, NULL }, -- { "brdrhair", NULL, NULL }, -- { "brdrs", NULL, NULL }, -- { "brdrsh", NULL, NULL }, -- { "brdrth", NULL, NULL }, -- { "brdrw", NULL, NULL }, -+ { "bgbdiag", NULL, NULL }, -+ { "bgcross", NULL, NULL }, -+ { "bgdcross", NULL, NULL }, -+ { "bgfdiag", NULL, NULL }, -+ { "bghoriz", NULL, NULL }, -+ { "bgkbdiag", NULL, NULL }, -+ { "bgkcross", NULL, NULL }, -+ { "bgkdcross", NULL, NULL }, -+ { "bgkfdiag", NULL, NULL }, -+ { "bgkhoriz", NULL, NULL }, -+ { "bgkvert", NULL, NULL }, -+ { "bgvert", NULL, NULL }, -+ { "brdrcf", NULL, NULL }, -+ { "brdrdb", NULL, NULL }, -+ { "brdrdot", NULL, NULL }, -+ { "brdrhair", NULL, NULL }, -+ { "brdrs", NULL, NULL }, -+ { "brdrsh", NULL, NULL }, -+ { "brdrth", NULL, NULL }, -+ { "brdrw", NULL, NULL }, - #endif -- { NULL, NULL, NULL} -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_c [] = { -- { "caps", &cmd_caps, NULL }, -- { "cb", cmd_cb, NULL }, -- { "cf", cmd_cf, NULL }, -- { "colortbl", &cmd_colortbl, "color table" }, -- { "cols", NULL, "columns (not implemented)" }, -- { "column", NULL, "column break (not implemented)" }, -- { "cbpat", NULL, "Paragraph Shading" }, -- { "cellx", NULL, "Table Definitions" }, -- { "cfpat", NULL, NULL }, -- { "cgrid", NULL, NULL }, -- { "charrsid", NULL, "Revision Mark (ignore)" }, -- { "clbgbcross", NULL, NULL }, -- { "clbgbdiag", NULL, NULL }, -- { "clbgbkbdiag", NULL, NULL }, -- { "clbgbkcross", NULL, NULL }, -- { "clbgbkdcross", NULL, NULL }, -- { "clbgbkfdiag", NULL, NULL }, -- { "clbgbkhor", NULL, NULL }, -- { "clbgbkvert", NULL, NULL }, -- { "clbgdcross", NULL, NULL }, -- { "clbgfdiag", NULL, NULL }, -- { "clbghoriz", NULL, NULL }, -- { "clbgvert", NULL, NULL }, -- { "clbrdrb", NULL, NULL }, -- { "clbrdrl", NULL, NULL }, -- { "clbrdrr", NULL, NULL }, -- { "clbrdrt", NULL, NULL }, -- { "clcbpat", NULL, NULL }, -- { "clcfpat", NULL, NULL }, -- { "clmgf", NULL, NULL }, -- { "clmrg", NULL, NULL }, -- { "clshdng", NULL, NULL }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_c [] = { -+ { "caps", &cmd_caps, NULL }, -+ { "cb", cmd_cb, NULL }, -+ { "cf", cmd_cf, NULL }, -+ { "colortbl", &cmd_colortbl, "color table" }, -+ { "cols", NULL, "columns (not implemented)" }, -+ { "column", NULL, "column break (not implemented)" }, -+ { "cbpat", NULL, "Paragraph Shading" }, -+ { "cellx", NULL, "Table Definitions" }, -+ { "cfpat", NULL, NULL }, -+ { "cgrid", NULL, NULL }, -+ { "charrsid", NULL, "Revision Mark (ignore)" }, -+ { "clbgbcross", NULL, NULL }, -+ { "clbgbdiag", NULL, NULL }, -+ { "clbgbkbdiag", NULL, NULL }, -+ { "clbgbkcross", NULL, NULL }, -+ { "clbgbkdcross", NULL, NULL }, -+ { "clbgbkfdiag", NULL, NULL }, -+ { "clbgbkhor", NULL, NULL }, -+ { "clbgbkvert", NULL, NULL }, -+ { "clbgdcross", NULL, NULL }, -+ { "clbgfdiag", NULL, NULL }, -+ { "clbghoriz", NULL, NULL }, -+ { "clbgvert", NULL, NULL }, -+ { "clbrdrb", NULL, NULL }, -+ { "clbrdrl", NULL, NULL }, -+ { "clbrdrr", NULL, NULL }, -+ { "clbrdrt", NULL, NULL }, -+ { "clcbpat", NULL, NULL }, -+ { "clcfpat", NULL, NULL }, -+ { "clmgf", NULL, NULL }, -+ { "clmrg", NULL, NULL }, -+ { "clshdng", NULL, NULL }, -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_d [] = { -- { "deff", NULL, "Default Font" }, -- { "dn", &cmd_dn, NULL }, -+static CmdHashItem hashArray_d [] = { -+ { "deff", NULL, "Default Font" }, -+ { "dn", &cmd_dn, NULL }, - #if 0 -- { "dibitmap", NULL, NULL }, -+ { "dibitmap", NULL, NULL }, - #endif -- { NULL, NULL, NULL} -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_e [] = { -- { "emdash", cmd_emdash, NULL }, -- { "endash", cmd_endash, NULL }, -- { "embo", &cmd_emboss, NULL }, -- { "expand", &cmd_expand, NULL }, -- { "expnd", &cmd_expand, NULL }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_e [] = { -+ { "emdash", cmd_emdash, NULL }, -+ { "endash", cmd_endash, NULL }, -+ { "embo", &cmd_emboss, NULL }, -+ { "expand", &cmd_expand, NULL }, -+ { "expnd", &cmd_expand, NULL }, -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_f [] = { -- { "f", cmd_f, NULL }, -- { "fdecor", cmd_fdecor, NULL }, -- { "fmodern", cmd_fmodern, NULL }, -- { "fnil", cmd_fnil, NULL }, -- { "fonttbl", cmd_fonttbl, "font table" }, -- { "froman", cmd_froman, NULL }, -- { "fs", cmd_fs, NULL }, -- { "fscript", cmd_fscript, NULL }, -- { "fswiss", cmd_fswiss, NULL }, -- { "ftech", cmd_ftech, NULL }, -- { "field", cmd_field, NULL }, -- { "footer", cmd_footer, NULL }, -- { "footerf", cmd_footerf, NULL }, -- { "footerl", cmd_footerl, NULL }, -- { "footerr", cmd_footerr, NULL }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_f [] = { -+ { "f", cmd_f, NULL }, -+ { "fdecor", cmd_fdecor, NULL }, -+ { "fmodern", cmd_fmodern, NULL }, -+ { "fnil", cmd_fnil, NULL }, -+ { "fonttbl", cmd_fonttbl, "font table" }, -+ { "froman", cmd_froman, NULL }, -+ { "fs", cmd_fs, NULL }, -+ { "fscript", cmd_fscript, NULL }, -+ { "fswiss", cmd_fswiss, NULL }, -+ { "ftech", cmd_ftech, NULL }, -+ { "field", cmd_field, NULL }, -+ { "footer", cmd_footer, NULL }, -+ { "footerf", cmd_footerf, NULL }, -+ { "footerl", cmd_footerl, NULL }, -+ { "footerr", cmd_footerr, NULL }, -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_h [] = { -- { "highlight", &cmd_highlight, NULL }, -- { "header", cmd_header, NULL }, -- { "headerf", cmd_headerf, NULL }, -- { "headerl", cmd_headerl, NULL }, -- { "headerr", cmd_headerr, NULL }, -- { "hl", cmd_ignore, "hyperlink within object" }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_h [] = { -+ { "highlight", &cmd_highlight, NULL }, -+ { "header", cmd_header, NULL }, -+ { "headerf", cmd_headerf, NULL }, -+ { "headerl", cmd_headerl, NULL }, -+ { "headerr", cmd_headerr, NULL }, -+ { "hl", cmd_ignore, "hyperlink within object" }, -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_i [] = { -- { "i", &cmd_i, NULL }, -- { "info", &cmd_info, NULL }, -- { "insrsid", NULL, "Revision Mark (ignore)" }, -- { "intbl", &cmd_intbl, NULL }, -- { "impr", &cmd_engrave, NULL }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_i [] = { -+ { "i", &cmd_i, NULL }, -+ { "info", &cmd_info, NULL }, -+ { "insrsid", NULL, "Revision Mark (ignore)" }, -+ { "intbl", &cmd_intbl, NULL }, -+ { "impr", &cmd_engrave, NULL }, -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_j [] = { -- { "jpegblip", &cmd_jpegblip, NULL }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_j [] = { -+ { "jpegblip", &cmd_jpegblip, NULL }, -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_l [] = { -- { "ldblquote", &cmd_ldblquote, NULL }, -- { "line", &cmd_line, NULL }, -- { "lquote", &cmd_lquote, NULL }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_l [] = { -+ { "ldblquote", &cmd_ldblquote, NULL }, -+ { "line", &cmd_line, NULL }, -+ { "lquote", &cmd_lquote, NULL }, -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_m [] = { -- { "mac", &cmd_mac , NULL }, -- { "macpict", &cmd_macpict, NULL }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_m [] = { -+ { "mac", &cmd_mac , NULL }, -+ { "macpict", &cmd_macpict, NULL }, -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_n [] = { -- { "nosupersub", &cmd_nosupersub, NULL }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_n [] = { -+ { "nosupersub", &cmd_nosupersub, NULL }, -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_o [] = { -- { "outl", &cmd_outl, NULL }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_o [] = { -+ { "outl", &cmd_outl, NULL }, -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_p [] = { -- { "page", &cmd_page, NULL }, -- { "par", &cmd_par, NULL }, -- { "pc", &cmd_pc , NULL }, -- { "pca", &cmd_pca , NULL }, -- { "pich", &cmd_pich, NULL }, -- { "pict", &cmd_pict, "picture" }, -- { "picw", &cmd_picw, NULL }, -- { "plain", &cmd_plain, NULL }, -- { "pngblip", &cmd_pngblip, NULL }, -- { "pnmetafile", &cmd_pnmetafile, NULL }, -+static CmdHashItem hashArray_p [] = { -+ { "page", &cmd_page, NULL }, -+ { "par", &cmd_par, NULL }, -+ { "pc", &cmd_pc , NULL }, -+ { "pca", &cmd_pca , NULL }, -+ { "pich", &cmd_pich, NULL }, -+ { "pict", &cmd_pict, "picture" }, -+ { "picw", &cmd_picw, NULL }, -+ { "plain", &cmd_plain, NULL }, -+ { "pngblip", &cmd_pngblip, NULL }, -+ { "pnmetafile", &cmd_pnmetafile, NULL }, - #if 0 -- { "piccropb", NULL, NULL }, -- { "piccropl", NULL, NULL }, -- { "piccropr", NULL, NULL }, -- { "piccropt", NULL, NULL }, -- { "pichgoal", NULL, NULL }, -- { "pichgoal", NULL, NULL }, -- { "picscaled", NULL, NULL }, -- { "picscalex", NULL, NULL }, -- { "picwgoal", NULL, NULL }, -+ { "piccropb", NULL, NULL }, -+ { "piccropl", NULL, NULL }, -+ { "piccropr", NULL, NULL }, -+ { "piccropt", NULL, NULL }, -+ { "pichgoal", NULL, NULL }, -+ { "pichgoal", NULL, NULL }, -+ { "picscaled", NULL, NULL }, -+ { "picscalex", NULL, NULL }, -+ { "picwgoal", NULL, NULL }, - #endif -- { NULL, NULL, NULL} -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_r [] = { -- { "rdblquote", &cmd_rdblquote, NULL }, -- { "rquote", &cmd_rquote, NULL }, -- { "rtf", &cmd_rtf, NULL }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_r [] = { -+ { "rdblquote", &cmd_rdblquote, NULL }, -+ { "rquote", &cmd_rquote, NULL }, -+ { "rtf", &cmd_rtf, NULL }, -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_s [] = { -- { "s", cmd_s, "style" }, -- { "sect", &cmd_sect, "section break"}, -- { "scaps", &cmd_scaps, NULL }, -- { "super", &cmd_super, NULL }, -- { "sub", &cmd_sub, NULL }, -- { "shad", &cmd_shad, NULL }, -- { "strike", &cmd_strike, NULL }, -- { "striked", &cmd_striked, NULL }, -- { "strikedl", &cmd_strikedl, NULL }, -- { "stylesheet", &cmd_ignore, "style sheet" }, -- { "shp", cmd_shp, "drawn shape" }, -+static CmdHashItem hashArray_s [] = { -+ { "s", cmd_s, "style" }, -+ { "sect", &cmd_sect, "section break"}, -+ { "scaps", &cmd_scaps, NULL }, -+ { "super", &cmd_super, NULL }, -+ { "sub", &cmd_sub, NULL }, -+ { "shad", &cmd_shad, NULL }, -+ { "strike", &cmd_strike, NULL }, -+ { "striked", &cmd_striked, NULL }, -+ { "strikedl", &cmd_strikedl, NULL }, -+ { "stylesheet", &cmd_ignore, "style sheet" }, -+ { "shp", cmd_shp, "drawn shape" }, - #if 0 -- { "shading", NULL, NULL }, -+ { "shading", NULL, NULL }, - #endif -- { NULL, NULL, NULL} -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_t [] = { -- { "tab", &cmd_tab, NULL }, -- { "tc", cmd_tc, "TOC entry" }, -- { "tcn", cmd_tcn, "TOC entry" }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_t [] = { -+ { "tab", &cmd_tab, NULL }, -+ { "tc", cmd_tc, "TOC entry" }, -+ { "tcn", cmd_tcn, "TOC entry" }, -+ { NULL, NULL, NULL} - }; --static HashItem hashArray_u [] = { -- { "u", &cmd_u, NULL }, -- { "ul", &cmd_ul, NULL }, -- { "up", &cmd_up, NULL }, -- { "uld", &cmd_uld, NULL }, -- { "uldash", &cmd_uldash, NULL }, -- { "uldashd", &cmd_uldashd, NULL }, -- { "uldashdd", &cmd_uldashdd, NULL }, -- { "uldb", &cmd_uldb, NULL }, -- { "ulnone", &cmd_ulnone, NULL }, -- { "ulth", &cmd_ulth, NULL }, -- { "ulthd", &cmd_ulthd, NULL }, -- { "ulthdash", &cmd_ulthdash, NULL }, -- { "ulw", &cmd_ulw, NULL }, -- { "ulwave", &cmd_ulwave, NULL }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_u [] = { -+ { "u", &cmd_u, NULL }, -+ { "ul", &cmd_ul, NULL }, -+ { "up", &cmd_up, NULL }, -+ { "uld", &cmd_uld, NULL }, -+ { "uldash", &cmd_uldash, NULL }, -+ { "uldashd", &cmd_uldashd, NULL }, -+ { "uldashdd", &cmd_uldashdd, NULL }, -+ { "uldb", &cmd_uldb, NULL }, -+ { "ulnone", &cmd_ulnone, NULL }, -+ { "ulth", &cmd_ulth, NULL }, -+ { "ulthd", &cmd_ulthd, NULL }, -+ { "ulthdash", &cmd_ulthdash, NULL }, -+ { "ulw", &cmd_ulw, NULL }, -+ { "ulwave", &cmd_ulwave, NULL }, -+ { NULL, NULL, NULL} - }; - --static HashItem hashArray_v [] = { -- { "v", NULL, "Hidden Text" }, -- { NULL, NULL, NULL } -+static CmdHashItem hashArray_v [] = { -+ { "v", NULL, "Hidden Text" }, -+ { NULL, NULL, NULL } - }; - --static HashItem hashArray_w [] = { -- { "wbmbitspixel", &cmd_wbmbitspixel, NULL }, -- { "wmetafile", &cmd_wmetafile, NULL }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_w [] = { -+ { "wbmbitspixel", &cmd_wbmbitspixel, NULL }, -+ { "wmetafile", &cmd_wmetafile, NULL }, -+ { NULL, NULL, NULL} - }; - --static HashItem hashArray_x [] = { -- { "xe", cmd_xe, "index entry" }, -- { NULL, NULL, NULL} -+static CmdHashItem hashArray_x [] = { -+ { "xe", cmd_xe, "index entry" }, -+ { NULL, NULL, NULL} - }; - --static HashItem *hash [26] = { -- hashArray_a, -- hashArray_b, -- hashArray_c, -- hashArray_d, -- hashArray_e, -- hashArray_f, -- NULL, -- hashArray_h, -- hashArray_i, -- hashArray_j, -- NULL, -- hashArray_l, -- hashArray_m, -- hashArray_n, -- hashArray_o, -- hashArray_p, -- NULL, -- hashArray_r, -- hashArray_s, -- hashArray_t, -- hashArray_u, -- hashArray_v, -- hashArray_w, -- hashArray_x, -- NULL, NULL -+static CmdHashItem *hash [26] = { -+ hashArray_a, -+ hashArray_b, -+ hashArray_c, -+ hashArray_d, -+ hashArray_e, -+ hashArray_f, -+ NULL, -+ hashArray_h, -+ hashArray_i, -+ hashArray_j, -+ NULL, -+ hashArray_l, -+ hashArray_m, -+ hashArray_n, -+ hashArray_o, -+ hashArray_p, -+ NULL, -+ hashArray_r, -+ hashArray_s, -+ hashArray_t, -+ hashArray_u, -+ hashArray_v, -+ hashArray_w, -+ hashArray_x, -+ NULL, NULL - }; - - -@@ -3038,53 +3037,56 @@ static HashItem *hash [26] = { - *=======================================================================*/ - - void --print_with_special_exprs (char *s) { -- int ch; -- int state; -+print_with_special_exprs (const struct OutputContext *oc, char *s) { -+ int ch; -+ int state; -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; - --enum { SMALL=0, BIG=1 }; -+ enum { SMALL=0, BIG=1 }; - -- CHECK_PARAM_NOT_NULL(s); -+ CHECK_PARAM_NOT_NULL(s); - -- state=SMALL; /* Pacify gcc, st001906 - 0.19.6 */ -- if (simulate_smallcaps) { -- if (*s >= 'a' && *s <= 'z') { -- state=SMALL; -- if (safe_printf(0, op->smaller_begin)) fprintf(stderr, TOO_MANY_ARGS, "smaller_begin"); -- } -- else -- state=BIG; -- } -+ state=SMALL; /* Pacify gcc, st001906 - 0.19.6 */ -+ if (oc->conversion->simulate_smallcaps) { -+ if (*s >= 'a' && *s <= 'z') { -+ state=SMALL; -+ if (safe_printf(device, 0, oc->personality->smaller_begin)) fprintf(stderr, TOO_MANY_ARGS, "smaller_begin"); -+ } -+ else -+ state=BIG; -+ } - -- while ((ch=*s)) { -- char *post_trans = NULL; -+ while ((ch=*s)) { -+ char *post_trans = NULL; - -- if (simulate_allcaps || simulate_smallcaps) -- ch = toupper (ch); -+ if (oc->conversion->simulate_allcaps || oc->conversion->simulate_smallcaps) -+ ch = toupper (ch); - -- if (ch >= 0x20 && ch < 0x80) { -- post_trans = op_translate_char (op, desc, ch); -- if(post_trans) -- printf("%s",post_trans); -- } -+ if (ch >= 0x20 && ch < 0x80) { -+ post_trans = op_translate_char (oc->conversion, oc->personality, ch); -+ if(post_trans) { -+ safe_printf(device, 0, post_trans); -+ free(post_trans); -+ } -+ } - -- s++; -+ s++; - -- if (simulate_smallcaps) { -- ch = *s; -- if (ch >= 'a' && ch <= 'z') { -- if (state==BIG) -- if (safe_printf(0, op->smaller_begin)) fprintf(stderr, TOO_MANY_ARGS, "smaller_begin"); -- state=SMALL; -- } -- else -- { -- if (state==SMALL) -- if (safe_printf(0, op->smaller_end)) fprintf(stderr, TOO_MANY_ARGS, "smaller_end"); -- state=BIG; -- } -- } -- } -+ if (oc->conversion->simulate_smallcaps) { -+ ch = *s; -+ if (ch >= 'a' && ch <= 'z') { -+ if (state==BIG) -+ if (safe_printf(device, 0, oc->personality->smaller_begin)) fprintf(stderr, TOO_MANY_ARGS, "smaller_begin"); -+ state=SMALL; -+ } -+ else -+ { -+ if (state==SMALL) -+ if (safe_printf(device, 0, oc->personality->smaller_end)) fprintf(stderr, TOO_MANY_ARGS, "smaller_end"); -+ state=BIG; -+ } -+ } -+ } - } - - -@@ -3097,16 +3099,18 @@ enum { SMALL=0, BIG=1 }; - *=======================================================================*/ - - static void --begin_table() -+begin_table(const struct OutputContext *oc) - { -- within_table=TRUE; -- have_printed_row_begin = FALSE; -- have_printed_cell_begin = FALSE; -- have_printed_row_end = FALSE; -- have_printed_cell_end = FALSE; -- attrstack_push(); -- starting_body(); -- if (safe_printf(0, op->table_begin)) fprintf(stderr, TOO_MANY_ARGS, "table_begin"); -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ oc->conversion->within_table=TRUE; -+ oc->conversion->have_printed_row_begin = FALSE; -+ oc->conversion->have_printed_cell_begin = FALSE; -+ oc->conversion->have_printed_row_end = FALSE; -+ oc->conversion->have_printed_cell_end = FALSE; -+ attrstack_push(oc->conversion); -+ starting_body(oc); -+ if (safe_printf(device, 0, oc->personality->table_begin)) fprintf(stderr, TOO_MANY_ARGS, "table_begin"); - } - - -@@ -3119,23 +3123,25 @@ begin_table() - *=======================================================================*/ - - void --end_table () -+end_table (const struct OutputContext *oc) - { -- if (within_table) { -- if (!have_printed_cell_end) { -- attr_pop_dump(); -- if (safe_printf(0, op->table_cell_end)) fprintf(stderr, TOO_MANY_ARGS, "table_cell_end"); -- } -- if (!have_printed_row_end) { -- if (safe_printf(0, op->table_row_end)) fprintf(stderr, TOO_MANY_ARGS, "table_row_end"); -- } -- if (safe_printf(0, op->table_end)) fprintf(stderr, TOO_MANY_ARGS, "table_end"); -- within_table=FALSE; -- have_printed_row_begin = FALSE; -- have_printed_cell_begin = FALSE; -- have_printed_row_end = FALSE; -- have_printed_cell_end = FALSE; -- } -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->conversion->within_table) { -+ if (!oc->conversion->have_printed_cell_end) { -+ attr_pop_dump(); -+ if (safe_printf(device, 0, oc->personality->table_cell_end)) fprintf(stderr, TOO_MANY_ARGS, "table_cell_end"); -+ } -+ if (!oc->conversion->have_printed_row_end) { -+ if (safe_printf(device, 0, oc->personality->table_row_end)) fprintf(stderr, TOO_MANY_ARGS, "table_row_end"); -+ } -+ if (safe_printf(device, 0, oc->personality->table_end)) fprintf(stderr, TOO_MANY_ARGS, "table_end"); -+ oc->conversion->within_table=FALSE; -+ oc->conversion->have_printed_row_begin = FALSE; -+ oc->conversion->have_printed_cell_begin = FALSE; -+ oc->conversion->have_printed_row_end = FALSE; -+ oc->conversion->have_printed_cell_end = FALSE; -+ } - } - - -@@ -3148,21 +3154,23 @@ end_table () - *=======================================================================*/ - - void --starting_text() { -- if (within_table) { -- if (!have_printed_row_begin) { -- if (safe_printf(0, op->table_row_begin)) fprintf(stderr, TOO_MANY_ARGS, "table_row_begin"); -- have_printed_row_begin=TRUE; -- have_printed_row_end=FALSE; -- have_printed_cell_begin=FALSE; -- } -- if (!have_printed_cell_begin) { -- if (safe_printf(0, op->table_cell_begin)) fprintf(stderr, TOO_MANY_ARGS, "table_cell_begin"); -- attrstack_express_all(); -- have_printed_cell_begin=TRUE; -- have_printed_cell_end=FALSE; -- } -- } -+starting_text(const struct OutputContext *oc) { -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ if (oc->conversion->within_table) { -+ if (!oc->conversion->have_printed_row_begin) { -+ if (safe_printf(device, 0, oc->personality->table_row_begin)) fprintf(stderr, TOO_MANY_ARGS, "table_row_begin"); -+ oc->conversion->have_printed_row_begin=TRUE; -+ oc->conversion->have_printed_row_end=FALSE; -+ oc->conversion->have_printed_cell_begin=FALSE; -+ } -+ if (!oc->conversion->have_printed_cell_begin) { -+ if (safe_printf(device, 0, oc->personality->table_cell_begin)) fprintf(stderr, TOO_MANY_ARGS, "table_cell_begin"); -+ attrstack_express_all(); -+ oc->conversion->have_printed_cell_begin=TRUE; -+ oc->conversion->have_printed_cell_end=FALSE; -+ } -+ } - } - - -@@ -3176,25 +3184,27 @@ starting_text() { - *=======================================================================*/ - - static void --starting_paragraph_align (int align) -+starting_paragraph_align (const struct OutputContext *oc, int align) - { -- if (within_header && align != ALIGN_LEFT) -- starting_body(); -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; - -- switch (align) -- { -- case ALIGN_CENTER: -- if (safe_printf(0, op->center_begin)) fprintf(stderr, TOO_MANY_ARGS, "center_begin"); -- break; -- case ALIGN_LEFT: -- break; -- case ALIGN_RIGHT: -- if (safe_printf(0, op->align_right_begin)) fprintf(stderr, TOO_MANY_ARGS, "align_right_begin"); -- break; -- case ALIGN_JUSTIFY: -- if (safe_printf(0, op->justify_begin)) fprintf(stderr, TOO_MANY_ARGS, "justify_begin"); /* But this is correct */ -- break; -- } -+ if (oc->conversion->within_header && align != ALIGN_LEFT) -+ starting_body(oc); -+ -+ switch (align) -+ { -+ case ALIGN_CENTER: -+ if (safe_printf(device, 0, oc->personality->center_begin)) fprintf(stderr, TOO_MANY_ARGS, "center_begin"); -+ break; -+ case ALIGN_LEFT: -+ break; -+ case ALIGN_RIGHT: -+ if (safe_printf(device, 0, oc->personality->align_right_begin)) fprintf(stderr, TOO_MANY_ARGS, "align_right_begin"); -+ break; -+ case ALIGN_JUSTIFY: -+ if (safe_printf(device, 0, oc->personality->justify_begin)) fprintf(stderr, TOO_MANY_ARGS, "justify_begin"); /* But this is correct */ -+ break; -+ } - } - - -@@ -3207,21 +3217,23 @@ starting_paragraph_align (int align) - *=======================================================================*/ - - static void --ending_paragraph_align (int align) -+ending_paragraph_align (const struct OutputContext *oc, int align) - { -- switch (align) { -- case ALIGN_CENTER: -- if (safe_printf(0, op->center_end)) fprintf(stderr, TOO_MANY_ARGS, "center_end"); -- break; -- case ALIGN_LEFT: -- break; -- case ALIGN_RIGHT: -- if (safe_printf(0, op->align_right_end)) fprintf(stderr, TOO_MANY_ARGS, "align_right_end"); -- break; -- case ALIGN_JUSTIFY: -- if (safe_printf(0, op->justify_end)) fprintf(stderr, TOO_MANY_ARGS, "justify_end"); -- break; -- } -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; -+ -+ switch (align) { -+ case ALIGN_CENTER: -+ if (safe_printf(device, 0, oc->personality->center_end)) fprintf(stderr, TOO_MANY_ARGS, "center_end"); -+ break; -+ case ALIGN_LEFT: -+ break; -+ case ALIGN_RIGHT: -+ if (safe_printf(device, 0, oc->personality->align_right_end)) fprintf(stderr, TOO_MANY_ARGS, "align_right_end"); -+ break; -+ case ALIGN_JUSTIFY: -+ if (safe_printf(device, 0, oc->personality->justify_end)) fprintf(stderr, TOO_MANY_ARGS, "justify_end"); -+ break; -+ } - } - - -@@ -3234,411 +3246,411 @@ ending_paragraph_align (int align) - *=======================================================================*/ - - static void --word_print_core (Word *w) -+word_print_core (const struct OutputContext *oc, Word *w) - { -- char *s; -- FILE *pictfile=NULL; -- int is_cell_group=FALSE; -- int paragraph_begined=FALSE; -- int paragraph_align=ALIGN_LEFT; -+ char *s; -+ FILE *pictfile=NULL; -+ int is_cell_group=FALSE; -+ int paragraph_begined=FALSE; -+ int paragraph_align=ALIGN_LEFT; -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; - -- CHECK_PARAM_NOT_NULL(w); -+ CHECK_PARAM_NOT_NULL(w); - -- if (!coming_pars_that_are_tabular && within_table) { -- end_table(); -- } -- else if (coming_pars_that_are_tabular && !within_table) { -- begin_table(); -- } -+ if (!oc->conversion->coming_pars_that_are_tabular && oc->conversion->within_table) { -+ end_table(oc); -+ } -+ else if (oc->conversion->coming_pars_that_are_tabular && !oc->conversion->within_table) { -+ begin_table(oc); -+ } - -- /* Mark our place in the stack */ -- attrstack_push(); -+ /* Mark our place in the stack */ -+ attrstack_push(oc->conversion); - -- while (w) { -+ while (w) { - -- s = word_string (w); -+ s = word_string (oc->conversion, w); - -- if (s) { -+ if (s) { - -- /*--Ignore whitespace in header--------------------*/ -- if (*s==' ' && within_header) { -- /* no op */ -- } -- else -- /*--Handle word -----------------------------------*/ -- if (s[0] != '\\') -- { -- starting_body(); -- starting_text(); -+ /*--Ignore whitespace in header--------------------*/ -+ if (*s==' ' && oc->conversion->within_header) { -+ /* no op */ -+ } -+ else -+ /*--Handle word -----------------------------------*/ -+ if (s[0] != '\\') -+ { -+ starting_body(oc); -+ starting_text(oc); - -- if (!paragraph_begined) { -- starting_paragraph_align (paragraph_align); -- paragraph_begined=TRUE; -- } -+ if (!paragraph_begined) { -+ starting_paragraph_align (oc, paragraph_align); -+ paragraph_begined=TRUE; -+ } - -- /*----------------------------------------*/ -- if (within_picture) { -- starting_body(); -- if (!pictfile && !nopict_mode) { -- char *ext=NULL; -- switch (picture_type) { -- case PICT_WB: ext="bmp"; break; -- case PICT_WM: ext="wmf"; break; -- case PICT_MAC: ext="pict"; break; -- case PICT_JPEG: ext="jpg"; break; -- case PICT_PNG: ext="png"; break; -- case PICT_DI: ext="dib"; break; /* Device independent bitmap=??? */ -- case PICT_PM: ext="pmm"; break; /* OS/2 metafile=??? */ -- } -- sprintf(picture_path, "pict%03d.%s", -- picture_file_number++,ext); -- pictfile=fopen(picture_path,"w"); -- } -+ /*----------------------------------------*/ -+ if (oc->conversion->within_picture) { -+ starting_body(oc); -+ if (!pictfile && !oc->conversion->options->nopict_mode) { -+ char *ext=NULL; -+ switch (oc->conversion->picture_type) { -+ case PICT_WB: ext="bmp"; break; -+ case PICT_WM: ext="wmf"; break; -+ case PICT_MAC: ext="pict"; break; -+ case PICT_JPEG: ext="jpg"; break; -+ case PICT_PNG: ext="png"; break; -+ case PICT_DI: ext="dib"; break; /* Device independent bitmap=??? */ -+ case PICT_PM: ext="pmm"; break; /* OS/2 metafile=??? */ -+ } -+ sprintf(oc->conversion->picture_path, "pict%03d.%s", -+ oc->conversion->picture_file_number++,ext); -+ pictfile=fopen(oc->conversion->picture_path,"w"); -+ } - -- if (s[0]!=' ') { -- char *s2; -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("picture data found, "); -- if (picture_wmetafile_type_str) { -- printf("WMF type is %s, ", -- picture_wmetafile_type_str); -- } -- printf("picture dimensions are %d by %d, depth %d", -- picture_width, picture_height, picture_bits_per_pixel); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- if (picture_width && picture_height && picture_bits_per_pixel) { -- s2=s; -- while (*s2) { -- unsigned int tmp,value; -- tmp=tolower(*s2++); -- if (tmp>'9') tmp-=('a'-10); -- else tmp-='0'; -- value=16*tmp; -- tmp=tolower(*s2++); -- if (tmp>'9') tmp-=('a'-10); -- else tmp-='0'; -- value+=tmp; -- if (pictfile) { -- fprintf(pictfile,"%c", value); -- } -- } -- } -- } -- } -- /*----------------------------------------*/ -- else { -- total_chars_this_line += strlen(s); -+ if (s[0]!=' ') { -+ char *s2; -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("picture data found, "); -+ if (oc->conversion->picture_wmetafile_type_str) { -+ printf("WMF type is %s, ", -+ oc->conversion->picture_wmetafile_type_str); -+ } -+ printf("picture dimensions are %d by %d, depth %d", -+ oc->conversion->picture_width, oc->conversion->picture_height, oc->conversion->picture_bits_per_pixel); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ if (oc->conversion->picture_width && oc->conversion->picture_height && oc->conversion->picture_bits_per_pixel) { -+ s2=s; -+ while (*s2) { -+ unsigned int tmp,value; -+ tmp=tolower(*s2++); -+ if (tmp>'9') tmp-=('a'-10); -+ else tmp-='0'; -+ value=16*tmp; -+ tmp=tolower(*s2++); -+ if (tmp>'9') tmp-=('a'-10); -+ else tmp-='0'; -+ value+=tmp; -+ if (pictfile) { -+ fprintf(pictfile,"%c", value); -+ } -+ } -+ } -+ } -+ } -+ /*----------------------------------------*/ -+ else { -+ oc->conversion->total_chars_this_line += strlen(s); - -- if (op->word_begin) -- if (safe_printf(0, op->word_begin)) fprintf(stderr, TOO_MANY_ARGS, "word_begin"); -+ if (oc->personality->word_begin) -+ if (safe_printf(device, 0, oc->personality->word_begin)) fprintf(stderr, TOO_MANY_ARGS, "word_begin"); - -- print_with_special_exprs (s); -+ print_with_special_exprs (oc, s); - -- if (op->word_end) -- if (safe_printf(0, op->word_end)) fprintf(stderr, TOO_MANY_ARGS, "word_end"); -- } -+ if (oc->personality->word_end) -+ if (safe_printf(device, 0, oc->personality->word_end)) fprintf(stderr, TOO_MANY_ARGS, "word_end"); -+ } - - -- } -- /* output an escaped backslash */ -- /* do we need special handling for latex? */ -- else if (*(s+1) == '\\') -- { -- s++; -- putchar('\\'); -- } -- else if (*(s+1) == '{') -- { -- s++; -- putchar('{'); -- } -- else if (*(s+1) == '}') -- { -- s++; -- putchar('}'); -- } -- /*---Handle RTF keywords---------------------------*/ -- else { -+ } -+ /* output an escaped backslash */ -+ /* do we need special handling for latex? */ -+ else if (*(s+1) == '\\') -+ { -+ s++; -+ putchar('\\'); -+ } -+ else if (*(s+1) == '{') -+ { -+ s++; -+ putchar('{'); -+ } -+ else if (*(s+1) == '}') -+ { -+ s++; -+ putchar('}'); -+ } -+ /*---Handle RTF keywords---------------------------*/ -+ else { - -- int done=FALSE; -- s++; --/*----Paragraph alignment----------------------------------------------------*/ -- if (!strcmp ("ql", s)) -- paragraph_align = ALIGN_LEFT; -- else if (!strcmp ("qr", s)) -- paragraph_align = ALIGN_RIGHT; -- else if (!strcmp ("qj", s)) -- paragraph_align = ALIGN_JUSTIFY; -- else if (!strcmp ("qc", s)) -- paragraph_align = ALIGN_CENTER; -- else if (!strcmp ("pard", s)) -- { -- /* Clear out all font attributes. -- */ -- attr_pop_all(); -+ int done=FALSE; -+ s++; -+ /*----Paragraph alignment----------------------------------------------------*/ -+ if (!strcmp ("ql", s)) -+ paragraph_align = ALIGN_LEFT; -+ else if (!strcmp ("qr", s)) -+ paragraph_align = ALIGN_RIGHT; -+ else if (!strcmp ("qj", s)) -+ paragraph_align = ALIGN_JUSTIFY; -+ else if (!strcmp ("qc", s)) -+ paragraph_align = ALIGN_CENTER; -+ else if (!strcmp ("pard", s)) -+ { -+ /* Clear out all font attributes. -+ */ -+ attr_pop_all(oc); - -- if (coming_pars_that_are_tabular) { -- --coming_pars_that_are_tabular; -- } -+ if (oc->conversion->coming_pars_that_are_tabular) { -+ --oc->conversion->coming_pars_that_are_tabular; -+ } - -- /* Clear out all paragraph attributes. -- */ -- ending_paragraph_align(paragraph_align); -- paragraph_align = ALIGN_LEFT; -- paragraph_begined = FALSE; -- } --/*----Table keywords---------------------------------------------------------*/ -- else -- if (!strcmp (s, "cell")) { -+ /* Clear out all paragraph attributes. -+ */ -+ ending_paragraph_align (oc, paragraph_align); -+ paragraph_align = ALIGN_LEFT; -+ paragraph_begined = FALSE; -+ } -+ /*----Table keywords---------------------------------------------------------*/ -+ else -+ if (!strcmp (s, "cell")) { - -- is_cell_group=TRUE; -- if (!have_printed_cell_begin) { -- /* Need this with empty cells */ -- if (safe_printf(0, op->table_cell_begin)) fprintf(stderr, TOO_MANY_ARGS, "table_cell_begin"); -- attrstack_express_all(); -- } -- attr_pop_dump(); -- if (safe_printf(0, op->table_cell_end)) fprintf(stderr, TOO_MANY_ARGS, "table_cell_end"); -- have_printed_cell_begin = FALSE; -- have_printed_cell_end=TRUE; -- } -- else if (!strcmp (s, "row")) { -+ is_cell_group=TRUE; -+ if (!oc->conversion->have_printed_cell_begin) { -+ /* Need this with empty cells */ -+ if (safe_printf(device, 0, oc->personality->table_cell_begin)) fprintf(stderr, TOO_MANY_ARGS, "table_cell_begin"); -+ attrstack_express_all(); -+ } -+ attr_pop_dump(); -+ if (safe_printf(device, 0, oc->personality->table_cell_end)) fprintf(stderr, TOO_MANY_ARGS, "table_cell_end"); -+ oc->conversion->have_printed_cell_begin = FALSE; -+ oc->conversion->have_printed_cell_end=TRUE; -+ } -+ else if (!strcmp (s, "row")) { - -- if (within_table) { -- if (safe_printf(0, op->table_row_end)) fprintf(stderr, TOO_MANY_ARGS, "table_row_end"); -- have_printed_row_begin = FALSE; -- have_printed_row_end=TRUE; -- } else { -- if (debug_mode) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("end of table row"); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- } -- } -+ if (oc->conversion->within_table) { -+ if (safe_printf(device, 0, oc->personality->table_row_end)) fprintf(stderr, TOO_MANY_ARGS, "table_row_end"); -+ oc->conversion->have_printed_row_begin = FALSE; -+ oc->conversion->have_printed_row_end=TRUE; -+ } else { -+ if (oc->conversion->options->debug_mode) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("end of table row"); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ } -+ } - --/*----Special chars---------------------------------------------------------*/ -- else if (*s == '\'') { -- /* \'XX is a hex char code expression */ -+ /*----Special chars---------------------------------------------------------*/ -+ else if (*s == '\'') { -+ /* \'XX is a hex char code expression */ - -- int ch = h2toi (&s[1]); -- char *s2; -+ int ch = h2toi (&s[1]); -+ char *s2; - - #if 1 /* daved - 0.21.2 */ -- if(ch > h2toi("7f") && ch < h2toi("a1")) -- { -- /* 2 byte char - read 2nd */ -- int ch2; -- char *snext; -- int *doublet; -- w = w->next; -- snext = word_string (w); -- if(*snext == '\\' && *(snext+1) == '\'') -- { -- /* all looks good */ -- ch2 = h2toi(&snext[2]); -+ if(ch > h2toi("7f") && ch < h2toi("a1")) -+ { -+ /* 2 byte char - read 2nd */ -+ int ch2; -+ char *snext; -+ int *doublet; -+ w = w->next; -+ snext = word_string (oc->conversion, w); -+ if(*snext == '\\' && *(snext+1) == '\'') -+ { -+ /* all looks good */ -+ ch2 = h2toi(&snext[2]); - #if 0 -- fprintf(stderr,"ch, ch2 = %o %o\n", ch, ch2); -+ fprintf(stderr,"ch, ch2 = %o %o\n", ch, ch2); - #endif -- doublet = (int *)my_malloc(12); -- *doublet = (int)ch; -- *(doublet+1) = (int)ch2; -- *(doublet+2) = 0; -+ doublet = (int *)unrtf_malloc(12); -+ *doublet = (int)ch; -+ *(doublet+1) = (int)ch2; -+ *(doublet+2) = 0; - #if 0 -- fprintf(stderr, "doublet = %o %o\n", *doublet, *(doublet+1)); -+ fprintf(stderr, "doublet = %o %o\n", *doublet, *(doublet+1)); - #endif -- desc2 = desc; -- desc = my_iconv_open("UTF-8", "SHIFT_JIS"); -+ oc->conversion->desc2 = oc->conversion->desc; -+ oc->conversion->desc = my_iconv_open(oc->conversion, "UTF-8", "SHIFT_JIS"); - #if 1 -- s2 = op_translate_doublet (op, desc, ch, ch2); -+ s2 = op_translate_doublet (oc->conversion, oc->personality, ch, ch2); - #else -- s2 = op_translate_str (op, desc, doublet); -+ s2 = op_translate_str (oc->conversion, oc->personality, doublet); - #endif -- free(doublet); -- desc = my_iconv_close(desc); -- desc = desc2; -- my_iconv_t_make_invalid(&desc2); -- } -- } -- else -+ free(doublet); -+ oc->conversion->desc = my_iconv_close(oc->conversion->desc); -+ oc->conversion->desc = oc->conversion->desc2; -+ my_iconv_t_make_invalid(&oc->conversion->desc2); -+ } -+ } -+ else - #endif --//standard -- s2 = op_translate_char (op, desc, ch); -- if (!s2 || !*s2) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("char 0x%02x",ch); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } else { -- if (op->word_begin) -- if (safe_printf(0, op->word_begin)) fprintf(stderr, TOO_MANY_ARGS, "word_begin"); -- -- printf("%s", s2); -+ //standard -+ s2 = op_translate_char (oc->conversion, oc->personality, ch); -+ if (!s2 || !*s2) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("char 0x%02x",ch); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } else { -+ if (oc->personality->word_begin) -+ if (safe_printf(device, 0, oc->personality->word_begin)) fprintf(stderr, TOO_MANY_ARGS, "word_begin"); - -- if (op->word_end) -- if (safe_printf(0, op->word_end)) fprintf(stderr, TOO_MANY_ARGS, "word_end"); -- } -- } -- else --/*----Search the RTF command hash-------------------------------------------*/ -- { -- int ch; -- int index=0; -- int have_param = FALSE, param = 0; -- HashItem *hip; -- char *p; -- int match = FALSE; /* Pacify gcc, st001906 - 0.19.6 */ -+ printf("%s", s2); - -- /* Look for a parameter */ -- p = s; -- while (*p && (!isdigit(*p) && *p != '-')) p++; -- if (*p && (isdigit(*p) || *p == '-')) { -- have_param = TRUE; -- param = atoi(p); -- } -+ if (oc->personality->word_end) -+ if (safe_printf(device, 0, oc->personality->word_end)) fprintf(stderr, TOO_MANY_ARGS, "word_end"); -+ } -+ } -+ else -+ /*----Search the RTF command hash-------------------------------------------*/ -+ { -+ int ch; -+ int index=0; -+ int have_param = FALSE, param = 0; -+ CmdHashItem *hip; -+ char *p; -+ int match = FALSE; /* Pacify gcc, st001906 - 0.19.6 */ - -- /* Generate a hash index */ -- ch = tolower(*s); -- if (ch >= 'a' && ch <= 'z') -- hip = hash[ch - 'a']; -- else -- hip = hashArray_other; -+ /* Look for a parameter */ -+ p = s; -+ while (*p && (!isdigit(*p) && *p != '-')) p++; -+ if (*p && (isdigit(*p) || *p == '-')) { -+ have_param = TRUE; -+ param = atoi(p); -+ } - -- if (!hip) { -- if (debug_mode) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("Unfamiliar RTF command: %s (HashIndex not found)", s); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- } -- else { -- while (!done) { -- match = FALSE; -+ /* Generate a hash index */ -+ ch = tolower(*s); -+ if (ch >= 'a' && ch <= 'z') -+ hip = hash[ch - 'a']; -+ else -+ hip = hashArray_other; - -- if (have_param) { -- int len=p-s; -- if (!hip[index].name[len] && !strncmp(s, hip[index].name, len)) -- match = TRUE; -- } -- else -- match = !strcmp(s, hip[index].name); -+ if (!hip) { -+ if (oc->conversion->options->debug_mode) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("Unfamiliar RTF command: %s (HashIndex not found)", s); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ } -+ else { -+ while (!done) { -+ match = FALSE; - -- if (match) { -+ if (have_param) { -+ int len=p-s; -+ if (!hip[index].name[len] && !strncmp(s, hip[index].name, len)) -+ match = TRUE; -+ } -+ else -+ match = !strcmp(s, hip[index].name); - -- char *debug; -- int terminate_group; -+ if (match) { - -- if (hip[index].func) { --//unicode -- terminate_group = hip[index].func (w,paragraph_align, have_param, param); -- /* daved - 0.19.4 - unicode support may need to skip only one word */ -- if (terminate_group == SKIP_ONE_WORD) -- w=w->next; -- else -- if (terminate_group) -- while(w) w=w->next; -- } -+ char *debug; -+ int terminate_group; - -- debug=hip[index].debug_print; -+ if (hip[index].func) { -+ //unicode -+ terminate_group = hip[index].func (oc, w, paragraph_align, have_param, param); -+ /* daved - 0.19.4 - unicode support may need to skip only one word */ -+ if (terminate_group == SKIP_ONE_WORD) -+ w=w->next; -+ else -+ if (terminate_group) -+ while(w) w=w->next; -+ } - -- if (debug && debug_mode) { -- if (safe_printf(0, op->comment_begin)) -- fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("%s", debug); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -+ debug=hip[index].debug_print; - -- done=TRUE; -- } -- else { -- index++; -- if (!hip[index].name) -- done = TRUE; -- } -- } -- } -- if (!match) { -- if (debug_mode) { -- if (safe_printf(0, op->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -- printf("Unfamiliar RTF command: %s", s); -- if (safe_printf(0, op->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -- } -- } -- } -- } --/*-------------------------------------------------------------------------*/ -- } else { -+ if (debug && oc->conversion->options->debug_mode) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) -+ fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("%s", debug); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } - -- Word *child; -+ done=TRUE; -+ } -+ else { -+ index++; -+ if (!hip[index].name) -+ done = TRUE; -+ } -+ } -+ } -+ if (!match) { -+ if (oc->conversion->options->debug_mode) { -+ if (safe_printf(device, 0, oc->personality->comment_begin)) fprintf(stderr, TOO_MANY_ARGS, "comment_begin"); -+ printf("Unfamiliar RTF command: %s", s); -+ if (safe_printf(device, 0, oc->personality->comment_end)) fprintf(stderr, TOO_MANY_ARGS, "comment_end"); -+ } -+ } -+ } -+ } -+ /*-------------------------------------------------------------------------*/ -+ } else { - -- child = w->child; -+ Word *child; - -- if (!paragraph_begined) { -- starting_paragraph_align (paragraph_align); -- paragraph_begined=TRUE; -- } -+ child = w->child; - -- if (child) -- word_print_core (child); -- } -+ if (!paragraph_begined) { -+ starting_paragraph_align (oc, paragraph_align); -+ paragraph_begined=TRUE; -+ } - -- if (w) -- w = w->next; -- } -+ if (child) -+ word_print_core (oc, child); -+ } - -- if (within_picture) { -- if(pictfile) { -- fclose(pictfile); -- if (safe_printf(0, op->imagelink_begin)) fprintf(stderr, TOO_MANY_ARGS, "imagelink_begin"); -- printf("%s", picture_path); -- if (safe_printf(0, op->imagelink_end)) fprintf(stderr, TOO_MANY_ARGS, "imagelink_end"); -- } -- within_picture=FALSE; -- } -+ if (w) -+ w = w->next; -+ } - -- /* Undo font attributes UNLESS we're doing table cells -- * since they would appear between and . -- */ -+ if (oc->conversion->within_picture) { -+ if(pictfile) { -+ fclose(pictfile); -+ if (safe_printf(device, 0, oc->personality->imagelink_begin)) fprintf(stderr, TOO_MANY_ARGS, "imagelink_begin"); -+ printf("%s", oc->conversion->picture_path); -+ if (safe_printf(device, 0, oc->personality->imagelink_end)) fprintf(stderr, TOO_MANY_ARGS, "imagelink_end"); -+ } -+ oc->conversion->within_picture=FALSE; -+ } - -- if (!is_cell_group) -- attr_pop_all(); -- else -- attr_drop_all(); -+ /* Undo font attributes UNLESS we're doing table cells -+ * since they would appear between and . -+ */ - -- /* Undo paragraph alignment -- */ -- if (paragraph_begined) -- ending_paragraph_align (paragraph_align); -+ if (!is_cell_group) -+ attr_pop_all(oc); -+ else -+ attr_drop_all(); - -- attrstack_drop(); -+ /* Undo paragraph alignment -+ */ -+ if (paragraph_begined) -+ ending_paragraph_align (oc, paragraph_align); - -- if((s = attr_get_param(ATTR_FONTFACE)) != NULL && -- strstr(s,"Symbol") != NULL) -- { -- if (!my_iconv_is_valid(desc2)) -- desc2 = desc; -- else -- desc = my_iconv_close(desc); -+ attrstack_drop(oc); - -- desc = my_iconv_open("UTF-8", FONT_SYMBOL); -- } -- else if((s = attr_get_param(ATTR_FONTFACE)) != NULL && -- strstr(s,"Greek") != NULL) -- { -- if (!my_iconv_is_valid(desc2)) -- desc2 = desc; -- else -- desc = my_iconv_close(desc); -+ if((s = attr_get_param(oc->conversion, ATTR_FONTFACE)) != NULL && -+ strstr(s,"Symbol") != NULL) -+ { -+ if (!my_iconv_is_valid(oc->conversion->desc2)) -+ oc->conversion->desc2 = oc->conversion->desc; -+ else -+ oc->conversion->desc = my_iconv_close(oc->conversion->desc); - -- desc = my_iconv_open("UTF-8", FONT_GREEK); -- } -- else -- if (my_iconv_is_valid(desc2)) /* AF - 0.21.0-rc2 */ -- { -- my_iconv_close(desc); -- desc = desc2; -- my_iconv_t_make_invalid(&desc2); -- } -+ oc->conversion->desc = my_iconv_open(oc->conversion, "UTF-8", FONT_SYMBOL); -+ } -+ else if((s = attr_get_param(oc->conversion, ATTR_FONTFACE)) != NULL && -+ strstr(s,"Greek") != NULL) -+ { -+ if (!my_iconv_is_valid(oc->conversion->desc2)) -+ oc->conversion->desc2 = oc->conversion->desc; -+ else -+ oc->conversion->desc = my_iconv_close(oc->conversion->desc); - -+ oc->conversion->desc = my_iconv_open(oc->conversion, "UTF-8", FONT_GREEK); -+ } -+ else -+ if (my_iconv_is_valid(oc->conversion->desc2)) /* AF - 0.21.0-rc2 */ -+ { -+ my_iconv_close(oc->conversion->desc); -+ oc->conversion->desc = oc->conversion->desc2; -+ my_iconv_t_make_invalid(&oc->conversion->desc2); -+ } - } - - -@@ -3652,37 +3664,227 @@ word_print_core (Word *w) - *=======================================================================*/ - - void --word_print (Word *w) -+word_print (const struct OutputContext *oc, Word *w) - { -- CHECK_PARAM_NOT_NULL (w); -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; - -- if (!inline_mode) { -+ CHECK_PARAM_NOT_NULL (w); -+ -+ if (!oc->conversion->options->inline_mode) { - #if 1 /* AK3 - AF */ -- if (safe_printf(0, op->document_begin)) fprintf(stderr, TOO_MANY_ARGS, "document_begin"); -- if (safe_printf(0, op->header_begin)) fprintf(stderr, TOO_MANY_ARGS, "header_begin"); -- if (safe_printf(0, op->utf8_encoding)) fprintf(stderr, TOO_MANY_ARGS, "utf8_encoding"); -+ if (safe_printf(device, 0, oc->personality->document_begin)) fprintf(stderr, TOO_MANY_ARGS, "document_begin"); -+ if (safe_printf(device, 0, oc->personality->header_begin)) fprintf(stderr, TOO_MANY_ARGS, "header_begin"); -+ if (safe_printf(device, 0, oc->personality->utf8_encoding)) fprintf(stderr, TOO_MANY_ARGS, "utf8_encoding"); - #else -- printf(op->document_begin); -- printf(op->header_begin); -+ printf(oc->personality->document_begin); -+ printf(oc->personality->header_begin); - #endif -- } -+ } - -- print_banner (); -+ print_banner (oc); - -- within_header=TRUE; -- have_printed_body=FALSE; -- within_table=FALSE; -- simulate_allcaps=FALSE; -- word_print_core (w); -- end_table(); -+ oc->conversion->within_header=TRUE; -+ oc->conversion->have_printed_body=FALSE; -+ oc->conversion->within_table=FALSE; -+ oc->conversion->simulate_allcaps=FALSE; -+ word_print_core (oc, w); -+ end_table (oc); - -- if (!inline_mode) { -+ if (!oc->conversion->options->inline_mode) { - #if 1 /* AK3 - AF */ -- if (safe_printf(0, op->body_end)) fprintf(stderr, TOO_MANY_ARGS, "body_end"); -- if (safe_printf(0, op->document_end)) fprintf(stderr, TOO_MANY_ARGS, "document_end"); -+ if (safe_printf(device, 0, oc->personality->body_end)) fprintf(stderr, TOO_MANY_ARGS, "body_end"); -+ if (safe_printf(device, 0, oc->personality->document_end)) fprintf(stderr, TOO_MANY_ARGS, "document_end"); - #else -- printf(op->body_end); -- printf(op->document_end); -+ printf(oc->personality->body_end); -+ printf(oc->personality->document_end); - #endif -- } -+ } -+} -+ -+/* public functions */ -+void unrtf_set_output_device (unRTFOptions *options, unrtf_output_device_func output_func, void *output_data) -+{ -+ options->device.print = output_func; -+ options->device.data = output_data; -+} -+ -+/*======================================================================== -+ * Name: main -+ * Purpose: Main control function. -+ * Args: Args. -+ * Returns: Exit code. -+ *=======================================================================*/ -+ -+static int stdout_print(void *null, const char *data, size_t data_len) -+{ -+ return printf ("%s", data); -+} -+ -+static char *format_path(const unRTFOptions *options) -+{ -+ size_t fullname_len; -+ char *fullname; -+ -+ if (!options->output_format || !options->config_directory) -+ return 0; -+ -+ fullname_len = strlen (options->output_format) + strlen (options->config_directory) + 6; -+ fullname = malloc(fullname_len + 1); -+ sprintf (fullname, "%s/%s.conf", options->config_directory, options->output_format); -+ -+ return fullname; -+} -+ -+/* TODO: make use of mmap */ -+int unrtf_convert_from_string (unRTFOptions *options, const char *input_str, size_t input_len) -+{ -+ Word *word; -+ char *path, *env_path_p; -+ ConversionContext cc; -+ OutputContext oc; -+ -+ if (!options) -+ return 0; -+ -+ if (!input_str || !input_len) -+ return 0; -+ -+ if (!options->output_format) -+ options->output_format = DEFAULT_OUTPUT; -+ if (!options->config_directory) -+ { -+ if ((env_path_p = getenv("UNRTF_SEARCH_PATH")) != NULL) -+ { -+ if (options->verbose_mode) -+ fprintf (stderr, "got environment path: %s\n", env_path_p); -+ options->config_directory = env_path_p; -+ } -+ else -+ options->config_directory = DEFAULT_UNRTF_SEARCH_PATH; -+ } -+ -+ path = format_path(options); -+ if (!path) -+ return 0; -+ -+ if (access(path, R_OK) != 0) -+ { -+ free (path); -+ return 0; -+ } -+ -+ if (!options->device.print) -+ unrtf_set_output_device (options, stdout_print, NULL); -+ -+ memset (&cc, 0, sizeof (struct ConversionContext)); -+ -+ hash_init (&cc); -+ -+ cc.read_buf = input_str; -+ cc.read_buf_end = input_len; -+ -+ cc.current_max_length = 1; -+ cc.ungot_char = -1; -+ cc.ungot_char2 = -1; -+ cc.ungot_char3 = -1; -+ -+ cc.picture_file_number=1; -+ cc.picture_bits_per_pixel=1; -+ cc.picture_type = PICT_UNKNOWN; -+ -+ cc.desc.desc = (iconv_t) -1; -+ cc.desc2.desc = (iconv_t) -1; -+ -+ cc.options = options; -+ -+ oc.personality = user_init(&cc, path); -+ oc.conversion = &cc; -+ -+ /* All the work starts here. word_read() should keep reading words until -+ * the end of the file. */ -+ word = word_read(&cc); -+ -+ if (options->dump_mode) { -+ word_dump(&cc, word); -+ printf("\n"); -+ } else { -+ /* Should we also optimize word before dump? - AF */ -+ /* word = optimize_word(oc.conversion, word); */ -+ word_print(&oc, word); -+ } -+ -+ /* marcossamaral - 0.19.9 */ -+ if (options->verbose_mode || options->debug_mode) { -+ unsigned long total=0; -+ total = hash_stats(&cc); -+ fprintf(stderr, "Done.\n"); -+ fprintf(stderr, "%lu words were hashed.\n", total); -+ } -+ -+ if (options->debug_mode) { -+ fprintf(stderr, "Total memory allocated %ld bytes.\n", -+ total_malloced()); -+ } -+ -+ hash_free(&cc); -+ if (cc.input_str) -+ unrtf_free(cc.input_str); -+ word_free(word); -+ fonttable_free(oc.conversion); -+ if (my_iconv_is_valid(oc.conversion->desc)) -+ my_iconv_close(oc.conversion->desc); -+ op_free (oc.personality); -+ free (path); -+ -+ return 1; /* success */ -+} -+ -+int unrtf_convert_from_filename (unRTFOptions *options, const char *filename) -+{ -+ FILE *f; -+ size_t read_len, total_len, max_len; -+ char *content; -+ char buffer[4096]; -+ int is_stdin = 0, rc; -+ -+ if (!filename || strcmp(filename, "-") == 0) -+ { -+ is_stdin = 1; -+ f = stdin; -+ filename = ""; -+ } -+ else -+ { -+ f = fopen (filename, "r"); -+ if (!f) -+ return 0; -+ } -+ -+ if (options->verbose_mode || options->debug_mode) fprintf(stderr, "Processing %s...\n", filename); -+ -+ max_len = 4096; -+ total_len = 0; -+ content = malloc (max_len + 1); -+ do -+ { -+ read_len = fread (buffer, sizeof (char), 4096, f); -+ memcpy (content + total_len, buffer, read_len); -+ total_len += read_len; -+ if (total_len + 4096 > max_len) -+ { -+ max_len = total_len + 4096; -+ content = realloc (content, max_len + 1); -+ } -+ } -+ while (read_len == 4096); -+ -+ if (!is_stdin) -+ fclose (f); -+ -+ content[total_len] = 0; -+ rc = unrtf_convert_from_string (options, content, total_len); -+ -+ free (content); -+ -+ return rc; - } -diff -durpN unrtf-0.21.2.old/src/convert.h unrtf-0.21.2/src/convert.h ---- unrtf-0.21.2.old/src/convert.h 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/convert.h 2013-01-17 02:41:09.685864239 +0100 -@@ -36,18 +36,135 @@ - - #ifndef _CONVERT - -+#include "my_iconv.h" -+ - enum { -- CHARSET_ANSI=1, -- CHARSET_MAC, -- CHARSET_CP437, -- CHARSET_CP850, -+ CHARSET_ANSI=1, -+ CHARSET_MAC, -+ CHARSET_CP437, -+ CHARSET_CP850, - }; - - #ifndef _WORD - #include "word.h" - #endif - --extern void word_print (Word*); -+typedef struct { -+ int num; -+ char *name; -+} FontEntry; -+ -+#define MAX_FONTS (8192) -+ -+/* RTF color table colors are RGB */ -+ -+typedef struct { -+ unsigned char r,g,b; -+} Color; -+ -+#define MAX_COLORS (1024) -+ -+/* For each RTF text block (the text within braces) we must keep -+ * an AttrStack which is a stack of attributes and their optional -+ * parameter. Since RTF text blocks are nested, these make up a -+ * stack of stacks. And, since RTF text blocks inherit attributes -+ * from parent blocks, all new AttrStacks do the same from -+ * their parent AttrStack. -+ */ -+#define MAX_ATTRS (10000) -+ -+typedef struct _stack { -+ unsigned char attr_stack[MAX_ATTRS]; -+ char *attr_stack_params[MAX_ATTRS]; -+ int tos; -+ struct _stack *next; -+} AttrStack; -+ -+typedef struct _hi { -+ struct _hi *next; -+ char *str; -+ unsigned long value; -+} HashItem; -+ -+typedef struct ConversionContext { -+ const struct unRTFOptions *options; -+ -+ HashItem *hash[256]; -+ unsigned long hash_length[256]; -+ unsigned long hash_value; -+ -+ int lineno; /* Used for error reporting and final line count. */ -+ -+ int banner_printed; -+ -+ int within_picture; -+ int picture_file_number; -+ char picture_path[256]; -+ int picture_width; -+ int picture_height; -+ int picture_bits_per_pixel; -+ int picture_type; -+ int picture_wmetafile_type; -+ char *picture_wmetafile_type_str; -+ -+ int have_printed_body; -+ int within_header; -+ -+ char *hyperlink_base; -+ -+ FontEntry font_table[MAX_FONTS]; -+ int total_fonts; -+ -+ Color color_table[MAX_COLORS]; -+ int total_colors; -+ -+ my_iconv_t desc; -+ my_iconv_t desc2; -+ -+ /* Previously in word_print_core function -+ */ -+ int total_chars_this_line; /* for simulating \tab */ -+ -+ /* This value is set by attr_push and attr_pop -+ */ -+ int simulate_smallcaps; -+ int simulate_allcaps; -+ -+ int coming_pars_that_are_tabular; -+ int within_table; -+ int have_printed_row_begin; -+ int have_printed_cell_begin; -+ int have_printed_row_end; -+ int have_printed_cell_end; -+ -+ /* attr.c */ -+ AttrStack *stack_of_stacks; -+ AttrStack *stack_of_stacks_top; -+ -+ /* word.c */ -+ int indent_level; -+ -+ /* parse.c */ -+ char *input_str; -+ unsigned long current_max_length; -+ int ungot_char; -+ int ungot_char2; -+ int ungot_char3; -+ int last_returned_ch; -+ int buffer_size; -+ -+ const char *read_buf; -+ int read_buf_end; -+ int read_buf_index; -+ -+} ConversionContext; -+ -+struct OutputContext; -+ -+extern void word_print (const struct OutputContext *, Word*); -+extern void starting_body(const struct OutputContext *); -+extern void starting_text(const struct OutputContext *); -+ - #define FONT_GREEK "cp1253" - #define FONT_SYMBOL "SYMBOL" - -diff -durpN unrtf-0.21.2.old/src/defs.h unrtf-0.21.2/src/defs.h ---- unrtf-0.21.2.old/src/defs.h 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/defs.h 2013-01-17 02:41:09.685864239 +0100 -@@ -64,9 +64,6 @@ - #define SKIP_ONE_WORD 2 - #endif - --#define USAGE "unrtf [--version] [--verbose] [--help] [--nopict|-n] [--noremap] [--html] [--text] [--vt] [--latex] [--rtf] [-P config_search_path] [-t )] " -- -- - /* Default names for RTF's default fonts */ - #define FONTNIL_STR "Times,TimesRoman,TimesNewRoman" - #define FONTROMAN_STR "Times,Palatino" -@@ -76,3 +73,6 @@ - #define FONTDECOR_STR "ZapfChancery" - #define FONTTECH_STR "Symbol" - -+/* This one should be deduce from the configure script */ -+#define DEFAULT_UNRTF_SEARCH_PATH "/usr/local/lib/unrtf/" -+#define DEFAULT_OUTPUT "html" -diff -durpN unrtf-0.21.2.old/src/.deps/attr.Po unrtf-0.21.2/src/.deps/attr.Po ---- unrtf-0.21.2.old/src/.deps/attr.Po 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/.deps/attr.Po 2013-01-17 02:47:40.017847101 +0100 -@@ -0,0 +1 @@ -+# dummy -diff -durpN unrtf-0.21.2.old/src/.deps/convert.Po unrtf-0.21.2/src/.deps/convert.Po ---- unrtf-0.21.2.old/src/.deps/convert.Po 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/.deps/convert.Po 2013-01-17 02:47:40.021847101 +0100 -@@ -0,0 +1 @@ -+# dummy -diff -durpN unrtf-0.21.2.old/src/.deps/error.Po unrtf-0.21.2/src/.deps/error.Po ---- unrtf-0.21.2.old/src/.deps/error.Po 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/.deps/error.Po 2013-01-17 02:47:40.025847101 +0100 -@@ -0,0 +1 @@ -+# dummy -diff -durpN unrtf-0.21.2.old/src/.deps/hash.Po unrtf-0.21.2/src/.deps/hash.Po ---- unrtf-0.21.2.old/src/.deps/hash.Po 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/.deps/hash.Po 2013-01-17 02:47:40.029847100 +0100 -@@ -0,0 +1 @@ -+# dummy -diff -durpN unrtf-0.21.2.old/src/.deps/main.Po unrtf-0.21.2/src/.deps/main.Po ---- unrtf-0.21.2.old/src/.deps/main.Po 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/.deps/main.Po 2013-01-17 02:47:40.033847100 +0100 -@@ -0,0 +1 @@ -+# dummy -diff -durpN unrtf-0.21.2.old/src/.deps/malloc.Po unrtf-0.21.2/src/.deps/malloc.Po ---- unrtf-0.21.2.old/src/.deps/malloc.Po 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/.deps/malloc.Po 2013-01-17 02:47:40.033847100 +0100 -@@ -0,0 +1 @@ -+# dummy -diff -durpN unrtf-0.21.2.old/src/.deps/my_iconv.Po unrtf-0.21.2/src/.deps/my_iconv.Po ---- unrtf-0.21.2.old/src/.deps/my_iconv.Po 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/.deps/my_iconv.Po 2013-01-17 02:47:40.037847100 +0100 -@@ -0,0 +1 @@ -+# dummy -diff -durpN unrtf-0.21.2.old/src/.deps/output.Po unrtf-0.21.2/src/.deps/output.Po ---- unrtf-0.21.2.old/src/.deps/output.Po 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/.deps/output.Po 2013-01-17 02:47:40.041847100 +0100 -@@ -0,0 +1 @@ -+# dummy -diff -durpN unrtf-0.21.2.old/src/.deps/parse.Po unrtf-0.21.2/src/.deps/parse.Po ---- unrtf-0.21.2.old/src/.deps/parse.Po 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/.deps/parse.Po 2013-01-17 02:47:40.045847100 +0100 -@@ -0,0 +1 @@ -+# dummy -diff -durpN unrtf-0.21.2.old/src/.deps/path.Po unrtf-0.21.2/src/.deps/path.Po ---- unrtf-0.21.2.old/src/.deps/path.Po 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/.deps/path.Po 2013-01-17 02:47:40.049847100 +0100 -@@ -0,0 +1 @@ -+# dummy -diff -durpN unrtf-0.21.2.old/src/.deps/unicode.Po unrtf-0.21.2/src/.deps/unicode.Po ---- unrtf-0.21.2.old/src/.deps/unicode.Po 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/.deps/unicode.Po 2013-01-17 02:47:40.053847099 +0100 -@@ -0,0 +1 @@ -+# dummy -diff -durpN unrtf-0.21.2.old/src/.deps/user.Po unrtf-0.21.2/src/.deps/user.Po ---- unrtf-0.21.2.old/src/.deps/user.Po 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/.deps/user.Po 2013-01-17 02:47:40.057847099 +0100 -@@ -0,0 +1 @@ -+# dummy -diff -durpN unrtf-0.21.2.old/src/.deps/util.Po unrtf-0.21.2/src/.deps/util.Po ---- unrtf-0.21.2.old/src/.deps/util.Po 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/.deps/util.Po 2013-01-17 02:47:40.061847099 +0100 -@@ -0,0 +1 @@ -+# dummy -diff -durpN unrtf-0.21.2.old/src/.deps/word.Po unrtf-0.21.2/src/.deps/word.Po ---- unrtf-0.21.2.old/src/.deps/word.Po 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/.deps/word.Po 2013-01-17 02:47:40.061847099 +0100 -@@ -0,0 +1 @@ -+# dummy -diff -durpN unrtf-0.21.2.old/src/error.c unrtf-0.21.2/src/error.c ---- unrtf-0.21.2.old/src/error.c 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/error.c 2013-01-17 02:41:09.685864239 +0100 -@@ -51,27 +51,11 @@ - #include - #endif - -+#include "convert.h" - #include "defs.h" - #include "main.h" - - -- --/*======================================================================== -- * Name: usage -- * Purpose: Prints usage information and exits with an error. -- * Args: None. -- * Returns: None. -- *=======================================================================*/ -- --void --usage () --{ -- fprintf(stderr, "Usage: %s\n", USAGE); -- exit(-3); --} -- -- -- - /*======================================================================== - * Name: error_handler - * Purpose: Prints error message and other useful info, then exits. -@@ -80,10 +64,10 @@ usage () - *=======================================================================*/ - - void --error_handler (char* message) -+error_handler (const struct ConversionContext *cc, char* message) - { - #if 1 -- fprintf(stderr, "Error (line %d): %s\n", lineno, message); -+ fprintf(stderr, "Error (line %d): %s\n", cc->lineno, message); - #else - fprintf(stderr, "Error: %s\n", message); - #endif -diff -durpN unrtf-0.21.2.old/src/error.h unrtf-0.21.2/src/error.h ---- unrtf-0.21.2.old/src/error.h 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/error.h 2013-01-17 02:41:09.685864239 +0100 -@@ -37,9 +37,10 @@ - - #define CHECK_MALLOC_SUCCESS(XX) { if ((XX)==NULL) { fprintf (stderr, "internal error: cannot allocate memory in %s at %d\n", __FILE__, __LINE__); exit (1); }} - -+struct ConversionContext; - - extern void usage(void); --extern void error_handler (char*); -+extern void error_handler (const struct ConversionContext *, char*); - extern void warning_handler (char*); - - -diff -durpN unrtf-0.21.2.old/src/GNUmakefile unrtf-0.21.2/src/GNUmakefile ---- unrtf-0.21.2.old/src/GNUmakefile 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/GNUmakefile 2013-01-17 02:43:38.797857692 +0100 -@@ -0,0 +1,34 @@ -+# -*-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 -diff -durpN unrtf-0.21.2.old/src/hash.c unrtf-0.21.2/src/hash.c ---- unrtf-0.21.2.old/src/hash.c 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/hash.c 2013-01-17 02:43:16.581858668 +0100 -@@ -53,24 +53,20 @@ - #include - #endif - -+#ifdef HAVE_STDLIB_H -+#include -+#endif -+ -+#ifdef HAVE_STDINT_H -+#include -+#endif -+ -+#include "convert.h" - #include "error.h" - #include "main.h" - #include "malloc.h" - -- --typedef struct _hi { -- struct _hi *next; -- char *str; -- unsigned long value; --} HashItem; -- -- --/* Index by first char of string */ --static HashItem *hash[256]; --static unsigned long hash_length[256]; --static unsigned long hash_value=0; -- -- -+#include "hash.h" - - /*======================================================================== - * Name: hash_init -@@ -80,13 +76,13 @@ static unsigned long hash_value=0; - *=======================================================================*/ - - void --hash_init () -+hash_init (struct ConversionContext *cc) - { -- int i; -- for (i=0; i<256; i++) { -- hash[i]=NULL; -- hash_length[i]=0; -- } -+ int i; -+ for (i=0; i<256; i++) { -+ cc->hash[i]=NULL; -+ cc->hash_length[i]=0; -+ } - } - - -@@ -101,14 +97,14 @@ hash_init () - *=======================================================================*/ - - unsigned long --hash_stats () -+hash_stats (struct ConversionContext *cc) - { -- int i; -- unsigned long total=0; -- for (i=0; i<256; i++) { -- total += hash_length[i]; -- } -- return(total); -+ int i; -+ unsigned long total=0; -+ for (i=0; i<256; i++) { -+ total += cc->hash_length[i]; -+ } -+ return(total); - } - - -@@ -121,32 +117,32 @@ hash_stats () - *=======================================================================*/ - - static HashItem * --hashitem_new (char *str) -+hashitem_new (struct ConversionContext *cc, char *str) - { -- HashItem *hi; -- unsigned long i; -- -- hi=(HashItem*) my_malloc(sizeof(HashItem)); -- if (!hi) -- error_handler("Out of memory"); -- memset ((void*)hi, 0, sizeof (HashItem)); -- -- hi->str = my_strdup(str); -+ HashItem *hi; -+ unsigned long i; - -- i = *str; -- if (i=='\\') i=str[1]; -- i <<= 24; -- hi->value = i | (hash_value++ & 0xffffff); -- hi->next = NULL; -+ hi=(HashItem*) unrtf_malloc(sizeof(HashItem)); -+ if (!hi) -+ error_handler(cc, "Out of memory"); -+ memset ((void*)hi, 0, sizeof (HashItem)); -+ -+ hi->str = unrtf_strdup(cc, str); -+ -+ i = *str; -+ if (i=='\\') i=str[1]; -+ i <<= 24; -+ hi->value = i | (cc->hash_value++ & 0xffffff); -+ hi->next = NULL; - - #if 0 -- if (debug_mode) { -- printf ("\n", -- hi->value, hi->str); -- } -+ if (debug_mode) { -+ printf ("\n", -+ hi->value, hi->str); -+ } - #endif - -- return hi; -+ return hi; - } - - -@@ -158,7 +154,7 @@ hashitem_new (char *str) - *=======================================================================*/ - - unsigned long --hash_get_index (char *str) -+hash_get_index (struct ConversionContext *cc, char *str) - { - #if 1 /* daved - 0.19.1 */ - unsigned short index; -@@ -177,17 +173,17 @@ hash_get_index (char *str) - if (ch=='\\' && *(str+1)) - ch = *(str+1); - index = ch; -- hi = hash[index]; -+ hi = cc->hash[index]; - while (hi) { - if (!strcmp(hi->str,str)) - return hi->value; - hi=hi->next; - } - /* not in hash */ -- hi = hashitem_new (str); -- hi->next = hash[index]; -- hash [index] = hi; -- ++hash_length [index]; -+ hi = hashitem_new (cc, str); -+ hi->next = cc->hash[index]; -+ cc->hash [index] = hi; -+ ++cc->hash_length [index]; - return hi->value; - } - -@@ -201,13 +197,13 @@ hash_get_index (char *str) - *=======================================================================*/ - - char* --hash_get_string (unsigned long value) -+hash_get_string (const struct ConversionContext *cc, unsigned long value) - { -- int index; -+ uint8_t index; - HashItem *hi; - -- index = value >> 24; -- hi = hash[index]; -+ index = (uint8_t)(value >> 24); -+ hi = cc->hash[index]; - while (hi) { - if (hi->value == value) - return hi->str; -@@ -216,3 +212,27 @@ hash_get_string (unsigned long value) - warning_handler("Word not in hash"); - return NULL; - } -+ -+static void -+hashitem_free (HashItem *item) -+{ -+ HashItem *next = item->next; -+ -+ unrtf_free (item->str); -+ free (item); -+ if (next) -+ hashitem_free(next); -+} -+ -+void -+hash_free (struct ConversionContext *cc) -+{ -+ int i; -+ for (i=0; i<256; i++) { -+ if (cc->hash[i]) { -+ hashitem_free(cc->hash[i]); -+ } -+ cc->hash[i]=NULL; -+ cc->hash_length[i]=0; -+ } -+} -diff -durpN unrtf-0.21.2.old/src/hash.h unrtf-0.21.2/src/hash.h ---- unrtf-0.21.2.old/src/hash.h 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/hash.h 2013-01-17 02:41:09.685864239 +0100 -@@ -32,11 +32,15 @@ - * 16 Dec 07, daved@physiol.usyd.edu.au: updated to GPL v3 - *--------------------------------------------------------------------*/ - -+#ifndef HASH_H -+#define HASH_H 1 - -+struct ConversionContext; - --extern void hash_init (void); --extern unsigned long hash_stats (void); --extern unsigned long hash_get_index (char *); --extern char* hash_get_string (unsigned long ); -- -+extern void hash_init (struct ConversionContext *); -+extern unsigned long hash_stats (struct ConversionContext *); -+extern unsigned long hash_get_index (struct ConversionContext *, char *); -+extern char* hash_get_string (const struct ConversionContext *, unsigned long); -+extern void hash_free (struct ConversionContext *); - -+#endif /* HASH_H */ -diff -durpN unrtf-0.21.2.old/src/main.c unrtf-0.21.2/src/main.c ---- unrtf-0.21.2.old/src/main.c 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/main.c 2013-01-17 02:41:09.685864239 +0100 -@@ -1,23 +1,23 @@ - /*============================================================================= -- GNU UnRTF, a command-line program to convert RTF documents to other formats. -- Copyright (C) 2000, 2001, 2004 by Zachary Smith -+ GNU UnRTF, a command-line program to convert RTF documents to other formats. -+ Copyright (C) 2000, 2001, 2004 by Zachary Smith - -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. - -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. - -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -- The maintainer is reachable by electronic mail at daved@physiol.usyd.edu.au --=============================================================================*/ -+ The maintainer is reachable by electronic mail at daved@physiol.usyd.edu.au -+ =============================================================================*/ - - - /*---------------------------------------------------------------------- -@@ -45,7 +45,7 @@ - * 17 Dec 07, daved@physiol.usyd.edu.au: support for --noremap from - * David Santinoli - * 09 Nov 08, arkadiusz.firus@gmail.com: support for -t -- and read stdin if no input file provided -+ and read stdin if no input file provided - * 13 Dec 08, daved@physiol.usyd.edu.au: search path code - * 17 Jan 10, daved@physiol.usyd.edu.au: change search path to directory - * containing output conf and font charmap files -@@ -70,263 +70,136 @@ - #include - - #include "defs.h" --#include "error.h" --#include "word.h" --#include "convert.h" --#include "parse.h" --#include "hash.h" --#include "malloc.h" --#include "path.h" -+#include "unrtf.h" - --#include "output.h" --#include "user.h" - #include "main.h" --#include "util.h" -- --int nopict_mode; /* TRUE => Do not write \pict's to files */ --int dump_mode; /* TRUE => Output a dump of the RTF word tree */ --int debug_mode; /* TRUE => Output debug comments within HTML */ --int lineno; /* Used for error reporting and final line count. */ --int simple_mode; /* TRUE => Output HTML without SPAN/DIV tags -- This would -- probably be more useful if we could pull out tags -- as well. */ --int inline_mode; /* TRUE => Output HTML without HTML/BODY/HEAD -- This is -- buggy. I've seen it output pages of tags. */ --/* marcossamaral - 0.19.9 */ --int verbose_mode; /* TRUE => Output additional informations about unrtf */ --int no_remap_mode; /* don't remap codepoints */ -- -- --OutputPersonality *op = NULL; - - /*======================================================================== -- * Name: get_config -- * Purpose: Updates output acording to information found in file path. -- * Args: Path to configuration file, OutputPersonality, mode. -- If mode == 0 configuration file is defined by user. -- If mode == 1 configuration file is in CONFIG_DIR. -- * Returns: Updated OutputPersonality. -+ * Name: usage -+ * Purpose: Prints usage information and exits with an error. -+ * Args: None. -+ * Returns: None. - *=======================================================================*/ - --OutputPersonality * --get_config(char *path, OutputPersonality *op, int mode) -+void -+usage () - { -- char *absolute_path; -- char *user_path; -- char u_success=0; -- struct path_dir *path_dir_p; -- -- switch(mode) -- { -- case 0: -- if(n_path_dirs == 0) -- { -- fprintf(stderr,"no directories to search for %s\n", path); -- exit(1); -- } -- for(path_dir_p = &topdir; path_dir_p->dir_name; path_dir_p = path_dir_p->next) -- { -- char *p; -- p = path_dir_p->dir_name; -- if(*(p+strlen(p)-1) != '/') -- p = concatenate(p, "/"); -- p=concatenate(p, path); -- user_path=concatenate(p, ".conf"); -- if(access(user_path, F_OK|R_OK)) -- continue; -- op = user_init(op, user_path); -- u_success++; -- break; -- } -- if(!u_success) -- { -- fprintf(stderr, "failed to find %s.conf in search path dirs\n", path); -- exit(1); -- } -- break; -- case 1: -- path = concatenate(CONFIG_DIR, path); -- absolute_path = concatenate(path, ".conf"); -- op = user_init(op, absolute_path); -- my_free(absolute_path); -- break; -- default: -- error_handler("Error in function get_config (file main.c)."); -- } -- -- return op; -+ fprintf(stderr, "Usage: %s\n", USAGE); -+ exit(-3); - } - --/*======================================================================== -- * Name: main -- * Purpose: Main control function. -- * Args: Args. -- * Returns: Exit code. -- *=======================================================================*/ -- - int - main (int argc, char **argv) - { -- FILE *f; -- Word * word; -- char *path = NULL; -- char *env_path_p = '\0'; -- -- int i; -- nopict_mode = debug_mode = dump_mode = inline_mode = no_remap_mode = FALSE; -- /* initialize search path to compiled-in value */ -- search_path = DEFAULT_UNRTF_SEARCH_PATH; -+ unRTFOptions unrtf_options; -+ int show_version = 0, i, free_path = 0; -+ char *path = NULL, *old_path; -+ size_t path_len; - -- if((env_path_p = getenv("UNRTF_SEARCH_PATH")) != NULL) -- { -- if(verbose_mode) -- fprintf(stderr, "got environment path: %s\n", env_path_p); -- search_path=env_path_p; -- } -+ memset (&unrtf_options, 0, sizeof (unRTFOptions)); - -- /* Handle arguments */ -+ /* Handle arguments */ - -- for (i = 1; i < argc; i++) { -- if (!strcmp("--dump", argv[i])) dump_mode = TRUE; -- else if (!strcmp("-d", argv[i])) dump_mode = TRUE; -- else if (!strcmp("--debug", argv[i])) debug_mode = TRUE; -- else if (!strcmp("--verbose", argv[i])) verbose_mode = TRUE; -- else if (!strcmp("--simple", argv[i])) simple_mode = TRUE; -- else if (!strcmp("--noremap", argv[i])) no_remap_mode = TRUE; -- else if (!strcmp("-t", argv[i])) -- { -- if ((i + 1) < argc && *argv[i + 1] != '-') -- { -- i++; -- if(!path_checked && check_dirs() == 0) -- { -- fprintf(stderr,"no config dirs for %s\n", argv[i]); -- exit(1); -- } -- op = get_config(argv[i], op, 0); -- } -- } -- else if (!strcmp("-P", argv[i])) -- { -- if(i+1 > argc) -- { -- fprintf(stderr,"-P needs a path argument\n"); -- exit(1); -- } -- search_path=argv[++i]; -- } -- else if (!strcmp("--inline", argv[i])) inline_mode = TRUE; -- else if (!strcmp("--help", argv[i])) { -- usage(); -- } -- else if (!strcmp("--version", argv[i])) { -- fprintf(stderr, "%s\n", PACKAGE_VERSION); -- fprintf(stderr, "search path is: %s\n", search_path); -- exit(0); -- } -- else if (!strcmp("--nopict", argv[i])) nopict_mode = TRUE; -- else if (!strcmp("-n", argv[i])) nopict_mode = TRUE; -- else if (!strncmp("--", argv[i], 2)) -+ for (i = 1; i < argc; i++) { -+ if (!strcmp("--dump", argv[i])) unrtf_options.dump_mode = TRUE; -+ else if (!strcmp("-d", argv[i])) unrtf_options.dump_mode = TRUE; -+ else if (!strcmp("--debug", argv[i])) unrtf_options.debug_mode = TRUE; -+ else if (!strcmp("--verbose", argv[i])) unrtf_options.verbose_mode = TRUE; -+ else if (!strcmp("--simple", argv[i])) unrtf_options.simple_mode = TRUE; -+ else if (!strcmp("--noremap", argv[i])) unrtf_options.no_remap_mode = TRUE; -+ else if (!strcmp("-t", argv[i])) -+ { -+ if ((i + 1) < argc && *argv[i + 1] != '-') -+ { -+ i++; -+ unrtf_options.output_format = argv[i]; -+ } -+ else -+ { -+ fprintf(stderr, "-t needs a path argument\n"); -+ exit(1); -+ } -+ } -+ else if (!strcmp("-P", argv[i])) -+ { -+ if ((i + 1) < argc && *argv[i + 1] != '-') -+ { -+ i++; -+ unrtf_options.config_directory = argv[i]; -+ } -+ else -+ { -+ fprintf(stderr,"-P needs a path argument\n"); -+ exit(1); -+ } -+ } -+ else if (!strcmp("--inline", argv[i])) unrtf_options.inline_mode = TRUE; -+ else if (!strcmp("--help", argv[i])) { -+ usage(); -+ } -+ else if (!strcmp("--version", argv[i])) { -+ show_version = 1; -+ } -+ else if (!strcmp("--nopict", argv[i])) unrtf_options.nopict_mode = TRUE; -+ else if (!strcmp("-n", argv[i])) unrtf_options.nopict_mode = TRUE; -+ else if (!strncmp("--", argv[i], 2)) - #if 0 /* daved 0.21.1 */ -- op = get_config(&argv[i][2], op, 1) -+ op = get_config(&cc, &argv[i][2], op, 1) - #else -- { -- if(!path_checked && check_dirs() == 0) -- { -- fprintf(stderr,"no config dirs for %s\n", argv[i]); -- exit(1); -- } -- op = get_config(&argv[i][2], op, 0); -- } -+ { -+ unrtf_options.output_format = argv[i] + 2; -+ } - #endif -- else { -- if (*argv[i] == '-') usage(); -- -- if (path) -- usage(); -- else -- path = argv[i]; -- } -- } -- -- -- -- if (op == NULL) -- op = get_config(DEFAULT_OUTPUT, op, 1); -- if(!path_checked && check_dirs() == 0) -- { -- fprintf(stderr,"no config directories\n"); -- exit(1); -- } -- -- -- hash_init(); -- -- /* Program information */ -- if (verbose_mode || debug_mode) { -- fprintf(stderr, "This is UnRTF "); -- fprintf(stderr, "version %s\n", PACKAGE_VERSION); -- fprintf(stderr, "By Dave Davey, Marcos Serrou do Amaral and Arkadiusz Firus\n"); -- fprintf(stderr, "Original Author: Zachary Smith\n"); -- show_dirs(); -- } -- -- if (debug_mode) fprintf(stderr, "Debug mode.\n"); -- if (dump_mode) fprintf(stderr, "Dump mode.\n"); -- -- /* Open file for reading. Append ".rtf" to file name if not supplied. */ -- if (path == NULL) -- f = stdin; -- else -- { -- f = fopen(path, "r"); -- if (!f) { -- char path2[200]; -- strcpy(path2, path); -- strcat(path2, ".rtf"); -- f = fopen(path2, "r"); -- if (!f) -- error_handler("Cannot open input file"); -- } -- } -- -- if (verbose_mode || debug_mode) fprintf(stderr, "Processing %s...\n", path); -- -- /* Keep track of lines processed. This is arbitrary to the user as -- * RTF ignores newlines. May be helpful in error tracking. */ -- lineno = 0; -+ else { -+ if (*argv[i] == '-') usage(); - -- /* All the work starts here. word_read() should keep reading words until -- * the end of the file. */ -- word = word_read(f); -+ if (path) -+ usage(); -+ else -+ path = argv[i]; -+ } -+ } - -- if (dump_mode) { -- word_dump(word); -- printf("\n"); -- } else { --/* Should we also optimize word before dump? - AF */ -- word = optimize_word(word); -- word_print(word); -- } -+ if (show_version) { -+ fprintf(stderr, "%s\n", PACKAGE_VERSION); -+ fprintf(stderr, "search path is: %s\n", -+ (unrtf_options.config_directory -+ ? unrtf_options.config_directory : DEFAULT_UNRTF_SEARCH_PATH)); -+ exit(0); -+ } - -- fclose(f); -+ /* Program information */ -+ if (unrtf_options.verbose_mode || unrtf_options.debug_mode) { -+ fprintf(stderr, "This is UnRTF "); -+ fprintf(stderr, "version %s\n", PACKAGE_VERSION); -+ fprintf(stderr, "By Dave Davey, Marcos Serrou do Amaral and Arkadiusz Firus\n"); -+ fprintf(stderr, "Original Author: Zachary Smith\n"); -+ fprintf(stderr, "Configuration directory: %s\n", -+ (unrtf_options.config_directory -+ ? unrtf_options.config_directory -+ : DEFAULT_UNRTF_SEARCH_PATH)); -+ } - -- /* marcossamaral - 0.19.9 */ -- if(verbose_mode || debug_mode) { -- unsigned long total=0; -- total = hash_stats(); -- fprintf(stderr, "Done.\n"); -- fprintf(stderr, "%lu words were hashed.\n", total); -- } -+ if (unrtf_options.debug_mode) fprintf(stderr, "Debug mode.\n"); -+ if (unrtf_options.dump_mode) fprintf(stderr, "Dump mode.\n"); - -- if (debug_mode) { -- fprintf(stderr, "Total memory allocated %ld bytes.\n", -- total_malloced()); -- } -+ /* Check file access for reading. Append ".rtf" to file name if not supplied. */ -+ if (path && access(path, R_OK) != 0) { -+ path_len = strlen(path); -+ old_path = path; -+ path = malloc (path_len + 5); -+ sprintf (path, "%s.rtf", old_path); -+ if (access(path, R_OK) != 0) { -+ free (path); -+ fprintf (stderr, "Cannot access input file.\n"); -+ exit (10); -+ } -+ free_path = 1; -+ } - -- /* May as well */ -- word_free(word); -+ unrtf_convert_from_filename (&unrtf_options, path); -+ if (free_path) -+ free (path); - -- return 0; -+ return 0; - } -- -diff -durpN unrtf-0.21.2.old/src/main.h unrtf-0.21.2/src/main.h ---- unrtf-0.21.2.old/src/main.h 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/main.h 2013-01-17 02:41:09.685864239 +0100 -@@ -35,21 +35,8 @@ - * 17 Jan 10, daved@physiol.usyd.edu.au: change CONFIG_DIR to drop outputs/ - *--------------------------------------------------------------------*/ - -- --extern int lineno; --extern int debug_mode; --extern int simple_mode; --extern int inline_mode; --extern int no_remap_mode; -- -- - #ifndef _OUTPUT - #include "output.h" - #endif - --#define CONFIG_DIR "/usr/local/lib/unrtf/" --#define DEFAULT_OUTPUT "html" -- --extern OutputPersonality *op; -- -- -+#define USAGE "unrtf [--version] [--verbose] [--help] [--nopict|-n] [--noremap] [--html] [--text] [--vt] [--latex] [--rtf] [-P config_search_path] [-t )] " -diff -durpN unrtf-0.21.2.old/src/Makefile unrtf-0.21.2/src/Makefile ---- unrtf-0.21.2.old/src/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/Makefile 2013-01-17 02:52:06.525835400 +0100 -@@ -0,0 +1,494 @@ -+# Makefile.in generated by automake 1.11.1 from Makefile.am. -+# src/Makefile. Generated from Makefile.in by configure. -+ -+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -+# Inc. -+# This Makefile.in is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. -+ -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -+# PARTICULAR PURPOSE. -+ -+ -+ -+# This is the Makefile.am that deals with the program proper. -+# It all works automagically. -+ -+ -+pkgdatadir = $(datadir)/unrtf -+pkgincludedir = $(includedir)/unrtf -+pkglibdir = $(libdir)/unrtf -+pkglibexecdir = $(libexecdir)/unrtf -+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -+install_sh_DATA = $(install_sh) -c -m 644 -+install_sh_PROGRAM = $(install_sh) -c -+install_sh_SCRIPT = $(install_sh) -c -+INSTALL_HEADER = $(INSTALL_DATA) -+transform = $(program_transform_name) -+NORMAL_INSTALL = : -+PRE_INSTALL = : -+POST_INSTALL = : -+NORMAL_UNINSTALL = : -+PRE_UNINSTALL = : -+POST_UNINSTALL = : -+build_triplet = x86_64-unknown-linux-gnu -+host_triplet = x86_64-unknown-linux-gnu -+bin_PROGRAMS = unrtf$(EXEEXT) -+subdir = src -+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in -+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -+am__aclocal_m4_deps = $(top_srcdir)/configure.ac -+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ -+ $(ACLOCAL_M4) -+mkinstalldirs = $(install_sh) -d -+CONFIG_HEADER = $(top_builddir)/config.h -+CONFIG_CLEAN_FILES = -+CONFIG_CLEAN_VPATH_FILES = -+am__installdirs = "$(DESTDIR)$(bindir)" -+PROGRAMS = $(bin_PROGRAMS) -+am_unrtf_OBJECTS = attr.$(OBJEXT) convert.$(OBJEXT) error.$(OBJEXT) \ -+ hash.$(OBJEXT) my_iconv.$(OBJEXT) main.$(OBJEXT) \ -+ malloc.$(OBJEXT) output.$(OBJEXT) parse.$(OBJEXT) \ -+ path.$(OBJEXT) unicode.$(OBJEXT) user.$(OBJEXT) util.$(OBJEXT) \ -+ word.$(OBJEXT) -+unrtf_OBJECTS = $(am_unrtf_OBJECTS) -+unrtf_LDADD = $(LDADD) -+DEFAULT_INCLUDES = -I. -I$(top_builddir) -+depcomp = $(SHELL) $(top_srcdir)/config/depcomp -+am__depfiles_maybe = depfiles -+am__mv = mv -f -+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ -+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -+CCLD = $(CC) -+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -+SOURCES = $(unrtf_SOURCES) -+DIST_SOURCES = $(unrtf_SOURCES) -+ETAGS = etags -+CTAGS = ctags -+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -+ACLOCAL = ${SHELL} /home/jkerihuel/Projects/sogo/OpenChange/unrtf-0.21.2/config/missing --run aclocal-1.11 -+AMTAR = ${SHELL} /home/jkerihuel/Projects/sogo/OpenChange/unrtf-0.21.2/config/missing --run tar -+AUTOCONF = ${SHELL} /home/jkerihuel/Projects/sogo/OpenChange/unrtf-0.21.2/config/missing --run autoconf -+AUTOHEADER = ${SHELL} /home/jkerihuel/Projects/sogo/OpenChange/unrtf-0.21.2/config/missing --run autoheader -+AUTOMAKE = ${SHELL} /home/jkerihuel/Projects/sogo/OpenChange/unrtf-0.21.2/config/missing --run automake-1.11 -+AWK = mawk -+CC = gcc -+CCDEPMODE = depmode=gcc3 -+CFLAGS = -g -O2 -+CPP = gcc -E -+CPPFLAGS = -+CYGPATH_W = echo -+DEFS = -DHAVE_CONFIG_H -+DEPDIR = .deps -+ECHO_C = -+ECHO_N = -n -+ECHO_T = -+EGREP = /bin/grep -E -+EXEEXT = -+GREP = /bin/grep -+INSTALL = /usr/bin/install -c -+INSTALL_DATA = ${INSTALL} -m 644 -+INSTALL_PROGRAM = ${INSTALL} -+INSTALL_SCRIPT = ${INSTALL} -+INSTALL_STRIP_PROGRAM = $(install_sh) -c -s -+LDFLAGS = -+LIBOBJS = -+LIBS = -+LTLIBOBJS = -+MAINT = # -+MAKEINFO = ${SHELL} /home/jkerihuel/Projects/sogo/OpenChange/unrtf-0.21.2/config/missing --run makeinfo -+MKDIR_P = /bin/mkdir -p -+OBJEXT = o -+PACKAGE = unrtf -+PACKAGE_BUGREPORT = bug-unrtf@gnu.org -+PACKAGE_NAME = unrtf -+PACKAGE_STRING = unrtf 0.21.2 -+PACKAGE_TARNAME = unrtf -+PACKAGE_VERSION = 0.21.2 -+PATH_SEPARATOR = : -+SET_MAKE = -+SHELL = /bin/bash -+STRIP = -+VERSION = 0.21.2 -+abs_builddir = /home/jkerihuel/Projects/sogo/OpenChange/unrtf-0.21.2/src -+abs_srcdir = /home/jkerihuel/Projects/sogo/OpenChange/unrtf-0.21.2/src -+abs_top_builddir = /home/jkerihuel/Projects/sogo/OpenChange/unrtf-0.21.2 -+abs_top_srcdir = /home/jkerihuel/Projects/sogo/OpenChange/unrtf-0.21.2 -+ac_ct_CC = gcc -+am__include = include -+am__leading_dot = . -+am__quote = -+am__tar = ${AMTAR} chof - "$$tardir" -+am__untar = ${AMTAR} xf - -+bindir = ${exec_prefix}/bin -+build = x86_64-unknown-linux-gnu -+build_alias = -+build_cpu = x86_64 -+build_os = linux-gnu -+build_vendor = unknown -+builddir = . -+datadir = ${datarootdir} -+datarootdir = ${prefix}/share -+docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} -+dvidir = ${docdir} -+exec_prefix = ${prefix} -+host = x86_64-unknown-linux-gnu -+host_alias = -+host_cpu = x86_64 -+host_os = linux-gnu -+host_vendor = unknown -+htmldir = ${docdir} -+includedir = ${prefix}/include -+infodir = ${datarootdir}/info -+install_sh = ${SHELL} /home/jkerihuel/Projects/sogo/OpenChange/unrtf-0.21.2/config/install-sh -+libdir = ${exec_prefix}/lib -+libexecdir = ${exec_prefix}/libexec -+localedir = ${datarootdir}/locale -+localstatedir = ${prefix}/var -+mandir = ${datarootdir}/man -+mkdir_p = /bin/mkdir -p -+oldincludedir = /usr/include -+pdfdir = ${docdir} -+prefix = /usr/local -+program_transform_name = s,x,x, -+psdir = ${docdir} -+sbindir = ${exec_prefix}/sbin -+sharedstatedir = ${prefix}/com -+srcdir = . -+sysconfdir = ${prefix}/etc -+target_alias = -+top_build_prefix = ../ -+top_builddir = .. -+top_srcdir = .. -+unrtf_SOURCES = attr.c attr.h \ -+ convert.c convert.h \ -+ defs.h \ -+ error.c error.h \ -+ hash.c hash.h \ -+ my_iconv.c my_iconv.h \ -+ main.c main.h \ -+ malloc.c malloc.h \ -+ output.c output.h \ -+ parse.c parse.h \ -+ path.c path.h \ -+ unicode.c unicode.h \ -+ user.c user.h \ -+ util.c util.h \ -+ word.c word.h -+ -+all: all-am -+ -+.SUFFIXES: -+.SUFFIXES: .c .o .obj -+$(srcdir)/Makefile.in: # $(srcdir)/Makefile.am $(am__configure_deps) -+ @for dep in $?; do \ -+ case '$(am__configure_deps)' in \ -+ *$$dep*) \ -+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ -+ && { if test -f $@; then exit 0; else break; fi; }; \ -+ exit 1;; \ -+ esac; \ -+ done; \ -+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ -+ $(am__cd) $(top_srcdir) && \ -+ $(AUTOMAKE) --gnu src/Makefile -+.PRECIOUS: Makefile -+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status -+ @case '$?' in \ -+ *config.status*) \ -+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ -+ *) \ -+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ -+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ -+ esac; -+ -+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) -+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -+ -+$(top_srcdir)/configure: # $(am__configure_deps) -+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -+$(ACLOCAL_M4): # $(am__aclocal_m4_deps) -+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -+$(am__aclocal_m4_deps): -+install-binPROGRAMS: $(bin_PROGRAMS) -+ @$(NORMAL_INSTALL) -+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" -+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ -+ for p in $$list; do echo "$$p $$p"; done | \ -+ sed 's/$(EXEEXT)$$//' | \ -+ while read p p1; do if test -f $$p; \ -+ then echo "$$p"; echo "$$p"; else :; fi; \ -+ done | \ -+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ -+ sed 'N;N;N;s,\n, ,g' | \ -+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ -+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ -+ if ($$2 == $$4) files[d] = files[d] " " $$1; \ -+ else { print "f", $$3 "/" $$4, $$1; } } \ -+ END { for (d in files) print "f", d, files[d] }' | \ -+ while read type dir files; do \ -+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ -+ test -z "$$files" || { \ -+ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ -+ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ -+ } \ -+ ; done -+ -+uninstall-binPROGRAMS: -+ @$(NORMAL_UNINSTALL) -+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ -+ files=`for p in $$list; do echo "$$p"; done | \ -+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -+ -e 's/$$/$(EXEEXT)/' `; \ -+ test -n "$$list" || exit 0; \ -+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ -+ cd "$(DESTDIR)$(bindir)" && rm -f $$files -+ -+clean-binPROGRAMS: -+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) -+unrtf$(EXEEXT): $(unrtf_OBJECTS) $(unrtf_DEPENDENCIES) -+ @rm -f unrtf$(EXEEXT) -+ $(LINK) $(unrtf_OBJECTS) $(unrtf_LDADD) $(LIBS) -+ -+mostlyclean-compile: -+ -rm -f *.$(OBJEXT) -+ -+distclean-compile: -+ -rm -f *.tab.c -+ -+include ./$(DEPDIR)/attr.Po -+include ./$(DEPDIR)/convert.Po -+include ./$(DEPDIR)/error.Po -+include ./$(DEPDIR)/hash.Po -+include ./$(DEPDIR)/main.Po -+include ./$(DEPDIR)/malloc.Po -+include ./$(DEPDIR)/my_iconv.Po -+include ./$(DEPDIR)/output.Po -+include ./$(DEPDIR)/parse.Po -+include ./$(DEPDIR)/path.Po -+include ./$(DEPDIR)/unicode.Po -+include ./$(DEPDIR)/user.Po -+include ./$(DEPDIR)/util.Po -+include ./$(DEPDIR)/word.Po -+ -+.c.o: -+ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -+ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -+# source='$<' object='$@' libtool=no \ -+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -+# $(COMPILE) -c $< -+ -+.c.obj: -+ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -+ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -+# source='$<' object='$@' libtool=no \ -+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -+# $(COMPILE) -c `$(CYGPATH_W) '$<'` -+ -+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) -+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ -+ unique=`for i in $$list; do \ -+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ -+ done | \ -+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ -+ END { if (nonempty) { for (i in files) print i; }; }'`; \ -+ mkid -fID $$unique -+tags: TAGS -+ -+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ -+ $(TAGS_FILES) $(LISP) -+ set x; \ -+ here=`pwd`; \ -+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ -+ unique=`for i in $$list; do \ -+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ -+ done | \ -+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ -+ END { if (nonempty) { for (i in files) print i; }; }'`; \ -+ shift; \ -+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ -+ test -n "$$unique" || unique=$$empty_fix; \ -+ if test $$# -gt 0; then \ -+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ -+ "$$@" $$unique; \ -+ else \ -+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ -+ $$unique; \ -+ fi; \ -+ fi -+ctags: CTAGS -+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ -+ $(TAGS_FILES) $(LISP) -+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ -+ unique=`for i in $$list; do \ -+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ -+ done | \ -+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ -+ END { if (nonempty) { for (i in files) print i; }; }'`; \ -+ test -z "$(CTAGS_ARGS)$$unique" \ -+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ -+ $$unique -+ -+GTAGS: -+ here=`$(am__cd) $(top_builddir) && pwd` \ -+ && $(am__cd) $(top_srcdir) \ -+ && gtags -i $(GTAGS_ARGS) "$$here" -+ -+distclean-tags: -+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -+ -+distdir: $(DISTFILES) -+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ -+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ -+ list='$(DISTFILES)'; \ -+ dist_files=`for file in $$list; do echo $$file; done | \ -+ sed -e "s|^$$srcdirstrip/||;t" \ -+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ -+ case $$dist_files in \ -+ */*) $(MKDIR_P) `echo "$$dist_files" | \ -+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ -+ sort -u` ;; \ -+ esac; \ -+ for file in $$dist_files; do \ -+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ -+ if test -d $$d/$$file; then \ -+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ -+ if test -d "$(distdir)/$$file"; then \ -+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ -+ fi; \ -+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ -+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ -+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ -+ fi; \ -+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ -+ else \ -+ test -f "$(distdir)/$$file" \ -+ || cp -p $$d/$$file "$(distdir)/$$file" \ -+ || exit 1; \ -+ fi; \ -+ done -+check-am: all-am -+check: check-am -+all-am: Makefile $(PROGRAMS) -+installdirs: -+ for dir in "$(DESTDIR)$(bindir)"; do \ -+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ -+ done -+install: install-am -+install-exec: install-exec-am -+install-data: install-data-am -+uninstall: uninstall-am -+ -+install-am: all-am -+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -+ -+installcheck: installcheck-am -+install-strip: -+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ -+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ -+ `test -z '$(STRIP)' || \ -+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -+mostlyclean-generic: -+ -+clean-generic: -+ -+distclean-generic: -+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -+ -+maintainer-clean-generic: -+ @echo "This command is intended for maintainers to use" -+ @echo "it deletes files that may require special tools to rebuild." -+clean: clean-am -+ -+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am -+ -+distclean: distclean-am -+ -rm -rf ./$(DEPDIR) -+ -rm -f Makefile -+distclean-am: clean-am distclean-compile distclean-generic \ -+ distclean-tags -+ -+dvi: dvi-am -+ -+dvi-am: -+ -+html: html-am -+ -+html-am: -+ -+info: info-am -+ -+info-am: -+ -+install-data-am: -+ -+install-dvi: install-dvi-am -+ -+install-dvi-am: -+ -+install-exec-am: install-binPROGRAMS -+ -+install-html: install-html-am -+ -+install-html-am: -+ -+install-info: install-info-am -+ -+install-info-am: -+ -+install-man: -+ -+install-pdf: install-pdf-am -+ -+install-pdf-am: -+ -+install-ps: install-ps-am -+ -+install-ps-am: -+ -+installcheck-am: -+ -+maintainer-clean: maintainer-clean-am -+ -rm -rf ./$(DEPDIR) -+ -rm -f Makefile -+maintainer-clean-am: distclean-am maintainer-clean-generic -+ -+mostlyclean: mostlyclean-am -+ -+mostlyclean-am: mostlyclean-compile mostlyclean-generic -+ -+pdf: pdf-am -+ -+pdf-am: -+ -+ps: ps-am -+ -+ps-am: -+ -+uninstall-am: uninstall-binPROGRAMS -+ -+.MAKE: install-am install-strip -+ -+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ -+ clean-generic ctags distclean distclean-compile \ -+ distclean-generic distclean-tags distdir dvi dvi-am html \ -+ html-am info info-am install install-am install-binPROGRAMS \ -+ install-data install-data-am install-dvi install-dvi-am \ -+ install-exec install-exec-am install-html install-html-am \ -+ install-info install-info-am install-man install-pdf \ -+ install-pdf-am install-ps install-ps-am install-strip \ -+ installcheck installcheck-am installdirs maintainer-clean \ -+ maintainer-clean-generic mostlyclean mostlyclean-compile \ -+ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ -+ uninstall-am uninstall-binPROGRAMS -+ -+ -+# Tell versions [3.59,3.63) of GNU make to not export all variables. -+# Otherwise a system limit (for SysV at least) may be exceeded. -+.NOEXPORT: -diff -durpN unrtf-0.21.2.old/src/Makefile.am unrtf-0.21.2/src/Makefile.am ---- unrtf-0.21.2.old/src/Makefile.am 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/Makefile.am 2013-01-17 02:41:09.685864239 +0100 -@@ -13,7 +13,6 @@ unrtf_SOURCES = attr.c attr.h \ - malloc.c malloc.h \ - output.c output.h \ - parse.c parse.h \ -- path.c path.h \ - unicode.c unicode.h \ - user.c user.h \ - util.c util.h \ -diff -durpN unrtf-0.21.2.old/src/malloc.c unrtf-0.21.2/src/malloc.c ---- unrtf-0.21.2.old/src/malloc.c 2010-07-09 07:13:05.000000000 +0200 -+++ unrtf-0.21.2/src/malloc.c 2013-01-17 02:41:09.685864239 +0100 -@@ -28,6 +28,8 @@ - * much memory is being used. - *---------------------------------------------------------------------- - * Changes: -+ * 21 Aug 12, wsourdeau@inverse.ca: renamed "my_*" to "unrtf_*", to -+ * avoid symbol classes with other libraries - * 14 Aug 01, tuorfa@yahoo.com: added Turbo C support. - * 16 Aug 01, Lars Unger : added Amiga/GCC support. - * 22 Sep 01, tuorfa@yahoo.com: added function-level comment blocks -@@ -35,7 +37,7 @@ - * 08 Oct 03, daved@physiol.usyd.edu.au: added stdlib.h for linux - * 29 Mar 05, daved@physiol.usyd.edu.au: changes requested by ZT Smith - * 16 Dec 07, daved@physiol.usyd.edu.au: updated to GPL v3 -- * 09 Nov 08, arkadiusz.firus@gmail.com: added my_realloc -+ * 09 Nov 08, arkadiusz.firus@gmail.com: added unrtf_realloc - *--------------------------------------------------------------------*/ - - #ifdef HAVE_CONFIG_H -@@ -60,14 +62,14 @@ - static unsigned long count=0; - - /*======================================================================== -- * Name: my_malloc -+ * Name: unrtf_malloc - * Purpose: Internal version of malloc necessary for record keeping. - * Args: Amount. - * Returns: Pointer. - *=======================================================================*/ - - char * --my_malloc (unsigned long size) { -+unrtf_malloc (unsigned long size) { - char *ptr; - - ptr = malloc (size); -@@ -78,14 +80,14 @@ my_malloc (unsigned long size) { - } - - /*======================================================================== -- * Name: my_free -+ * Name: unrtf_free - * Purpose: Internal version of free necessary for record keeping. - * Args: Pointer. - * Returns: None. - *=======================================================================*/ - - void --my_free (char* ptr) { -+unrtf_free (char* ptr) { - CHECK_PARAM_NOT_NULL(ptr); - - free (ptr); -@@ -93,20 +95,20 @@ my_free (char* ptr) { - - #if 1 /* AK3 - AF */ - /*======================================================================== -- * Name: my_realloc -+ * Name: unrtf_realloc - * Purpose: Internal version of realloc necessary for record keeping. - * Args: Pointer. - * Returns: None. - *=======================================================================*/ - char * --my_realloc(char *ptr, unsigned long old_size, unsigned long new_size) -+unrtf_realloc(char *ptr, unsigned long old_size, unsigned long new_size) - { -- char *new_ptr = my_malloc(new_size); -+ char *new_ptr = unrtf_malloc(new_size); - - if (new_ptr != NULL) - memcpy(new_ptr, ptr, old_size); - -- my_free(ptr); -+ unrtf_free(ptr); - - return new_ptr; - } -@@ -128,26 +130,26 @@ total_malloced (void) { - - - /*======================================================================== -- * Name: my_strdup -+ * Name: unrtf_strdup - * Purpose: Internal version of strdup necessary for record keeping. - * Args: String. - * Returns: String. - *=======================================================================*/ - - char * --my_strdup (char *src) { -- unsigned long len; -- char *ptr; -+unrtf_strdup (struct ConversionContext *cc, char *src) { -+ unsigned long len; -+ char *ptr; - -- CHECK_PARAM_NOT_NULL(src); -+ CHECK_PARAM_NOT_NULL(src); - -- len = strlen(src); -- ptr = my_malloc (len+1); -- if (!ptr) -- error_handler ("out of memory in strdup()"); -+ len = strlen(src); -+ ptr = unrtf_malloc (len+1); -+ if (!ptr) -+ error_handler (cc, "out of memory in strdup()"); - -- strcpy (ptr, src); -- return ptr; -+ sprintf (ptr, "%s", src); -+ return ptr; - } - /* added by daved */ - #include -@@ -163,5 +165,5 @@ rpl_malloc (size_t n) - { - if (n == 0) - n = 1; --return malloc (n); -+ return malloc (n); - } -diff -durpN unrtf-0.21.2.old/src/malloc.c.orig unrtf-0.21.2/src/malloc.c.orig ---- unrtf-0.21.2.old/src/malloc.c.orig 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/malloc.c.orig 1970-01-01 01:00:00.000000000 +0100 -@@ -1,152 +0,0 @@ --/*============================================================================= -- GNU UnRTF, a command-line program to convert RTF documents to other formats. -- Copyright (C) 2000,2001,2004 by Zachary Smith -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- -- The maintainer is reachable by electronic mail at daved@physiol.usyd.edu.au --=============================================================================*/ -- -- --/*---------------------------------------------------------------------- -- * Module name: malloc -- * Author name: Zachary Smith -- * Create date: 01 Aug 01 -- * Purpose: Memory management. Allows us to keep track of how -- * much memory is being used. -- *---------------------------------------------------------------------- -- * Changes: -- * 14 Aug 01, tuorfa@yahoo.com: added Turbo C support. -- * 16 Aug 01, Lars Unger : added Amiga/GCC support. -- * 22 Sep 01, tuorfa@yahoo.com: added function-level comment blocks -- * 28 Sep 01, tuorfa@yahoo.com: removed Turbo C support. -- * 08 Oct 03, daved@physiol.usyd.edu.au: added stdlib.h for linux -- * 29 Mar 05, daved@physiol.usyd.edu.au: changes requested by ZT Smith -- * 16 Dec 07, daved@physiol.usyd.edu.au: updated to GPL v3 -- * 09 Nov 08, arkadiusz.firus@gmail.com: added my_realloc -- *--------------------------------------------------------------------*/ -- --#ifdef HAVE_CONFIG_H --#include --#endif -- --#ifdef HAVE_STDIO_H --#include --#endif -- --#ifdef HAVE_STDLIB_H --#include --#endif -- --#ifdef HAVE_STRING_H --#include --#endif -- --#include "error.h" --#include "malloc.h" -- --static unsigned long count=0; -- --/*======================================================================== -- * Name: my_malloc -- * Purpose: Internal version of malloc necessary for record keeping. -- * Args: Amount. -- * Returns: Pointer. -- *=======================================================================*/ -- --char * --my_malloc (unsigned long size) { -- char *ptr; -- -- ptr = malloc (size); -- if (ptr) -- count += size; -- -- return ptr; --} -- --/*======================================================================== -- * Name: my_free -- * Purpose: Internal version of free necessary for record keeping. -- * Args: Pointer. -- * Returns: None. -- *=======================================================================*/ -- --void --my_free (char* ptr) { -- CHECK_PARAM_NOT_NULL(ptr); -- -- free (ptr); --} -- --#if 1 /* AK3 - AF */ --/*======================================================================== -- * Name: my_realloc -- * Purpose: Internal version of realloc necessary for record keeping. -- * Args: Pointer. -- * Returns: None. -- *=======================================================================*/ --char * --my_realloc(char *ptr, unsigned long old_size, unsigned long new_size) --{ -- char *new_ptr = my_malloc(new_size); -- -- if (new_ptr != NULL) -- memcpy(new_ptr, ptr, old_size); -- -- my_free(ptr); -- -- return new_ptr; --} --#endif -- --/*======================================================================== -- * Name: total_malloced -- * Purpose: Returns total amount of memory thus far allocated. Called at -- * the end of main() when in debug mode. -- * Args: None. -- * Returns: Amount. -- *=======================================================================*/ -- --unsigned long --total_malloced (void) { -- return count; --} -- -- -- --/*======================================================================== -- * Name: my_strdup -- * Purpose: Internal version of strdup necessary for record keeping. -- * Args: String. -- * Returns: String. -- *=======================================================================*/ -- --char * --my_strdup (char *src) { -- unsigned long len; -- char *ptr; -- -- CHECK_PARAM_NOT_NULL(src); -- -- len = strlen(src); -- ptr = my_malloc (len+1); -- if (!ptr) -- error_handler ("out of memory in strdup()"); -- -- strcpy (ptr, src); -- return ptr; --} -- -diff -durpN unrtf-0.21.2.old/src/malloc.h unrtf-0.21.2/src/malloc.h ---- unrtf-0.21.2.old/src/malloc.h 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/malloc.h 2013-01-17 02:41:09.685864239 +0100 -@@ -32,9 +32,10 @@ - * 09 Nov 08, arkadiusz.firus@gmail.com: added my_realloc - *--------------------------------------------------------------------*/ - --extern char * my_malloc (unsigned long); --extern void my_free (char*); --extern char * my_realloc(char*, unsigned long, unsigned long); --extern unsigned long total_malloced (void); --extern char * my_strdup (char*); -+struct ConversionContext; - -+extern char * unrtf_malloc (unsigned long); -+extern void unrtf_free (char*); -+extern char * unrtf_realloc(char*, unsigned long, unsigned long); -+extern unsigned long total_malloced (void); -+extern char * unrtf_strdup (struct ConversionContext *, char*); -diff -durpN unrtf-0.21.2.old/src/my_iconv.c unrtf-0.21.2/src/my_iconv.c ---- unrtf-0.21.2.old/src/my_iconv.c 2010-08-16 06:12:43.000000000 +0200 -+++ unrtf-0.21.2/src/my_iconv.c 2013-01-17 02:41:09.685864239 +0100 -@@ -12,154 +12,133 @@ - #include - #include - --#include "malloc.h" --#include "my_iconv.h" --#include "util.h" - #if 1 /* daved 0.21.1 */ - #include "unicode.h" --#include "path.h" - #include - #include - #endif - --extern int verbose_mode; -+#include "convert.h" -+#include "malloc.h" -+#include "my_iconv.h" -+#include "util.h" -+#include "unrtf.h" -+ -+#define MY_ICONV_T_CLEAR {(iconv_t) -1, NULL} - - my_iconv_t --my_iconv_open(const char *tocode, const char *fromcode) -+my_iconv_open(const struct ConversionContext *cc, const char *tocode, const char *fromcode) - { -- char *path; -- FILE *f; -- my_iconv_t cd = MY_ICONV_T_CLEAR; -- int c, i; -+ char *path; -+ FILE *f; -+ my_iconv_t cd = MY_ICONV_T_CLEAR; -+ int c, i; - -- if ((cd.desc = iconv_open(tocode, fromcode)) == (iconv_t) -1) -- { --#if 1 /* daved 0.21.1 */ -- struct path_dir *path_dir_p; -- char u_success=0; -- for(path_dir_p = &topdir; path_dir_p->dir_name; path_dir_p = path_dir_p->next) -- { -- char *p; -- p = path_dir_p->dir_name; -- if(*(p+strlen(p)-1) != '/') -- p = concatenate(p, "/"); -- p = concatenate(p, fromcode); -- path=concatenate(p, ".charmap"); -- if(access(path, F_OK|R_OK)) -- continue; -- u_success++; -- break; -- } -- if(!u_success) -- { --#else -- path = concatenate(CHARMAP_DIR, fromcode); --#endif --#if 1 /* daved 0.21.1 */ -- } -- if((f = fopen(path, "r")) == NULL && verbose_mode) -- fprintf(stderr, "failed to open charmap file %s\n", path); --#else -- f = fopen(path, "r"); --#endif -+ if ((cd.desc = iconv_open(tocode, fromcode)) == (iconv_t) -1) -+ { -+ path = unrtf_malloc((strlen(cc->options->config_directory) + strlen(fromcode) + 10) * sizeof(char)); -+ sprintf (path, "%s/%s.charmap", cc->options->config_directory, fromcode); - -- if (f != NULL) -- { -- cd.char_table = (char **)my_malloc(char_table_size * sizeof(char *)); -- c = fgetc(f); -+ if((f = fopen(path, "r")) == NULL && cc->options->verbose_mode) -+ fprintf(stderr, "failed to open charmap file %s\n", path); - -- for (i = 0; i < char_table_size && c != EOF; i++) -- { -- if (c == '<') -- cd.char_table[i] = get_unicode_char(f); -- leave_line(f); -- c = fgetc(f); -- } -+ if (f != NULL) -+ { -+ cd.char_table = (char **)unrtf_malloc(char_table_size * sizeof(char *)); -+ c = fgetc(f); - -- fclose(f); -- } -+ for (i = 0; i < char_table_size && c != EOF; i++) -+ { -+ if (c == '<') -+ cd.char_table[i] = get_unicode_char(f); -+ leave_line(f); -+ c = fgetc(f); -+ } - -- my_free(path); -- } -+ fclose(f); -+ } - -- return cd; -+ unrtf_free(path); -+ } -+ -+ return cd; - } - - size_t - my_iconv(my_iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) - { -- int c, i; -- size_t result = 0; -+ int c, i; -+ size_t result = 0; - -- if (cd.desc == (iconv_t) -1) { -- if (cd.char_table != NULL) -- { -- while (*inbytesleft > 0 && *outbytesleft > 0) -- { -- c = (int) **inbuf; -- if (c < 0) -- c = 256 + c; -+ if (cd.desc == (iconv_t) -1) { -+ if (cd.char_table != NULL) -+ { -+ while (*inbytesleft > 0 && *outbytesleft > 0) -+ { -+ c = (int) **inbuf; -+ if (c < 0) -+ c = 256 + c; - -- if (cd.char_table[c] != NULL) -- { -- for (i = 0; cd.char_table[c][i] != '\0' && *outbytesleft > 0; i++) -- { -- **outbuf = cd.char_table[c][i]; -- (*outbytesleft)--; -- (*outbuf)++; -- } -- } -+ if (cd.char_table[c] != NULL) -+ { -+ for (i = 0; cd.char_table[c][i] != '\0' && *outbytesleft > 0; i++) -+ { -+ **outbuf = cd.char_table[c][i]; -+ (*outbytesleft)--; -+ (*outbuf)++; -+ } -+ } - -- (*inbuf)++; -- (*inbytesleft)--; -- result++; -- } -- } -- } -- else -- result = iconv(cd.desc, inbuf, inbytesleft, outbuf, outbytesleft); -+ (*inbuf)++; -+ (*inbytesleft)--; -+ result++; -+ } -+ } -+ } -+ else -+ result = iconv(cd.desc, inbuf, inbytesleft, outbuf, outbytesleft); - -- return result; -+ return result; - } - - my_iconv_t - my_iconv_close(my_iconv_t cd) - { -- int i; -+ int i; - -- if (cd.char_table != NULL) -- { -- for (i = 0; i < char_table_size; i++) -- { -- my_free(cd.char_table[i]); -- } -+ if (cd.char_table != NULL) -+ { -+ for (i = 0; i < char_table_size; i++) -+ { -+ unrtf_free(cd.char_table[i]); -+ } - -- my_free((void *)cd.char_table); -- cd.char_table = NULL; -- } -+ unrtf_free((void *)cd.char_table); -+ cd.char_table = NULL; -+ } - -- if (cd.desc != (iconv_t) -1) -- { -- iconv_close(cd.desc); -- cd.desc = (iconv_t) -1; -- } -+ if (cd.desc != (iconv_t) -1) -+ { -+ iconv_close(cd.desc); -+ cd.desc = (iconv_t) -1; -+ } - -- return cd; -+ return cd; - } - - int - my_iconv_is_valid (my_iconv_t cd) - { -- if (cd.desc != (iconv_t) -1 || cd.char_table != NULL) -- return 1; -+ if (cd.desc != (iconv_t) -1 || cd.char_table != NULL) -+ return 1; - -- return 0; -+ return 0; - } - - void - my_iconv_t_make_invalid(my_iconv_t *cd) - { -- cd->desc = (iconv_t) -1; -- cd->char_table = NULL; -+ cd->desc = (iconv_t) -1; -+ cd->char_table = NULL; - } - -diff -durpN unrtf-0.21.2.old/src/my_iconv.h unrtf-0.21.2/src/my_iconv.h ---- unrtf-0.21.2.old/src/my_iconv.h 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/my_iconv.h 2013-01-17 02:41:09.685864239 +0100 -@@ -5,6 +5,9 @@ - * Purpose: my_conv definitions - *--------------------------------------------------------------------*/ - -+#ifndef _MY_ICONV -+#define _MY_ICONV 1 -+ - #ifndef HAVE_ICONV_H - #include - #define HAVE_ICONV_H -@@ -19,9 +22,9 @@ typedef struct - char **char_table; - } my_iconv_t; - --#define MY_ICONV_T_CLEAR {(iconv_t) -1, NULL} -+struct ConversionContext; - --my_iconv_t my_iconv_open(const char *tocode, const char *fromcode); -+my_iconv_t my_iconv_open(const struct ConversionContext *cc, const char *tocode, const char *fromcode); - - size_t my_iconv(my_iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); - -@@ -31,3 +34,4 @@ int my_iconv_is_valid(my_iconv_t cd); - - void my_iconv_t_make_invalid(my_iconv_t *cd); - -+#endif /* _MY_ICONV */ -diff -durpN unrtf-0.21.2.old/src/output.c unrtf-0.21.2/src/output.c ---- unrtf-0.21.2.old/src/output.c 2011-06-07 14:04:38.000000000 +0200 -+++ unrtf-0.21.2/src/output.c 2013-01-17 02:41:09.685864239 +0100 -@@ -1,23 +1,23 @@ - /*============================================================================= -- GNU UnRTF, a command-line program to convert RTF documents to other formats. -- Copyright (C) 2000,2001,2004 by Zachary Smith -+ GNU UnRTF, a command-line program to convert RTF documents to other formats. -+ Copyright (C) 2000,2001,2004 by Zachary Smith - -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. - -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. - -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -- The maintainer is reachable by electronic mail at daved@physiol.usyd.edu.au --=============================================================================*/ -+ The maintainer is reachable by electronic mail at daved@physiol.usyd.edu.au -+ =============================================================================*/ - - - /*---------------------------------------------------------------------- -@@ -38,7 +38,7 @@ - * David Santinoli - * 09 Nov 08, arkadiusz.firus@gmail.com: use iconv - * 21 Aug 10, daved@physiol.usyd.edu.au: add code to deal with character -- doublets (see convert.c) -+ doublets (see convert.c) - *--------------------------------------------------------------------*/ - - -@@ -64,7 +64,8 @@ - #include "output.h" - #include "main.h" - #include "convert.h" -- -+#include "unrtf.h" -+#include "user.h" - - #ifndef HAVE_ATTR_H - #include "attr.h" -@@ -79,16 +80,16 @@ - *=======================================================================*/ - - OutputPersonality* --op_create () -+op_create (const struct ConversionContext *cc) - { -- OutputPersonality* new_op; -+ OutputPersonality* new_op; - -- new_op = (OutputPersonality*) my_malloc (sizeof(OutputPersonality)); -- if (!new_op) -- error_handler ("cannot allocate output personality"); -+ new_op = (OutputPersonality*) unrtf_malloc (sizeof(OutputPersonality)); -+ if (!new_op) -+ error_handler (cc, "cannot allocate output personality"); - -- memset ((void*) new_op, 0, sizeof (OutputPersonality)); -- return new_op; -+ memset ((void*) new_op, 0, sizeof (OutputPersonality)); -+ return new_op; - } - - /*======================================================================== -@@ -102,13 +103,15 @@ op_create () - void - op_free (OutputPersonality *op) - { -- CHECK_PARAM_NOT_NULL(op); -- -- my_free ((void*) op); --} -+ CHECK_PARAM_NOT_NULL(op); - -+ free_user_definitions(op); - -+ if (op->aliases) -+ free_collection(op->aliases); - -+ unrtf_free ((void*) op); -+} - - /*======================================================================== - * Name: op_translate_char -@@ -119,102 +122,113 @@ op_free (OutputPersonality *op) - *=======================================================================*/ - - char * --op_translate_char (OutputPersonality *op, my_iconv_t cd, int ch) -+op_translate_char (const struct ConversionContext *cc, const OutputPersonality *op, int ch) - { -- short start; -- char *result=NULL; -- static char output_buffer[2]={ 0, 0 }; -- char *inbuf, *outbuf; -- size_t inbytes = (ch / 256) + 1, outbytes = inbytes * 4, i; -+ char *result=NULL; -+ static char output_buffer[2]={ 0, 0 }; -+ char *inbuf, *outbuf, *originbuf, *origoutbuf, *alias; -+ size_t inbytes = (ch / 256) + 1, outbytes = inbytes * 4, i; -+ my_iconv_t cd; - -- CHECK_PARAM_NOT_NULL(op); -+ CHECK_PARAM_NOT_NULL(op); - -- if (no_remap_mode == TRUE && ch < 256) -- { -- output_buffer[0]=ch; -- result=output_buffer; -- } -- else -- if (result == NULL) -- { -- inbuf = my_malloc(inbytes + 1); -- outbuf = my_malloc(outbytes + 1); -+ if (cc->options->no_remap_mode == TRUE && ch < 256) -+ { -+ output_buffer[0]=ch; -+ result=strdup(output_buffer); -+ } -+ else -+ if (result == NULL) -+ { -+ originbuf = inbuf = unrtf_malloc(inbytes + 1); -+ origoutbuf = outbuf = unrtf_malloc(outbytes + 1); - -- for (i = inbytes - 1; ch > 255; i--) -- { -- inbuf[i] = ch % 256; -- ch /= 256; -- } -+ for (i = inbytes - 1; ch > 255; i--) -+ { -+ inbuf[i] = ch % 256; -+ ch /= 256; -+ } - -- inbuf[0] = ch; -- inbuf[inbytes] = '\0'; -- i = outbytes; -- if (!my_iconv_is_valid(cd)) -- { -- cd = my_iconv_open("UTF-8", "cp1252"); -+ inbuf[0] = ch; -+ inbuf[inbytes] = '\0'; -+ i = outbytes; -+ if (!my_iconv_is_valid(cc->desc)) -+ { -+ cd = my_iconv_open(cc, "UTF-8", "cp1252"); - -- if (my_iconv(cd, &inbuf, &inbytes, &outbuf, &outbytes) == -1) -- { -+ if (my_iconv(cd, &inbuf, &inbytes, &outbuf, &outbytes) == -1) -+ { - #if 1 /* daved */ -- fprintf(stderr, "unrtf: Error in executing iconv1\n"); -+ fprintf(stderr, "unrtf: Error in executing iconv1\n"); - #else -- fprintf(stderr, "unrtf: Error in executing iconv1\n"); -+ fprintf(stderr, "unrtf: Error in executing iconv1\n"); - #endif -- return NULL; -- } -+ free (originbuf); -+ free (origoutbuf); -+ return NULL; -+ } - -- my_iconv_close(cd); -- } -- else -+ my_iconv_close(cd); -+ } -+ else - -- if (my_iconv(cd, &inbuf, &inbytes, &outbuf, &outbytes) == -1) -- { -- fprintf(stderr, "unrtf: Error in executing iconv\n"); -- return NULL; -- } -- *outbuf = '\0'; -- outbuf -= i - outbytes; --/* Conversion from string to utf8 code number */ -- inbytes = 0; -+ if (my_iconv(cc->desc, &inbuf, &inbytes, &outbuf, &outbytes) == -1) -+ { -+ fprintf(stderr, "unrtf: Error in executing iconv\n"); -+ free (originbuf); -+ free (origoutbuf); -+ return NULL; -+ } -+ *outbuf = '\0'; -+ outbuf -= i - outbytes; -+ /* Conversion from string to utf8 code number */ -+ inbytes = 0; - -- for (i = 0; outbuf[i] != '\0'; i++) -- inbytes++; -+ for (i = 0; outbuf[i] != '\0'; i++) -+ inbytes++; - -- ch = 0; -+ ch = 0; - -- for (i = 0; i < inbytes; i++) -- { -- if (i == 0) -- switch (inbytes) -- { -- case 1: -- ch = outbuf[0]; -- break; -- case 2: -- ch = (unsigned char) outbuf[0] - 192; -- break; -- case 3: -- ch = (unsigned char) outbuf[0] - 224; -- break; -- case 4: -- ch = (unsigned char) outbuf[0] - 240; -- break; -- } -- else -- ch = (ch * 64) + ((unsigned char) outbuf[i] - 128); -- } --/* End of conversion*/ -+ for (i = 0; i < inbytes; i++) -+ { -+ if (i == 0) -+ switch (inbytes) -+ { -+ case 1: -+ ch = outbuf[0]; -+ break; -+ case 2: -+ ch = (unsigned char) outbuf[0] - 192; -+ break; -+ case 3: -+ ch = (unsigned char) outbuf[0] - 224; -+ break; -+ case 4: -+ ch = (unsigned char) outbuf[0] - 240; -+ break; -+ } -+ else -+ ch = (ch * 64) + ((unsigned char) outbuf[i] - 128); -+ } -+ /* End of conversion*/ - -- result = get_alias(op, ch); -+ alias = get_alias(op, ch); - -- if (result == NULL) -- if (ch > 127 && op->unisymbol_print) -- result = assemble_string(op->unisymbol_print, ch); -- else -- result = outbuf; -- } -+ if (alias == NULL) -+ { -+ if (ch > 127 && op->unisymbol_print) -+ result = assemble_string(op->unisymbol_print, ch); -+ else -+ result = strdup(outbuf); -+ } -+ else -+ result = strdup(alias); - -- return result; -+ free (originbuf); -+ free (origoutbuf); -+ } -+ -+ return result; - } - - #if 0 /* daved - 0.21.2 */ -@@ -227,123 +241,122 @@ op_translate_char (OutputPersonality *op - *=======================================================================*/ - - char * --op_translate_str (OutputPersonality *op, my_iconv_t cd, int * doublet) -+op_translate_str (const struct ConversionContext *cc, OutputPersonality *op, my_iconv_t cd, int * doublet) - { -- short start; -- char *result=NULL; -- static char output_buffer[3]={ 0, 0, 0 }; -- unsigned char *inbuf; -- char *outbuf; -- int ch; -+ char *result=NULL; -+ static char output_buffer[3]={ 0, 0, 0 }; -+ unsigned char *inbuf; -+ char *outbuf; -+ int ch; - -- fprintf(stderr, "doublet = %o %o\n", *doublet, *(doublet+1)); -+ fprintf(stderr, "doublet = %o %o\n", *doublet, *(doublet+1)); - #if 0 -- size_t inbytes = (ch / 256) + 1, outbytes = inbytes * 4, i; -+ size_t inbytes = (ch / 256) + 1, outbytes = inbytes * 4, i; - #else -- size_t inbytes = 3, outbytes = inbytes * 4, i; -+ size_t inbytes = 3, outbytes = inbytes * 4, i; - #endif - -- CHECK_PARAM_NOT_NULL(op); -+ CHECK_PARAM_NOT_NULL(op); - - #if 0 -- if (no_remap_mode == TRUE && ch < 256) -- { -- output_buffer[0]=ch; -- result=output_buffer; -- } -- else -- if (result == NULL) -- { -+ if (cc->options->no_remap_mode == TRUE && ch < 256) -+ { -+ output_buffer[0]=ch; -+ result=output_buffer; -+ } -+ else -+ if (result == NULL) -+ { - #endif -- inbuf = (char *) my_malloc(inbytes + 1); -- *inbuf = *doublet; -- *(inbuf+1) = (unsigned char *) *(doublet+1); -- *(inbuf+2) = 0; -- fprintf(stderr, "inbuf = %o %o\n", *inbuf, *(inbuf+1)); -- outbuf = my_malloc(outbytes + 1); -+ inbuf = (char *) unrtf_malloc(inbytes + 1); -+ *inbuf = *doublet; -+ *(inbuf+1) = (unsigned char *) *(doublet+1); -+ *(inbuf+2) = 0; -+ fprintf(stderr, "inbuf = %o %o\n", *inbuf, *(inbuf+1)); -+ outbuf = unrtf_malloc(outbytes + 1); - - #if 0 - -- for (i = inbytes - 1; ch > 255; i--) -- { -- inbuf[i] = ch % 256; -- ch /= 256; -- } -+ for (i = inbytes - 1; ch > 255; i--) -+ { -+ inbuf[i] = ch % 256; -+ ch /= 256; -+ } - -- inbuf[0] = ch; -- inbuf[inbytes] = '\0'; -+ inbuf[0] = ch; -+ inbuf[inbytes] = '\0'; - #endif -- i = outbytes; -- if (!my_iconv_is_valid(cd)) -- { -- cd = my_iconv_open("UTF-8", "cp1252"); -+ i = outbytes; -+ if (!my_iconv_is_valid(cd)) -+ { -+ cd = my_iconv_open("UTF-8", "cp1252"); - -- if (my_iconv(cd, &inbuf, &inbytes, &outbuf, &outbytes) == -1) -- { -- fprintf(stderr, "unrtf: Error in executing iconv1\n"); -- return NULL; -- } -+ if (my_iconv(cd, &inbuf, &inbytes, &outbuf, &outbytes) == -1) -+ { -+ fprintf(stderr, "unrtf: Error in executing iconv1\n"); -+ return NULL; -+ } - -- my_iconv_close(cd); -- } -- else -- { -+ my_iconv_close(cd); -+ } -+ else -+ { - -- if (my_iconv(cd, &inbuf, &inbytes, &outbuf, &outbytes) == -1) -- { -+ if (my_iconv(cd, &inbuf, &inbytes, &outbuf, &outbytes) == -1) -+ { - #if 1 /* daved */ -- fprintf(stderr, "unrtf: Error in executing iconv - inbytes=%d inbuf[0]=%o inbuf[1]=%o\n", inbytes, inbuf[0], inbuf[1]); -+ fprintf(stderr, "unrtf: Error in executing iconv - inbytes=%d inbuf[0]=%o inbuf[1]=%o\n", inbytes, inbuf[0], inbuf[1]); - #else -- fprintf(stderr, "unrtf: Error in executing iconv\n"); -+ fprintf(stderr, "unrtf: Error in executing iconv\n"); - #endif -- return NULL; -- } -- } -- *outbuf = '\0'; -- outbuf -= i - outbytes; --/* Conversion from string to utf8 code number */ -- inbytes = 0; -+ return NULL; -+ } -+ } -+ *outbuf = '\0'; -+ outbuf -= i - outbytes; -+ /* Conversion from string to utf8 code number */ -+ inbytes = 0; - -- for (i = 0; outbuf[i] != '\0'; i++) -- inbytes++; -+ for (i = 0; outbuf[i] != '\0'; i++) -+ inbytes++; - -- ch = 0; -+ ch = 0; - -- for (i = 0; i < inbytes; i++) -- { -- if (i == 0) -- switch (inbytes) -- { -- case 1: -- ch = outbuf[0]; -- break; -- case 2: -- ch = (unsigned char) outbuf[0] - 192; -- break; -- case 3: -- ch = (unsigned char) outbuf[0] - 224; -- break; -- case 4: -- ch = (unsigned char) outbuf[0] - 240; -- break; -- } -- else -- ch = (ch * 64) + ((unsigned char) outbuf[i] - 128); -- } --/* End of conversion*/ -+ for (i = 0; i < inbytes; i++) -+ { -+ if (i == 0) -+ switch (inbytes) -+ { -+ case 1: -+ ch = outbuf[0]; -+ break; -+ case 2: -+ ch = (unsigned char) outbuf[0] - 192; -+ break; -+ case 3: -+ ch = (unsigned char) outbuf[0] - 224; -+ break; -+ case 4: -+ ch = (unsigned char) outbuf[0] - 240; -+ break; -+ } -+ else -+ ch = (ch * 64) + ((unsigned char) outbuf[i] - 128); -+ } -+ /* End of conversion*/ - -- result = get_alias(op, ch); -+ result = get_alias(op, ch); - -- if (result == NULL) -- if (ch > 127 && op->unisymbol_print) -- result = assemble_string(op->unisymbol_print, ch); -- else -- result = outbuf; -+ if (result == NULL) -+ if (ch > 127 && op->unisymbol_print) -+ result = assemble_string(op->unisymbol_print, ch); -+ else -+ result = outbuf; - #if 0 /* daved 0.21.2 */ -- } -+ } - #endif - -- return result; -+ return result; - } - #endif - -@@ -357,113 +370,115 @@ op_translate_str (OutputPersonality *op, - *=======================================================================*/ - - char * --op_translate_doublet (OutputPersonality *op, my_iconv_t cd, int ch1, int ch2) -+op_translate_doublet (const struct ConversionContext *cc, const OutputPersonality *op, int ch1, int ch2) - { -- short start; -- char *result=NULL; -- static char output_buffer[3]={ 0, 0, 0 }; -- unsigned char *inbuf; -- char *outbuf; -- int ch; -+ char *result=NULL; -+ static char output_buffer[3]={ 0, 0, 0 }; -+ char *inbuf; -+ char *outbuf; -+ int ch; -+ my_iconv_t cd; - - #if 0 -- size_t inbytes = (ch / 256) + 1, outbytes = inbytes * 4, i; -+ size_t inbytes = (ch / 256) + 1, outbytes = inbytes * 4, i; - #else -- size_t inbytes = 3, outbytes = inbytes * 4, i; -+ size_t inbytes = 3, outbytes = inbytes * 4, i; - #if 0 -- fprintf(stderr, "doublet = %o %o\n", ch1, ch2); -+ fprintf(stderr, "doublet = %o %o\n", ch1, ch2); - #endif - #endif - -- CHECK_PARAM_NOT_NULL(op); -+ CHECK_PARAM_NOT_NULL(op); - -- if (no_remap_mode == TRUE && ch < 256) -- { -- output_buffer[0]=ch1; -- output_buffer[1]=ch2; -- result=output_buffer; -- } -- else -- if (result == NULL) -- { -- inbuf = (char *) my_malloc(inbytes + 1); -- *inbuf = ch1; -- *(inbuf+1) = ch2; -- *(inbuf+2) = 0; -+ if (cc->options->no_remap_mode == TRUE && ch < 256) -+ { -+ output_buffer[0]=ch1; -+ output_buffer[1]=ch2; -+ result=output_buffer; -+ } -+ else -+ if (result == NULL) -+ { -+ inbuf = (char *) unrtf_malloc(inbytes + 1); -+ *inbuf = ch1; -+ *(inbuf+1) = ch2; -+ *(inbuf+2) = 0; - #if 0 -- fprintf(stderr, "inbuf = %o %o\n", *inbuf, *(inbuf+1)); -+ fprintf(stderr, "inbuf = %o %o\n", *inbuf, *(inbuf+1)); - #endif -- outbuf = my_malloc(outbytes + 1); -+ outbuf = unrtf_malloc(outbytes + 1); - -- i = outbytes; -- if (!my_iconv_is_valid(cd)) -- { -- cd = my_iconv_open("UTF-8", "cp1252"); -+ i = outbytes; -+ if (!my_iconv_is_valid(cc->desc)) -+ { -+ cd = my_iconv_open(cc, "UTF-8", "cp1252"); - -- if (my_iconv(cd, (char **)&inbuf, (size_t *)&inbytes, (char **)&outbuf, &outbytes) == -1) -- { -- fprintf(stderr, "unrtf: Error in executing iconv1\n"); -- return NULL; -- } -+ if (my_iconv(cd, (char **)&inbuf, (size_t *)&inbytes, (char **)&outbuf, &outbytes) == -1) -+ { -+ fprintf(stderr, "unrtf: Error in executing iconv1\n"); -+ return NULL; -+ } - -- my_iconv_close(cd); -- } -- else -- { -+ my_iconv_close(cd); -+ } -+ else -+ { - -- if (my_iconv(cd, (char **)&inbuf, (size_t *)&inbytes, (char **)&outbuf, &outbytes) == -1) -- { -+ if (my_iconv(cc->desc, (char **)&inbuf, (size_t *)&inbytes, (char **)&outbuf, &outbytes) == -1) -+ { - #if 1 /* daved */ -- fprintf(stderr, "unrtf: Error in executing iconv - inbytes=%d inbuf[0]=%o inbuf[1]=%o\n", inbytes, inbuf[0], inbuf[1]); -+ fprintf(stderr, "unrtf: Error in executing iconv - inbytes=%d inbuf[0]=%o inbuf[1]=%o\n", inbytes, inbuf[0], inbuf[1]); - #else -- fprintf(stderr, "unrtf: Error in executing iconv\n"); -+ fprintf(stderr, "unrtf: Error in executing iconv\n"); - #endif -- return NULL; -- } -- } -- *outbuf = '\0'; -- outbuf -= i - outbytes; --/* Conversion from string to utf8 code number */ -- inbytes = 0; -+ return NULL; -+ } -+ } -+ *outbuf = '\0'; -+ outbuf -= i - outbytes; -+ /* Conversion from string to utf8 code number */ -+ inbytes = 0; - -- for (i = 0; outbuf[i] != '\0'; i++) -- inbytes++; -+ for (i = 0; outbuf[i] != '\0'; i++) -+ inbytes++; - -- ch = 0; -+ ch = 0; - -- for (i = 0; i < inbytes; i++) -- { -- if (i == 0) -- switch (inbytes) -- { -- case 1: -- ch = outbuf[0]; -- break; -- case 2: -- ch = (unsigned char) outbuf[0] - 192; -- break; -- case 3: -- ch = (unsigned char) outbuf[0] - 224; -- break; -- case 4: -- ch = (unsigned char) outbuf[0] - 240; -- break; -- } -- else -- ch = (ch * 64) + ((unsigned char) outbuf[i] - 128); -- } --/* End of conversion*/ -+ for (i = 0; i < inbytes; i++) -+ { -+ if (i == 0) -+ switch (inbytes) -+ { -+ case 1: -+ ch = outbuf[0]; -+ break; -+ case 2: -+ ch = (unsigned char) outbuf[0] - 192; -+ break; -+ case 3: -+ ch = (unsigned char) outbuf[0] - 224; -+ break; -+ case 4: -+ ch = (unsigned char) outbuf[0] - 240; -+ break; -+ } -+ else -+ ch = (ch * 64) + ((unsigned char) outbuf[i] - 128); -+ } -+ /* End of conversion*/ - -- result = get_alias(op, ch); -+ result = get_alias(op, ch); - -- if (result == NULL) -- if (ch > 127 && op->unisymbol_print) -- result = assemble_string(op->unisymbol_print, ch); -- else -- result = outbuf; -- } -+ if (result == NULL) -+ { -+ if (ch > 127 && op->unisymbol_print) -+ result = assemble_string(op->unisymbol_print, ch); -+ else -+ result = outbuf; -+ } -+ } - -- return result; -+ return result; - } - #endif - /*======================================================================== -@@ -475,123 +490,113 @@ op_translate_doublet (OutputPersonality - *=======================================================================*/ - - void --op_begin_std_fontsize (OutputPersonality *op, int size) -+op_begin_std_fontsize (const OutputContext *oc, int size) - { -- int found_std_expr = FALSE; -+ int found_std_expr = FALSE; -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; - -- CHECK_PARAM_NOT_NULL(op); -+ CHECK_PARAM_NOT_NULL(oc); - -- /* Look for an exact match with a standard point size. -- */ -- switch (size) { -- case 8: -- if (op->fontsize8_begin) { -- if (safe_printf(0, op->fontsize8_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize8_begin"); -- found_std_expr = TRUE; -- } -- break; -- case 10: -- if (op->fontsize10_begin) { -- if (safe_printf(0, op->fontsize10_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize10_begin"); -- found_std_expr = TRUE; -- } -- break; -- case 12: -- if (op->fontsize12_begin) { -- if (safe_printf(0, op->fontsize12_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize12_begin"); -- found_std_expr = TRUE; -- } -- break; -- case 14: -- if (op->fontsize14_begin) { -- if (safe_printf(0, op->fontsize14_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize14_begin"); -- found_std_expr = TRUE; -- } -- break; -- case 18: -- if (op->fontsize18_begin) { -- if (safe_printf(0, op->fontsize18_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize18_begin"); -- found_std_expr = TRUE; -- } -- break; -- case 24: -- if (op->fontsize24_begin) { -- if (safe_printf(0, op->fontsize24_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize24_begin"); -- found_std_expr = TRUE; -- } -- break; -- case 36: -- if (op->fontsize36_begin) { -- if (safe_printf(0, op->fontsize36_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize36_begin"); -- found_std_expr = TRUE; -- } -- break; -- case 48: -- if (op->fontsize48_begin) { -- if (safe_printf(0, op->fontsize48_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize48_begin"); -- found_std_expr = TRUE; -- } -- break; -- } -+ /* Look for an exact match with a standard point size. -+ */ -+ switch (size) { -+ case 8: -+ if (oc->personality->fontsize8_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize8_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize8_begin"); -+ found_std_expr = TRUE; -+ } -+ break; -+ case 10: -+ if (oc->personality->fontsize10_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize10_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize10_begin"); -+ found_std_expr = TRUE; -+ } -+ break; -+ case 12: -+ if (oc->personality->fontsize12_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize12_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize12_begin"); -+ found_std_expr = TRUE; -+ } -+ break; -+ case 14: -+ if (oc->personality->fontsize14_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize14_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize14_begin"); -+ found_std_expr = TRUE; -+ } -+ break; -+ case 18: -+ if (oc->personality->fontsize18_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize18_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize18_begin"); -+ found_std_expr = TRUE; -+ } -+ break; -+ case 24: -+ if (oc->personality->fontsize24_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize24_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize24_begin"); -+ found_std_expr = TRUE; -+ } -+ break; -+ case 36: -+ if (oc->personality->fontsize36_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize36_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize36_begin"); -+ found_std_expr = TRUE; -+ } -+ break; -+ case 48: -+ if (oc->personality->fontsize48_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize48_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize48_begin"); -+ found_std_expr = TRUE; -+ } -+ break; -+ } - -- /* If no exact match, try to write out a change to the -- * exact point size. -- */ -- if (!found_std_expr) { -- if (op->fontsize_begin) { -- char expr[16]; -- sprintf (expr, "%d", size); -- if (safe_printf (1, op->fontsize_begin, expr)) fprintf(stderr, TOO_MANY_ARGS, "fontsize_begin"); -- } else { -- /* If we cannot write out a change for the exact -- * point size, we must approximate to a standard -- * size. -- */ -- if (size<9 && op->fontsize8_begin) { -- if (safe_printf(0, op->fontsize8_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize8_begin"); -- } else -- if (size<11 && op->fontsize10_begin) { -- if (safe_printf(0, op->fontsize10_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize10_begin"); -- } else -- if (size<13 && op->fontsize12_begin) { -- if (safe_printf(0, op->fontsize12_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize12_begin"); -- } else -- if (size<16 && op->fontsize14_begin) { -- if (safe_printf(0, op->fontsize14_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize14_begin"); -- } else -- if (size<21 && op->fontsize18_begin) { -- if (safe_printf(0, op->fontsize18_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize18_begin"); -- } else -- if (size<30 && op->fontsize24_begin) { -- if (safe_printf(0, op->fontsize24_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize24_begin"); -- } else -- if (size<42 && op->fontsize36_begin) { -- if (safe_printf(0, op->fontsize36_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize36_begin"); -- } else -- if (size>40 && op->fontsize48_begin) { -- if (safe_printf(0, op->fontsize48_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize48_begin"); -- } else -- /* If we can't even produce a good approximation, -- * just try to get a font size near 12 point. -- */ -- if (op->fontsize12_begin) -- if (safe_printf(0, op->fontsize12_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize12_begin"); -- else -- if (op->fontsize14_begin) -- if (safe_printf(0, op->fontsize14_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize14_begin"); -- else -- if (op->fontsize10_begin) -- if (safe_printf(0, op->fontsize10_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize10_begin"); -- else -- if (op->fontsize18_begin) -- if (safe_printf(0, op->fontsize18_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize18_begin"); -- else -- if (op->fontsize8_begin) -- if (safe_printf(0, op->fontsize8_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize8_begin"); -- else -- error_handler ("output personality lacks sufficient font size change capability"); -- } -- } -+ /* If no exact match, try to write out a change to the -+ * exact point size. -+ */ -+ if (!found_std_expr) { -+ if (oc->personality->fontsize_begin) { -+ char expr[16]; -+ sprintf (expr, "%d", size); -+ if (safe_printf(device, 1, oc->personality->fontsize_begin, expr)) fprintf(stderr, TOO_MANY_ARGS, "fontsize_begin"); -+ } else { -+ /* If we cannot write out a change for the exact -+ * point size, we must approximate to a standard -+ * size. -+ */ -+ if (size<9 && oc->personality->fontsize8_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize8_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize8_begin"); -+ } else if (size<11 && oc->personality->fontsize10_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize10_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize10_begin"); -+ } else if (size<13 && oc->personality->fontsize12_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize12_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize12_begin"); -+ } else if (size<16 && oc->personality->fontsize14_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize14_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize14_begin"); -+ } else if (size<21 && oc->personality->fontsize18_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize18_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize18_begin"); -+ } else if (size<30 && oc->personality->fontsize24_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize24_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize24_begin"); -+ } else if (size<42 && oc->personality->fontsize36_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize36_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize36_begin"); -+ } else if (size>40 && oc->personality->fontsize48_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize48_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize48_begin"); -+ } else if (oc->personality->fontsize12_begin) { -+ /* If we can't even produce a good approximation, -+ * just try to get a font size near 12 point. -+ */ -+ if (safe_printf(device, 0, oc->personality->fontsize12_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize12_begin"); -+ } else if (oc->personality->fontsize14_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize14_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize14_begin"); -+ } else if (oc->personality->fontsize10_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize10_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize10_begin"); -+ } else if (oc->personality->fontsize18_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize18_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize18_begin"); -+ } else if (oc->personality->fontsize8_begin) { -+ if (safe_printf(device, 0, oc->personality->fontsize8_begin)) fprintf(stderr, TOO_MANY_ARGS, "fontsize8_begin"); -+ } else { -+ error_handler (oc->conversion, "output personality lacks sufficient font size change capability"); -+ } -+ } -+ } - } - - -@@ -604,123 +609,113 @@ op_begin_std_fontsize (OutputPersonality - *=======================================================================*/ - - void --op_end_std_fontsize (OutputPersonality *op, int size) -+op_end_std_fontsize (const OutputContext *oc, int size) - { -- int found_std_expr = FALSE; -+ int found_std_expr = FALSE; -+ const struct unRTFOutputDevice *device = &oc->conversion->options->device; - -- CHECK_PARAM_NOT_NULL(op); -+ CHECK_PARAM_NOT_NULL(oc); - -- /* Look for an exact match with a standard point size. -- */ -- switch (size) { -- case 8: -- if (op->fontsize8_end) { -- if (safe_printf(0, op->fontsize8_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize8_end"); -- found_std_expr = TRUE; -- } -- break; -- case 10: -- if (op->fontsize10_end) { -- if (safe_printf(0, op->fontsize10_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize10_end"); -- found_std_expr = TRUE; -- } -- break; -- case 12: -- if (op->fontsize12_end) { -- if (safe_printf(0, op->fontsize12_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize12_end"); -- found_std_expr = TRUE; -- } -- break; -- case 14: -- if (op->fontsize14_end) { -- if (safe_printf(0, op->fontsize14_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize14_end"); -- found_std_expr = TRUE; -- } -- break; -- case 18: -- if (op->fontsize18_end) { -- if (safe_printf(0, op->fontsize18_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize18_end"); -- found_std_expr = TRUE; -- } -- break; -- case 24: -- if (op->fontsize24_end) { -- if (safe_printf(0, op->fontsize24_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize24_end"); -- found_std_expr = TRUE; -- } -- break; -- case 36: -- if (op->fontsize36_end) { -- if (safe_printf(0, op->fontsize36_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize36_end"); -- found_std_expr = TRUE; -- } -- break; -- case 48: -- if (op->fontsize48_end) { -- if (safe_printf(0, op->fontsize48_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize48_end"); -- found_std_expr = TRUE; -- } -- break; -- } -+ /* Look for an exact match with a standard point size. -+ */ -+ switch (size) { -+ case 8: -+ if (oc->personality->fontsize8_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize8_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize8_end"); -+ found_std_expr = TRUE; -+ } -+ break; -+ case 10: -+ if (oc->personality->fontsize10_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize10_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize10_end"); -+ found_std_expr = TRUE; -+ } -+ break; -+ case 12: -+ if (oc->personality->fontsize12_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize12_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize12_end"); -+ found_std_expr = TRUE; -+ } -+ break; -+ case 14: -+ if (oc->personality->fontsize14_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize14_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize14_end"); -+ found_std_expr = TRUE; -+ } -+ break; -+ case 18: -+ if (oc->personality->fontsize18_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize18_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize18_end"); -+ found_std_expr = TRUE; -+ } -+ break; -+ case 24: -+ if (oc->personality->fontsize24_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize24_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize24_end"); -+ found_std_expr = TRUE; -+ } -+ break; -+ case 36: -+ if (oc->personality->fontsize36_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize36_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize36_end"); -+ found_std_expr = TRUE; -+ } -+ break; -+ case 48: -+ if (oc->personality->fontsize48_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize48_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize48_end"); -+ found_std_expr = TRUE; -+ } -+ break; -+ } - -- /* If no exact match, try to write out a change to the -- * exact point size. -- */ -- if (!found_std_expr) { -- if (op->fontsize_end) { -- char expr[16]; -- sprintf (expr, "%d", size); -- if (safe_printf(1, op->fontsize_end, expr)) fprintf(stderr, TOO_MANY_ARGS, "fontsize_end"); -- } else { -- /* If we cannot write out a change for the exact -- * point size, we must approximate to a standard -- * size. -- */ -- if (size<9 && op->fontsize8_end) { -- if (safe_printf(0, op->fontsize8_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize8_end"); -- } else -- if (size<11 && op->fontsize10_end) { -- if (safe_printf(0, op->fontsize10_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize10_end"); -- } else -- if (size<13 && op->fontsize12_end) { -- if (safe_printf(0, op->fontsize12_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize12_end"); -- } else -- if (size<16 && op->fontsize14_end) { -- if (safe_printf(0, op->fontsize14_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize14_end"); -- } else -- if (size<21 && op->fontsize18_end) { -- if (safe_printf(0, op->fontsize18_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize18_end"); -- } else -- if (size<30 && op->fontsize24_end) { -- if (safe_printf(0, op->fontsize24_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize24_end"); -- } else -- if (size<42 && op->fontsize36_end) { -- if (safe_printf(0, op->fontsize36_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize36_end"); -- } else -- if (size>40 && op->fontsize48_end) { -- if (safe_printf(0, op->fontsize48_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize48_end"); -- } else -- /* If we can't even produce a good approximation, -- * just try to get a font size near 12 point. -- */ -- if (op->fontsize12_end) -- if (safe_printf(0, op->fontsize12_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize12_end"); -- else -- if (op->fontsize14_end) -- if (safe_printf(0, op->fontsize14_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize14_end"); -- else -- if (op->fontsize10_end) -- if (safe_printf(0, op->fontsize10_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize10_end"); -- else -- if (op->fontsize18_end) -- if (safe_printf(0, op->fontsize18_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize18_end"); -- else -- if (op->fontsize8_end) -- if (safe_printf(0, op->fontsize8_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize8_end"); -- else -- error_handler ("output personality lacks sufficient font size change capability"); -- } -- } -+ /* If no exact match, try to write out a change to the -+ * exact point size. -+ */ -+ if (!found_std_expr) { -+ if (oc->personality->fontsize_end) { -+ char expr[16]; -+ sprintf (expr, "%d", size); -+ if (safe_printf(device, 1, oc->personality->fontsize_end, expr)) fprintf(stderr, TOO_MANY_ARGS, "fontsize_end"); -+ } else { -+ /* If we cannot write out a change for the exact -+ * point size, we must approximate to a standard -+ * size. -+ */ -+ if (size<9 && oc->personality->fontsize8_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize8_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize8_end"); -+ } else if (size<11 && oc->personality->fontsize10_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize10_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize10_end"); -+ } else if (size<13 && oc->personality->fontsize12_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize12_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize12_end"); -+ } else if (size<16 && oc->personality->fontsize14_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize14_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize14_end"); -+ } else if (size<21 && oc->personality->fontsize18_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize18_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize18_end"); -+ } else if (size<30 && oc->personality->fontsize24_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize24_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize24_end"); -+ } else if (size<42 && oc->personality->fontsize36_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize36_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize36_end"); -+ } else if (size>40 && oc->personality->fontsize48_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize48_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize48_end"); -+ } else if (oc->personality->fontsize12_end) { -+ /* If we can't even produce a good approximation, -+ * just try to get a font size near 12 point. -+ */ -+ if (safe_printf(device, 0, oc->personality->fontsize12_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize12_end"); -+ } else if (oc->personality->fontsize14_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize14_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize14_end"); -+ } else if (oc->personality->fontsize10_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize10_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize10_end"); -+ } else if (oc->personality->fontsize18_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize18_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize18_end"); -+ } else if (oc->personality->fontsize8_end) { -+ if (safe_printf(device, 0, oc->personality->fontsize8_end)) fprintf(stderr, TOO_MANY_ARGS, "fontsize8_end"); -+ } else { -+ error_handler (oc->conversion, "output personality lacks sufficient font size change capability"); -+ } -+ } -+ } - } - - #if 1 /* AK3 - AF */ -@@ -734,7 +729,7 @@ op_end_std_fontsize (OutputPersonality * - void - add_alias(OutputPersonality *op, int nr, char *text) - { -- op->aliases = (Aliases *)add_to_collection((Collection *)op->aliases, nr, text); -+ op->aliases = (Aliases *)add_to_collection((Collection *)op->aliases, nr, text); - } - - /*======================================================================== -@@ -745,9 +740,8 @@ add_alias(OutputPersonality *op, int nr, - *=======================================================================*/ - - char * --get_alias(OutputPersonality *op, int nr) -+get_alias(const OutputPersonality *op, int nr) - { -- return get_from_collection((Collection *)op->aliases, nr); -+ return get_from_collection((Collection *)op->aliases, nr); - } - #endif -- -diff -durpN unrtf-0.21.2.old/src/output.h unrtf-0.21.2/src/output.h ---- unrtf-0.21.2.old/src/output.h 2010-08-12 03:09:02.000000000 +0200 -+++ unrtf-0.21.2/src/output.h 2013-01-17 02:41:09.685864239 +0100 -@@ -44,227 +44,228 @@ - typedef Collection Aliases; - - typedef struct { -- int cp; -- unsigned short chars[128]; -+ int cp; -+ unsigned short chars[128]; - } CodepageInfo; - -+typedef struct OutputPersonality { -+ char *comment_begin; -+ char *comment_end; - --typedef struct { -- char *comment_begin; -- char *comment_end; -- -- char *document_begin; -- char *document_end; -+ char *document_begin; -+ char *document_end; - -- char *header_begin; -- char *header_end; -+ char *header_begin; -+ char *header_end; - -- char *document_title_begin; -- char *document_title_end; -+ char *document_title_begin; -+ char *document_title_end; - -- char *document_keywords_begin; -- char *document_keywords_end; -+ char *document_keywords_begin; -+ char *document_keywords_end; - -- char *document_author_begin; -- char *document_author_end; -+ char *document_author_begin; -+ char *document_author_end; - -- char *document_changedate_begin; -- char *document_changedate_end; -+ char *document_changedate_begin; -+ char *document_changedate_end; - -- char *body_begin; -- char *body_end; -+ char *body_begin; -+ char *body_end; - -- char *word_begin; -- char *word_end; -+ char *word_begin; -+ char *word_end; - -- char *paragraph_begin; -- char *paragraph_end; -+ char *paragraph_begin; -+ char *paragraph_end; - -- char *center_begin; -- char *center_end; -+ char *center_begin; -+ char *center_end; - -- char *align_left_begin; -- char *align_left_end; -+ char *align_left_begin; -+ char *align_left_end; - -- char *align_right_begin; -- char *align_right_end; -+ char *align_right_begin; -+ char *align_right_end; - -- char *justify_begin; -- char *justify_end; -+ char *justify_begin; -+ char *justify_end; - -- char *forced_space; -- char *line_break; -- char *page_break; -+ char *forced_space; -+ char *line_break; -+ char *page_break; - -- char *hyperlink_begin; -- char *hyperlink_end; -+ char *hyperlink_begin; -+ char *hyperlink_end; - -- char *imagelink_begin; -- char *imagelink_end; -+ char *imagelink_begin; -+ char *imagelink_end; - -- char *table_begin; -- char *table_end; -+ char *table_begin; -+ char *table_end; - -- char *table_row_begin; -- char *table_row_end; -+ char *table_row_begin; -+ char *table_row_end; - -- char *table_cell_begin; -- char *table_cell_end; -+ char *table_cell_begin; -+ char *table_cell_end; - -- /* Character attributes */ -- char *font_begin; -- char *font_end; -+ /* Character attributes */ -+ char *font_begin; -+ char *font_end; - -- char *fontsize_begin; -- char *fontsize_end; -+ char *fontsize_begin; -+ char *fontsize_end; - -- /* standard font sizes are optional */ -- char *fontsize8_begin; -- char *fontsize8_end; -+ /* standard font sizes are optional */ -+ char *fontsize8_begin; -+ char *fontsize8_end; - -- char *fontsize10_begin; -- char *fontsize10_end; -+ char *fontsize10_begin; -+ char *fontsize10_end; - -- char *fontsize12_begin; -- char *fontsize12_end; -+ char *fontsize12_begin; -+ char *fontsize12_end; - -- char *fontsize14_begin; -- char *fontsize14_end; -+ char *fontsize14_begin; -+ char *fontsize14_end; - -- char *fontsize18_begin; -- char *fontsize18_end; -+ char *fontsize18_begin; -+ char *fontsize18_end; - -- char *fontsize24_begin; -- char *fontsize24_end; -+ char *fontsize24_begin; -+ char *fontsize24_end; - -- char *fontsize36_begin; -- char *fontsize36_end; -+ char *fontsize36_begin; -+ char *fontsize36_end; - -- char *fontsize48_begin; -- char *fontsize48_end; -+ char *fontsize48_begin; -+ char *fontsize48_end; - -- char *smaller_begin; -- char *smaller_end; -+ char *smaller_begin; -+ char *smaller_end; - -- char *bigger_begin; -- char *bigger_end; -+ char *bigger_begin; -+ char *bigger_end; - -- char *foreground_begin; -- char *foreground_end; -+ char *foreground_begin; -+ char *foreground_end; - -- char *background_begin; -- char *background_end; -+ char *background_begin; -+ char *background_end; - -- char *bold_begin; -- char *bold_end; -+ char *bold_begin; -+ char *bold_end; - -- char *italic_begin; -- char *italic_end; -+ char *italic_begin; -+ char *italic_end; - -- char *underline_begin; -- char *underline_end; -+ char *underline_begin; -+ char *underline_end; - -- char *dbl_underline_begin; -- char *dbl_underline_end; -+ char *dbl_underline_begin; -+ char *dbl_underline_end; - -- char *superscript_begin; -- char *superscript_end; -+ char *superscript_begin; -+ char *superscript_end; - -- char *subscript_begin; -- char *subscript_end; -+ char *subscript_begin; -+ char *subscript_end; - -- char *strikethru_begin; -- char *strikethru_end; -+ char *strikethru_begin; -+ char *strikethru_end; - -- char *dbl_strikethru_begin; -- char *dbl_strikethru_end; -+ char *dbl_strikethru_begin; -+ char *dbl_strikethru_end; - -- char *emboss_begin; -- char *emboss_end; -+ char *emboss_begin; -+ char *emboss_end; - -- char *engrave_begin; -- char *engrave_end; -+ char *engrave_begin; -+ char *engrave_end; - -- char *shadow_begin; -- char *shadow_end; -+ char *shadow_begin; -+ char *shadow_end; - -- char *outline_begin; -- char *outline_end; -+ char *outline_begin; -+ char *outline_end; - -- char *small_caps_begin; -- char *small_caps_end; -+ char *small_caps_begin; -+ char *small_caps_end; - -- char *pointlist_begin; -- char *pointlist_end; -+ char *pointlist_begin; -+ char *pointlist_end; - -- char *pointlist_item_begin; -- char *pointlist_item_end; -+ char *pointlist_item_begin; -+ char *pointlist_item_end; - -- char *numericlist_begin; -- char *numericlist_end; -+ char *numericlist_begin; -+ char *numericlist_end; - -- char *numericlist_item_begin; -- char *numericlist_item_end; -+ char *numericlist_item_begin; -+ char *numericlist_item_end; - -- char *expand_begin; -- char *expand_end; -+ char *expand_begin; -+ char *expand_end; - -- char *toc_entry_begin; -- char *toc_entry_end; -+ char *toc_entry_begin; -+ char *toc_entry_end; - -- char *index_entry_begin; -- char *index_entry_end; -+ char *index_entry_begin; -+ char *index_entry_end; - -- char *fonttable_begin; -- char *fonttable_end; -- char *fonttable_fontnr; -- char *fonttable_fontname; -+ char *fonttable_begin; -+ char *fonttable_end; -+ char *fonttable_fontnr; -+ char *fonttable_fontname; - -- /* XX These should really be replaced by references -- * to one of the charsets. -- */ -- struct { -- char *bullet; -- char *left_quote; -- char *right_quote; -- char *left_dbl_quote; -- char *right_dbl_quote; -- char *nonbreaking_space; -- char *emdash; -- char *endash; -- char *lessthan; -- char *greaterthan; -- char *amp; -- char *copyright; -- char *trademark; -- char *nonbreaking_hyphen; -- char *optional_hyphen; -- } chars; -+ /* XX These should really be replaced by references -+ * to one of the charsets. -+ */ -+ struct { -+ char *bullet; -+ char *left_quote; -+ char *right_quote; -+ char *left_dbl_quote; -+ char *right_dbl_quote; -+ char *nonbreaking_space; -+ char *emdash; -+ char *endash; -+ char *lessthan; -+ char *greaterthan; -+ char *amp; -+ char *copyright; -+ char *trademark; -+ char *nonbreaking_hyphen; -+ char *optional_hyphen; -+ } chars; - -- int simulate_small_caps : 1; -- int simulate_all_caps : 1; -- int simulate_word_underline : 1; -- char *unisymbol_print; -- char *utf8_encoding; -- Aliases *aliases; --} --OutputPersonality; -+ int simulate_small_caps : 1; -+ int simulate_all_caps : 1; -+ int simulate_word_underline : 1; -+ char *unisymbol_print; -+ char *utf8_encoding; -+ Aliases *aliases; -+} OutputPersonality; - -+typedef struct OutputContext { -+ struct ConversionContext *conversion; -+ struct OutputPersonality *personality; -+} OutputContext; - --extern OutputPersonality* op_create(void); -+extern OutputPersonality* op_create(const struct ConversionContext *); - extern void op_free (OutputPersonality*); --extern char* op_translate_char (OutputPersonality *op, my_iconv_t cd, int ch); -+extern char* op_translate_char (const struct ConversionContext *cc, const OutputPersonality *op, int ch); - #if 1 /* daved - 0.21.2 */ --extern char* op_translate_str (OutputPersonality *op, my_iconv_t cd, int * doublet); --extern char* op_translate_doublet (OutputPersonality *op, my_iconv_t cd, int ch1, int ch2); -+extern char* op_translate_str (const struct ConversionContext *cc, const OutputPersonality *op, int * doublet); -+extern char* op_translate_doublet (const struct ConversionContext *cc, const OutputPersonality *op, int ch1, int ch2); - #endif - --extern void op_begin_std_fontsize (OutputPersonality*, int); --extern void op_end_std_fontsize (OutputPersonality*, int); -+extern void op_begin_std_fontsize (const struct OutputContext *, int); -+extern void op_end_std_fontsize (const struct OutputContext *, int); - --void add_alias(OutputPersonality *op, int nr, char *text); --char *get_alias(OutputPersonality *op, int nr); -+void add_alias(struct OutputPersonality *op, int nr, char *text); -+char *get_alias(const struct OutputPersonality *op, int nr); - - #define _OUTPUT - #endif -- -diff -durpN unrtf-0.21.2.old/src/parse.c unrtf-0.21.2/src/parse.c ---- unrtf-0.21.2.old/src/parse.c 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/parse.c 2013-01-17 02:41:09.685864239 +0100 -@@ -1,23 +1,23 @@ - /*============================================================================= -- GNU UnRTF, a command-line program to convert RTF documents to other formats. -- Copyright (C) 2000,2001 Zachary Thayer Smith -+ GNU UnRTF, a command-line program to convert RTF documents to other formats. -+ Copyright (C) 2000,2001 Zachary Thayer Smith - -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. - -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. - -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -- The author is reachable by electronic mail at tuorfa@yahoo.com. --=============================================================================*/ -+ The author is reachable by electronic mail at tuorfa@yahoo.com. -+ =============================================================================*/ - - - /*---------------------------------------------------------------------- -@@ -59,6 +59,7 @@ - #include - #endif - -+#include "convert.h" - #include "defs.h" - #include "parse.h" - #include "malloc.h" -@@ -67,14 +68,6 @@ - #include "word.h" - #include "hash.h" - -- -- --/* local to getchar stuff */ --static int ungot_char = -1; --static int ungot_char2 = -1; --static int ungot_char3 = -1; -- -- - /*======================================================================== - * Name: my_unget_char - * Purpose: My own unget routine, handling up to 3 ungot characters. -@@ -82,30 +75,16 @@ static int ungot_char3 = -1; - * Returns: None. - *=======================================================================*/ - --static void my_unget_char (int ch) -+static void my_unget_char (struct ConversionContext *cc, int ch) - { -- if (ungot_char>=0 && ungot_char2>=0 && ungot_char3>=0) -- error_handler("More than 3 ungot chars"); -+ if (cc->ungot_char>=0 && cc->ungot_char2>=0 && cc->ungot_char3>=0) -+ error_handler(cc, "More than 3 ungot chars"); - -- ungot_char3 = ungot_char2; -- ungot_char2 = ungot_char; -- ungot_char = ch; -+ cc->ungot_char3 = cc->ungot_char2; -+ cc->ungot_char2 = cc->ungot_char; -+ cc->ungot_char = ch; - } - -- --static int last_returned_ch=0; -- -- --#define READ_BUF_LEN 2048 --static int buffer_size = 0; --static char *read_buf = NULL; --static int read_buf_end = 0; --static int read_buf_index = 0; -- -- -- -- -- - /*======================================================================== - * Name: my_getchar - * Purpose: Gets a character: either an ungot one, or a buffered one. -@@ -113,76 +92,54 @@ static int read_buf_index = 0; - * Returns: Character, or EOF. - *=======================================================================*/ - --static int my_getchar (FILE* f) -+static int my_getchar (struct ConversionContext *cc) - { -- int ch; -- -- CHECK_PARAM_NOT_NULL(f); -+ int ch; - -- if (ungot_char>=0) { -- ch = ungot_char; -- ungot_char = ungot_char2; -- ungot_char2 = ungot_char3; -- ungot_char3 = -1; -- last_returned_ch = ch; -- if(ch > 255) -- { -- fprintf(stderr, "returning bad ch = '%c' (0%o)\n", -- ch, ch); -- } -- return ch; -- } -- do { -- if (read_buf_index >= read_buf_end) { -- if (!read_buf) { -- buffer_size = READ_BUF_LEN; -- read_buf = my_malloc (buffer_size); -- if (!read_buf) { -- buffer_size /= 4; -- read_buf = my_malloc (buffer_size); -- if (!read_buf) -- error_handler("Cannot allocate read buffer"); -- } -- } -- read_buf_end = fread (read_buf, 1, buffer_size, f); -- read_buf_index = 0; -- if (!read_buf_end) -- return EOF; -- } -- ch = read_buf [read_buf_index++]; -+ if (cc->ungot_char>=0) { -+ ch = cc->ungot_char; -+ cc->ungot_char = cc->ungot_char2; -+ cc->ungot_char2 = cc->ungot_char3; -+ cc->ungot_char3 = -1; -+ cc->last_returned_ch = ch; -+ if(ch > 255) -+ { -+ fprintf(stderr, "returning bad ch = '%c' (0%o)\n", -+ ch, ch); -+ } -+ return ch; -+ } -+ do { -+ if (cc->read_buf_index >= cc->read_buf_end) { -+ return EOF; -+ } -+ ch = cc->read_buf [cc->read_buf_index++]; - -- if (ch=='\n') { -- lineno++; -- /* Convert \(newline) into \par here */ -- if (last_returned_ch=='\\') { -- my_unget_char (' '); -- my_unget_char ('r'); -- my_unget_char ('a'); -- ch = 'p'; -- break; -- } -- } -- } -- while (ch=='\r' /* || ch=='\n' */ ); -+ if (ch=='\n') { -+ cc->lineno++; -+ /* Convert \(newline) into \par here */ -+ if (cc->last_returned_ch=='\\') { -+ my_unget_char (cc, ' '); -+ my_unget_char (cc, 'r'); -+ my_unget_char (cc, 'a'); -+ ch = 'p'; -+ break; -+ } -+ } -+ } -+ while (ch=='\r' /* || ch=='\n' */ ); - -- if (ch=='\t') ch = ' '; -+ if (ch=='\t') ch = ' '; - -- last_returned_ch = ch; -- if(ch > 255) -- { -- fprintf(stderr,"returning bad ch '%c' (0%o)\n", ch, ch); -- exit(1); -- } -- return ch; -+ cc->last_returned_ch = ch; -+ if(ch > 255) -+ { -+ fprintf(stderr,"returning bad ch '%c' (0%o)\n", ch, ch); -+ exit(1); -+ } -+ return ch; - } - -- --/* local to read_word */ --static char *input_str = NULL; --static unsigned long current_max_length = 1; -- -- -- - /*======================================================================== - * Name: expand_word_buffer - * Purpose: Expands the buffer used to store an incoming word. -@@ -192,22 +149,22 @@ static unsigned long current_max_length - *=======================================================================*/ - - static int --expand_word_buffer () -+expand_word_buffer (struct ConversionContext *cc) - { -- char *new_ptr; -- unsigned long old_length; -- if (!input_str) -- error_handler("No input buffer allocated"); -- old_length = current_max_length; -- current_max_length *= 2; -- new_ptr = my_malloc (current_max_length); -- if (!new_ptr) -- error_handler("Out of memory while resizing buffer"); -+ char *new_ptr; -+ unsigned long old_length; -+ if (!cc->input_str) -+ error_handler(cc, "No input buffer allocated"); -+ old_length = cc->current_max_length; -+ cc->current_max_length *= 2; -+ new_ptr = unrtf_malloc (cc->current_max_length); -+ if (!new_ptr) -+ error_handler(cc, "Out of memory while resizing buffer"); - -- memcpy (new_ptr, input_str, old_length); -- my_free(input_str); -- input_str = new_ptr; -- return TRUE; -+ memcpy (new_ptr, cc->input_str, old_length); -+ unrtf_free(cc->input_str); -+ cc->input_str = new_ptr; -+ return TRUE; - } - - -@@ -222,183 +179,184 @@ expand_word_buffer () - *=======================================================================*/ - - static int --read_word (FILE *f) -+read_word (struct ConversionContext *cc) - { -- int ch, ch2; -- unsigned long ix=0; -- int have_whitespace=FALSE; -- int is_control_word=FALSE; -- int has_numeric_param=FALSE; /* if is_control_word==TRUE */ -- int need_unget=FALSE; -- -- CHECK_PARAM_NOT_NULL(f); -+ int ch, ch2; -+ unsigned long ix=0; -+ int have_whitespace=FALSE; -+ int is_control_word=FALSE; -+ int has_numeric_param=FALSE; /* if is_control_word==TRUE */ -+ int need_unget=FALSE; - -- current_max_length = 10; /* XX */ -+ cc->current_max_length = 10; /* XX */ - -- /* Get some storage for a word. -- */ -- input_str = my_malloc (current_max_length); -- if (!input_str) -- error_handler("Cannot allocate word storage"); -+ /* Get some storage for a word. -+ */ -+ if (cc->input_str) { -+ unrtf_free(cc->input_str); -+ } -+ cc->input_str = unrtf_malloc (cc->current_max_length); -+ if (!cc->input_str) -+ error_handler(cc, "Cannot allocate word storage"); - -- do { -- ch = my_getchar(f); -- } -- while (ch=='\n'); -+ do { -+ ch = my_getchar(cc); -+ } -+ while (ch=='\n'); - -- if (ch==' ') -- { -- /* Compress multiple space chars down to one. -- */ -- while (ch == ' ') { -- ch = my_getchar(f); -- have_whitespace=TRUE; -- } -- if (have_whitespace) { -- my_unget_char (ch); -- input_str[0]=' '; -- input_str[1]=0; -- return 1; -- } -- } -+ if (ch==' ') -+ { -+ /* Compress multiple space chars down to one. -+ */ -+ while (ch == ' ') { -+ ch = my_getchar(cc); -+ have_whitespace=TRUE; -+ } -+ if (have_whitespace) { -+ my_unget_char (cc, ch); -+ cc->input_str[0]=' '; -+ cc->input_str[1]=0; -+ return 1; -+ } -+ } - -- switch(ch) -- { -- case EOF: -- return 0; -+ switch(ch) -+ { -+ case EOF: -+ return 0; - -- case '\\': -- ch2 = my_getchar(f); -+ case '\\': -+ ch2 = my_getchar(cc); - -- /* Look for two-character command words. -- */ -- switch (ch2) -- { -- case '\n': -- strcpy (input_str, "\\par"); -- return 4; -- case '~': -- case '{': -- case '}': -- case '\\': -- case '_': -- case '-': -- input_str[0] = '\\'; -- input_str[1] = ch2; -- input_str[2] = 0; -- return 2; -- case '\'': -- /* Preserve \'## expressions (hex char exprs) for later. -- */ -- input_str[0]='\\'; -- input_str[1]='\''; -- ix=2; -- if(ix==current_max_length) { -- if (!expand_word_buffer ()) -- error_handler("Word too long"); -- } -- ch = my_getchar(f); -- input_str[ix++]=ch; -- if(ix==current_max_length) { -- if (!expand_word_buffer ()) -- error_handler("Word too long"); -- } -- ch = my_getchar(f); -- input_str[ix++]=ch; -- if(ix==current_max_length) { -- if (!expand_word_buffer ()) -- error_handler("Word too long"); -- } -- input_str[ix]=0; -- return ix; -- } -+ /* Look for two-character command words. -+ */ -+ switch (ch2) -+ { -+ case '\n': -+ strcpy (cc->input_str, "\\par"); -+ return 4; -+ case '~': -+ case '{': -+ case '}': -+ case '\\': -+ case '_': -+ case '-': -+ cc->input_str[0] = '\\'; -+ cc->input_str[1] = ch2; -+ cc->input_str[2] = 0; -+ return 2; -+ case '\'': -+ /* Preserve \'## expressions (hex char exprs) for later. -+ */ -+ cc->input_str[0]='\\'; -+ cc->input_str[1]='\''; -+ ix=2; -+ if(ix==cc->current_max_length) { -+ if (!expand_word_buffer (cc)) -+ error_handler(cc, "Word too long"); -+ } -+ ch = my_getchar(cc); -+ cc->input_str[ix++]=ch; -+ if(ix==cc->current_max_length) { -+ if (!expand_word_buffer (cc)) -+ error_handler(cc, "Word too long"); -+ } -+ ch = my_getchar(cc); -+ cc->input_str[ix++]=ch; -+ if(ix==cc->current_max_length) { -+ if (!expand_word_buffer (cc)) -+ error_handler(cc, "Word too long"); -+ } -+ cc->input_str[ix]=0; -+ return ix; -+ } - -- is_control_word=TRUE; -- ix=1; -- input_str[0]=ch; -- ch=ch2; -- break; -+ is_control_word=TRUE; -+ ix=1; -+ cc->input_str[0]=ch; -+ ch=ch2; -+ break; - -- case '\t': -- /* In RTF, a tab char is the same as \tab. -- */ -- strcpy (input_str, "\\tab"); -- return 4; -+ case '\t': -+ /* In RTF, a tab char is the same as \tab. -+ */ -+ strcpy (cc->input_str, "\\tab"); -+ return 4; - -- case '{': -- case '}': -- case ';': -- input_str[0]=ch; -- input_str[1]=0; -- return 1; -+ case '{': -+ case '}': -+ case ';': -+ cc->input_str[0]=ch; -+ cc->input_str[1]=0; -+ return 1; - -- } -+ } - -- while (ch!=EOF) -- { -- /* Several chars always ends a word, and we need to save them. -- */ -- if (ch=='\t' || ch=='{' || ch=='}' || ch=='\\') { -- need_unget=TRUE; -- break; -- } -+ while (ch!=EOF) -+ { -+ /* Several chars always ends a word, and we need to save them. -+ */ -+ if (ch=='\t' || ch=='{' || ch=='}' || ch=='\\') { -+ need_unget=TRUE; -+ break; -+ } - -- /* A newline always ends a command word; we don't save it. -- * A newline is ignored if this is not a command word. -- */ -- if (ch=='\n') { -- if (is_control_word) -- break; -- ch = my_getchar(f); -- continue; -- } -+ /* A newline always ends a command word; we don't save it. -+ * A newline is ignored if this is not a command word. -+ */ -+ if (ch=='\n') { -+ if (is_control_word) -+ break; -+ ch = my_getchar(cc); -+ continue; -+ } - -- /* A semicolon always ends a command word; we do save it. -- * A semicolon never ends a regular word. -- */ -- if (ch==';') { -- if (is_control_word) { -- need_unget=TRUE; -- break; -- } -- } -+ /* A semicolon always ends a command word; we do save it. -+ * A semicolon never ends a regular word. -+ */ -+ if (ch==';') { -+ if (is_control_word) { -+ need_unget=TRUE; -+ break; -+ } -+ } - -- /* In this parser, a space character terminates -- * any word, and if it does not follow a command, -- * then it is a word in itself. -- */ -- if (ch==' ') { -- if (!is_control_word) -- need_unget=TRUE; -- break; -- } -+ /* In this parser, a space character terminates -+ * any word, and if it does not follow a command, -+ * then it is a word in itself. -+ */ -+ if (ch==' ') { -+ if (!is_control_word) -+ need_unget=TRUE; -+ break; -+ } - -- /* Identify a control word's numeric parameter. -- */ -- if (is_control_word) { -- if (!has_numeric_param && (isdigit(ch) || ch=='-')) -- has_numeric_param = TRUE; -- else -- if (has_numeric_param && !isdigit(ch)) { -- if (ch!=' ') -- need_unget=TRUE; -- break; -- } -- } -+ /* Identify a control word's numeric parameter. -+ */ -+ if (is_control_word) { -+ if (!has_numeric_param && (isdigit(ch) || ch=='-')) -+ has_numeric_param = TRUE; -+ else -+ if (has_numeric_param && !isdigit(ch)) { -+ if (ch!=' ') -+ need_unget=TRUE; -+ break; -+ } -+ } - -- input_str[ix++] = ch; -- if (ix==current_max_length) { -- if (!expand_word_buffer ()) -- error_handler("Word too long"); -- } -- ch = my_getchar (f); -- } -+ cc->input_str[ix++] = ch; -+ if (ix==cc->current_max_length) { -+ if (!expand_word_buffer (cc)) -+ error_handler(cc, "Word too long"); -+ } -+ ch = my_getchar (cc); -+ } - -- if (need_unget) -- my_unget_char(ch); -+ if (need_unget) -+ my_unget_char(cc, ch); - -- input_str[ix]=0; -- return ix; -+ cc->input_str[ix]=0; -+ return ix; - } - - -@@ -412,44 +370,42 @@ read_word (FILE *f) - *=======================================================================*/ - - Word * --word_read (FILE* f) { -- Word * prev_word = NULL; -- Word * first_word = NULL; -- Word * new_word = NULL; /* temp */ -- -- CHECK_PARAM_NOT_NULL(f); -- -- do { -- if (!read_word(f)) -- return first_word; -+word_read (struct ConversionContext *cc) { -+ Word * prev_word = NULL; -+ Word * first_word = NULL; -+ Word * new_word = NULL; /* temp */ - -- if (input_str[0] == '{') { -- /* Process subwords */ -+ do { -+ if (!read_word(cc)) -+ return first_word; - -- /* Create a dummy word to point to a sublist */ -- new_word = word_new(NULL); -- if (!new_word) -- error_handler("Cannot allocate word"); -+ if (cc->input_str[0] == '{') { -+ /* Process subwords */ - -- /* Get the sublist */ -- new_word->child = word_read(f); -+ /* Create a dummy word to point to a sublist */ -+ new_word = word_new(cc, NULL); -+ if (!new_word) -+ error_handler(cc, "Cannot allocate word"); - -- } else if (input_str[0] == '}') { -- return first_word; -- } else { -- new_word = word_new(input_str); -- } -+ /* Get the sublist */ -+ new_word->child = word_read(cc); -+ -+ } else if (cc->input_str[0] == '}') { -+ return first_word; -+ } else { -+ new_word = word_new(cc, cc->input_str); -+ } - -- if (prev_word) -- prev_word->next = new_word; -+ if (prev_word) -+ prev_word->next = new_word; - -- if (!first_word) -- first_word = new_word; -+ if (!first_word) -+ first_word = new_word; - -- prev_word = new_word; -+ prev_word = new_word; - -- /* Free up the memory allocated by read_word. */ -- my_free(input_str); -- input_str = NULL; -- } while (1); -+ /* Free up the memory allocated by read_word. */ -+ unrtf_free(cc->input_str); -+ cc->input_str = NULL; -+ } while (1); - } -diff -durpN unrtf-0.21.2.old/src/parse.h unrtf-0.21.2/src/parse.h ---- unrtf-0.21.2.old/src/parse.h 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/parse.h 2013-01-17 02:41:09.685864239 +0100 -@@ -38,8 +38,6 @@ - #include "word.h" - #endif - -+struct ConversionContext; - --extern Word *word_read(FILE*); -- -- -- -+extern Word *word_read(struct ConversionContext *cc); -diff -durpN unrtf-0.21.2.old/src/path.c unrtf-0.21.2/src/path.c ---- unrtf-0.21.2.old/src/path.c 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/path.c 1970-01-01 01:00:00.000000000 +0100 -@@ -1,55 +0,0 @@ --#include --#include --#include --#include -- --#include "path.h" -- --struct path_dir *path_dir_p = &topdir; -- --int check_dirs() --{ -- char *p; -- char *colon; -- char *dir_name; -- int a; -- -- for(p = search_path; *p != '\0';) -- { -- dir_name = p; -- if((colon = strchr(p, ':')) != NULL) -- { -- p = colon; -- *p++ = '\0'; -- } -- else -- p += strlen(p); -- a = access(dir_name, R_OK|X_OK); -- if(a) -- continue; -- path_dir_p->dir_name = dir_name; -- if((path_dir_p->next = (struct path_dir *)malloc(sizeof (struct path_dir))) == NULL) -- { -- fprintf(stderr,"cannot malloc\n"); -- exit(1); -- } -- path_dir_p = path_dir_p->next; -- path_dir_p->dir_name = 0; -- n_path_dirs++; -- } -- path_checked = 1; -- return(n_path_dirs); --} -- --void show_dirs() --{ -- if(n_path_dirs == 0) -- { -- fprintf(stderr,"no directories to show\n"); -- exit(1); -- } -- fprintf(stderr,"show_dirs: %d directories\n", n_path_dirs); -- for(path_dir_p = &topdir; path_dir_p->dir_name; path_dir_p = path_dir_p->next) -- fprintf(stderr,"directory = %s\n", path_dir_p->dir_name); --} -- -diff -durpN unrtf-0.21.2.old/src/path.h unrtf-0.21.2/src/path.h ---- unrtf-0.21.2.old/src/path.h 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/path.h 1970-01-01 01:00:00.000000000 +0100 -@@ -1,16 +0,0 @@ --#define DEFAULT_UNRTF_SEARCH_PATH "/usr/local/lib/unrtf/" -- --char *search_path; --int n_path_dirs; --int path_checked; -- --struct path_dir --{ -- char *dir_name; -- struct path_dir *next; --}; -- --struct path_dir topdir; -- --int check_dirs(); --void show_dirs(); -diff -durpN unrtf-0.21.2.old/src/unicode.c unrtf-0.21.2/src/unicode.c ---- unrtf-0.21.2.old/src/unicode.c 2011-06-07 14:06:43.000000000 +0200 -+++ unrtf-0.21.2/src/unicode.c 2013-01-17 02:41:09.685864239 +0100 -@@ -55,20 +55,20 @@ unicode_to_string(int uc) - - if (uc < 0x7f) - { -- string = my_malloc(2 * sizeof(char)); -+ string = unrtf_malloc(2 * sizeof(char)); - string[0] = (unsigned char) uc; - string[1] = '\0'; - } - else if (uc < 0x7ff) - { -- string = my_malloc(3 * sizeof(char)); -+ string = unrtf_malloc(3 * sizeof(char)); - string[0] = (unsigned char) 192 + (uc / 64); - string[1] = (unsigned char) 128 + (uc % 64); - string[2] = '\0'; - } - else if (uc < 0xffff) - { -- string = my_malloc(4 * sizeof(char)); -+ string = unrtf_malloc(4 * sizeof(char)); - string[0] = (unsigned char) 224 + (uc / (64 * 64)); - string[1] = (unsigned char) 128 + ((uc / 64) % 64); - string[2] = (unsigned char) 128 + (uc % 64); -@@ -76,7 +76,7 @@ unicode_to_string(int uc) - } - else if (uc < 0x1FFFFF) - { -- string = my_malloc(5 * sizeof(char)); -+ string = unrtf_malloc(5 * sizeof(char)); - string[0] = (unsigned char) 240 + (uc / (64 * 64 * 64)); - string[1] = (unsigned char) 128 + ((uc / (64 * 64)) % 64); - string[2] = (unsigned char) 128 + ((uc / 64) % 64); -@@ -85,7 +85,7 @@ unicode_to_string(int uc) - } - else if (uc < 0x3FFFFFF) - { -- string = my_malloc(6 * sizeof(char)); -+ string = unrtf_malloc(6 * sizeof(char)); - string[0] = (unsigned char) 248 + (uc / (64 * 64 * 64 * 64)); - string[1] = (unsigned char) 128 + ((uc / (64 * 64 * 64)) % 64); - string[2] = (unsigned char) 128 + ((uc / (64 * 64)) % 64); -@@ -95,7 +95,7 @@ unicode_to_string(int uc) - } - else if (uc < 0x7FFFFFFF) - { -- string = my_malloc(7 * sizeof(char)); -+ string = unrtf_malloc(7 * sizeof(char)); - string[0] = (unsigned char) 252 + (uc / (64 * 64 * 64 * 64 * 64)); - string[1] = (unsigned char) 128 + ((uc / (64 * 64 * 64 * 64)) % 64); - string[2] = (unsigned char) 128 + ((uc / (64 * 64 * 64)) % 64); -@@ -122,7 +122,7 @@ char * - get_unicode_char(FILE *file) - { - int allocated = 5, len = 0, uc; -- char c, *unicode_number = my_malloc(allocated * sizeof(char)); -+ char c, *unicode_number = unrtf_malloc(allocated * sizeof(char)); - - c = fgetc(file); - -@@ -139,7 +139,7 @@ get_unicode_char(FILE *file) - if (len == allocated) - { - allocated *= 2; -- unicode_number = my_realloc(unicode_number, allocated / 2, allocated); -+ unicode_number = unrtf_realloc(unicode_number, allocated / 2, allocated); - } - } - -diff -durpN unrtf-0.21.2.old/src/unrtf.h unrtf-0.21.2/src/unrtf.h ---- unrtf-0.21.2.old/src/unrtf.h 1970-01-01 01:00:00.000000000 +0100 -+++ unrtf-0.21.2/src/unrtf.h 2013-01-17 02:41:09.689864239 +0100 -@@ -0,0 +1,55 @@ -+/*=========================================================================== -+ GNU UnRTF, a command-line program to convert RTF documents to other formats. -+ Copyright (C) 2000,2001,2004 by Zachary Smith -+ Copyright (C) 2011 by Inverse -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ -+ The maintainer is reachable by electronic mail at daved@physiol.usyd.edu.au -+===========================================================================*/ -+ -+#ifndef UNRTF_H -+#define UNRTF_H -+ -+typedef int (*unrtf_output_device_func)(void *, const char *, size_t); -+ -+struct unRTFOutputDevice { -+ unrtf_output_device_func print; -+ void *data; -+}; -+ -+typedef struct unRTFOptions { -+ struct unRTFOutputDevice device; /* stdout if NULL */ -+ const char *config_directory; -+ const char *output_format; /* DEFAULT_OUTPUT if NULL */ -+ -+ int nopict_mode; /* TRUE => Do not write \pict's to files */ -+ int dump_mode; /* TRUE => Output a dump of the RTF word tree */ -+ int debug_mode; /* TRUE => Output debug comments within HTML */ -+ int simple_mode; /* TRUE => Output HTML without SPAN/DIV tags -- This would -+ probably be more useful if we could pull out tags -+ as well. */ -+ int inline_mode; /* TRUE => Output HTML without HTML/BODY/HEAD -- This is -+ buggy. I've seen it output pages of tags. */ -+ /* marcossamaral - 0.19.9 */ -+ int verbose_mode; /* TRUE => Output additional informations about unrtf */ -+ int no_remap_mode; /* don't remap codepoints */ -+} unRTFOptions; -+ -+void unrtf_set_output_device (unRTFOptions *, unrtf_output_device_func, void *); -+int unrtf_convert_from_filename (unRTFOptions *, const char *); -+int unrtf_convert_from_string (unRTFOptions *, const char *, size_t); -+ -+#endif /* UNRTF_H */ -diff -durpN unrtf-0.21.2.old/src/user.c unrtf-0.21.2/src/user.c ---- unrtf-0.21.2.old/src/user.c 2011-06-07 14:08:17.000000000 +0200 -+++ unrtf-0.21.2/src/user.c 2013-01-17 02:41:09.689864239 +0100 -@@ -7,7 +7,7 @@ - *---------------------------------------------------------------------- - * Changes: - * 21 Aug 10, daved@physiol.usyd.edu.au: test feof() rather than EOF for -- AIX support -+ AIX support - *--------------------------------------------------------------------*/ - - #ifndef HAVE_STDIO_H -@@ -38,9 +38,9 @@ - - typedef struct my_F - { -- FILE *file; -- int line_nr; -- char *name; -+ FILE *file; -+ int line_nr; -+ char *name; - } my_FILE; - - -@@ -54,15 +54,15 @@ typedef struct my_F - my_FILE * - my_fopen(char *file_name, char *mode) - { -- my_FILE *f = (my_FILE *) malloc(sizeof(my_FILE)); -+ my_FILE *f = (my_FILE *) malloc(sizeof(my_FILE)); - -- if ((f->file = fopen(file_name, "r")) == NULL || (f->name = my_malloc((strlen(file_name) + 1) * sizeof(char))) == NULL) -- return NULL; -+ if ((f->file = fopen(file_name, "r")) == NULL || (f->name = unrtf_malloc((strlen(file_name) + 1) * sizeof(char))) == NULL) -+ return NULL; - -- f->line_nr = 1; -- strcpy(f->name, file_name); -+ f->line_nr = 1; -+ strcpy(f->name, file_name); - -- return f; -+ return f; - } - - /*======================================================================== -@@ -75,8 +75,8 @@ my_fopen(char *file_name, char *mode) - void - my_fclose(my_FILE *f) - { -- fclose(f->file); -- my_free(f->name); -+ fclose(f->file); -+ unrtf_free(f->name); - } - - /*======================================================================== -@@ -86,103 +86,103 @@ my_fclose(my_FILE *f) - * Returns: Definition or NULL on error. - *=======================================================================*/ - --#define ADD_CHAR(char)\ -- if (def_buffer_length == chars_nr)\ -- {\ -- if ((def = my_realloc(def, def_buffer_length, def_buffer_length * 2)) == NULL)\ -- {\ -- perror("Cannot allocate memory.");\ -- return NULL;\ -- }\ -- def_buffer_length *= 2;\ -- }\ -- def[chars_nr] = char;\ -- chars_nr++; -+#define ADD_CHAR(char) \ -+ if (def_buffer_length == chars_nr) \ -+ { \ -+ if ((def = unrtf_realloc(def, def_buffer_length, def_buffer_length * 2)) == NULL) \ -+ { \ -+ perror("Cannot allocate memory."); \ -+ return NULL; \ -+ } \ -+ def_buffer_length *= 2; \ -+ } \ -+ def[chars_nr] = char; \ -+ chars_nr++; - - char * - give_definition(my_FILE *file) - { -- char c, c2 = 0, c3 = 0, c4 = 0, *def, *unicode_char; -- int i; -- unsigned long def_buffer_length = STANDARD_BUFFER_LENGTH, chars_nr = 0; -+ char c, c2 = 0, c3 = 0, c4 = 0, *def, *unicode_char; -+ int i; -+ unsigned long def_buffer_length = STANDARD_BUFFER_LENGTH, chars_nr = 0; - -- if ((def = my_malloc(def_buffer_length)) == NULL) -- return NULL; -+ if ((def = unrtf_malloc(def_buffer_length)) == NULL) -+ return NULL; - -- c = fgetc(file->file); -+ c = fgetc(file->file); - -- while (c == '\t' || c == '#') -- { -- if (c == '#') -- leave_line(file->file); -- else -- { -- c = fgetc(file->file); -+ while (c == '\t' || c == '#') -+ { -+ if (c == '#') -+ leave_line(file->file); -+ else -+ { -+ c = fgetc(file->file); - - #if 1 /* daved 0.21.2 */ -- while (c != '\n' && !feof(file->file)) -+ while (c != '\n' && !feof(file->file)) - #else -- while (c != '\n' && c != EOF) -+ while (c != '\n' && c != EOF) - #endif -- { -- if (c == 'U' && c2 == '<' && (c3 != '\\' || (c3 == '\\' && c4 == '\\'))) -- { -- unicode_char = get_unicode_char(file->file); -+ { -+ if (c == 'U' && c2 == '<' && (c3 != '\\' || (c3 == '\\' && c4 == '\\'))) -+ { -+ unicode_char = get_unicode_char(file->file); - -- for (i = 0; unicode_char[i] != '\0'; i++) -- ADD_CHAR(unicode_char[i]) -- c = fgetc(file->file); -- c2 = 0; -- c3 = 0; -- c4 = 0; -- } -- else -- { -- if (c2 == '<') -- { -- ADD_CHAR('<'); -- } -+ for (i = 0; unicode_char[i] != '\0'; i++) -+ ADD_CHAR(unicode_char[i]) -+ c = fgetc(file->file); -+ c2 = 0; -+ c3 = 0; -+ c4 = 0; -+ } -+ else -+ { -+ if (c2 == '<') -+ { -+ ADD_CHAR('<'); -+ } - -- /* daved - support \n in definitions */ -- if (c == 'n' && c2 == '\\') -- { -- ADD_CHAR('\n'); -- } -- else -- if (c != '<' && c != '\\' || (c == '\\' && c2 == '\\')) -- { -- ADD_CHAR(c) -- } -+ /* daved - support \n in definitions */ -+ if (c == 'n' && c2 == '\\') -+ { -+ ADD_CHAR('\n'); -+ } -+ else -+ if (c != '<' && c != '\\' || (c == '\\' && c2 == '\\')) -+ { -+ ADD_CHAR(c); -+ } - -- c4 = c3; -- c3 = c2; -- c2 = c; -- c = fgetc(file->file); -- } -- } -+ c4 = c3; -+ c3 = c2; -+ c2 = c; -+ c = fgetc(file->file); -+ } -+ } - -- file->line_nr++; -- ADD_CHAR('\n'); -- } -+ file->line_nr++; -+ ADD_CHAR('\n'); -+ } - -- c = fgetc(file->file); -- } -+ c = fgetc(file->file); -+ } - - #if 1 /* daved 0.21.2 */ -- if (!feof(file->file)) -+ if (!feof(file->file)) - #else -- if (c != EOF) -+ if (c != EOF) - #endif -- { -- ungetc(c, file->file); -- } -+ { -+ ungetc(c, file->file); -+ } - -- if (chars_nr > 0) -- def[chars_nr - 1] = '\0'; -- else -- def[0] = '\0'; -+ if (chars_nr > 0) -+ def[chars_nr - 1] = '\0'; -+ else -+ def[0] = '\0'; - -- return def; -+ return def; - } - - /*======================================================================== -@@ -190,49 +190,71 @@ give_definition(my_FILE *file) - * Purpose: Tries to match known tag names with first argument - * Args: Tag name, Output Personality, file to read from - * Returns: -1 on error, -- 0 on success, -- 1 when tag name "name" is unknown -+ 0 on success, -+ 1 when tag name "name" is unknown - *=======================================================================*/ - - int - match_name (char *name, OutputPersonality *op, my_FILE *file) - { -- struct definition -- { -- char *name; -- char **variable; -- } defs[] = DEFS_ARRAY(op); -- -- char *endptr; -- int i; -+ struct definition -+ { -+ char *name; -+ char **variable; -+ } defs[] = DEFS_ARRAY(op); -+ char *def, *endptr; -+ int i; - - #if 1 /* daved 0.21.0-rc2 */ -- for (i = 0; defs[i].name && strcmp(defs[i].name, name); i++); -+ for (i = 0; defs[i].name && strcmp(defs[i].name, name); i++); - -- if (!defs[i].name) -+ if (!defs[i].name) - #else -- for (i = 0; defs[i].name[0] != '\0' && strcmp(defs[i].name, name); i++); -+ for (i = 0; defs[i].name[0] != '\0' && strcmp(defs[i].name, name); i++); - -- if (defs[i].name[0] == '\0') -+ if (defs[i].name[0] == '\0') - #endif -- { -- i = strtol(name, &endptr, 10); -+ { -+ i = strtol(name, &endptr, 10); - -- if (*endptr == '\0') -- add_alias(op, i, give_definition(file)); -- else if (name[0] == '<' && name[1] == 'U') -- add_alias(op, get_unicode(&name[2]), give_definition(file)); -- else -- { -- fprintf(stderr, "unrtf: unknown name \"%s\" in line %d of \"%s\"\n", name, file->line_nr, file->name); -- return 1; -- } -- } -- else -- if ((*defs[i].variable = give_definition(file)) == NULL) -- return -1; -+ def = give_definition(file); -+ if (*endptr == '\0') -+ add_alias(op, i, def); -+ else if (name[0] == '<' && name[1] == 'U') -+ add_alias(op, get_unicode(&name[2]), def); -+ else -+ { -+ unrtf_free (def); -+ fprintf(stderr, "unrtf: unknown name \"%s\" in line %d of \"%s\"\n", name, file->line_nr, file->name); -+ return 1; -+ } -+ unrtf_free (def); -+ } -+ else -+ if ((*defs[i].variable = give_definition(file)) == NULL) -+ return -1; - -- return 0; -+ return 0; -+} -+ -+void -+free_user_definitions (OutputPersonality *op) -+{ -+ struct definition -+ { -+ char *name; -+ char **variable; -+ } defs[] = DEFS_ARRAY(op); -+ char *variable; -+ int i; -+ -+ for (i = 0; defs[i].name; i++) -+ { -+ variable = *defs[i].variable; -+ if (variable) -+ free(variable); -+ *defs[i].variable = NULL; -+ } - } - - /*======================================================================== -@@ -243,52 +265,55 @@ match_name (char *name, OutputPersonalit - *=======================================================================*/ - - OutputPersonality * --user_init (OutputPersonality *op, char *definitions_file_path) -+user_init (const struct ConversionContext *cc, char *definitions_file_path) - { -- my_FILE *f; -- char name_buffer[BUFFER_SIZE]; -+ my_FILE *f; -+ char name_buffer[BUFFER_SIZE]; -+ OutputPersonality *op; - -- if (op == NULL) -- op = op_create(); -+ op = op_create(cc); - -- if ((f = my_fopen(definitions_file_path, "r")) == NULL) -- { -- perror(definitions_file_path); -- return op; -- } -+ if ((f = my_fopen(definitions_file_path, "r")) == NULL) -+ { -+ perror(definitions_file_path); -+ op_free (op); -+ op = NULL; -+ return op; -+ } - - #if 1 /* daved 0.21.2 */ -- while -- ( -- fgets(name_buffer, BUFFER_SIZE - 1, f->file) != NULL -- && -- !feof(f->file) -- ) -+ while -+ ( -+ fgets(name_buffer, BUFFER_SIZE - 1, f->file) != NULL -+ && -+ !feof(f->file) -+ ) - #else -- while (fgets(name_buffer, BUFFER_SIZE - 1, f->file) != NULL) -+ while (fgets(name_buffer, BUFFER_SIZE - 1, f->file) != NULL) - #endif -- { -- if (name_buffer[strlen(name_buffer) - 1] != '\n') -- leave_line(f->file); -+ { -+ if (name_buffer[strlen(name_buffer) - 1] != '\n') -+ leave_line(f->file); - -- f->line_nr++; -+ f->line_nr++; - -- if (name_buffer[0] != '#' && name_buffer[0] != '\n') -- { -- name_buffer[strlen(name_buffer) - 1] = '\0'; -+ if (name_buffer[0] != '#' && name_buffer[0] != '\n') -+ { -+ name_buffer[strlen(name_buffer) - 1] = '\0'; - -- if (match_name(name_buffer, op, f) == -1) -- { -- my_fclose(f); -- free(f); -- return NULL; -- } -- } -- } -+ if (match_name(name_buffer, op, f) == -1) -+ { -+ my_fclose(f); -+ free(f); -+ op_free (op); -+ return NULL; -+ } -+ } -+ } - -- my_fclose(f); -- free(f); -+ my_fclose(f); -+ free(f); - -- return op; -+ return op; - } - -diff -durpN unrtf-0.21.2.old/src/user.h unrtf-0.21.2/src/user.h ---- unrtf-0.21.2.old/src/user.h 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/user.h 2013-01-17 02:41:09.689864239 +0100 -@@ -151,9 +151,10 @@ - - #ifndef _USER - -+struct ConversionContext; - --extern OutputPersonality* user_init(OutputPersonality *, char *tags_file_path); -- -+extern OutputPersonality* user_init(const struct ConversionContext *cc, char *tags_file_path); -+extern void free_user_definitions (OutputPersonality *op); - - #define _USER - #endif -diff -durpN unrtf-0.21.2.old/src/util.c unrtf-0.21.2/src/util.c ---- unrtf-0.21.2.old/src/util.c 2010-08-09 14:05:30.000000000 +0200 -+++ unrtf-0.21.2/src/util.c 2013-01-17 02:41:09.689864239 +0100 -@@ -110,7 +110,7 @@ concatenate (const char *s1, const char - { - char *result; - -- result = my_malloc((strlen(s1) + strlen(s2) + 1) * sizeof(char)); -+ result = unrtf_malloc((strlen(s1) + strlen(s2) + 1) * sizeof(char)); - strcpy(result, s1); - strcat(result, s2); - -diff -durpN unrtf-0.21.2.old/src/word.c unrtf-0.21.2/src/word.c ---- unrtf-0.21.2.old/src/word.c 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/word.c 2013-01-17 02:41:09.689864239 +0100 -@@ -1,23 +1,23 @@ - /*============================================================================= -- GNU UnRTF, a command-line program to convert RTF documents to other formats. -- Copyright (C) 2000,2001,2004 by Zachary Smith -+ GNU UnRTF, a command-line program to convert RTF documents to other formats. -+ Copyright (C) 2000,2001,2004 by Zachary Smith - -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. - -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. - -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -- The maintainer is reachable by electronic mail at daved@physiol.usyd.edu.au --=============================================================================*/ -+ The maintainer is reachable by electronic mail at daved@physiol.usyd.edu.au -+ =============================================================================*/ - - - /*---------------------------------------------------------------------- -@@ -69,6 +69,7 @@ - #endif - - #include "defs.h" -+#include "convert.h" - #include "parse.h" - #include "malloc.h" - #include "main.h" -@@ -77,10 +78,6 @@ - #include "hash.h" - - --/* For word_dump */ --static int indent_level=0; -- -- - /*======================================================================== - * Name: word_string - * Purpose: Obtains the string of a Word object. This involves accessing -@@ -90,12 +87,14 @@ static int indent_level=0; - *=======================================================================*/ - - char * --word_string (Word *w) { -- char *str; -- CHECK_PARAM_NOT_NULL(w); -- if (w->hash_index) str = hash_get_string (w->hash_index); -- else str = NULL; -- return str; -+word_string (const struct ConversionContext *cc, Word *w) { -+ char *str; -+ CHECK_PARAM_NOT_NULL(w); -+ -+ if (w->hash_index) str = hash_get_string (cc, w->hash_index); -+ else str = NULL; -+ -+ return str; - } - - -@@ -108,24 +107,22 @@ word_string (Word *w) { - *=======================================================================*/ - - Word * --word_new (char *str) { -- Word * w; -+word_new (struct ConversionContext *cc, char *str) { -+ Word * w; - -- w = (Word *) my_malloc(sizeof(Word)); -- if (!w) -- error_handler ("out of memory"); -- memset ((void*) w, 0, sizeof(Word)); -- if (!w) error_handler ("cannot allocate a Word"); -+ w = (Word *) unrtf_malloc(sizeof(Word)); -+ if (!w) -+ error_handler (cc, "out of memory"); -+ memset ((void*) w, 0, sizeof(Word)); -+ if (!w) error_handler (cc, "cannot allocate a Word"); - -- if (str) w->hash_index = hash_get_index (str); -- else w->hash_index = 0; -+ if (str) w->hash_index = hash_get_index (cc, str); -+ else w->hash_index = 0; - -- return w; -+ return w; - } - - -- -- - /*======================================================================== - * Name: word_free - * Purpose: Deallocates a Word object. This is only called at the end of -@@ -135,20 +132,20 @@ word_new (char *str) { - *=======================================================================*/ - - void word_free (Word *w) { -- Word *prev; -- Word *w2; -+ Word *prev; -+ Word *w2; - -- CHECK_PARAM_NOT_NULL(w); -+ CHECK_PARAM_NOT_NULL(w); - -- while (w) { -- w2 = w->child; -- if (w2) -- word_free(w2); -+ while (w) { -+ w2 = w->child; -+ if (w2) -+ word_free(w2); - -- prev = w; -- w = w->next; -- my_free((char*) prev); -- } -+ prev = w; -+ w = w->next; -+ unrtf_free((char*) prev); -+ } - } - - -@@ -165,14 +162,14 @@ void word_free (Word *w) { - static void - print_indentation (int level) - { -- int i; -+ int i; - -- if (level) { -- for (i=0;iindent_level += 2; -+ print_indentation (cc->indent_level); - -- while (w) { -- s = word_string (w); -- if (s) { -- printf ("\"%s\" ", s); -- } else { -- if (w->child) { -- word_dump (w->child); -- printf ("\n"); -- print_indentation (indent_level); -- } -- else -- warning_handler ("Word object has no string and no children"); -- } -- w = w->next; -- } -+ while (w) { -+ s = word_string (cc, w); -+ if (s) { -+ printf ("\"%s\" ", s); -+ } else { -+ if (w->child) { -+ word_dump (cc, w->child); -+ printf ("\n"); -+ print_indentation (cc->indent_level); -+ } -+ else -+ warning_handler ("Word object has no string and no children"); -+ } -+ w = w->next; -+ } - -- indent_level -= 2; -+ cc->indent_level -= 2; - } - - #if 1 /* AK6 - AF */ -@@ -223,56 +220,56 @@ word_dump (Word *w) - * Returns: Optimized word. - *=======================================================================*/ - Word * --optimize_word(Word *w) -+optimize_word(const struct ConversionContext *cc, Word *w) - { -- char *s, *s1; -- int i = 0, len; -- Collection *c = NULL; -- Tag tags_to_opt[] = OPT_ARRAY; -- Word *root = w, *w2; -+ char *s, *s1; -+ int i = 0, len; -+ Collection *c = NULL; -+ Tag tags_to_opt[] = OPT_ARRAY; -+ Word *root = w, *w2; - -- for (; w != NULL; w = w->next) -- { -+ for (; w != NULL; w = w->next) -+ { - -- if (s = word_string(w)) -- { -- for (i = 0; tags_to_opt[i].name[0] != '\0'; i++) -- { -- if (tags_to_opt[i].has_param) -- { -- len = strlen(tags_to_opt[i].name); -- if (!strncmp(tags_to_opt[i].name, s, len) && (isdigit(s[len]) || s[len] == '-')) -- break; -- } -- else -- if (!strcmp(tags_to_opt[i].name, s)) -- break; -- } -+ if (s = word_string(cc, w)) -+ { -+ for (i = 0; tags_to_opt[i].name[0] != '\0'; i++) -+ { -+ if (tags_to_opt[i].has_param) -+ { -+ len = strlen(tags_to_opt[i].name); -+ if (!strncmp(tags_to_opt[i].name, s, len) && (isdigit(s[len]) || s[len] == '-')) -+ break; -+ } -+ else -+ if (!strcmp(tags_to_opt[i].name, s)) -+ break; -+ } - -- if (tags_to_opt[i].name[0] != '\0') -- { -- s1 = get_from_collection(c, i); -+ if (tags_to_opt[i].name[0] != '\0') -+ { -+ s1 = get_from_collection(c, i); - -- if (s != NULL && s1 != NULL && !strcmp(s1, s)) -- { -- w2->next = w->next; -- my_free((char *)w); -- w = w2; -- } -- else -- c = add_to_collection(c, i, s); -- } -- } -+ if (s != NULL && s1 != NULL && !strcmp(s1, s)) -+ { -+ w2->next = w->next; -+ unrtf_free((char *)w); -+ w = w2; -+ } -+ else -+ c = add_to_collection(c, i, s); -+ } -+ } - -- if (w->child != NULL) -- w->child = optimize_word(w->child); -+ if (w->child != NULL) -+ w->child = optimize_word(cc, w->child); - -- w2 = w; -- } -+ w2 = w; -+ } - --// free_collection(c); -+ free_collection(c); - -- return root; -+ return root; - } - #endif - -diff -durpN unrtf-0.21.2.old/src/word.h unrtf-0.21.2/src/word.h ---- unrtf-0.21.2.old/src/word.h 2010-07-04 04:30:58.000000000 +0200 -+++ unrtf-0.21.2/src/word.h 2013-01-17 02:41:09.689864239 +0100 -@@ -41,14 +41,15 @@ typedef struct _w { - struct _w * child; - } Word; - --extern Word* word_new (char*); -+struct ConversionContext; -+ -+extern Word* word_new (struct ConversionContext *, char*); - extern void word_free (Word*); --extern Word* word_read (FILE*); --extern char* word_string (Word*); --extern void word_dump (Word*); -+extern char* word_string (const struct ConversionContext *, Word*); -+extern void word_dump (struct ConversionContext *, Word*); - extern void word_print_html (Word*); - --extern Word* optimize_word(Word*); -+extern Word* optimize_word(const struct ConversionContext *, Word*); - - typedef struct _t { - char *name; diff --git a/OpenChange/unrtf-0.21.2.tar.gz b/OpenChange/unrtf-0.21.2.tar.gz deleted file mode 100644 index 421ba59f0..000000000 Binary files a/OpenChange/unrtf-0.21.2.tar.gz and /dev/null differ diff --git a/OpenChange/unrtf_config_h b/OpenChange/unrtf_config_h deleted file mode 100644 index 193142ba9..000000000 --- a/OpenChange/unrtf_config_h +++ /dev/null @@ -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 header file. */ -#define HAVE_CTYPE_H 1 - -/* Define to 1 if you have the 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 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 header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDIO_H 1 - -/* Define to 1 if you have the 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 header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the 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 header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the 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 */ diff --git a/Scripts/fail2ban/sogo-filter.conf b/Scripts/fail2ban/sogo-filter.conf new file mode 100644 index 000000000..b6d2da58e --- /dev/null +++ b/Scripts/fail2ban/sogo-filter.conf @@ -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 '.*' for user '.*' might not have worked + +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# +ignoreregex = diff --git a/Scripts/fail2ban/sogo-jail.local b/Scripts/fail2ban/sogo-jail.local new file mode 100644 index 000000000..4a403e70f --- /dev/null +++ b/Scripts/fail2ban/sogo-jail.local @@ -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 + diff --git a/Scripts/openchange_cleanup.py b/Scripts/openchange_cleanup.py index c646cff75..9ceeca85a 100755 --- a/Scripts/openchange_cleanup.py +++ b/Scripts/openchange_cleanup.py @@ -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) - sqlCleanup(username) + 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,24 +155,43 @@ 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): - import MySQLdb + 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) + conn = MySQLdb.connect(host=dbhost, port=int(dbport), user=dbuser, passwd=dbpass, db=dbname) c=conn.cursor() tablename="socfs_%s" % (username) c.execute("TRUNCATE TABLE %s" % tablename) @@ -177,28 +199,38 @@ def mysqlCleanup(dbhost, dbport, dbuser, dbpass, dbname, username): def postgresqlCleanup(dbhost, dbport, dbuser, dbpass, dbname, username): - import pg + 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() diff --git a/Scripts/sogo.conf b/Scripts/sogo.conf new file mode 100644 index 000000000..caff050a6 --- /dev/null +++ b/Scripts/sogo.conf @@ -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; +} diff --git a/Scripts/sogo.cron b/Scripts/sogo.cron index b9824d1e6..85c9f740c 100644 --- a/Scripts/sogo.cron +++ b/Scripts/sogo.cron @@ -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 diff --git a/Scripts/sql-update-2.0.4b_to_2.0.5-mysql.sh b/Scripts/sql-update-2.0.4b_to_2.0.5-mysql.sh new file mode 100755 index 000000000..567274e4a --- /dev/null +++ b/Scripts/sql-update-2.0.4b_to_2.0.5-mysql.sh @@ -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 diff --git a/SoObjects/Appointments/Arabic.lproj/Localizable.strings b/SoObjects/Appointments/Arabic.lproj/Localizable.strings new file mode 100644 index 000000000..23754f510 --- /dev/null +++ b/SoObjects/Appointments/Arabic.lproj/Localizable.strings @@ -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}."; diff --git a/SoObjects/Appointments/Danish.lproj/Localizable.strings b/SoObjects/Appointments/Danish.lproj/Localizable.strings index 164a6a47a..8718169b7 100644 --- a/SoObjects/Appointments/Danish.lproj/Localizable.strings +++ b/SoObjects/Appointments/Danish.lproj/Localizable.strings @@ -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}."; diff --git a/SoObjects/Appointments/GNUmakefile b/SoObjects/Appointments/GNUmakefile index 308926b3a..10fd04297 100644 --- a/SoObjects/Appointments/GNUmakefile +++ b/SoObjects/Appointments/GNUmakefile @@ -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 diff --git a/SoObjects/Appointments/Russian.lproj/Localizable.strings b/SoObjects/Appointments/Russian.lproj/Localizable.strings index ec30c6c7c..67539d7ab 100644 --- a/SoObjects/Appointments/Russian.lproj/Localizable.strings +++ b/SoObjects/Appointments/Russian.lproj/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." diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 904cf896e..b54cb846c 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -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) { - 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]; - } + if ([dateRange containsDate: [component startDate]]) + { + newRecord = [self fixupRecord: [component quickRecord]]; + [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,16 +922,33 @@ 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]; + [ma addObject: newRecord]; + else + newRecord = nil; } if (newRecord) - [self _fixExceptionRecord: newRecord fromRow: row]; + { + 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 diff --git a/SoObjects/Appointments/SOGoAppointmentObject.m b/SoObjects/Appointments/SOGoAppointmentObject.m index d54f0d1d4..a2d279ec0 100644 --- a/SoObjects/Appointments/SOGoAppointmentObject.m +++ b/SoObjects/Appointments/SOGoAppointmentObject.m @@ -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]) @@ -1892,25 +1889,38 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent if ([[newEvent attendees] count] || [[oldEvent attendees] count]) { 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; } // diff --git a/SoObjects/Appointments/SOGoWebAppointmentFolder.m b/SoObjects/Appointments/SOGoWebAppointmentFolder.m index 0c405ffba..f5c004c84 100644 --- a/SoObjects/Appointments/SOGoWebAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoWebAppointmentFolder.m @@ -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 * Ludovic Marcotte @@ -37,6 +37,7 @@ #import #import #import +#import #import #import #import @@ -69,27 +70,23 @@ 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]; + } + authValue + = [[self folderPropertyValueInCategory: @"WebCalendarsAuthentication"] + decryptWithKey: userPassword]; + parts = [authValue componentsSeparatedByString: @":"]; + if ([parts count] == 2) + { + keys = [NSArray arrayWithObjects: @"username", @"password", nil]; + authData = [NSDictionary dictionaryWithObjects: parts + forKeys: keys]; } else - { - authValue - = [[self folderPropertyValueInCategory: @"WebCalendarsAuthentication"] - decryptWithKey: userPassword]; - parts = [authValue componentsSeparatedByString: @":"]; - if ([parts count] == 2) - { - keys = [NSArray arrayWithObjects: @"username", @"password", nil]; - authData = [NSDictionary dictionaryWithObjects: parts - forKeys: keys]; - } - else - authData = nil; - } + authData = nil; return authData; } @@ -99,18 +96,18 @@ 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) - { - if (!username) - username = @""; - if (!password) - password = @""; - authValue = [NSString stringWithFormat: @"%@:%@", username, password]; - [self setFolderPropertyValue: [authValue encryptWithKey: userPassword] - inCategory: @"WebCalendarsAuthentication"]; - } + userPassword = [[self authenticatorInContext: context] passwordInContext: context]; + if ([userPassword length] == 0) { + userPassword = [[SOGoSystemDefaults sharedSystemDefaults] encryptionKey]; + } + + if (!username) + username = @""; + if (!password) + password = @""; + authValue = [NSString stringWithFormat: @"%@:%@", username, password]; + [self setFolderPropertyValue: [authValue encryptWithKey: userPassword] + inCategory: @"WebCalendarsAuthentication"]; } - (NSDictionary *) loadWebCalendar diff --git a/SoObjects/Contacts/Arabic.lproj/Localizable.strings b/SoObjects/Contacts/Arabic.lproj/Localizable.strings new file mode 100644 index 000000000..188cc411b --- /dev/null +++ b/SoObjects/Contacts/Arabic.lproj/Localizable.strings @@ -0,0 +1 @@ +"Personal Address Book" = "دفتر العناوين الشخصية"; diff --git a/SoObjects/Contacts/GNUmakefile b/SoObjects/Contacts/GNUmakefile index d0f3e2965..23871c73d 100644 --- a/SoObjects/Contacts/GNUmakefile +++ b/SoObjects/Contacts/GNUmakefile @@ -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 diff --git a/SoObjects/Contacts/SOGoContactSourceFolder.m b/SoObjects/Contacts/SOGoContactSourceFolder.m index b270460c1..faa4f5ed5 100644 --- a/SoObjects/Contacts/SOGoContactSourceFolder.m +++ b/SoObjects/Contacts/SOGoContactSourceFolder.m @@ -200,7 +200,10 @@ - (NSArray *) toOneRelationshipKeys { - return [source allEntryIDs]; + NSString *userDomain; + + userDomain = [[context activeUser] domain]; + return [source allEntryIDsVisibleFromDomain: userDomain]; } - (NSException *) saveLDIFEntry: (SOGoContactLDIFEntry *) ldifEntry diff --git a/SoObjects/Mailer/GNUmakefile b/SoObjects/Mailer/GNUmakefile index f4bbae9b2..db5edc0b0 100644 --- a/SoObjects/Mailer/GNUmakefile +++ b/SoObjects/Mailer/GNUmakefile @@ -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 \ diff --git a/SoObjects/Mailer/SOGoMailArabicForward.wo/SOGoMailArabicForward.html b/SoObjects/Mailer/SOGoMailArabicForward.wo/SOGoMailArabicForward.html new file mode 100644 index 000000000..379fc9c16 --- /dev/null +++ b/SoObjects/Mailer/SOGoMailArabicForward.wo/SOGoMailArabicForward.html @@ -0,0 +1,13 @@ +<#newLine/> +<#newLine/> +<#newLine/> +-------- الرسالة الاصلية --------<#newLine/> +الموضوع: <#subject/><#newLine/> +التاريخ: <#date/><#newLine/> +من: <#from/><#newLine/> +<#hasReplyTo>ردً على: <#replyTo/><#hasOrganization>المنظمة: <#organization/>إلى: <#to/><#newLine/> +<#hasCc>CC: <#cc/><#hasNewsGroups>مجموعات الأخبار: <#newsgroups/><#hasReferences>المراجع: <#references/><#newLine/> +<#newLine/> +<#messageBody/><#newLine/> +<#newLine/> +<#signature/><#newLine/> diff --git a/SoObjects/Mailer/SOGoMailArabicForward.wo/SOGoMailArabicForward.wod b/SoObjects/Mailer/SOGoMailArabicForward.wo/SOGoMailArabicForward.wod new file mode 100644 index 000000000..7787fa18e --- /dev/null +++ b/SoObjects/Mailer/SOGoMailArabicForward.wo/SOGoMailArabicForward.wod @@ -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; +} diff --git a/SoObjects/Mailer/SOGoMailArabicReply.wo/SOGoMailArabicReply.html b/SoObjects/Mailer/SOGoMailArabicReply.wo/SOGoMailArabicReply.html new file mode 100644 index 000000000..377f1025a --- /dev/null +++ b/SoObjects/Mailer/SOGoMailArabicReply.wo/SOGoMailArabicReply.html @@ -0,0 +1,16 @@ +<#replyPlacementOnTop><#newLine/> +<#newLine/> +<#signaturePlacementOnTop><#newLine/> +<#signature/><#newLine/> +<#outlookMode>-------- الرسالة الأصلية --------<#newLine/> +الموضوع: <#subject/><#newLine/> +التاريخ: <#date/><#newLine/> +من: <#from/><#newLine/> +<#hasReplyTo>ردً علي: <#replyTo/><#hasOrganization>المنظمة: <#organization/>إلى: <#to/><#newLine/> +<#hasCc>CC: <#cc/><#hasNewsGroups>مجموعات الأخبار: <#newsgroups/><#hasReferences>المراجع: <#references/><#newLine/> +<#standardMode>في <#date/>, <#from/> كتب:<#newLine/> +<#newLine/> +<#messageBody/><#newLine/> +<#replyPlacementOnBottom><#newLine/> +<#newLine/> +<#signaturePlacementOnBottom><#signature/><#newLine/> diff --git a/SoObjects/Mailer/SOGoMailArabicReply.wo/SOGoMailArabicReply.wod b/SoObjects/Mailer/SOGoMailArabicReply.wo/SOGoMailArabicReply.wod new file mode 100644 index 000000000..3fbed6d61 --- /dev/null +++ b/SoObjects/Mailer/SOGoMailArabicReply.wo/SOGoMailArabicReply.wod @@ -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; +} diff --git a/SoObjects/Mailer/SOGoMailForward.h b/SoObjects/Mailer/SOGoMailForward.h index c2e4c9134..032733692 100644 --- a/SoObjects/Mailer/SOGoMailForward.h +++ b/SoObjects/Mailer/SOGoMailForward.h @@ -1,8 +1,6 @@ /* SOGoMailForward.h - this file is part of SOGo * - * Copyright (C) 2007 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2007-2013 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -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 diff --git a/SoObjects/Mailer/SOGoMailForward.m b/SoObjects/Mailer/SOGoMailForward.m index 9beca2887..3fcdb840a 100644 --- a/SoObjects/Mailer/SOGoMailForward.m +++ b/SoObjects/Mailer/SOGoMailForward.m @@ -1,8 +1,6 @@ /* SOGoMailForward.m - this file is part of SOGo * - * Copyright (C) 2007-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2007-2013 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -243,6 +241,9 @@ @end +@implementation SOGoMailArabicForward +@end + @implementation SOGoMailBrazilianPortugueseForward @end @@ -297,6 +298,9 @@ @implementation SOGoMailRussianForward @end +@implementation SOGoMailSlovakForward +@end + @implementation SOGoMailUkrainianForward @end diff --git a/SoObjects/Mailer/SOGoMailPolishReply.wo/SOGoMailPolishReply.html b/SoObjects/Mailer/SOGoMailPolishReply.wo/SOGoMailPolishReply.html index e2e085a4a..fb574905e 100644 --- a/SoObjects/Mailer/SOGoMailPolishReply.wo/SOGoMailPolishReply.html +++ b/SoObjects/Mailer/SOGoMailPolishReply.wo/SOGoMailPolishReply.html @@ -8,7 +8,7 @@ Data: <#date/><#newLine/> Od: <#from/><#newLine/> <#hasReplyTo>Odpowiedź do: <#replyTo/><#hasOrganization>Organizacja: <#organization/>Do: <#to/><#newLine/> <#hasCc>DW: <#cc/><#hasNewsGroups>Grupy dyskusyjne: <#newsgroups/><#hasReferences>Odniesienia: <#references/><#newLine/> -<#standardMode>Dnia <#date/>, <#from/> napisał(a):<#newLine/> +<#standardMode>W dniu: <#date/>, <#from/> napisał(a):<#newLine/> <#newLine/> <#messageBody/><#newLine/> <#replyPlacementOnBottom><#newLine/> diff --git a/SoObjects/Mailer/SOGoMailReply.h b/SoObjects/Mailer/SOGoMailReply.h index 4ee5828d2..20b698f76 100644 --- a/SoObjects/Mailer/SOGoMailReply.h +++ b/SoObjects/Mailer/SOGoMailReply.h @@ -1,8 +1,6 @@ /* SOGoMailReply.h - this file is part of SOGo * - * Copyright (C) 2007-2010 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2007-2013 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -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 diff --git a/SoObjects/Mailer/SOGoMailReply.m b/SoObjects/Mailer/SOGoMailReply.m index b49bf3800..5738d520f 100644 --- a/SoObjects/Mailer/SOGoMailReply.m +++ b/SoObjects/Mailer/SOGoMailReply.m @@ -1,8 +1,6 @@ /* SOGoMailReply.m - this file is part of SOGo * - * Copyright (C) 2007-2009 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2007-2013 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -101,6 +99,9 @@ @end +@implementation SOGoMailArabicReply +@end + @implementation SOGoMailBrazilianPortugueseReply @end @@ -155,6 +156,9 @@ @implementation SOGoMailRussianReply @end +@implementation SOGoMailSlovakReply +@end + @implementation SOGoMailUkrainianReply @end diff --git a/SoObjects/SOGo/LDAPSource.m b/SoObjects/SOGo/LDAPSource.m index 302944673..0abf57afa 100644 --- a/SoObjects/SOGo/LDAPSource.m +++ b/SoObjects/SOGo/LDAPSource.m @@ -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; diff --git a/SoObjects/SOGo/NSString+Utilities.m b/SoObjects/SOGo/NSString+Utilities.m index 768cae86f..506344284 100644 --- a/SoObjects/SOGo/NSString+Utilities.m +++ b/SoObjects/SOGo/NSString+Utilities.m @@ -195,18 +195,27 @@ static int cssEscapingCount; startLocation--; matchRange.location = startLocation + 1; - currentUrlRange = [selfCopy _rangeOfURLInRange: matchRange]; - if (![ranges hasRangeIntersection: currentUrlRange]) - if (currentUrlRange.length > matchLength) - [newRanges addNonNSObject: ¤tUrlRange - withSize: sizeof (NSRange) - copy: YES]; - - rest.location = NSMaxRange (currentUrlRange); - length = [selfCopy length]; - rest.length = length - rest.location; - matchRange = [selfCopy rangeOfString: match - options: 0 range: rest]; + // 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) + [newRanges addNonNSObject: ¤tUrlRange + withSize: sizeof (NSRange) + copy: YES]; + + rest.location = NSMaxRange (currentUrlRange); + length = [selfCopy length]; + rest.length = length - rest.location; + matchRange = [selfCopy rangeOfString: match + options: 0 range: rest]; + } + else + { + matchRange.location = NSNotFound; + } } // Make the substitutions, keep track of the new offset diff --git a/SoObjects/SOGo/SOGoDefaults.plist b/SoObjects/SOGo/SOGoDefaults.plist index e0e0a2aa1..1ff09173c 100644 --- a/SoObjects/SOGo/SOGoDefaults.plist +++ b/SoObjects/SOGo/SOGoDefaults.plist @@ -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", diff --git a/SoObjects/SOGo/SOGoGroup.m b/SoObjects/SOGo/SOGoGroup.m index 63010ec13..4a170be9b 100644 --- a/SoObjects/SOGo/SOGoGroup.m +++ b/SoObjects/SOGo/SOGoGroup.m @@ -57,6 +57,7 @@ #include "SOGoGroup.h" #import +#import #import #import @@ -224,6 +225,7 @@ NSDictionary *d; SOGoUser *user; NSArray *o; + NSAutoreleasePool *pool; int i, c; if (!_members) @@ -259,35 +261,39 @@ // 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]; if (user) - { - [logins addObject: login]; - [_members addObject: user]; - } + { + [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]; if (user) - { - [logins addObject: login]; - [_members addObject: user]; - } + { + [logins addObject: login]; + [_members addObject: user]; + } + [pool release]; } - // We are done fetching members, let's cache the members of the group - // (ie., their UIDs) in memcached to speed up -hasMemberWithUID. - [[SOGoCache sharedCache] setValue: [logins componentsJoinedByString: @","] - forKey: [NSString stringWithFormat: @"%@+%@", _identifier, _domain]]; + // We are done fetching members, let's cache the members of the group + // (ie., their UIDs) in memcached to speed up -hasMemberWithUID. + [[SOGoCache sharedCache] setValue: [logins componentsJoinedByString: @","] + forKey: [NSString stringWithFormat: @"%@+%@", _identifier, _domain]]; } else { diff --git a/SoObjects/SOGo/SOGoSAML2Session.m b/SoObjects/SOGo/SOGoSAML2Session.m index e9258d694..9fda46089 100644 --- a/SoObjects/SOGo/SOGoSAML2Session.m +++ b/SoObjects/SOGo/SOGoSAML2Session.m @@ -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]; diff --git a/SoObjects/SOGo/SOGoSieveManager.m b/SoObjects/SOGo/SOGoSieveManager.m index d75f9dba4..603e21e28 100644 --- a/SoObjects/SOGo/SOGoSieveManager.m +++ b/SoObjects/SOGo/SOGoSieveManager.m @@ -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."; @@ -474,8 +474,8 @@ static NSString *sieveScriptName = @"sogo"; sieveAction = [NSString stringWithFormat: @"%@ %@", method, [argument asSieveQuotedString]]; else if ([method isEqualToString: @"reject"]) - sieveAction = [NSString stringWithFormat: @"%@ %@", - method, [argument asSieveQuotedString]]; + sieveAction = [NSString stringWithFormat: @"%@ %@", + method, [argument asSieveQuotedString]]; else scriptError = [NSString stringWithFormat: @"Action has unknown method '%@'", @@ -605,9 +605,9 @@ static NSString *sieveScriptName = @"sogo"; // // - (BOOL) updateFiltersForLogin: (NSString *) theLogin - authname: (NSString *) theAuthName - password: (NSString *) thePassword - account: (SOGoMailAccount *) theAccount + authname: (NSString *) theAuthName + password: (NSString *) thePassword + account: (SOGoMailAccount *) theAccount { NSMutableArray *req; NSMutableString *script, *header; @@ -777,30 +777,30 @@ static NSString *sieveScriptName = @"sogo"; b = YES; if (days == 0) - days = 7; + days = 7; [req addObjectUniquely: @"vacation"]; // Skip mailing lists if (ignore) - [script appendString: @"if allof ( not exists [\"list-help\", \"list-unsubscribe\", \"list-subscribe\", \"list-owner\", \"list-post\", \"list-archive\", \"list-id\", \"Mailing-List\"], not header :comparator \"i;ascii-casemap\" :is \"Precedence\" [\"list\", \"bulk\", \"junk\"], not header :comparator \"i;ascii-casemap\" :matches \"To\" \"Multiple recipients of*\" ) {"]; + [script appendString: @"if allof ( not exists [\"list-help\", \"list-unsubscribe\", \"list-subscribe\", \"list-owner\", \"list-post\", \"list-archive\", \"list-id\", \"Mailing-List\"], not header :comparator \"i;ascii-casemap\" :is \"Precedence\" [\"list\", \"bulk\", \"junk\"], not header :comparator \"i;ascii-casemap\" :matches \"To\" \"Multiple recipients of*\" ) {"]; [script appendFormat: @"vacation :days %d :addresses [", days]; for (i = 0; i < [addresses count]; i++) - { - [script appendFormat: @"\"%@\"", [addresses objectAtIndex: i]]; + { + [script appendFormat: @"\"%@\"", [addresses objectAtIndex: i]]; - if (i == [addresses count]-1) - [script appendString: @"] "]; - else - [script appendString: @", "]; - } + if (i == [addresses count]-1) + [script appendString: @"] "]; + else + [script appendString: @", "]; + } [script appendFormat: @"text:\r\n%@\r\n.\r\n;\r\n", text]; if (ignore) - [script appendString: @"}\r\n"]; + [script appendString: @"}\r\n"]; } @@ -819,14 +819,14 @@ static NSString *sieveScriptName = @"sogo"; addresses = [NSArray arrayWithObject: addresses]; for (i = 0; i < [addresses count]; i++) - { + { v = [addresses objectAtIndex: i]; if (v && [v length] > 0) [script appendFormat: @"redirect \"%@\";\r\n", v]; } if ([[values objectForKey: @"keepCopy"] boolValue]) - [script appendString: @"keep;\r\n"]; + [script appendString: @"keep;\r\n"]; } if ([req count]) @@ -854,19 +854,20 @@ static NSString *sieveScriptName = @"sogo"; result = [client putScript: sieveScriptName script: script]; if (![[result valueForKey:@"result"] boolValue]) { - NSLog(@"Could not upload Sieve script: %@", result); - [client closeConnection]; - return NO; + NSLog(@"Could not upload Sieve script: %@", result); + [client closeConnection]; + return NO; } result = [client setActiveScript: sieveScriptName]; if (![[result valueForKey:@"result"] boolValue]) { - NSLog(@"Could not enable Sieve script: %@", result); - [client closeConnection]; - return NO; + NSLog(@"Could not enable Sieve script: %@", result); + [client closeConnection]; + return NO; } } + [client closeConnection]; return YES; } diff --git a/SoObjects/SOGo/SOGoSource.h b/SoObjects/SOGo/SOGoSource.h index ebf085200..2415f408c 100644 --- a/SoObjects/SOGo/SOGoSource.h +++ b/SoObjects/SOGo/SOGoSource.h @@ -61,6 +61,7 @@ inDomain: (NSString *) domain; - (NSArray *) allEntryIDs; +- (NSArray *) allEntryIDsVisibleFromDomain: (NSString *) domain; - (NSArray *) fetchContactsMatching: (NSString *) filter inDomain: (NSString *) domain; diff --git a/SoObjects/SOGo/SOGoSystemDefaults.h b/SoObjects/SOGo/SOGoSystemDefaults.h index 24d211350..2057f24b0 100644 --- a/SoObjects/SOGo/SOGoSystemDefaults.h +++ b/SoObjects/SOGo/SOGoSystemDefaults.h @@ -43,6 +43,7 @@ - (BOOL) debugLeaks; - (int) vmemLimit; - (BOOL) trustProxyAuthentication; +- (NSString *) encryptionKey; - (BOOL) useRelativeURLs; - (BOOL) isWebAccessEnabled; diff --git a/SoObjects/SOGo/SOGoSystemDefaults.m b/SoObjects/SOGo/SOGoSystemDefaults.m index 4f5c5651a..e724c4fb9 100644 --- a/SoObjects/SOGo/SOGoSystemDefaults.m +++ b/SoObjects/SOGo/SOGoSystemDefaults.m @@ -349,6 +349,11 @@ _injectConfigurationFromFile (NSMutableDictionary *defaultsDict, return [self boolForKey: @"SOGoTrustProxyAuthentication"]; } +- (NSString *) encryptionKey; +{ + return [self stringForKey: @"SOGoEncryptionKey"]; +} + - (BOOL) useRelativeURLs { return [self boolForKey: @"WOUseRelativeURLs"]; diff --git a/SoObjects/SOGo/SOGoUserManager.h b/SoObjects/SOGo/SOGoUserManager.h index 23ef643df..6564e10b2 100644 --- a/SoObjects/SOGo/SOGoUserManager.h +++ b/SoObjects/SOGo/SOGoUserManager.h @@ -82,11 +82,19 @@ - (NSString *) getLoginForDN: (NSString *) theDN; - (BOOL) checkLogin: (NSString *) _login - password: (NSString *) _pwd + password: (NSString *) _pwd domain: (NSString **) _domain - perr: (SOGoPasswordPolicyError *) _perr - expire: (int *) _expire - grace: (int *) _grace; + perr: (SOGoPasswordPolicyError *) _perr + 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 diff --git a/SoObjects/SOGo/SOGoUserManager.m b/SoObjects/SOGo/SOGoUserManager.m index 28fec2a21..d6a0f9a5b 100644 --- a/SoObjects/SOGo/SOGoUserManager.m +++ b/SoObjects/SOGo/SOGoUserManager.m @@ -448,11 +448,28 @@ static Class NSNullK; } - (BOOL) checkLogin: (NSString *) _login - password: (NSString *) _pwd + password: (NSString *) _pwd domain: (NSString **) _domain - perr: (SOGoPasswordPolicyError *) _perr - expire: (int *) _expire - grace: (int *) _grace + 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); @@ -482,9 +499,9 @@ static Class NSNullK; { checkOK = YES; if (!currentUser) - { - currentUser = [NSMutableDictionary dictionary]; - } + { + currentUser = [NSMutableDictionary dictionary]; + } // It's important to cache the password here as we might have cached the // user's entry in -contactInfosForUserWithUIDorEmail: and if we don't diff --git a/SoObjects/SOGo/SOGoWebAuthenticator.h b/SoObjects/SOGo/SOGoWebAuthenticator.h index 5a3533c70..a2d9eeb5b 100644 --- a/SoObjects/SOGo/SOGoWebAuthenticator.h +++ b/SoObjects/SOGo/SOGoWebAuthenticator.h @@ -42,11 +42,19 @@ + (id) sharedSOGoWebAuthenticator; - (BOOL) checkLogin: (NSString *) _login - password: (NSString *) _pwd + password: (NSString *) _pwd domain: (NSString **) _domain - perr: (SOGoPasswordPolicyError *) _perr - expire: (int *) _expire - grace: (int *) _grace; + perr: (SOGoPasswordPolicyError *) _perr + 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 diff --git a/SoObjects/SOGo/SOGoWebAuthenticator.m b/SoObjects/SOGo/SOGoWebAuthenticator.m index a4e722811..639ca4ec0 100644 --- a/SoObjects/SOGo/SOGoWebAuthenticator.m +++ b/SoObjects/SOGo/SOGoWebAuthenticator.m @@ -110,11 +110,28 @@ } - (BOOL) checkLogin: (NSString *) _login - password: (NSString *) _pwd + password: (NSString *) _pwd domain: (NSString **) _domain - perr: (SOGoPasswordPolicyError *) _perr - expire: (int *) _expire - grace: (int *) _grace + 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; diff --git a/SoObjects/SOGo/SQLSource.m b/SoObjects/SOGo/SQLSource.m index c2db99f7d..7d0de6c07 100644 --- a/SoObjects/SOGo/SQLSource.m +++ b/SoObjects/SOGo/SQLSource.m @@ -37,6 +37,8 @@ #import #import +#import + #import "SOGoConstants.h" #import "NSString+Utilities.h" #import "NSString+Crypto.h" @@ -626,23 +628,94 @@ 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]; cm = [GCSChannelManager defaultChannelManager]; 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 { @@ -699,16 +777,26 @@ lowerFilter, lowerFilter]; if (_mailFields && [_mailFields count] > 0) - { - [sql appendString: [self _whereClauseFromArray: _mailFields value: lowerFilter exact: NO]]; - } + { + [sql appendString: [self _whereClauseFromArray: _mailFields value: lowerFilter exact: NO]]; + } [sql appendString: @")"]; 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]; } diff --git a/Tests/Integration/preferences.py b/Tests/Integration/preferences.py index 854f7cb0c..f66ac0dea 100644 --- a/Tests/Integration/preferences.py +++ b/Tests/Integration/preferences.py @@ -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", diff --git a/Tests/Integration/test-davacl.py b/Tests/Integration/test-davacl.py index 0298a973a..986a27be5 100755 --- a/Tests/Integration/test-davacl.py +++ b/Tests/Integration/test-davacl.py @@ -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 diff --git a/Tests/Integration/utilities.py b/Tests/Integration/utilities.py index 20f70ad18..3b7f31441 100644 --- a/Tests/Integration/utilities.py +++ b/Tests/Integration/utilities.py @@ -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 + + diff --git a/Tools/sogo-ealarms-notify.m b/Tools/sogo-ealarms-notify.m index 0e1f281f7..47fe3a3b5 100644 --- a/Tools/sogo-ealarms-notify.m +++ b/Tools/sogo-ealarms-notify.m @@ -23,28 +23,29 @@ #import #import +#import + #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]) - rc = -1; + rc = -1; [notifier release]; } else diff --git a/Tools/sogo-slapd-sockd.m b/Tools/sogo-slapd-sockd.m index fd7662be3..300aec4a3 100644 --- a/Tools/sogo-slapd-sockd.m +++ b/Tools/sogo-slapd-sockd.m @@ -23,13 +23,14 @@ #import #import +#import + #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]) diff --git a/UI/AdministrationUI/Arabic.lproj/Localizable.strings b/UI/AdministrationUI/Arabic.lproj/Localizable.strings new file mode 100644 index 000000000..44e7695fb --- /dev/null +++ b/UI/AdministrationUI/Arabic.lproj/Localizable.strings @@ -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" = "

وحدة إدارة قوائم الصلاحيات تسمح بتعديل صلاحيات تقويم ودفتر العناوين لكل مستخدم.

لتعديل قائمة صلاحيات خاصة بمجلد مستخدم, اكتب اسم المستخدم في حقل البحث في الجزء العلوي من النافذة واضغط مرتين على المجلد المطلوب.

"; diff --git a/UI/AdministrationUI/GNUmakefile b/UI/AdministrationUI/GNUmakefile index 3b8ecd176..d57aee9dc 100644 --- a/UI/AdministrationUI/GNUmakefile +++ b/UI/AdministrationUI/GNUmakefile @@ -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 \ diff --git a/UI/Common/Arabic.lproj/Localizable.strings b/UI/Common/Arabic.lproj/Localizable.strings new file mode 100644 index 000000000..2f3b62db7 --- /dev/null +++ b/UI/Common/Arabic.lproj/Localizable.strings @@ -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" = "س"; diff --git a/UI/Common/BrazilianPortuguese.lproj/Localizable.strings b/UI/Common/BrazilianPortuguese.lproj/Localizable.strings index c2079131f..47c6c9901 100644 --- a/UI/Common/BrazilianPortuguese.lproj/Localizable.strings +++ b/UI/Common/BrazilianPortuguese.lproj/Localizable.strings @@ -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"; diff --git a/UI/Common/Danish.lproj/Localizable.strings b/UI/Common/Danish.lproj/Localizable.strings index 4d202bb81..1c4f4456a 100644 --- a/UI/Common/Danish.lproj/Localizable.strings +++ b/UI/Common/Danish.lproj/Localizable.strings @@ -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"; diff --git a/UI/Common/GNUmakefile b/UI/Common/GNUmakefile index 488ab9fc1..5eaf6c036 100644 --- a/UI/Common/GNUmakefile +++ b/UI/Common/GNUmakefile @@ -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 \ diff --git a/UI/Common/Russian.lproj/Localizable.strings b/UI/Common/Russian.lproj/Localizable.strings index 180f6bdc8..aca037cee 100644 --- a/UI/Common/Russian.lproj/Localizable.strings +++ b/UI/Common/Russian.lproj/Localizable.strings @@ -16,6 +16,7 @@ "Log Console (dev.)" = "Вход Console (dev.)"; "User" = "Пользователь"; +"Vacation message is enabled" = "Сообщение об отпуске включено"; "Help" = "Помощь"; diff --git a/UI/Contacts/Arabic.lproj/Localizable.strings b/UI/Contacts/Arabic.lproj/Localizable.strings new file mode 100644 index 000000000..004bd95ca --- /dev/null +++ b/UI/Contacts/Arabic.lproj/Localizable.strings @@ -0,0 +1,208 @@ +/* this file is in UTF-8 format! */ + +"Contact" = "بيانات شخص"; +"Address" = "عنوان"; +"Photos" = "صور"; +"Other" = "اخرى"; + +"Address Books" = "دفاتر العناوين"; +"Addressbook" = "دفتر العناوين"; +"Addresses" = "عناوين"; +"Update" = "تحديث"; +"Cancel" = "إلغاء"; +"Common" = "مشترك"; +"Contact editor" = "تحرير بيانات شخص"; +"Contact viewer" = "معاينة بيانات شخص"; +"Email" = "بريد إلكتروني"; +"Screen Name" = "اسم"; +"Extended" = "موسعة"; +"Fax" = "فاكس"; +"Firstname" = "الاسم الاول"; +"Home" = "منزل"; +"HomePhone" = "رقم المنزل"; +"Lastname" = "الاسم الاخير"; +"Location" = "الموقع"; +"MobilePhone" = "رقم المحمول"; +"Name" = "الاسم"; +"OfficePhone" = "رقم المكتب"; +"Organization" = "الجهة"; +"Work Phone" = "رقم العمل"; +"Phone" = "رقم الهاتف"; +"Phones" = "ارقام هواتف"; +"Postal" = "بريد"; +"Save" = "حفظ"; +"Internet" = "انترنت"; +"Unit" = "وحدة"; +"delete" = "مسح"; +"edit" = "تعديل"; +"invalidemailwarn" = "البريد الإلكتروني المحدد غير صالح"; +"invaliddatewarn" = "التاريخ المحدد غير صالح."; +"new" = "جديد"; +"Preferred Phone" = "رقم الهاتف المفضل"; + +"Move To" = "نقل الى"; +"Copy To" = "نسخ الى"; +"Add to:" = "إضافة الى:"; + +/* Tooltips */ + +"Create a new address book card" = "إنشاء بطاقة جديدة بدفتر العناوين "; +"Create a new list" = "إنشاء قائمة جديدة"; +"Edit the selected card" = "تحرير بطاقة مختارة"; +"Send a mail message" = "إرسال رسالة بريد"; +"Delete selected card or address book" = "حذف بطاقة أو دفتر عناوين محدد"; +"Reload all contacts" = "تحديث كافة جهات الاتصال"; + +"htmlMailFormat_UNKNOWN" = "غير معروف"; +"htmlMailFormat_FALSE" = "نص عادي"; +"htmlMailFormat_TRUE" = "HTML"; + +"Name or Email" = "الاسم أو البريد الإلكتروني"; +"Category" = "فئة"; +"Personal Addressbook" = "دفتر العناوين الشخصية"; +"Search in Addressbook" = "البحث في دفتر العناوين"; + +"New Card" = "بطاقة جديدة"; +"New List" = "قائمة جديدة"; +"Properties" = "خصائص"; +"Sharing..." = "مشاركة ..."; +"Write" = "كتابة"; +"Delete" = "مسح"; +"Instant Message" = "رسالة لحظية"; +"Add..." = "إضافة..."; +"Remove" = "مسح"; + +"Please wait..." = "يرجى الانتظار..."; +"No possible subscription" = "لا يوجد إشتراك"; + +"Preferred" = "المفضل"; +"Display:" = "عرض:"; +"Display Name:" = "الاسم المعروض:"; +"Email:" = "البريد الالكتروني:"; +"Additional Email:" = "بريد إلكتروني إضافي"; + +"Phone Number:" = "رقم الهاتف:"; +"Prefers to receive messages formatted as:" = "يفضل تلقي رسائل منسقة على النحو التالي:"; +"Screen Name:" = "أسم التعريف:"; +"Categories:" = "الفئات:"; + +"First:" = "الاول:"; +"Last:" = "الاخير:"; +"Nickname:" = "الاسم الرمزي:"; + +"Telephone" = "رقم الهاتف:"; +"Work:" = "العمل:"; +"Home:" = "المنزل:"; +"Fax:" = "الفاكس:"; +"Mobile:" = "المحمول"; +"Pager:" = "النداء:"; + +/* categories */ +"contacts_category_labels" = "الزميل، المنافس، العملاء، الصديق، العائلة، شريك تجاري، مقدم خدمة، الصحافة ، كبار الشخصيات"; +"Categories" = "الفئات"; +"New category" = "فئة جديدة"; + +/* adresses */ +"Title:" = "اللقب:"; +"Service:" = "الخدمة:"; +"Company:" = "الشركة:"; +"Department:" = "الادارة:"; +"Organization:" = "الجهة"; +"Address:" = "العنوان:"; +"City:" = "المدينة:"; +"State_Province:" = "الولاية / الاقليم / المحافظة:"; +"ZIP_Postal Code:" = "الرمز البريدي:"; +"Country:" = "الدولة:"; +"Web Page:" = "صفحة الانترنت:"; + +"Work" = "العمل"; +"Other Infos" = "معلومات أخرى"; + +"Note:" = "ملاحظة:"; +"Timezone:" = "المنطقة الزمنية:"; +"Birthday:" = "تاريخ الميلاد:"; +"Birthday (yyyy-mm-dd):" = "تاريخ الميلاد (يوم-شهر-سنة):"; +"Freebusy URL:" = "موقع مشغول /حر:"; + +"Add as..." = "إضافة إلى ..."; +"Recipient" = "مستلم"; +"Carbon Copy" = "نسخة من"; +"Blind Carbon Copy" = "نسخة مخفية من"; + +"New Addressbook..." = "دفتر عناوين جديدة ..."; +"Subscribe to an Addressbook..." = "الاشتراك في دفتر العناوين ..."; +"Remove the selected Addressbook" = "إزالة دفتر العناوين المحدد"; + +"Name of the Address Book" = "اسم دفتر العناوين"; +"Are you sure you want to delete the selected address book?" += "هل أنت متأكد أنك تريد حذف دفتر العناوين المحدد؟"; +"You cannot remove nor unsubscribe from a public addressbook." += "لا يمكنك إزالة أو إلغاء الاشتراك من دفترالعناوين العامة."; +"You cannot remove nor unsubscribe from your personal addressbook." += "لا يمكنك إزالة أو إلغاء الاشتراك من دفتر العناوين الشخصية."; + +"Are you sure you want to delete the selected contacts?" += "هل أنت متأكد أنك تريد حذف الأسماء المحدد؟"; + +"You cannot delete the card of \"%{0}\"." += "لا يمكنك حذف البطاقة من \"%{0}\"."; + +"Address Book Name" = "اسم دفتر الكتاب"; + +"You cannot subscribe to a folder that you own!" += "لا يمكنك الاشتراك في مجلد تمتلكه."; +"Unable to subscribe to that folder!" += "غير قادر على الاشتراك في هذا المجلد."; + +/* acls */ +"Access rights to" = "صلاحية الدخول الى"; +"For user" = "للمستخدم"; + +"Any Authenticated User" = "أي مستخدم مسجل"; +"Public Access" = "وصول الجمهور"; + +"This person can add cards to this addressbook." += "يمكن لهذا الشخص إضافة بطاقات إلى دفتر العناوين المحدد."; +"This person can edit the cards of this addressbook." += "يمكن لهذا الشخص تحرير بطاقات من دفتر العناوين المحدد."; +"This person can list the content of this addressbook." += "يمكن لهذا الشخص عرض محتويات دفتر العناوين المحدد."; +"This person can read the cards of this addressbook." += "يمكن لهذا الشخص قراءة بطاقات من دفتر العناوين المحدد."; +"This person can erase cards from this addressbook." += "يمكن لهذا الشخص محو بطاقات من دفتر العناوين المحدد."; + +"The selected contact has no email address." += "الاسم الذي تم اختياره ليس لديه عنوان البريد الإلكتروني."; + +"Please select a contact." = "الرجاء اختيار إحدى جهات الاتصال."; + +/* Error messages for move and copy */ + +"SoAccessDeniedException" = "لا يمكنك الكتابة إلى دفتر العناوين المذكور."; +"Forbidden" = "لا يمكنك الكتابة إلى دفتر العناوين المذكور."; +"Invalid Contact" = "الاتصال المحدد لم يعد موجودا."; +"Unknown Destination Folder" = "دفتر العناوين المحدد المرسل اليه لم يعد موجودا."; + +/* Lists */ +"List details" = "تفاصيل القائمة"; +"List name:" = "اسم القائمة/"; +"List nickname:" = "اسم القائمة الرمزي:"; +"List description:" = "وصف القائمة:"; +"Members" = "أعضاء"; +"Contacts" = "جهات إتصال"; +"Add" = "إضافة"; +"Lists can't be moved or copied." = "لا يمكن أن يتم نقل القوائم أو نسخها."; +"Export" = "تصدير"; +"Export Address Book..." = "تصدير دفتر العناوين ..."; +"View Raw Source" = "عرض المصدر الخام"; +"Import Cards" = "استيراد بطاقات"; +"Select a vCard or LDIF file." = "حدد شكل vCard أو ملف LDIF."; +"Upload" = "تحميل الى"; +"Uploading" = "تحميل الى"; +"Done" = "تم"; +"An error occured while importing contacts." = "حدث خطأ أثناء استيراد جهات الاتصال."; +"No card was imported." = "لم يتم استيراد أي بطاقة."; +"A total of %{0} cards were imported in the addressbook." = "قد تم استيراد ما مجموعه%{0} بطاقات في دفتر العناوين."; + +"Reload" = "إعادة التحميل"; diff --git a/UI/Contacts/Danish.lproj/Localizable.strings b/UI/Contacts/Danish.lproj/Localizable.strings index 3fe4e82ec..2f8cd2602 100644 --- a/UI/Contacts/Danish.lproj/Localizable.strings +++ b/UI/Contacts/Danish.lproj/Localizable.strings @@ -154,7 +154,9 @@ "Unable to subscribe to that folder!" = "Det er ikke muligt at abonnere på denne mappe."; -"User rights for:" = "Brugerrettigheder:"; +/* acls */ +"Access rights to" = "Adgangsrettigheder til"; +"For user" = "For bruger"; "Any Authenticated User" = "Enhver godkendt bruger"; "Public Access" = "Offentlig adgang"; @@ -193,9 +195,11 @@ "Lists can't be moved or copied." = "Lister kan ikke flyttes eller kopieres."; "Export" = "Eksportér"; "Export Address Book..." = "Eksportér adressebog ..."; +"View Raw Source" = "Vis kilde"; "Import Cards" = "Importér kort"; "Select a vCard or LDIF file." = "Vælg en vCard - eller LDIF-fil."; "Upload" = "Indlæs"; +"Uploading" = "Uploader"; "Done" = "Udført"; "An error occured while importing contacts." = "Der opstod en fejl under importering af kontaktpersoner."; "No card was imported." = "Intet kort blev importeret."; diff --git a/UI/Contacts/GNUmakefile b/UI/Contacts/GNUmakefile index b51fda829..b29b0373d 100644 --- a/UI/Contacts/GNUmakefile +++ b/UI/Contacts/GNUmakefile @@ -6,7 +6,7 @@ BUNDLE_NAME = ContactsUI ContactsUI_PRINCIPAL_CLASS = ContactsUIProduct -ContactsUI_LANGUAGES = BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh +ContactsUI_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh ContactsUI_OBJC_FILES = \ UIxContactsUserFolders.m \ diff --git a/UI/Contacts/Polish.lproj/Localizable.strings b/UI/Contacts/Polish.lproj/Localizable.strings index 46c61ce70..d8ec02965 100644 --- a/UI/Contacts/Polish.lproj/Localizable.strings +++ b/UI/Contacts/Polish.lproj/Localizable.strings @@ -127,7 +127,7 @@ "Add as..." = "Dodaj jako"; "Recipient" = "Odbiorca"; "Carbon Copy" = "Do wiadomości"; -"Blind Carbon Copy" = "Ukryte do wiadomości"; +"Blind Carbon Copy" = "Ukryte DW"; "New Addressbook..." = "Nowa książka adresowa"; "Subscribe to an Addressbook..." = "Subskrybuj książkę adresową"; diff --git a/UI/Contacts/UIxContactFolderActions.h b/UI/Contacts/UIxContactFolderActions.h index c6f80c112..3e04de561 100644 --- a/UI/Contacts/UIxContactFolderActions.h +++ b/UI/Contacts/UIxContactFolderActions.h @@ -19,8 +19,8 @@ 02111-1307, USA. */ -#ifndef __UIxContactsListView_H__ -#define __UIxContactsListView_H__ +#ifndef __UIxContactFolderActions_H__ +#define __UIxContactFolderActions_H__ #import @@ -39,4 +39,4 @@ @end -#endif /* __UIxContactsListView_H__ */ +#endif /* __UIxContactFolderActions_H__ */ diff --git a/UI/Contacts/UIxContactFolderActions.m b/UI/Contacts/UIxContactFolderActions.m index 8e2bde448..ea416bc3a 100644 --- a/UI/Contacts/UIxContactFolderActions.m +++ b/UI/Contacts/UIxContactFolderActions.m @@ -288,4 +288,4 @@ return rc; } -@end /* UIxContactsListView */ +@end /* UIxContactFolderActions */ diff --git a/UI/MailPartViewers/Arabic.lproj/Localizable.strings b/UI/MailPartViewers/Arabic.lproj/Localizable.strings new file mode 100644 index 000000000..ddf59a018 --- /dev/null +++ b/UI/MailPartViewers/Arabic.lproj/Localizable.strings @@ -0,0 +1,46 @@ +ACCEPTED = "مقبول"; +COMPLETED = "منجز"; +DECLINED = "مرفوض"; +DELEGATED = "مفوض"; +"IN-PROCESS" = "جاري"; +"NEEDS-ACTION" = "بحاجة إلى عمل"; +TENTATIVE = "مؤقت"; +organized_by_you = "منظم من قبلك"; +you_are_an_attendee = "أنت أحد الحضور"; +add_info_text = " \"اضافة\" لا يوجد دعم حتى الآن من قبل سوجو."; +publish_info_text = "المرسل يعلمك بالحدث المرفق."; +cancel_info_text = "تم إلغاء دعوتك أو الحدث برمته."; +request_info_no_attendee = "يقترح عقد إجتماع للحضور. تلقيت هذه الرسالة بمثابة إشعار، وليس من المقرر لكم المشاركة."; +Appointment = "موعد"; + +Organizer = "منظم"; +Time = "الساعة"; +Attendees = "الحضور"; +request_info = "يدعوك للمشاركة في الاجتماع."; +"Add to calendar" = "إضافة الى التقويم"; +"Delete from calendar" = "مسح من التقويم"; +"Update status" = "تحديث الحالة"; +Accept = "قبول"; +Decline = "رفض"; +Tentative = "مؤقت"; +"Delegate ..." = "تفويض ..."; +"Delegated to" = "تفويض إلى ..."; +"Update status in calendar" = "تحديث الحالة فى التقويم"; +"delegated from" = "مفوض من "; + +reply_info_no_attendee = "تلقيت ردا على الحدث المسجل لكن الراسل ليس مشاركا."; +reply_info = "هذا هو الرد على دعوة الحدث التي قمت بها."; + +"to" = "إلى :"; + +"Untitled" = "بدون عنوان"; + +"Size" = "الحجم"; + +"Digital signature is not valid" = "التوقيع الرقمي غير صالح"; +"Message is signed" = "الرسالة موقعة"; +"Subject" = "العنوان"; +"From" = "من"; +"Date" = "التاريخ"; +"To" = "إلى"; +"Issuer" = "المصدر"; diff --git a/UI/MailPartViewers/GNUmakefile b/UI/MailPartViewers/GNUmakefile index 328141f7e..745914636 100644 --- a/UI/MailPartViewers/GNUmakefile +++ b/UI/MailPartViewers/GNUmakefile @@ -6,7 +6,7 @@ BUNDLE_NAME = MailPartViewers MailPartViewers_PRINCIPAL_CLASS = MailPartViewersProduct -MailPartViewers_LANGUAGES = BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh +MailPartViewers_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh MailPartViewers_OBJC_FILES += \ MailPartViewersProduct.m \ diff --git a/UI/MailerUI/Arabic.lproj/Localizable.strings b/UI/MailerUI/Arabic.lproj/Localizable.strings new file mode 100644 index 000000000..ed074efca --- /dev/null +++ b/UI/MailerUI/Arabic.lproj/Localizable.strings @@ -0,0 +1,296 @@ +/* this file is in UTF-8 format! */ + +/* Icon's label */ +"Create" = "أنشئ"; +"Empty Trash" = "أفرِغ سلة المهملات"; +"Delete" = "احذف"; +"Expunge" = "محا"; +"Forward" = "ارسال الى"; +"Get Mail" = "الحصول على البريد"; +"Junk" = "تافه"; +"Reply" = "رد"; +"Reply All" = "رد للكل"; +"Print" = "طباعة"; +"Stop" = "توقف"; +"Write" = "كتابة"; + +"Send" = "ارسال"; +"Contacts" = "عناوين"; +"Attach" = "إضافة مرفق"; +"Save" = "حفظ"; +"Options" = "خيارات"; +"Close" = "إغلاق"; +"Size" = "حجم"; + +/* Tooltips */ + +"Send this message now" = "إرسال هذه الرسالة الآن"; +"Select a recipient from an Address Book" = "حدد المستلم من دفتر العناوين"; +"Include an attachment" = "تضمين مرفق"; +"Save this message" = "حفظ هذه الرسالة"; +"Get new messages" = "الحصول على رسائل جديدة"; +"Create a new message" = "إنشاء رسالة جديدة"; +"Go to address book" = "انتقل إلى دفتر العناوين"; +"Reply to the message" = "الرد على الرسالة"; +"Reply to sender and all recipients" = "الرد للمرسل وجميع المتلقين"; +"Forward selected message" = "إرسال الرسالة المحددة"; +"Delete selected message or folder" = "مسح الرسالة او المجلد المحدد"; +"Mark the selected messages as junk" = "سجل الرسائل المحددة على انها تافهة"; +"Print this message" = "اطبع هذه الرسالة"; +"Stop the current transfer" = "وقف النقل الحالي"; +"Attachment" = "مرفق"; +"Unread" = "غير مقروء"; +"Flagged" = "تم وضع علامة عليه"; + +/* Main Frame */ + +"Home" = "الصفحة الرئيسية"; +"Calendar" = "التقويم"; +"Addressbook" = "دفتر العناوين"; +"Mail" = "البريد"; +"Right Administration" = "حق الإدارة"; + +"Help" = "مساعدة"; + +/* Mail account main windows */ + +"Welcome to the SOGo Mailer. Use the folder tree on the left to browse your mail accounts!" = "مرحبا بكم في خدمة سوجو البريدية. استخدم شجرة المجلد على اليسار لتصفح حسابات البريد الإلكتروني الخاص بك!"; + +"Read messages" = "قراءة الرسائل"; +"Write a new message" = "كتابة رسالة جديدة"; + +"Share: " = "مشاركة :"; +"Account: " = "حساب:"; +"Shared Account: " = "حساب مشاركة:"; + +/* acls */ +"Access rights to" = "حقوق الوصول إلى"; +"For user" = "الى مستخدم"; + +"Any Authenticated User" = "أي مستخدم مسجل"; + +"List and see this folder" = "فتح ورؤية هذا المجلد"; +"Read mails from this folder" = "قراءة الرسائل من هذا المجلد"; +"Mark mails read and unread" = "وضع علامة مقروء او غير مقروء على الرسائل"; +"Modify the flags of the mails in this folder" = "تعديل علامات الرسائل بهذا المجلد"; +"Insert, copy and move mails into this folder" = "إدراج، نسخ ونقل الرسائل في هذا المجلد"; +"Post mails" = "إضافة رسائل"; +"Add subfolders to this folder" = "إضافة مجلدات فرعية إلى هذا المجلد"; +"Remove this folder" = "مسح المجلد"; +"Erase mails from this folder" = "مسح الرسائل من هذا المجلد"; +"Expunge this folder" = "محو هذا المجلد"; +"Archive This Folder" = "أرشفة هذا المجلد"; +"Modify the acl of this folder" = "تعديل قائمة الصلاحيات لهذا المجلد"; + +"Saved Messages.zip" = "حفظ Messages.zip"; + +"Update" = "تحديث"; +"Cancel" = "إلغاء"; + +/* Mail edition */ + +"From" = "من"; +"Subject" = "الموضوع"; +"To" = "إلى"; +"Cc" = "نسخة الى"; +"Bcc" = "نسخة مخفية إلى"; +"Reply-To" = "الرد إلى"; +"Add address" = "إضافة عنوان"; + +"Attachments:" = "مرفقات:"; +"Open" = "فتح"; +"Select All" = "إختيار الكل"; +"Attach Web Page..." = "إرفاق صفحة ويب ..."; +"Attach File(s)..." = "إرفاق ملف (ملفات) ..."; + +"to" = "إلى"; +"cc" = "نسخة الى"; +"bcc" = "نسخة مخفية إلى"; + +"Edit Draft..." = "تعديل مسودة ..."; +"Load Images" = "تحميل صور"; + +"Return Receipt" = "عودة الإيصال"; +"The sender of this message has asked to be notified when you read this message. Do you with to notify the sender?" = "طلب مرسل هذه الرسالة أن يتم إعلامه عند قراءة هذه الرسالة. هل ترغب في إبلاغ المرسل؟"; +"Return Receipt (displayed) - %@"= "إيصال عودة (عرض) -٪ @"; +"This is a Return Receipt for the mail that you sent to %@.\n\nNote: This Return Receipt only acknowledges that the message was displayed on the recipient's computer. There is no guarantee that the recipient has read or understood the message contents." = "هذا هو الإيصال مقابل الرسالة الإلكترونية التي أرسلت إلى @٪\n\nملاحظة: هذا الإشعار بالاستلام لا يقر سوى أنه تم عرض رسالة على الكمبيوتر المستلم. ليس هناك ما يضمن أن المتلقي قد قرأ أو فهم محتويات الرسالة."; + +"Priority" = " الأولوية"; +"highest" = "قصوي"; +"high" = "أعلى"; +"normal" = "عادي"; +"low" = "قليلة"; +"lowest" = "دنيا"; + +"This mail is being sent from an unsecure network!" = "يتم إرسال هذا البريد من شبكة غير آمن!"; + +"Address Book:" = "دفتر العناوين:"; +"Search For:" = "البحث عن :"; + +/* Popup "show" */ + +"all" = "الكل"; +"read" = "قرأ"; +"unread" = "لم يقرأ"; +"deleted" = "مسح"; +"flagged" = "معلم"; + +/* MailListView */ + +"Sender" = "الراسل"; +"Subject or Sender" = "الموضوع أو المرسل"; +"To or Cc" = "إلى أو نسخة الى"; +"Entire Message" = "الرسالة كاملة"; + +"Date" = "التاريخ"; +"View" = "عرض"; +"All" = "الكل"; +"No message" = "لا يوجد رسالة"; +"messages" = "رسائل"; + +"first" = "الأول"; +"previous" = "السابق"; +"next" = "التالي"; +"last" = "آخر"; + +"msgnumber_to" = "إلى"; +"msgnumber_of" = "من"; + +"Mark Unread" = "سجل غير مقروء"; +"Mark Read" = "سجل مقروء"; + +"Untitled" = "بدون عنوان"; + +/* Tree */ + +"SentFolderName" = "البريد الصادر"; +"TrashFolderName" = "المهملات"; +"InboxFolderName" = "البريد الوارد"; +"DraftsFolderName" = "مسودات"; +"SieveFolderName" = "فلاتر"; +"OtherUsersFolderName" = "مستخدمين أخرين"; +"SharedFoldersName" = "مجلدات مشتركة"; +"Folders" = "مجلدات"; /* title line */ + +/* MailMoveToPopUp */ + +"MoveTo" = "نقل ومساعدة؛"; + +/* Address Popup menu */ +"Add to Address Book..." = "إضافة الى دفتر العناوين"; +"Compose Mail To" = "إنشاء بريد الى"; +"Create Filter From Message..." = "إنشاء فلتر من الرسالة ..."; + +/* Image Popup menu */ +"Save Image" = "حفظ الصورة"; +"Save Attachment" = "حفظ المرفقات"; + +/* Mailbox popup menus */ +"Open in New Mail Window" = "فتح في نافذة بريد جديدة"; +"Copy Folder Location" = "نسخ موقع المجلد"; +"Subscribe..." = "إشترك..."; +"Mark Folder Read" = "اجعل رسائل المجلد مقروءة"; +"New Folder..." = "مجلد جديد..."; +"Compact This Folder" = "ضغط هذا المجلد"; +"Search Messages..." = "ابحث عن رسائل ..."; +"Sharing..." = "مشاركة..."; +"New Subfolder..." = "مجلد فرعي جديد ..."; +"Rename Folder..." = "إعادة تسمية مجلد ..."; +"Delete Folder" = "مسح المجلد"; +"Use This Folder For" = "استخدم هذا المجلد لى"; +"Get Messages for Account" = "الحصول على الرسائل من حساب"; +"Properties..." = "خصائص ..."; +"Delegation..." = "تفويض..."; + +/* Use This Folder menu */ +"Sent Messages" = "الرسالة المرسلة"; +"Drafts" = "المسودات"; +"Deleted Messages" = "الرسائل المحذوفة"; + +/* Message list popup menu */ +"Open Message In New Window" = "إفنح الرسالة في نافذة جديدة"; +"Reply to Sender Only" = "الرد على المرسل فقط"; +"Reply to All" = "الرد على الكل"; +"Edit As New..." = "تعديل كالجديد ..."; +"Move To" = "نقل إلى"; +"Copy To" = "نسخ إلى"; +"Label" = "ملصق"; +"Mark" = "وضع علامة"; +"Save As..." = "حفظ باسم ..."; +"Print Preview" = "معاينة قبل الطباعة"; +"View Message Source" = "عرض مصدر الرسالة"; +"Print..." = "طباعة..."; +"Delete Message" = "مسح الرسالة"; +"Delete Selected Messages" = "مسح الرسائل المختارة"; + +"This Folder" = "هذا المجلد"; + +/* Label popup menu */ +"None" = "لا شيء"; +"Important" = "مهم"; +"Work" = "عمل"; +"Personal" = "شخصي"; +"To Do" = "تفعل"; +"Later" = "لاحقا"; + +/* Mark popup menu */ +"As Read" = "مقروء"; +"Thread As Read" = "الموضوع مقروء"; +"As Read By Date..." = "كما يقرأ من التاريخ"; +"All Read" = "الكل مقروء"; +"Flag" = "علم"; +"As Junk" = "غير هام"; +"As Not Junk" = "ليس غير هام"; +"Run Junk Mail Controls" = "تشغيل عناصر تحكم البريد غير المرغوب فيه"; + +/* Folder operations */ +"Name :" = "أسم:"; +"Enter the new name of your folder :" + = "أدخل اسم جديد للمجلد:"; +"Do you really want to move this folder into the trash ?" + = "هل تريد حقا نقل هذا المجلد إلى سلة المهملات؟"; +"Operation failed" = "فشلت عملية"; + +"Quota" = "مساحة تخزين:"; +"quotasFormat" = "%{0}% المستخدمة في %{1} ميغابايت"; + +"Please select a message." = "الرجاء اختيار رسالة."; +"Please select a message to print." = "الرجاء اختيار رسالة للطباعة."; +"Please select only one message to print." = "الرجاء اختيار رسالة واحدة فقط للطباعة."; +"The message you have selected doesn't exist anymore." = "الرسالة التي اخترتها لا وجود لها بعد الآن."; + +"The folder with name \"%{0}\" could not be created." += "المجلد الذي اسمه \"٪ {0}\" لا يمكن أن ينشأ."; +"This folder could not be renamed to \"%{0}\"." += "لا يمكن تغييراسم هذا المجلد إلى \"٪ {0}\"."; +"The folder could not be deleted." += "لا يمكن حذف المجلد."; +"The trash could not be emptied." += "لا يمكن تفريغ القمامة."; +"The folder functionality could not be changed." += "لا يمكن تغيير وظيفة المجلد ."; + +"You need to choose a non-virtual folder!" = "تحتاج إلى اختيار مجلد غير ظاهري!"; + +"Moving a message into its own folder is impossible!" += "لا يمكن نقل رسالة إلى المجلد الخاص بها!"; +"Copying a message into its own folder is impossible!" += "لا يمكن نسخ رسالة إلى المجلد الخاص بها !"; + +/* Message operations */ +"The messages could not be moved to the trash folder. Would you like to delete them immediately?" += "لا يمكن نقل الرسائل إلى مجلد سلة المهملات. هل ترغب في حذفها فورا؟"; + +/* Message editing */ +"error_missingsubject" = "الرسالة ليس بها موضوع. هل أنت متأكد من أنك تريد إرسالها؟"; +"error_missingrecipients" = "يرجى تحديد مستلم واحد على الأقل."; +"Send Anyway" = "إرسال على أي حال"; + +/* Message sending */ +"cannot send message: (smtp) all recipients discarded" = "لا يمكن إرسال الرسالة: جميع العناوين خاطئة."; +"cannot send message (smtp) - recipients discarded:" = "لا يمكن إرسال رسالة. العناوين التالية غير صالحة:"; +"cannot send message: (smtp) error when connecting" = "لا يمكن إرسال الرسالة: خطأ عند الاتصال إلى خادم SMTP."; + +/* Contacts list in mail editor */ +"Email" = "بريد إلكتروني"; +"Name" = "الاسم"; diff --git a/UI/MailerUI/BrazilianPortuguese.lproj/Localizable.strings b/UI/MailerUI/BrazilianPortuguese.lproj/Localizable.strings index 7ba9903a5..4cccf3143 100644 --- a/UI/MailerUI/BrazilianPortuguese.lproj/Localizable.strings +++ b/UI/MailerUI/BrazilianPortuguese.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Abrir em uma Nova Janela"; "Copy Folder Location" = "Copiar o Local da Pasta"; "Subscribe..." = "Inscrever-se..."; -"Mark Folder Read..." = "Marcar Pasta como Lido..."; +"Mark Folder Read" = "Marcar Pasta como Lido..."; "New Folder..." = "Nova Pasta..."; "Compact This Folder" = "Compactar Esta Pasta"; "Search Messages..." = "Procurar Mensagens..."; @@ -259,7 +259,6 @@ "Please select only one message to print." = "Por favor, selecione somente uma mensagem para imprimir."; "The message you have selected doesn't exist anymore." = "A mensagem que você selecionou não existe mais."; - "The folder with name \"%{0}\" could not be created." = "A pasta com o nome \"%{0}\" não pode ser criada."; "This folder could not be renamed to \"%{0}\"." @@ -292,5 +291,6 @@ "cannot send message (smtp) - recipients discarded:" = "Não é possível enviar a mensagem. Os seguintes endereços estão inválidos:"; "cannot send message: (smtp) error when connecting" = "Não é possível enviar a mensagem: erro ao conectar ao servidor SMTP."; -"Name" = "Nome"; +/* Contacts list in mail editor */ "Email" = "Email"; +"Name" = "Nome"; diff --git a/UI/MailerUI/Catalan.lproj/Localizable.strings b/UI/MailerUI/Catalan.lproj/Localizable.strings index 1543d6d5b..401299ece 100644 --- a/UI/MailerUI/Catalan.lproj/Localizable.strings +++ b/UI/MailerUI/Catalan.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Obrir missatge en una finestra nova"; "Copy Folder Location" = "Copiar adreça de la carpeta"; "Subscribe..." = "Subscriure..."; -"Mark Folder Read..." = "Marcar carpeta com a llegida..."; +"Mark Folder Read" = "Marcar carpeta com a llegida..."; "New Folder..." = "Crear carpeta..."; "Compact This Folder" = "Compactar aquesta carpeta"; "Search Messages..." = "Cercar missatges..."; diff --git a/UI/MailerUI/Czech.lproj/Localizable.strings b/UI/MailerUI/Czech.lproj/Localizable.strings index 79886fb13..212baea30 100644 --- a/UI/MailerUI/Czech.lproj/Localizable.strings +++ b/UI/MailerUI/Czech.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Otevřít v novém mailovém okně"; "Copy Folder Location" = "Kopírovat adresu složky"; "Subscribe..." = "Odebírat..."; -"Mark Folder Read..." = "Označit složku jako přečtenou..."; +"Mark Folder Read" = "Označit složku jako přečtenou..."; "New Folder..." = "Nová složka..."; "Compact This Folder" = "Provést údržbu složky"; "Search Messages..." = "Vyhledat zprávy..."; @@ -259,7 +259,6 @@ "Please select only one message to print." = "Zvolte pouze jednu zprávu, kterou chcete tisknout."; "The message you have selected doesn't exist anymore." = "Zpráva, kterou jste zvolili, již neexistuje."; - "The folder with name \"%{0}\" could not be created." = "Složka s názvem \"%{0}\" nemohla být vytvořena."; "This folder could not be renamed to \"%{0}\"." @@ -292,5 +291,6 @@ "cannot send message (smtp) - recipients discarded:" = "Zprávu nelze odeslat: následující adresy jsou neplatné:"; "cannot send message: (smtp) error when connecting" = "Zprávu nelze odeslat: při spojení se SMTP serverem došlo k chybě."; -"Name" = "Jméno"; +/* Contacts list in mail editor */ "Email" = "E-mail"; +"Name" = "Jméno"; diff --git a/UI/MailerUI/Danish.lproj/Localizable.strings b/UI/MailerUI/Danish.lproj/Localizable.strings index e6278659d..8e5592395 100644 --- a/UI/MailerUI/Danish.lproj/Localizable.strings +++ b/UI/MailerUI/Danish.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Attach" = "Vedhæft"; "Save" = "Gem"; "Options" = "Indstillinger"; +"Close" = "Luk"; "Size" = "Størrelse"; /* Tooltips */ @@ -63,8 +64,10 @@ "Shared Account: " = "Delt konto:"; /* acls */ -"Default Roles" = "Standard Roller"; -"User rights for:" = "Bruger rettigheder for:"; +"Access rights to" = "Adgangsrettigheder til"; +"For user" = "For bruger"; + +"Any Authenticated User" = "Alle godkendte brugere"; "List and see this folder" = "Udvid og se denne mappe"; "Read mails from this folder" = "Læs beskeder fra denne mappe"; @@ -104,16 +107,13 @@ "cc" = "Cc"; "bcc" = "Bcc"; -"Addressbook" = "Adressebog"; - "Edit Draft..." = "Redigér kladde ..."; "Load Images" = "Indlæs billeder"; "Return Receipt" = "Kvittering"; "The sender of this message has asked to be notified when you read this message. Do you with to notify the sender?" = "Afsenderen af ​​denne besked har bedt om at blive underrettet, når du læser denne besked. Vil du underrette afsenderen?"; -"Return Receipt (displayed) - %@"= "Kvittering (vist) -% @"; -"This is a Return Receipt for the mail that you sent to %@.\n\nNote: This Return Receipt only acknowledges that the message was displayed on the recipient's computer. There is no guarantee that the recipient has read or understood the message contents." = "Dette er en kvittering for den besked, du har sendt til% @ \ n \ n -Bemærk:. Denne kvittering anerkender kun, at budskabet blev vist på modtagerens computer. Der er ingen garanti for, at modtageren har læst eller forstået indholdet i beskeden."; +"Return Receipt (displayed) - %@"= "Kvittering (vist) - %@"; +"This is a Return Receipt for the mail that you sent to %@.\n\nNote: This Return Receipt only acknowledges that the message was displayed on the recipient's computer. There is no guarantee that the recipient has read or understood the message contents." = "Dette er en kvittering for den besked, du har sendt til %@\n\nBemærk:. Denne kvittering anerkender kun, at budskabet blev vist på modtagerens computer. Der er ingen garanti for, at modtageren har læst eller forstået indholdet i beskeden."; "Priority" = "Prioritet"; "highest" = "Højeste"; @@ -124,8 +124,8 @@ Bemærk:. Denne kvittering anerkender kun, at budskabet blev vist på modtageren "This mail is being sent from an unsecure network!" = "Denne besked bliver sendt fra et usikkert netværk!"; -"Address Book:" = ""; -"Search For:" = ""; +"Address Book:" = "Adressebog:"; +"Search For:" = "Søg efter:"; /* Popup "show" */ @@ -145,7 +145,6 @@ Bemærk:. Denne kvittering anerkender kun, at budskabet blev vist på modtageren "Date" = "Dato"; "View" = "Vis"; "All" = "Alle"; -"Unread" = "Ulæst"; "No message" = "Ingen besked"; "messages" = "Beskeder"; @@ -190,7 +189,7 @@ Bemærk:. Denne kvittering anerkender kun, at budskabet blev vist på modtageren "Open in New Mail Window" = "Åben i nyt vindue"; "Copy Folder Location" = "Kopier mappens lokation"; "Subscribe..." = "Abonnér ..."; -"Mark Folder Read..." = "Mark mappe som Læst ..."; +"Mark Folder Read" = "Mark mappe som Læst ..."; "New Folder..." = "Ny mappe ..."; "Compact This Folder" = "Komprimér denne mappe"; "Search Messages..." = "Søg beskeder ..."; @@ -212,7 +211,6 @@ Bemærk:. Denne kvittering anerkender kun, at budskabet blev vist på modtageren "Open Message In New Window" = "Åben besked i nyt vindue"; "Reply to Sender Only" = "Svar kun afsenderen"; "Reply to All" = "Svar alle"; -"Forward" = "Videresend"; "Edit As New..." = "Redigér som ..."; "Move To" = "Flyt til"; "Copy To" = "Kopier til"; @@ -261,11 +259,10 @@ Bemærk:. Denne kvittering anerkender kun, at budskabet blev vist på modtageren "Please select only one message to print." = "Vælg kun én besked til at udskrive."; "The message you have selected doesn't exist anymore." = "Den besked du har valgt findes ikke længere."; - "The folder with name \"%{0}\" could not be created." -= "Mappen med navnet \"% {0}\" kunne ikke oprettes."; += "Mappen med navnet \"%{0}\" kunne ikke oprettes."; "This folder could not be renamed to \"%{0}\"." -= "Denne mappe kan ikke omdøbes til \"% {0}\"."; += "Denne mappe kan ikke omdøbes til \"%{0}\"."; "The folder could not be deleted." = "Mappen kunne ikke slettes."; "The trash could not be emptied." @@ -285,14 +282,15 @@ Bemærk:. Denne kvittering anerkender kun, at budskabet blev vist på modtageren = "Beskederne kunne ikke flyttes til papirkurven. Vil du slette dem med det samme?"; /* Message editing */ -"error_validationfailed" = "Validering mislykkedes"; "error_missingsubject" = "Emne mangler"; "error_missingrecipients" = "Ingen modtagere angivet"; +"Send Anyway" = "Send alligevel"; /* Message sending */ "cannot send message: (smtp) all recipients discarded" = "Kan ikke sende besked: alle modtagere er ugyldige."; "cannot send message (smtp) - recipients discarded:" = "Kan ikke sende besked. Følgende adresser er ugyldige:"; "cannot send message: (smtp) error when connecting" = "Kan ikke sende besked: Fejl ved oprettelse til SMTP-server."; +/* Contacts list in mail editor */ +"Email" = "Mail"; "Name" = "Navn"; -"Email" = "E-mail"; diff --git a/UI/MailerUI/Dutch.lproj/Localizable.strings b/UI/MailerUI/Dutch.lproj/Localizable.strings index 6ec3c1358..87f98b0b4 100644 --- a/UI/MailerUI/Dutch.lproj/Localizable.strings +++ b/UI/MailerUI/Dutch.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "In nieuw e-mailvenster openen"; "Copy Folder Location" = "Kopieer maplocatie"; "Subscribe..." = "Abonneren..."; -"Mark Folder Read..." = "Map als gelezen markeren"; +"Mark Folder Read" = "Map als gelezen markeren"; "New Folder..." = "Nieuwe map..."; "Compact This Folder" = "Comprimeer deze map"; "Search Messages..." = "Zoeken..."; @@ -259,7 +259,6 @@ "Please select only one message to print." = "Selecteer een enkel bericht om af te drukken."; "The message you have selected doesn't exist anymore." = "Het bericht dat u selecteerde bestaat niet meer."; - "The folder with name \"%{0}\" could not be created." = "De map met naam \"%{0}\" kan niet gemaakt worden."; "This folder could not be renamed to \"%{0}\"." @@ -292,5 +291,6 @@ "cannot send message (smtp) - recipients discarded:" = "Kan bericht niet sturen: de volgende adressen zijn ongeldig:"; "cannot send message: (smtp) error when connecting" = "Kan bericht niet sturen: fout bij verbinden met de SMTP server."; -"Name" = "Naam"; +/* Contacts list in mail editor */ "Email" = "E-mail"; +"Name" = "Naam"; diff --git a/UI/MailerUI/English.lproj/Localizable.strings b/UI/MailerUI/English.lproj/Localizable.strings index 418bd6a49..92d7f6f5f 100644 --- a/UI/MailerUI/English.lproj/Localizable.strings +++ b/UI/MailerUI/English.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Open in New Mail Window"; "Copy Folder Location" = "Copy Folder Location"; "Subscribe..." = "Subscribe..."; -"Mark Folder Read..." = "Mark Folder Read..."; +"Mark Folder Read" = "Mark Folder Read"; "New Folder..." = "New Folder..."; "Compact This Folder" = "Compact This Folder"; "Search Messages..." = "Search Messages..."; diff --git a/UI/MailerUI/Finnish.lproj/Localizable.strings b/UI/MailerUI/Finnish.lproj/Localizable.strings index db4510da4..e5de5d9d9 100644 --- a/UI/MailerUI/Finnish.lproj/Localizable.strings +++ b/UI/MailerUI/Finnish.lproj/Localizable.strings @@ -15,7 +15,7 @@ "Write" = "Kirjoita"; "Send" = "Lähetä"; -"Contacts" = "Kontaktit"; +"Contacts" = "Yhteystiedot"; "Attach" = "Liitä"; "Save" = "Tallenna"; "Options" = "Asetukset"; @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Avaa uudessa viesti-ikkunassa"; "Copy Folder Location" = "Kopioi kansion sijainti"; "Subscribe..." = "Liity..."; -"Mark Folder Read..." = "Merkitse kansio luetuksi..."; +"Mark Folder Read" = "Merkitse kansio luetuksi..."; "New Folder..." = "Uusi kansio..."; "Compact This Folder" = "Pakkaa tämä kansio"; "Search Messages..." = "Etsi viestejä..."; @@ -259,7 +259,6 @@ "Please select only one message to print." = "Ole hyvä ja valitse vain yksi viesti tulostettavaksi."; "The message you have selected doesn't exist anymore." = "Valitsemaasi viestiä ei ole enää olemassa."; - "The folder with name \"%{0}\" could not be created." = "Kansiota \"%{0}\" ei voitu luoda."; "This folder could not be renamed to \"%{0}\"." @@ -292,5 +291,6 @@ "cannot send message (smtp) - recipients discarded:" = "Viestiä ei voi lähettää: seuraavat osoitteet ovat virheellisiä:"; "cannot send message: (smtp) error when connecting" = "Viestiä ei voi lähettää: virhe yhdistettäessä SMTP -palvelimeen."; -"Name" = "Nimi"; +/* Contacts list in mail editor */ "Email" = "Sähköposti"; +"Name" = "Nimi"; diff --git a/UI/MailerUI/French.lproj/Localizable.strings b/UI/MailerUI/French.lproj/Localizable.strings index 98a47adbf..e761a1a08 100644 --- a/UI/MailerUI/French.lproj/Localizable.strings +++ b/UI/MailerUI/French.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Ouvrir dans une nouvelle fenétre"; "Copy Folder Location" = "Copier l'adresse du dossier"; "Subscribe..." = "S'abonner..."; -"Mark Folder Read..." = "Marquer le dossier comme lu"; +"Mark Folder Read" = "Marquer le dossier comme lu"; "New Folder..." = "Nouveau dossier..."; "Compact This Folder" = "Compacter ce dossier"; "Search Messages..." = "Rechercher dans les messages..."; @@ -259,7 +259,6 @@ "Please select only one message to print." = "Veuillez ne sélectionner qu'un seul message à imprimer."; "The message you have selected doesn't exist anymore." = "Le message que vous avez selectionné n'existe plus."; - "The folder with name \"%{0}\" could not be created." = "Le dossier intitulé \"%{0}\" n'a pas pu être créé."; "This folder could not be renamed to \"%{0}\"." @@ -292,5 +291,6 @@ "cannot send message (smtp) - recipients discarded:" = "Le message n'a pas pu être envoyé car les adresses suivantes sont invalides :"; "cannot send message: (smtp) error when connecting" = "Le message n'a pas pu être envoyé: une erreur est survenue en tentant de rejoindre le serveur SMTP."; -"Name" = "Identité"; +/* Contacts list in mail editor */ "Email" = "Adresse électronique"; +"Name" = "Identité"; diff --git a/UI/MailerUI/GNUmakefile b/UI/MailerUI/GNUmakefile index dfce6342c..dc1fdb9cb 100644 --- a/UI/MailerUI/GNUmakefile +++ b/UI/MailerUI/GNUmakefile @@ -6,7 +6,7 @@ BUNDLE_NAME = MailerUI MailerUI_PRINCIPAL_CLASS = MailerUIProduct -MailerUI_LANGUAGES = BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh +MailerUI_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh MailerUI_OBJC_FILES += \ MailerUIProduct.m \ diff --git a/UI/MailerUI/German.lproj/Localizable.strings b/UI/MailerUI/German.lproj/Localizable.strings index a5bed3ef0..18accabf7 100644 --- a/UI/MailerUI/German.lproj/Localizable.strings +++ b/UI/MailerUI/German.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "In neuem Fenster öffnen"; "Copy Folder Location" = "Ordneradresse kopieren"; "Subscribe..." = "Abonnieren..."; -"Mark Folder Read..." = "Ordner als gelesen markieren"; +"Mark Folder Read" = "Ordner als gelesen markieren"; "New Folder..." = "Neuer Ordner..."; "Compact This Folder" = "Komprimieren"; "Search Messages..." = "Suchen..."; @@ -259,7 +259,6 @@ "Please select only one message to print." = "Bitte wählen Sie nur eine Nachricht zum Drucken aus."; "The message you have selected doesn't exist anymore." = "Die gewählte Nachricht existiert nicht mehr."; - "The folder with name \"%{0}\" could not be created." = "Der Ordner mit dem Namen \"%{0}\" konnte nicht erzeugt werden."; "This folder could not be renamed to \"%{0}\"." @@ -283,7 +282,7 @@ = "Die Nachricht(en) können nicht in den Papierkorb verschoben werden. Wollen Sie diese endgültig löschen?"; /* Message editing */ -"error_missingsubject" = "Der Betreff fehlt"; +"error_missingsubject" = "Der Betreff fehlt. Sind Sie sicher, dass Sie dies so senden möchten?"; "error_missingrecipients" = "Der Empfänger fehlt"; "Send Anyway" = "Trotzdem versenden"; @@ -292,5 +291,6 @@ "cannot send message (smtp) - recipients discarded:" = "Kann Nachricht nicht versenden: Die folgenden Addressen sind ungültig:"; "cannot send message: (smtp) error when connecting" = "Kann Nachricht nicht versenden: Fehler beim Verbinden mit dem SMTP-Server."; -"Name" = "Name"; +/* Contacts list in mail editor */ "Email" = "E-Mail"; +"Name" = "Name"; diff --git a/UI/MailerUI/Hungarian.lproj/Localizable.strings b/UI/MailerUI/Hungarian.lproj/Localizable.strings index 50234cbd5..9bd0d51c4 100644 --- a/UI/MailerUI/Hungarian.lproj/Localizable.strings +++ b/UI/MailerUI/Hungarian.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Megnyitás új üzenet ablakban"; "Copy Folder Location" = "Mappa helyének másolása"; "Subscribe..." = "Feliratkozás..."; -"Mark Folder Read..." = "Mappa megjelölése olvasottként..."; +"Mark Folder Read" = "Mappa megjelölése olvasottként..."; "New Folder..." = "Új mappa..."; "Compact This Folder" = "Mappa tömörítése"; "Search Messages..." = "Üzenetek keresése..."; @@ -259,7 +259,6 @@ "Please select only one message to print." = "Kérem csak egy üzenetet válasszon a nyomtatáshoz."; "The message you have selected doesn't exist anymore." = "A kijelölt üzenet már nem létezik."; - "The folder with name \"%{0}\" could not be created." = "\"%{0}\" néven nem hozható létre a mappa."; "This folder could not be renamed to \"%{0}\"." @@ -292,5 +291,6 @@ "cannot send message (smtp) - recipients discarded:" = "Az üzenetet nem lehetett elküldeni: az alábbi címzettek érvénytelenek:"; "cannot send message: (smtp) error when connecting" = "Az üzenetet nem lehetett elküldeni: hiba az SMTP kiszolgálóhoz történő csatlakozáskor."; -"Name" = "Név"; +/* Contacts list in mail editor */ "Email" = "Email"; +"Name" = "Név"; diff --git a/UI/MailerUI/Icelandic.lproj/Localizable.strings b/UI/MailerUI/Icelandic.lproj/Localizable.strings index a6f949997..f8a6cf239 100644 --- a/UI/MailerUI/Icelandic.lproj/Localizable.strings +++ b/UI/MailerUI/Icelandic.lproj/Localizable.strings @@ -186,7 +186,7 @@ "Open in New Mail Window" = "Opna í nýjum glugga fyrir póst"; "Copy Folder Location" = "Afrita staðsetningu möppu"; "Subscribe..." = "Fá áskrift..."; -"Mark Folder Read..." = "Merkja möppu sem lesna..."; +"Mark Folder Read" = "Merkja möppu sem lesna..."; "New Folder..." = "Ný mappa..."; "Compact This Folder" = "Þjappa þessari möppu"; "Search Messages..." = "Leita í Skilaboðum..."; diff --git a/UI/MailerUI/Italian.lproj/Localizable.strings b/UI/MailerUI/Italian.lproj/Localizable.strings index 138c23a80..5d5b84071 100644 --- a/UI/MailerUI/Italian.lproj/Localizable.strings +++ b/UI/MailerUI/Italian.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Apri in una nuova finestra"; "Copy Folder Location" = "Copia cartella"; "Subscribe..." = "Sottoscrivi..."; -"Mark Folder Read..." = "Contrassegna cartella come già letta..."; +"Mark Folder Read" = "Contrassegna cartella come già letta..."; "New Folder..." = "Nuova cartella..."; "Compact This Folder" = "Compatta cartella"; "Search Messages..." = "Cerca messaggi..."; diff --git a/UI/MailerUI/NorwegianBokmal.lproj/Localizable.strings b/UI/MailerUI/NorwegianBokmal.lproj/Localizable.strings index 4b4aa2ada..8d38c34fa 100644 --- a/UI/MailerUI/NorwegianBokmal.lproj/Localizable.strings +++ b/UI/MailerUI/NorwegianBokmal.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Åpne i nytt vindu"; "Copy Folder Location" = "Kopiere mappens lokasjon"; "Subscribe..." = "Abonnere..."; -"Mark Folder Read..." = "Merk mappe som lest..."; +"Mark Folder Read" = "Merk mappe som lest..."; "New Folder..." = "Ny mappe..."; "Compact This Folder" = "Komprimer mappen"; "Search Messages..." = "Søk meldinger..."; diff --git a/UI/MailerUI/NorwegianNynorsk.lproj/Localizable.strings b/UI/MailerUI/NorwegianNynorsk.lproj/Localizable.strings index 78ed3e9ec..27bb80b5b 100644 --- a/UI/MailerUI/NorwegianNynorsk.lproj/Localizable.strings +++ b/UI/MailerUI/NorwegianNynorsk.lproj/Localizable.strings @@ -186,7 +186,7 @@ "Open in New Mail Window" = "Åpne i nytt vindu"; "Copy Folder Location" = "Kopiere mappens lokasjon"; "Subscribe..." = "Abonnere..."; -"Mark Folder Read..." = "Merk mappe som lest..."; +"Mark Folder Read" = "Merk mappe som lest..."; "New Folder..." = "Ny mappe..."; "Compact This Folder" = "Komprimer mappen"; "Search Messages..." = "Søk meldinger..."; diff --git a/UI/MailerUI/Polish.lproj/Localizable.strings b/UI/MailerUI/Polish.lproj/Localizable.strings index 532e9db38..973baee49 100644 --- a/UI/MailerUI/Polish.lproj/Localizable.strings +++ b/UI/MailerUI/Polish.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Otwórz w nowym oknie"; "Copy Folder Location" = "Kopiuj położenie foldera"; "Subscribe..." = "Subskrybuj"; -"Mark Folder Read..." = "Oznacz folder jako przeczytany"; +"Mark Folder Read" = "Oznacz folder jako przeczytany"; "New Folder..." = "Nowy folder"; "Compact This Folder" = "Kompaktuj ten folder"; "Search Messages..." = "Szukaj wiadomości"; @@ -259,7 +259,6 @@ "Please select only one message to print." = "Zaznacz tylko jedną wiadomość do drukowania."; "The message you have selected doesn't exist anymore." = "Zaznaczona wiadomość już nie istnieje."; - "The folder with name \"%{0}\" could not be created." = "Nie można było utworzyć folderu o nazwie \"%{0}\"."; "This folder could not be renamed to \"%{0}\"." @@ -292,5 +291,6 @@ "cannot send message (smtp) - recipients discarded:" = "Nie można wysłać wiadomości - poniźsi odbiorcy zostali odrzuceni:"; "cannot send message: (smtp) error when connecting" = "Nie można wysłać wiadomości - błąd połączenia z serwerem SMTP"; -"Name" = "Nazwa"; +/* Contacts list in mail editor */ "Email" = "E-mail"; +"Name" = "Nazwa"; diff --git a/UI/MailerUI/Russian.lproj/Localizable.strings b/UI/MailerUI/Russian.lproj/Localizable.strings index b09c4ec0b..935200461 100644 --- a/UI/MailerUI/Russian.lproj/Localizable.strings +++ b/UI/MailerUI/Russian.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Открыть в новом окне"; "Copy Folder Location" = "Скопировать адрес папки"; "Subscribe..." = "Подписаться..."; -"Mark Folder Read..." = "Отметить все письма в папке как прочтенные..."; +"Mark Folder Read" = "Отметить все письма в папке как прочтенные..."; "New Folder..." = "Создать папку..."; "Compact This Folder" = "Сжать эту папку"; "Search Messages..." = "Поиск в сообщениях..."; @@ -259,7 +259,6 @@ "Please select only one message to print." = "Пожалуйста выберите только одно сообщение для печати."; "The message you have selected doesn't exist anymore." = "Сообщение, которое вы выбрали, не существует больше."; - "The folder with name \"%{0}\" could not be created." = "Не могу создать папку с именем \"%{0}\"."; "This folder could not be renamed to \"%{0}\"." @@ -292,5 +291,6 @@ "cannot send message (smtp) - recipients discarded:" = "Не удается отправить сообщение. Следующие адреса неверны:"; "cannot send message: (smtp) error when connecting" = "Не удается отправить сообщение: ошибка при соединении с сервером SMTP."; -"Name" = "ПолноеИмя"; +/* Contacts list in mail editor */ "Email" = "Email"; +"Name" = "ПолноеИмя"; diff --git a/UI/MailerUI/Slovak.lproj/Localizable.strings b/UI/MailerUI/Slovak.lproj/Localizable.strings index e6baeee7b..7bae452d5 100644 --- a/UI/MailerUI/Slovak.lproj/Localizable.strings +++ b/UI/MailerUI/Slovak.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Otvoriť v novom okne"; "Copy Folder Location" = "Kopírovať adresu priečinka"; "Subscribe..." = "Potvrď odber..."; -"Mark Folder Read..." = "Označ priečinok ako prečítaný..."; +"Mark Folder Read" = "Označ priečinok ako prečítaný..."; "New Folder..." = "Nový adresár"; "Compact This Folder" = "Vykonaj údržbu tohoto priečinku"; "Search Messages..." = "Hľadať správy"; @@ -259,7 +259,6 @@ "Please select only one message to print." = "Prosím vyberte iba jednu správu ktorú chcete tlačiť."; "The message you have selected doesn't exist anymore." = "Správa ktorú ste vybrali už neexistuje."; - "The folder with name \"%{0}\" could not be created." = "Priečinok s menom \"%{0}\" nemôže byť vytvorení."; "This folder could not be renamed to \"%{0}\"." @@ -292,5 +291,6 @@ "cannot send message (smtp) - recipients discarded:" = "Správa sa nedá odoslať: Nasledujúci príjemcovia nemajú platnú adresu:"; "cannot send message: (smtp) error when connecting" = "Správa sa nedá odoslať: chyba pri pripájaní na SMTP server."; -"Name" = "Meno"; +/* Contacts list in mail editor */ "Email" = "Email"; +"Name" = "Meno"; diff --git a/UI/MailerUI/SpanishArgentina.lproj/Localizable.strings b/UI/MailerUI/SpanishArgentina.lproj/Localizable.strings index 5166a2a7e..f8e9c707a 100644 --- a/UI/MailerUI/SpanishArgentina.lproj/Localizable.strings +++ b/UI/MailerUI/SpanishArgentina.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Abrir mensaje en nueva ventana"; "Copy Folder Location" = "Copiar dirección de la carpeta"; "Subscribe..." = "Suscribir..."; -"Mark Folder Read..." = "Marcar carpeta como leída..."; +"Mark Folder Read" = "Marcar carpeta como leída..."; "New Folder..." = "Crear carpeta..."; "Compact This Folder" = "Compactar esta carpeta"; "Search Messages..." = "Buscar mensajes..."; @@ -259,7 +259,6 @@ "Please select only one message to print." = "Para imprimir, seleccione sólo un mensaje."; "The message you have selected doesn't exist anymore." = "El mensaje seleccionado ya no existe."; - "The folder with name \"%{0}\" could not be created." = "La carpeta llamada \"%{0}\" no puede ser creada."; "This folder could not be renamed to \"%{0}\"." @@ -292,5 +291,6 @@ "cannot send message (smtp) - recipients discarded:" = "No se puede enviar el mensaje: (smtp) destinatarios descartados:"; "cannot send message: (smtp) error when connecting" = "No se puede enviar el mensaje: (smtp) error de conexión"; -"Name" = "Nombre Completo"; +/* Contacts list in mail editor */ "Email" = "Correo"; +"Name" = "Nombre Completo"; diff --git a/UI/MailerUI/SpanishSpain.lproj/Localizable.strings b/UI/MailerUI/SpanishSpain.lproj/Localizable.strings index a07103840..a70f71412 100644 --- a/UI/MailerUI/SpanishSpain.lproj/Localizable.strings +++ b/UI/MailerUI/SpanishSpain.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Abrir mensaje en nueva ventana"; "Copy Folder Location" = "Copiar dirección de la carpeta"; "Subscribe..." = "Suscribir..."; -"Mark Folder Read..." = "Marcar carpeta como leída..."; +"Mark Folder Read" = "Marcar carpeta como leída..."; "New Folder..." = "Crear carpeta..."; "Compact This Folder" = "Compactar esta carpeta"; "Search Messages..." = "Buscar mensajes..."; @@ -259,7 +259,6 @@ "Please select only one message to print." = "Para imprimir, seleccione sólo un mensaje."; "The message you have selected doesn't exist anymore." = "El mensaje seleccionado ya no existe."; - "The folder with name \"%{0}\" could not be created." = "La carpeta llamada \"%{0}\" no puede ser creada."; "This folder could not be renamed to \"%{0}\"." @@ -292,5 +291,6 @@ "cannot send message (smtp) - recipients discarded:" = "No se puede enviar el mensaje: (smtp) destinatarios descartados:"; "cannot send message: (smtp) error when connecting" = "No se puede enviar el mensaje: (smtp) error de conexión"; -"Name" = "Nombre Completo"; +/* Contacts list in mail editor */ "Email" = "Correo"; +"Name" = "Nombre Completo"; diff --git a/UI/MailerUI/Swedish.lproj/Localizable.strings b/UI/MailerUI/Swedish.lproj/Localizable.strings index d78d968ef..3ac0c88cd 100644 --- a/UI/MailerUI/Swedish.lproj/Localizable.strings +++ b/UI/MailerUI/Swedish.lproj/Localizable.strings @@ -186,7 +186,7 @@ "Open in New Mail Window" = "Öppna i nytt fönster"; "Copy Folder Location" = "Kopiera mappens sökväg"; "Subscribe..." = "Prenumrera..."; -"Mark Folder Read..." = "Märk mapp som läst..."; +"Mark Folder Read" = "Märk mapp som läst..."; "New Folder..." = "Ny mapp..."; "Compact This Folder" = "Komprimera mapp"; "Search Messages..." = "Sök meddelanden..."; diff --git a/UI/MailerUI/UIxMailFolderActions.m b/UI/MailerUI/UIxMailFolderActions.m index 729c24b5a..41d4afc5e 100644 --- a/UI/MailerUI/UIxMailFolderActions.m +++ b/UI/MailerUI/UIxMailFolderActions.m @@ -256,6 +256,17 @@ return response; } +- (id) markFolderReadAction +{ + id response; + + response = [[self clientObject] addFlagsToAllMessages: @"seen"]; + if (!response) + response = [self responseWith204]; + + return response; +} + - (WOResponse *) exportFolderAction { WOResponse *response; diff --git a/UI/MailerUI/Ukrainian.lproj/Localizable.strings b/UI/MailerUI/Ukrainian.lproj/Localizable.strings index 86bf825cf..8a7f7b729 100644 --- a/UI/MailerUI/Ukrainian.lproj/Localizable.strings +++ b/UI/MailerUI/Ukrainian.lproj/Localizable.strings @@ -189,7 +189,7 @@ "Open in New Mail Window" = "Відкрити в новому вікні"; "Copy Folder Location" = "Копіювати адресу теки"; "Subscribe..." = "Підписатись..."; -"Mark Folder Read..." = "Відзначити всі листи в теці прочитаними"; +"Mark Folder Read" = "Відзначити всі листи в теці прочитаними"; "New Folder..." = "Створити теку..."; "Compact This Folder" = "Стиснути цю теку"; "Search Messages..." = "Пошук повідомлень..."; diff --git a/UI/MailerUI/Welsh.lproj/Localizable.strings b/UI/MailerUI/Welsh.lproj/Localizable.strings index f30090f6a..61ad37797 100644 --- a/UI/MailerUI/Welsh.lproj/Localizable.strings +++ b/UI/MailerUI/Welsh.lproj/Localizable.strings @@ -186,7 +186,7 @@ "Open in New Mail Window" = "Agor mewn ffenestr Neges Newydd"; "Copy Folder Location" = "Copio Lleoliad Ffolder"; "Subscribe..." = "Tanysgrifio..."; -"Mark Folder Read..." = "Marcio Ffolder Darllenwyd..."; +"Mark Folder Read" = "Marcio Ffolder Darllenwyd..."; "New Folder..." = "Ffolder Newydd..."; "Compact This Folder" = "Cywasgu'r ffolder hwn"; "Search Messages..." = "Chwilio negeseuon..."; diff --git a/UI/MailerUI/product.plist b/UI/MailerUI/product.plist index 49941d90b..60d726ba0 100644 --- a/UI/MailerUI/product.plist +++ b/UI/MailerUI/product.plist @@ -132,6 +132,11 @@ actionClass = "UIxMailFolderActions"; actionName = "saveMessages"; }; + markRead = { + protectedBy = "View"; + actionClass = "UIxMailFolderActions"; + actionName = "markFolderRead"; + }; exportFolder = { protectedBy = "View"; actionClass = "UIxMailFolderActions"; diff --git a/UI/MainUI/Arabic.lproj/Locale b/UI/MainUI/Arabic.lproj/Locale new file mode 100644 index 000000000..c6c3d8187 --- /dev/null +++ b/UI/MainUI/Arabic.lproj/Locale @@ -0,0 +1,35 @@ +/* Arabic */ +{ + NSLanguageName = "Arabic"; + NSFormalName = "العربية"; + NSLocaleCode = "ar"; /* ISO 639-1 */ + NSLanguageCode = "ara"; /* ISO 639-2 */ + NSParentContext = ""; + + NSAMPMDesignation = ("ص", "م"); + NSCurrencySymbol = "$"; + NSDateFormatString = "%A, %B %e, %Y"; + NSDateTimeOrdering = MDYH; + NSDecimalDigits = ("٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩"); + NSDecimalSeparator = "."; + NSEarlierTimeDesignations = ("قبل", "آخر", "الماضي", "منذ"); + NSHourNameDesignations = ((0, "منتصف الليل"), (10, "صباحاُ"), (12, "ظهراُ", "الغداء"), (14, "عصراُ"), (19, "عشاءاُ")); + NSInternationalCurrencyString = EGP; /* ISO 4217 */ + NSLaterTimeDesignations = ("التالي"); + NSMonthNameArray = ("يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"); + NSNextDayDesignations = ("غدا"); + NSNextNextDayDesignations = ("اليوم التالي"); + NSPriorDayDesignations = ("أمس"); + NSShortDateFormatString = "%m/%e/%y"; + NSShortMonthNameArray = ("يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"); + NSShortTimeDateFormatString = "%m/%e/%y %I:%M %p"; + NSShortWeekDayNameArray = ("ح", "ن", "ث", "ر", "خ", "ج", "س"); + NSThisDayDesignations = ("اليوم", "الآن"); + NSThousandsSeparator = ","; + NSTimeDateFormatString = "%A, %B %e, %Y %I:%M:%S %p %Z"; + NSTimeFormatString = "%I:%M:%S %p"; + NSWeekDayNameArray = ("الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت"); + NSYearMonthWeekDesignations = ("سنة", "شهر", "أسبوع"); + NSPositiveCurrencyFormatString = "$9,999.00"; + NSNegativeCurrencyFormatString = "-$9,999.00"; +} diff --git a/UI/MainUI/Arabic.lproj/Localizable.strings b/UI/MainUI/Arabic.lproj/Localizable.strings new file mode 100644 index 000000000..bf38766c0 --- /dev/null +++ b/UI/MainUI/Arabic.lproj/Localizable.strings @@ -0,0 +1,78 @@ +/* this file is in UTF-8 format! */ + +"title" = "سوجو"; + +"Username:" = "اسم المستخدم:"; +"Password:" = "كلمة السر:"; +"Domain:" = "النطاق:"; +"Remember username" = "تذكر اسم المستخدم"; + +"Connect" = "اتصل"; + +"Wrong username or password." = "اسم المستخدم أو كلمة المرور خطأ."; +"cookiesNotEnabled" = "لا يمكنك الدخول لأنه تم تعطيل الكوكيز بالمتصفح الخاص بك . يرجى تمكين الكوكيز في إعدادات المتصفح الخاص بك وحاول مرة أخرى."; + +"browserNotCompatible" = "لقد اكتشفنا ان إصدار المتصفح الخاص بك غير معتمد على هذا الموقع. نحن نوصي بإستخدام فايرفوكس. انقر على الرابط أدناه لتحميل الإصدار الأحدث من هذا المتصفح."; +"alternativeBrowsers" = "بدلا من ذلك، يمكنك أيضا استخدام المتصفحات التالية المتوافقة"; +"alternativeBrowserSafari" = "بدلا من ذلك، يمكنك أيضا استخدام سفاري."; +"Download" = "نزِّل"; + +"Language:" = "اللغة:"; +"choose" = "إختار ..."; +"Arabic" = "العربية"; +"Catalan" = "Català"; +"Czech" = "Česky"; +"Danish" = "Dansk (Danmark)"; +"Dutch" = "Nederlands"; +"English" = "English"; +"Finnish" = "Suomi"; +"French" = "Français"; +"German" = "Deutsch"; +"Hungarian" = "Magyar"; +"Icelandic" = "Íslenska"; +"Italian" = "Italiano"; +"NorwegianBokmal" = "Norsk bokmål"; +"NorwegianNynorsk" = "Norsk nynorsk"; +"Polish" = "Polski"; +"BrazilianPortuguese" = "Português brasileiro"; +"Russian" = "Русский"; +"Slovak" = "Slovensky"; +"SpanishSpain" = "Español (España)"; +"SpanishArgentina" = "Español (Argentina)"; +"Swedish" = "Svenska"; +"Ukrainian" = "Українська"; +"Welsh" = "Cymraeg"; + +"About" = "حول"; +"AboutBox" = "قام بالبرمجة شركة إنفرز، سوجو هو برنامج خدمي كامل المزايا مع التركيز على التوسع والبساطة.
⏎\nسوجو يوفر واجهة غنية بتقنية AJAX ويدعم متصفحات متعددة من خلال استخدام البروتوكولات القياسية مثل اCalDAV وCardDAV.
⏎\nسوجو موزع بموجب GNU GPL النسخة 2 او الاحدث وبعض الاجزاء موزعة تحت GNU GPL النسخة 2. هذا البرنامج مجاني: أنت حر في تغييره وإعادة توزيعه. لا يوجد أي ضمان، إلى الحد الذي يسمح به القانون.
⏎\nانظر this page لخيارات الدعم المختلفة."; + +"Your account was locked due to too many failed attempts." = "تم وقف الدخول على حسابك بسبب الكثير من المحاولات الفاشلة."; +"Your account was locked due to an expired password." = "تم وقف الدخول على حسابك بسبب إنتهاء صلاحية كلمة السر."; +"Login failed due to unhandled error case: " = "فشل تسجيل الدخول بسبب حالة خطأ غير معروفة:"; +"Change your Password" = "تغيير كلمة السر الخاصة بك"; +"The password was changed successfully." = "تم تغيير كلمة المرور بنجاح."; +"Your password has expired, please enter a new one below:" = "كلمة السر الخاصة بك قد انتهت صلاحيتها، الرجاء إدخال واحدة جديدة فيما يلي:"; +"Password must not be empty." = "كلمة السر يجب ان لا تكون فارغة."; +"The passwords do not match. Please try again." = "كلمات المرور لا تتطابق. يرجى المحاولة مرة أخرى."; +"Password Grace Period" = "فترة السماح لكلمة السر "; +"You have %{0} logins remaining before your account is locked. Please change your password in the preference dialog." = "لديك عدد %{0} تسجيلات متبقية قبل وقف الدخول على حسابك. الرجاء تغيير كلمة السر في جزء الخيارات."; +"Password about to expire" = "صلاحية كلمة السر على وشك الانتهاء"; +"Your password is going to expire in %{0} %{1}." = "صلاحية كلمة السر الخاصة بك سوف تنتهي في %{0} %{1} ."; +"days" = "أيام"; +"hours" = "ساعات"; +"minutes" = "دقائق"; +"seconds" = "ثواني"; +"Password change failed" = "فشل تغيير كلمة المرور"; +"Password change failed - Permission denied" = "فشل تغيير كلمة المرور - تم رفض الإذن"; +"Password change failed - Insufficient password quality" = "فشل تغيير كلمة المرور - عدم كفاية جودة كلمة السر"; +"Password change failed - Password is too short" = "فشل تغيير كلمة المرور - كلمة قصيرة جدا"; +"Password change failed - Password is too young" = "فشل تغيير كلمة المرور - كلمة السر هي صغيرة جدا"; +"Password change failed - Password is in history" = "فشل تغيير كلمة المرور - كلمة السر مستخدمة سابقا"; +"Unhandled policy error: %{0}" = "Unhandled policy error: %{0}"; +"Unhandled error response" = "خطأ استجابة غير معالجة"; +"Password change is not supported." = "لا يتم اعتماد تغيير كلمة المرور."; +"Unhandled HTTP error code: %{0}" = "Unhandled HTTP error code: %{0}"; +"New password:" = "كلمة مرور جديدة:"; +"Confirmation:" = "تأكيد:"; +"Cancel" = "إلغاء"; +"Please wait..." = "يرجى الانتظار ..."; diff --git a/UI/MainUI/BrazilianPortuguese.lproj/Localizable.strings b/UI/MainUI/BrazilianPortuguese.lproj/Localizable.strings index 60e407d3d..4bc1a21ca 100644 --- a/UI/MainUI/BrazilianPortuguese.lproj/Localizable.strings +++ b/UI/MainUI/BrazilianPortuguese.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Idioma:"; "choose" = "Escolha ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/Catalan.lproj/Localizable.strings b/UI/MainUI/Catalan.lproj/Localizable.strings index 512b076ca..4a7817cec 100644 --- a/UI/MainUI/Catalan.lproj/Localizable.strings +++ b/UI/MainUI/Catalan.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Llengua:"; "choose" = "Triar ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/Czech.lproj/Localizable.strings b/UI/MainUI/Czech.lproj/Localizable.strings index 647cce61e..b97493efe 100644 --- a/UI/MainUI/Czech.lproj/Localizable.strings +++ b/UI/MainUI/Czech.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Jazyk:"; "choose" = "Vybrat ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/Danish.lproj/Localizable.strings b/UI/MainUI/Danish.lproj/Localizable.strings index 870ea6362..806108d4d 100644 --- a/UI/MainUI/Danish.lproj/Localizable.strings +++ b/UI/MainUI/Danish.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Sprog:"; "choose" = "Vælg ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/Dutch.lproj/Localizable.strings b/UI/MainUI/Dutch.lproj/Localizable.strings index 9e442ad20..073cc9638 100644 --- a/UI/MainUI/Dutch.lproj/Localizable.strings +++ b/UI/MainUI/Dutch.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Taal:"; "choose" = "Kies..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/English.lproj/Localizable.strings b/UI/MainUI/English.lproj/Localizable.strings index 8a9e22a44..294a8d0d6 100644 --- a/UI/MainUI/English.lproj/Localizable.strings +++ b/UI/MainUI/English.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Language:"; "choose" = "Choose ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/Finnish.lproj/Localizable.strings b/UI/MainUI/Finnish.lproj/Localizable.strings index 978b118da..0b3d54586 100644 --- a/UI/MainUI/Finnish.lproj/Localizable.strings +++ b/UI/MainUI/Finnish.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Kieli:"; "choose" = "Valitse ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/French.lproj/Localizable.strings b/UI/MainUI/French.lproj/Localizable.strings index 6d15c6097..b558427c1 100644 --- a/UI/MainUI/French.lproj/Localizable.strings +++ b/UI/MainUI/French.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Langue:"; "choose" = "Choisir ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/GNUmakefile b/UI/MainUI/GNUmakefile index 786f483e8..b2f8986c4 100644 --- a/UI/MainUI/GNUmakefile +++ b/UI/MainUI/GNUmakefile @@ -6,7 +6,7 @@ BUNDLE_NAME = MainUI MainUI_PRINCIPAL_CLASS = MainUIProduct -MainUI_LANGUAGES = BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh +MainUI_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh MainUI_OBJC_FILES += \ MainUIProduct.m \ diff --git a/UI/MainUI/German.lproj/Localizable.strings b/UI/MainUI/German.lproj/Localizable.strings index cb94f38c8..43d7cd413 100644 --- a/UI/MainUI/German.lproj/Localizable.strings +++ b/UI/MainUI/German.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Sprache:"; "choose" = "Auswählen"; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/Hungarian.lproj/Localizable.strings b/UI/MainUI/Hungarian.lproj/Localizable.strings index 61355c91d..3f0759575 100644 --- a/UI/MainUI/Hungarian.lproj/Localizable.strings +++ b/UI/MainUI/Hungarian.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Nyelv:"; "choose" = "Válasszon ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/Icelandic.lproj/Localizable.strings b/UI/MainUI/Icelandic.lproj/Localizable.strings index b0420b9a6..87a17a180 100644 --- a/UI/MainUI/Icelandic.lproj/Localizable.strings +++ b/UI/MainUI/Icelandic.lproj/Localizable.strings @@ -18,6 +18,7 @@ "Language:" = "Tungumál:"; "choose" = "Velja..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/Italian.lproj/Localizable.strings b/UI/MainUI/Italian.lproj/Localizable.strings index d8f6ff792..3fc8fde10 100644 --- a/UI/MainUI/Italian.lproj/Localizable.strings +++ b/UI/MainUI/Italian.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Lingua:"; "choose" = "Scegli..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/NorwegianBokmal.lproj/Localizable.strings b/UI/MainUI/NorwegianBokmal.lproj/Localizable.strings index 03aeee3da..4d74d0970 100644 --- a/UI/MainUI/NorwegianBokmal.lproj/Localizable.strings +++ b/UI/MainUI/NorwegianBokmal.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Språk:"; "choose" = "Velg ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/NorwegianNynorsk.lproj/Localizable.strings b/UI/MainUI/NorwegianNynorsk.lproj/Localizable.strings index e462e771a..a8171823b 100644 --- a/UI/MainUI/NorwegianNynorsk.lproj/Localizable.strings +++ b/UI/MainUI/NorwegianNynorsk.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Språk:"; "choose" = "Velg ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/Polish.lproj/Localizable.strings b/UI/MainUI/Polish.lproj/Localizable.strings index 37863c740..6e9db4694 100644 --- a/UI/MainUI/Polish.lproj/Localizable.strings +++ b/UI/MainUI/Polish.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Język:"; "choose" = "Wybierz ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/Russian.lproj/Localizable.strings b/UI/MainUI/Russian.lproj/Localizable.strings index 53dbe6152..7769a8b9c 100644 --- a/UI/MainUI/Russian.lproj/Localizable.strings +++ b/UI/MainUI/Russian.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Язык:"; "choose" = "Выбрать ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/SOGoRootPage.m b/UI/MainUI/SOGoRootPage.m index 50d1fba43..fb349ef61 100644 --- a/UI/MainUI/SOGoRootPage.m +++ b/UI/MainUI/SOGoRootPage.m @@ -182,7 +182,7 @@ SOGoUserDefaults *ud; SOGoSystemDefaults *sd; SOGoUser *loggedInUser; - NSString *username, *password, *language, *domain; + NSString *username, *password, *language, *domain, *remoteHost; NSArray *supportedLanguages; SOGoPasswordPolicyError err; @@ -200,9 +200,12 @@ language = [request formValueForKey: @"language"]; rememberLogin = [[request formValueForKey: @"rememberLogin"] boolValue]; domain = [request formValueForKey: @"domain"]; + /* this will always be set to something more or less useful by + * [WOHttpTransaction applyAdaptorHeadersWithHttpRequest] */ + remoteHost = [request headerForKey:@"x-webobjects-remote-host"]; if ((b = [auth checkLogin: username password: password domain: &domain - perr: &err expire: &expire grace: &grace]) + perr: &err expire: &expire grace: &grace useCache: NO]) && (err == PolicyNoError) // no password policy && ((expire < 0 && grace < 0) // no password policy or everything is alright @@ -211,7 +214,7 @@ { NSDictionary *json; - [self logWithFormat: @"successful login for user '%@' - expire = %d grace = %d", username, expire, grace]; + [self logWithFormat: @"successful login from '%@' for user '%@' - expire = %d grace = %d", remoteHost, username, expire, grace]; json = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: expire], @"expire", [NSNumber numberWithInt: grace], @"grace", nil]; @@ -248,7 +251,8 @@ } else { - [self logWithFormat: @"Login for user '%@' might not have worked - password policy: %d grace: %d expire: %d bound: %d", username, err, grace, expire, b]; + [self logWithFormat:@"Login from '%@' for user '%@' might not have worked - password policy: %d grace: %d expire: %d bound: %d", + remoteHost, username, err, grace, expire, b]; response = [self _responseWithLDAPPolicyError: err]; } diff --git a/UI/MainUI/SpanishArgentina.lproj/Localizable.strings b/UI/MainUI/SpanishArgentina.lproj/Localizable.strings index 6287039db..99f0cdbee 100644 --- a/UI/MainUI/SpanishArgentina.lproj/Localizable.strings +++ b/UI/MainUI/SpanishArgentina.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Idioma:"; "choose" = "Elija ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/SpanishSpain.lproj/Localizable.strings b/UI/MainUI/SpanishSpain.lproj/Localizable.strings index 91030f880..25e9987fd 100644 --- a/UI/MainUI/SpanishSpain.lproj/Localizable.strings +++ b/UI/MainUI/SpanishSpain.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Idioma:"; "choose" = "Elija ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/Swedish.lproj/Localizable.strings b/UI/MainUI/Swedish.lproj/Localizable.strings index 54f8aed1a..7a7189dc3 100644 --- a/UI/MainUI/Swedish.lproj/Localizable.strings +++ b/UI/MainUI/Swedish.lproj/Localizable.strings @@ -18,6 +18,7 @@ "Language:" = "Språk:"; "choose" = "Välj ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/Ukrainian.lproj/Localizable.strings b/UI/MainUI/Ukrainian.lproj/Localizable.strings index 3096a86bd..2032809c1 100644 --- a/UI/MainUI/Ukrainian.lproj/Localizable.strings +++ b/UI/MainUI/Ukrainian.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Language:" = "Мова:"; "choose" = "Вибрати ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/MainUI/Welsh.lproj/Localizable.strings b/UI/MainUI/Welsh.lproj/Localizable.strings index 0538cd395..e2873d63c 100644 --- a/UI/MainUI/Welsh.lproj/Localizable.strings +++ b/UI/MainUI/Welsh.lproj/Localizable.strings @@ -18,6 +18,7 @@ "Language:" = "Iaith:"; "choose" = "Dewis ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/Arabic.lproj/Localizable.strings b/UI/PreferencesUI/Arabic.lproj/Localizable.strings new file mode 100644 index 000000000..5b27b560a --- /dev/null +++ b/UI/PreferencesUI/Arabic.lproj/Localizable.strings @@ -0,0 +1,309 @@ +/* toolbar */ +"Save and Close" = "حفظ وإغلاق"; +"Close" = "إغلاق"; + +/* tabs */ +"General" = "عام"; +"Calendar Options" = "خيارات التقويم"; +"Contacts Options" = "خيارات جهات الاتصال"; +"Mail Options" = "خيارات البريد"; +"IMAP Accounts" = "حسابات IMAP"; +"Vacation" = "عطلة"; +"Forward" = "ارسال الى"; +"Password" = "كلمة السر"; +"Categories" = "الفئات"; +"Name" = "اسم "; +"Color" = "اللون"; +"Add" = "إضافة"; +"Delete" = "مسح"; + +/* contacts categories */ +"contacts_category_labels" = "الزميل، المنافس، العملاء، الصديق، العائلة، شريك تجاري، مقدم خدمة ، الصحافة ،كبار الشخصيات"; + +/* vacation (auto-reply) */ +"Enable vacation auto reply" = "تمكين الرد التلقائي أثناء العطلة"; +"Auto reply message :" = "رسالة الرد التلقائي:"; +"Email addresses (separated by commas) :" = "عناوين البريد الإلكتروني (مفصولة بفواصل):"; +"Add default email addresses" = "إضافة عناوين البريد الإلكتروني الافتراضية"; +"Days between responses :" = "عدد الأيام بين الردود:"; +"Do not send responses to mailing lists" = "لا ترسل ردود الى القوائم البريدية"; +"Disable auto reply on" = "تعطيل الرد التلقائي في"; +"Please specify your message and your email addresses for which you want to enable auto reply." += "يرجى تحديد رسالتك وعناوين البريد الإلكتروني التي تريد تمكين الرد التلقائي لها."; +"Your vacation message must not end with a single dot on a line." = "يجب أن لا تنتهي رسالة العطلة بنقطة واحدة على السطر."; +"End date of your auto reply must be in the future." += "يجب أن يكون تاريخ نهاية الرد التلقائي الخاص بك في المستقبل."; + +/* forward messages */ +"Forward incoming messages" = "أعد توجيه الرسائل القادمة"; +"Keep a copy" = "احتفظ بنسخة"; +"Please specify an address to which you want to forward your messages." += "يرجى تحديد العنوان الذي تريد إعادة توجيه رسائلك له."; + +/* d & t */ +"Current Time Zone :" = "التوقيت الزمني الحالى:"; +"Short Date Format :" = "التاريخ بالصيغة المختصرة:"; +"Long Date Format :" = "التاريخ بالصيغة الكاملة:"; +"Time Format :" = "تنسيق الوقت:"; + +"default" = "الافتراضي"; + +"shortDateFmt_0" = "%d-%b-%y"; + +"shortDateFmt_1" = "%d-%m-%y"; +"shortDateFmt_2" = "%d/%m/%y"; +"shortDateFmt_3" = "%e/%m/%y"; + +"shortDateFmt_4" = "%d-%m-%Y"; +"shortDateFmt_5" = "%d/%m/%Y"; + +"shortDateFmt_6" = "%m-%d-%y"; +"shortDateFmt_7" = "%m/%d/%y"; +"shortDateFmt_8" = "%m/%e/%y"; + +"shortDateFmt_9" = "%y-%m-%d"; +"shortDateFmt_10" = "%y/%m/%d"; +"shortDateFmt_11" = "%y.%m.%d"; + +"shortDateFmt_12" = "%Y-%m-%d"; +"shortDateFmt_13" = "%Y/%m/%d"; +"shortDateFmt_14" = "%Y.%m.%d"; + +"shortDateFmt_15" = ""; + +"longDateFmt_0" = "%A, %B %d, %Y"; +"longDateFmt_1" = "%B %d, %Y"; +"longDateFmt_2" = "%A, %d %B, %Y"; +"longDateFmt_3" = "%d %B, %Y"; +"longDateFmt_4" = ""; +"longDateFmt_5" = ""; +"longDateFmt_6" = ""; +"longDateFmt_7" = ""; +"longDateFmt_8" = ""; +"longDateFmt_9" = ""; +"longDateFmt_10" = ""; + +"timeFmt_0" = "%I:%M %p"; +"timeFmt_1" = "%H:%M"; +"timeFmt_2" = ""; +"timeFmt_3" = ""; +"timeFmt_4" = ""; + +/* calendar */ +"Week begins on :" = "بداية الاسبوع:"; +"Day start time :" = "بداية يوم العمل:"; +"Day end time :" = "نهاية يوم العمل:"; +"Day start time must be prior to day end time." = "يجب أن يكون وقت بداية يوم العمل قبل وقت نهاية يوم العمل."; +"Show time as busy outside working hours" = "إظهار الوقت خارج ساعات العمل على أنه مشغول"; +"First week of year :" = "الأسبوع الأول من السنة:"; +"Enable reminders for Calendar items" = "تمكين التذكيرات لعناصر التقويم"; +"Play a sound when a reminder comes due" += "تشغيل صوت للتذكير بموعد اقترب وقته"; +"Default reminder :" = "التذكير الإفتراضي:"; + +"firstWeekOfYear_January1" = "يبدأ في 1 يناير"; +"firstWeekOfYear_First4DayWeek" = "أول 4 ايام في الاسبوع"; +"firstWeekOfYear_FirstFullWeek" = "أول اسبوع كامل"; + +/* Default Calendar */ +"Default calendar :" = "التقويم الإفتراضي:"; +"selectedCalendar" = "التقويم المحدد"; +"personalCalendar" = "التقويم الشخصي"; +"firstCalendar" = "أول تقويم ممكن"; + +"reminderTime_0000" = "0 دقيقة"; +"reminderTime_0005" = "5 دقائق"; +"reminderTime_0010" = "10 دقائق"; +"reminderTime_0015" = "15 دقيقة"; +"reminderTime_0030" = "30 دقيقة"; +"reminderTime_0100" = "1 ساعة"; +"reminderTime_0200" = "2 ساعة"; +"reminderTime_0400" = "4 ساعات"; +"reminderTime_0800" = "8 ساعات"; +"reminderTime_1200" = "1/2 يوم"; +"reminderTime_2400" = "1 يوم"; +"reminderTime_4800" = "2 يوم"; + +/* Mailer */ +"Show subscribed mailboxes only" = "عرض صناديق البريد المشترك بها فقط"; +"Sort messages by threads" = "رتب الرسائل حسب المواضيع"; +"Check for new mail:" = "تحقق من وجود بريد جديد:"; +"messagecheck_manually" = "يدوي"; +"messagecheck_every_minute" = "كل دقيقة"; +"messagecheck_every_2_minutes" = "كل 2 دقيقة"; +"messagecheck_every_5_minutes" = "كل 5 دقائق"; +"messagecheck_every_10_minutes" = "كل 10 دقائق"; +"messagecheck_every_20_minutes" = "كل 20 دقيقة"; +"messagecheck_every_30_minutes" = "كل 30 دقيقة"; +"messagecheck_once_per_hour" = "مرة كل ساعة"; + +"Forward messages:" = "أعد توجيه الرسائل:"; +"messageforward_inline" = "مضمنة"; +"messageforward_attached" = "كمرفق"; + +"When replying to a message:" = "متى يُرَدُّ على الرِّسالة:"; +"replyplacement_above" = "بدء الرد فوق الاقتباس"; +"replyplacement_below" = "بدء الرد تحت الاقتباس"; +"And place my signature" = "ووضع توقيعي"; +"signatureplacement_above" = "تحت الرد الخاص بي"; +"signatureplacement_below" = "تحت الإقتباس"; +"Compose messages in" = "إنشاء رسائل في"; +"composemessagestype_html" = "HTML"; +"composemessagestype_text" = "نص عادي"; +"Display remote inline images" = "اعرِض الصور المضمَّنة عن بُعد"; +"displayremoteinlineimages_never" = "أبدًا"; +"displayremoteinlineimages_always" = "دائمًا"; + +/* IMAP Accounts */ +"New Mail Account" = "حساب بريد إلكتروني جديد"; + +"Server Name:" = "أسم الخادم:"; +"Port:" = "مدخل:"; +"Encryption:" = "التشفير:"; +"None" = "بلا"; +"User Name:" = "اسم المستخدم:"; +"Password:" = "كلمة المرور:"; + +"Full Name:" = "الإسم الكامل:"; +"Email:" = "البريد الإلكتروني:"; +"Reply To Email:" = "الرد على البريد الإلكتروني:"; +"Signature:" = "التوقيع:"; +"(Click to create)" = "(انقر للصنع)"; + +"Signature" = "التوقيع"; +"Please enter your signature below:" = "من فضلك ادخل توقيعك أدناه:"; + +"Please specify a valid sender address." = "من فضلك حدِّد عنوان مرسل صالح."; +"Please specify a valid reply-to address." = "من فضلك حدِّد عنوان ردٍّ صالح"; + +/* Additional Parameters */ +"Additional Parameters" = "معلمات إضافية"; + +/* password */ +"New password:" = "كلمة مرور جديدة:"; +"Confirmation:" = "تأكيد:"; +"Change" = "لا شيء"; + +/* Event+task classifications */ +"Default events classification :" = "تصنيف الأحداث الافتراضية:"; +"Default tasks classification :" = "تصنيف المهام الافتراضية :"; +"PUBLIC_item" = "علني"; +"CONFIDENTIAL_item" = "سري"; +"PRIVATE_item" = "خاص"; + +/* Event+task categories */ +"category_none" = "لا شيء"; +"calendar_category_labels" = "ذكرى، عيد ميلاد، مكالمات عمل، عملاء ، منافس، عملاء، المفضلات، المتابعة، الهدايا، أيام العطل، الأفكار، الاجتماع، قضايا، متنوعات ، شخصية،مشاريع، عطلة عامة، الحالة، الموردين ، السفر، عطلة"; + +/* Default module */ +"Calendar" = "تقويم"; +"Contacts" = "دفتر العناوين"; +"Mail" = "بريد"; +"Last" = "أخر إستخدام"; +"Default module :" = "وحدة نمطية افتراضية :"; + +"Language :" = "اللغة:"; +"choose" = "اختيار ..."; +"Arabic" = "العربية"; +"Catalan" = "Català"; +"Czech" = "Česky"; +"Danish" = "Dansk (Danmark)"; +"Dutch" = "Nederlands"; +"English" = "English"; +"Finnish" = "Suomi"; +"French" = "Français"; +"German" = "Deutsch"; +"Hungarian" = "Magyar"; +"Icelandic" = "Íslenska"; +"Italian" = "Italiano"; +"NorwegianBokmal" = "Norsk bokmål"; +"NorwegianNynorsk" = "Norsk nynorsk"; +"Polish" = "Polski"; +"BrazilianPortuguese" = "Português brasileiro"; +"Russian" = "Русский"; +"Slovak" = "Slovensky"; +"SpanishSpain" = "Español (España)"; +"SpanishArgentina" = "Español (Argentina)"; +"Swedish" = "Svenska"; +"Ukrainian" = "Українська"; +"Welsh" = "Cymraeg"; + +/* Return receipts */ +"When I receive a request for a return receipt:" = "عندما اتلقى طلبا لإرسال ايصال استلام:"; +"Never send a return receipt" = "لا ترسل إيصال استلام"; +"Allow return receipts for some messages" = "السماح بإرسال إيصالات استلام مقابل بعض الرسائل الواردة"; +"If I'm not in the To or Cc of the message:" = "إذا لم أكن من ضمن المرسل لهم او المرسل لهم نسخة:"; +"If the sender is outside my domain:" = "إذا كان المرسل من خارج النطاق:"; +"In all other cases:" = "في جميع الحالات الأخرى:"; + +"Never send" = "لم يرسل"; +"Always send" = "إرسال دائما"; +"Ask me" = "أسألني"; + +/* Filters - UIxPreferences */ +"Filters" = "قواعد تصفية"; +"Active" = "نشط"; +"Move Up" = "تحريك لأعلى"; +"Move Down" = "تحريك لأسفل"; + +/* Filters - UIxFilterEditor */ +"Filter name:" = "أسم قاعدة التصفية:"; +"For incoming messages that" = "عن الرسائل الواردة التي"; +"match all of the following rules:" = "تطابق كافة القواعد التالية:"; +"match any of the following rules:" = "تتطابق مع أي من القواعد التالية:"; +"match all messages" = "تطابق جميع الرسائل"; +"Perform these actions:" = "تنفيذ هذه الإجراءات:"; +"Untitled Filter" = "مرشح غير معنون"; + +"Subject" = "موضوع"; +"From" = "من"; +"To" = "إلى"; +"Cc" = "نسخة "; +"To or Cc" = "إلى أو نسخة"; +"Size (Kb)" = "الحجم (كيلو بايت)"; +"Header" = "قمة"; +"Flag the message with:" = " وضع إشارة على الرسالة مع:"; +"Discard the message" = "رفض الرسالة"; +"File the message in:" = "تقديم الرسالة في:"; +"Keep the message" = "الحفاظ على رسالة"; +"Forward the message to:" = "إعادة توجيه الرسالة إلى:"; +"Send a reject message:" = "إرسال رسالة رفض:"; +"Send a vacation message" = "إرسال رسالة عطلة"; +"Stop processing filter rules" = "إيقاف معالجة قواعد التصفية"; + +"is under" = "هو تحت"; +"is over" = "هو فوق"; +"is" = "هو "; +"is not" = "هو لا"; +"contains" = "يحتوي"; +"does not contain" = "لا يحتوي"; +"matches" = "يطابق"; +"does not match" = "لا يطابق"; +"matches regex" = "يطابق رجإكس"; +"does not match regex" = "لا يطابق رجإكس"; + +"Seen" = "نظر"; +"Deleted" = "حذف"; +"Answered" = "اجاب"; +"Flagged" = "وضع علامة عليه"; +"Junk" = "غير مرغوب به"; +"Not Junk" = "مرغوب به"; +"Label 1" = "ملصق 1"; +"Label 2" = "ملصق 2"; +"Label 3" = "ملصق 3"; +"Label 4" = "ملصق 4"; +"Label 5" = "ملصق 5"; + +"The password was changed successfully." = "غُيِّرت كلمة السِّر بنجَاح."; +"Password must not be empty." = "كلمة السر يجب ان لا تكون فارغة."; +"The passwords do not match. Please try again." = "كلمات المرور لا تتطابق. يرجى المحاولة مرة أخرى."; +"Password change failed" = "فشل تغيير كلمة المرور"; +"Password change failed - Permission denied" = "فشل تغيير كلمة المرور - تم رفض الإذن"; +"Password change failed - Insufficient password quality" = "فشل تغيير كلمة المرور - جودة كلمة السر غير كافية"; +"Password change failed - Password is too short" = "فشل تغيير كلمة المرور - كلمة قصيرة جدا"; +"Password change failed - Password is too young" = "فشل تغيير كلمة المرور - كلمة السر هي صغيرة جدا"; +"Password change failed - Password is in history" = "فشل تغيير كلمة المرور - كلمة السر مستخدمة من قبل"; +"Unhandled policy error: %{0}" = "خطأ غير معالج: %{0}"; +"Unhandled error response" = "إستجابة خاطئة غير معروفة"; +"Password change is not supported." = "لا يتم اعتماد تغيير كلمة المرور."; +"Unhandled HTTP error code: %{0}" = "Unhandled HTTP error code: %{0}"; diff --git a/UI/PreferencesUI/BrazilianPortuguese.lproj/Localizable.strings b/UI/PreferencesUI/BrazilianPortuguese.lproj/Localizable.strings index 56f500dee..d5eaccafb 100644 --- a/UI/PreferencesUI/BrazilianPortuguese.lproj/Localizable.strings +++ b/UI/PreferencesUI/BrazilianPortuguese.lproj/Localizable.strings @@ -204,6 +204,7 @@ "Language :" = "Idioma :"; "choose" = "Escolha ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/Catalan.lproj/Localizable.strings b/UI/PreferencesUI/Catalan.lproj/Localizable.strings index d7044d1f5..784b5b41c 100644 --- a/UI/PreferencesUI/Catalan.lproj/Localizable.strings +++ b/UI/PreferencesUI/Catalan.lproj/Localizable.strings @@ -204,6 +204,7 @@ "Language :" = "Language :"; "choose" = "Choose ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/Czech.lproj/Localizable.strings b/UI/PreferencesUI/Czech.lproj/Localizable.strings index 2616f662d..a0d3e9c2b 100644 --- a/UI/PreferencesUI/Czech.lproj/Localizable.strings +++ b/UI/PreferencesUI/Czech.lproj/Localizable.strings @@ -204,6 +204,7 @@ "Language :" = "Jazyk :"; "choose" = "Vybrat ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/Danish.lproj/Localizable.strings b/UI/PreferencesUI/Danish.lproj/Localizable.strings index 386377889..761afcd81 100644 --- a/UI/PreferencesUI/Danish.lproj/Localizable.strings +++ b/UI/PreferencesUI/Danish.lproj/Localizable.strings @@ -30,6 +30,7 @@ "Disable auto reply on" = "Deaktiver Autosvar til"; "Please specify your message and your email addresses for which you want to enable auto reply." = "Angiv venligst din besked og de e-mail-adresser, som du vil aktivere autosvar for."; +"Your vacation message must not end with a single dot on a line." = "Din ferie meddelelse må ikke slutte med et enkelt punktum på en linje."; "End date of your auto reply must be in the future." = "Sluttidspunkt for dit autosvar skal være i fremtiden."; @@ -75,10 +76,18 @@ "longDateFmt_2" = "%A, %d %B, %Y"; "longDateFmt_3" = "%d %B, %Y"; "longDateFmt_4" = ""; +"longDateFmt_5" = ""; +"longDateFmt_6" = ""; +"longDateFmt_7" = ""; +"longDateFmt_8" = ""; +"longDateFmt_9" = ""; +"longDateFmt_10" = ""; "timeFmt_0" = "%I:%M %p"; "timeFmt_1" = "%H:%M"; "timeFmt_2" = ""; +"timeFmt_3" = ""; +"timeFmt_4" = ""; /* calendar */ "Week begins on :" = "Uge start tidspunkt:"; @@ -132,6 +141,7 @@ "messageforward_inline" = "På linie"; "messageforward_attached" = "Som vedhæftet fil"; +"When replying to a message:" = "Når du besvarer en besked:"; "replyplacement_above" = "Start mit svar over citat"; "replyplacement_below" = "Start mit svar under citat"; "And place my signature" = "Og placér min signatur"; @@ -140,23 +150,32 @@ "Compose messages in" = "Skriv beskeder i"; "composemessagestype_html" = "HTML"; "composemessagestype_text" = "Almindelig tekst"; +"Display remote inline images" = "Vis eksterne indlejrede billeder"; +"displayremoteinlineimages_never" = "Aldrig"; +"displayremoteinlineimages_always" = "Altid"; /* IMAP Accounts */ "New Mail Account" = "Ny mail-konto"; "Server Name:" = "Server Navn:"; "Port:" = "Port:"; +"Encryption:" = "Krypteret:"; +"None" = "Ingen"; "User Name:" = "Brugernavn:"; "Password:" = "Adgangskode:"; "Full Name:" = "Fulde navn:"; "Email:" = "E-mail:"; +"Reply To Email:" = "Besvar på mail:"; "Signature:" = "Signatur:"; "(Click to create)" = "(Klik for at oprette)"; "Signature" = "Signatur:"; "Please enter your signature below:" = "Indsæt venligst din signatur nedenfor:"; +"Please specify a valid sender address." = "Angiv venligst en gyldig afsenderadresse."; +"Please specify a valid reply-to address." = "Angiv venligst en gyldig svar-til adresse."; + /* Additional Parameters */ "Additional Parameters" = "Yderligere parametre"; @@ -166,11 +185,11 @@ "Change" = "Skift"; /* Event+task classifications */ -"Default events classification :" = "Default events classification :"; -"Default tasks classification :" = "Default tasks classification :"; -"PUBLIC_item" = "Public"; -"CONFIDENTIAL_item" = "Confidential"; -"PRIVATE_item" = "Private"; +"Default events classification :" = "Standard begivenhedsklassifikation:"; +"Default tasks classification :" = "Standard opgaveklassifikation:"; +"PUBLIC_item" = "Offentlig"; +"CONFIDENTIAL_item" = "Fortrolig"; +"PRIVATE_item" = "Privat"; /* Event+task categories */ "category_none" = "Ingen"; @@ -185,23 +204,24 @@ "Language :" = "Sprog:"; "choose" = "Vælg ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; "Dutch" = "Nederlands"; "English" = "English"; -"Finnish" = "Suomi"; +"Finnish" = "Finsk"; "French" = "Français"; "German" = "Deutsch"; "Hungarian" = "Magyar"; -"Icelandic" = "Íslenska"; +"Icelandic" = "Islandsk"; "Italian" = "Italiano"; "NorwegianBokmal" = "Norsk"; "NorwegianNynorsk" = "Nynorsk"; "BrazilianPortuguese" = "Português brasileiro"; -"Polish" = "Polski"; +"Polish" = "Polsk"; "Russian" = "Русский"; -"Slovak" = "Slovensky"; +"Slovak" = "Slovensk"; "SpanishSpain" = "Spansk (Spanien)"; "SpanishArgentina" = "Spansk (Argentina)"; "Swedish" = "Svenska"; @@ -220,18 +240,6 @@ "Always send" = "Send altid"; "Ask me" = "Spørg mig"; -/* Return receipts */ -"When I receive a request for a return receipt:" = "Når jeg modtager en anmodning om en kvittering:"; -"Never send a return receipt" = "Send aldrig en kvittering"; -"Allow return receipts for some messages" = "Tillad kvitteringer for nogle beskeder"; -"If I'm not in the To or Cc of the message:" = "Hvis jeg ikke er i feltet Til eller Cc i meddelelsen:"; -"If the sender is outside my domain:" = "Hvis afsenderen er uden for mit domæne:"; -"In all other cases:" = "I alle andre tilfælde:"; - -"Never send" = "Send aldrig"; -"Always send" = "Send altid"; -"Ask me" = "Spørg mig"; - /* Filters - UIxPreferences */ "Filters" = "Filtre"; "Active" = "Aktiv"; @@ -245,6 +253,7 @@ "match any of the following rules:" = "match enhver af følgende regler:"; "match all messages" = "match alle beskeder"; "Perform these actions:" = "Udføre disse handlinger:"; +"Untitled Filter" = "Unavngivet filter"; "Subject" = "Emne"; "From" = "Fra"; @@ -285,6 +294,7 @@ "Label 4" = "Mærkat 4"; "Label 5" = "Mærkat 5"; +"The password was changed successfully." = "Adgangskoden er ændret."; "Password must not be empty." = "Adgangskode skal ikke."; "The passwords do not match. Please try again." = "Adgangskoderne stemmer ikke overens. Prøv venligst igen."; "Password change failed" = "Ændring af adgangskode mislykkedes"; @@ -297,5 +307,3 @@ "Unhandled error response" = "fejlreaktion"; "Password change is not supported." = "Adgangskodeændring er ikke understøttet."; "Unhandled HTTP error code: %{0}" = "HTTP fejlkode:%{0}"; -"New password:" = "Ny adgangskode:"; -"Confirmation:" = "Bekræftelse:"; diff --git a/UI/PreferencesUI/Dutch.lproj/Localizable.strings b/UI/PreferencesUI/Dutch.lproj/Localizable.strings index 7bcb3bb60..45c345516 100644 --- a/UI/PreferencesUI/Dutch.lproj/Localizable.strings +++ b/UI/PreferencesUI/Dutch.lproj/Localizable.strings @@ -204,6 +204,7 @@ "Language :" = "Taal:"; "choose" = "Kies..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/English.lproj/Localizable.strings b/UI/PreferencesUI/English.lproj/Localizable.strings index 306e02b72..481ecfb7b 100644 --- a/UI/PreferencesUI/English.lproj/Localizable.strings +++ b/UI/PreferencesUI/English.lproj/Localizable.strings @@ -204,6 +204,7 @@ "Language :" = "Language:"; "choose" = "Choose ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/Finnish.lproj/Localizable.strings b/UI/PreferencesUI/Finnish.lproj/Localizable.strings index 72f6be784..b4a9a7261 100644 --- a/UI/PreferencesUI/Finnish.lproj/Localizable.strings +++ b/UI/PreferencesUI/Finnish.lproj/Localizable.strings @@ -204,6 +204,7 @@ "Language :" = "Kieli:"; "choose" = "Valitse..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/French.lproj/Localizable.strings b/UI/PreferencesUI/French.lproj/Localizable.strings index 1c74c4bb7..73c301fea 100644 --- a/UI/PreferencesUI/French.lproj/Localizable.strings +++ b/UI/PreferencesUI/French.lproj/Localizable.strings @@ -204,6 +204,7 @@ "Language :" = "Langue :"; "choose" = "Choisir ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/GNUmakefile b/UI/PreferencesUI/GNUmakefile index 4a8040b38..7aa0511d2 100644 --- a/UI/PreferencesUI/GNUmakefile +++ b/UI/PreferencesUI/GNUmakefile @@ -6,7 +6,7 @@ BUNDLE_NAME = PreferencesUI PreferencesUI_PRINCIPAL_CLASS = PreferencesUIProduct -PreferencesUI_LANGUAGES = BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh +PreferencesUI_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh PreferencesUI_OBJC_FILES = \ PreferencesUIProduct.m \ diff --git a/UI/PreferencesUI/German.lproj/Localizable.strings b/UI/PreferencesUI/German.lproj/Localizable.strings index c835433ea..4e6bd1618 100644 --- a/UI/PreferencesUI/German.lproj/Localizable.strings +++ b/UI/PreferencesUI/German.lproj/Localizable.strings @@ -204,6 +204,7 @@ "Language :" = "Sprache :"; "choose" = "Auswählen"; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/Hungarian.lproj/Localizable.strings b/UI/PreferencesUI/Hungarian.lproj/Localizable.strings index 3a6cd9ca3..26af9a277 100644 --- a/UI/PreferencesUI/Hungarian.lproj/Localizable.strings +++ b/UI/PreferencesUI/Hungarian.lproj/Localizable.strings @@ -204,6 +204,7 @@ "Language :" = "Nyelv :"; "choose" = "Válasszon ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/Icelandic.lproj/Localizable.strings b/UI/PreferencesUI/Icelandic.lproj/Localizable.strings index 56c58b2dc..bc9ff1330 100644 --- a/UI/PreferencesUI/Icelandic.lproj/Localizable.strings +++ b/UI/PreferencesUI/Icelandic.lproj/Localizable.strings @@ -174,6 +174,7 @@ "Language :" = "Tungumál :"; "choose" = "Velja..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/Italian.lproj/Localizable.strings b/UI/PreferencesUI/Italian.lproj/Localizable.strings index 8228d54c7..d6daf9208 100644 --- a/UI/PreferencesUI/Italian.lproj/Localizable.strings +++ b/UI/PreferencesUI/Italian.lproj/Localizable.strings @@ -195,6 +195,7 @@ "Language :" = "Lingua :"; "choose" = "Scegli..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/NorwegianBokmal.lproj/Localizable.strings b/UI/PreferencesUI/NorwegianBokmal.lproj/Localizable.strings index 335470e5a..616b2fdf5 100644 --- a/UI/PreferencesUI/NorwegianBokmal.lproj/Localizable.strings +++ b/UI/PreferencesUI/NorwegianBokmal.lproj/Localizable.strings @@ -193,6 +193,7 @@ "Language :" = "Språk:"; "choose" = "Velg ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/NorwegianNynorsk.lproj/Localizable.strings b/UI/PreferencesUI/NorwegianNynorsk.lproj/Localizable.strings index 167a6a112..8e97a7694 100644 --- a/UI/PreferencesUI/NorwegianNynorsk.lproj/Localizable.strings +++ b/UI/PreferencesUI/NorwegianNynorsk.lproj/Localizable.strings @@ -181,6 +181,7 @@ "Language :" = "Språk:"; "choose" = "Velg ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/Polish.lproj/Localizable.strings b/UI/PreferencesUI/Polish.lproj/Localizable.strings index 2b6f3e58b..0a6a8433f 100644 --- a/UI/PreferencesUI/Polish.lproj/Localizable.strings +++ b/UI/PreferencesUI/Polish.lproj/Localizable.strings @@ -204,6 +204,7 @@ "Language :" = "Język:"; "choose" = "Wybierz"; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/Russian.lproj/Localizable.strings b/UI/PreferencesUI/Russian.lproj/Localizable.strings index 772387fb3..e3700265a 100644 --- a/UI/PreferencesUI/Russian.lproj/Localizable.strings +++ b/UI/PreferencesUI/Russian.lproj/Localizable.strings @@ -198,6 +198,7 @@ "Language :" = "Язык :"; "choose" = "Выбрать ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/Slovak.lproj/Localizable.strings b/UI/PreferencesUI/Slovak.lproj/Localizable.strings index 94eed87d5..65726f2df 100644 --- a/UI/PreferencesUI/Slovak.lproj/Localizable.strings +++ b/UI/PreferencesUI/Slovak.lproj/Localizable.strings @@ -204,6 +204,7 @@ "Language :" = "Jazyk:"; "choose" = "Vyber..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings b/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings index 0c9feedc5..fa67e8d55 100644 --- a/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings +++ b/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings @@ -198,6 +198,7 @@ "Language :" = "Idioma :"; "choose" = "Elija ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings b/UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings index 530b74095..1f42bb17c 100644 --- a/UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings +++ b/UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings @@ -204,6 +204,7 @@ "Language :" = "Idioma :"; "choose" = "Elija ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/Swedish.lproj/Localizable.strings b/UI/PreferencesUI/Swedish.lproj/Localizable.strings index 3949abf32..c1e981dbe 100644 --- a/UI/PreferencesUI/Swedish.lproj/Localizable.strings +++ b/UI/PreferencesUI/Swedish.lproj/Localizable.strings @@ -183,6 +183,7 @@ Servernamn:"; "Language :" = "Språk:"; "choose" = "Välj ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/Ukrainian.lproj/Localizable.strings b/UI/PreferencesUI/Ukrainian.lproj/Localizable.strings index ab6bb69cd..8a8ba55e5 100644 --- a/UI/PreferencesUI/Ukrainian.lproj/Localizable.strings +++ b/UI/PreferencesUI/Ukrainian.lproj/Localizable.strings @@ -193,6 +193,7 @@ "Language :" = "Мова :"; "choose" = "Choose ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/PreferencesUI/Welsh.lproj/Localizable.strings b/UI/PreferencesUI/Welsh.lproj/Localizable.strings index 7d4a35802..425195c15 100644 --- a/UI/PreferencesUI/Welsh.lproj/Localizable.strings +++ b/UI/PreferencesUI/Welsh.lproj/Localizable.strings @@ -181,6 +181,7 @@ "Language :" = "Iaith :"; "choose" = "Dewis ..."; +"Arabic" = "العربية"; "Catalan" = "Català"; "Czech" = "Česky"; "Danish" = "Dansk (Danmark)"; diff --git a/UI/Scheduler/Arabic.lproj/Localizable.strings b/UI/Scheduler/Arabic.lproj/Localizable.strings new file mode 100644 index 000000000..6fc599a80 --- /dev/null +++ b/UI/Scheduler/Arabic.lproj/Localizable.strings @@ -0,0 +1,536 @@ +/* this file is in UTF-8 format! */ + +/* Tooltips */ + +"Create a new event" = "إنشاء حدث جديد"; +"Create a new task" = "إنشاء مهمة جديدة"; +"Edit this event or task" = "تحرير هذا الحدث أو المهمة"; +"Delete this event or task" = "حذف هذا الحدث أو المهمة"; +"Go to today" = "انتقل إلى اليوم"; +"Switch to day view" = "التبديل إلى طريقة عرض اليوم"; +"Switch to week view" = "التبديل إلى طريقة عرض الأسبوع"; +"Switch to month view" = "التبديل إلى طريقة عرض الشهر"; +"Reload all calendars" = "تحديث جميع التقاويم"; + +/* Tabs */ +"Date" = "تاريخ"; +"Calendars" = "تقاويم"; + +/* Day */ + +"DayOfTheMonth" = "يوم من الشهر"; +"dayLabelFormat" = "%m/%d/%Y"; +"today" = "اليوم"; + +"Previous Day" = "اليوم السابق"; +"Next Day" = "اليوم اللاحق"; + +/* Week */ + +"Week" = "اسبوع"; +"this week" = "هذا الاسبوع"; + +"Week %d" = "أسبوع %d"; + +"Previous Week" = "الأسبوع السابق"; +"Next Week" = "الأسبوع القادم"; + +/* Month */ + +"this month" = "هذا الشهر"; + +"Previous Month" = "الشهر السابق"; +"Next Month" = "الشهر القادم"; + +/* Year */ + +"this year" = "هذه السنة"; + +/* Menu */ + +"Calendar" = "تقويم"; +"Contacts" = "جهة اتصال"; + +"New Calendar..." = "تقويم جديد..."; +"Delete Calendar" = "إلغاء تقويم..."; +"Unsubscribe Calendar" = "إلغاء مشاركة تقويم"; +"Sharing..." = "مشاركة..."; +"Export Calendar..." = "تصدير التقويم ..."; +"Import Events..." = "استيراد الأحداث ..."; +"Import Events" = "استيراد الأحداث"; +"Select an iCalendar file (.ics)." = "إختار ملف iCalendar file (.ics)."; +"Upload" = "تحميل"; +"Uploading" = "تحميل"; +"Publish Calendar..." = "نشر التقويم ..."; +"Reload Remote Calendars" = "تحديث التقويمات من خادم أخر"; +"Properties" = "خصائص"; +"Done" = "تم"; +"An error occurred while importing calendar." = "حدث خطأ أثناء استيراد تقويم."; +"No event was imported." = "لم يتم استيراد أي حدث."; +"A total of %{0} events were imported in the calendar." = "ما مجموعه%{0} من الأحداث تم استيرادها في التقويم."; + +"Compose E-Mail to All Attendees" = "إنشاء رسالة بريد إلكتروني لجميع الحاضرين"; +"Compose E-Mail to Undecided Attendees" = "إنشاء رسالة بريد إلكتروني الى الحضور الغير مؤكد حضورهم."; + +/* Folders */ +"Personal calendar" = "تقويم شخصي"; + +/* Misc */ + +"OpenGroupware.org" = "OpenGroupware.org"; +"Forbidden" = "ممنوع"; + +/* acls */ + +"Access rights to" = "صلاحية الدخول الى"; +"For user" = "للمستخدم"; + +"Any Authenticated User" = "أي مستخدم مسجل"; +"Public Access" = "وصول عام"; + +"label_Public" = "عام"; +"label_Private" = "خاص"; +"label_Confidential" = "سري"; + +"label_Viewer" = "عرض الكل"; +"label_DAndTViewer" = "عرض التاريخ والوقت"; +"label_Modifier" = "تعديل"; +"label_Responder" = "الاستجابة الى"; +"label_None" = "لا شئ"; + +"View All" = "عرض الكل"; +"View the Date & Time" = "عرض التاريخ والوقت"; +"Modify" = "تعديل"; +"Respond To" = "الاستجابة الى"; +"None" = "لا شئ"; + +"This person can create objects in my calendar." += "يمكن لهذا الشخص إنشاء الكائنات في تقويمي."; +"This person can erase objects from my calendar." += "يمكن لهذا الشخص مسح الكائنات في تقويمي."; + +/* Button Titles */ + +"Subscribe to a Calendar..." = "اشترك في تقويم"; +"Remove the selected Calendar" = "مسح التقويم المحدد"; + +"Name of the Calendar" = "اسم التقويم"; + +"new" = "جديد"; +"printview" = "معاينة قبل الطباعة"; +"edit" = "تعديل"; +"delete" = "مسح"; +"proposal" = "اقتراح"; +"Save and Close" = "حفظ وإغلاق"; +"Close" = "إغلاق"; +"Invite Attendees" = "دعوة لمشاركين"; +"Attach" = "إرفاق"; +"Update" = "تحديث"; +"Cancel" = "إلغاء"; +"show_rejected_apts" = "إظهار المواعيد المرفوضة"; +"hide_rejected_apts" = "إخفاء المواعيد المرفوضة"; + + +/* Schedule */ + +"Schedule" = "جدول"; +"No appointments found" = "لا يوجد مواعيد"; +"Meetings proposed by you" = "الاجتماعات التي اقترحتها"; +"Meetings proposed to you" = "الاجتماعات التي اقترحت لك"; +"sched_startDateFormat" = "%d/%m %H:%M"; +"action" = "تصرف"; +"accept" = "قبول"; +"decline" = "رفض"; +"more attendees" = "مزيد من الحضور"; +"Hide already accepted and rejected appointments" = "إخفاء المواعيد المقبولة والمرفوضة"; +"Show already accepted and rejected appointments" = "إظهار المواعيد المقبولة والمرفوضة"; + + +/* Appointments */ + +"Appointment viewer" = "عارض المواعيد"; +"Appointment editor" = "محرر المواعيد"; +"Appointment proposal" = "اقتراح المواعيد"; +"Appointment on" = "تشغيل المواعيد"; +"Start:" = "البدء:"; +"End:" = "النهاية:"; +"Due Date:" = "تاريخ الاستحقاق:"; +"Title:" = "العنوان:"; +"Calendar:" = "الحالة:"; +"Name" = "الاسم"; +"Email" = "البريد الإلكتروني"; +"Status:" = "الحالة:"; +"% complete" = "اكتمل %c"; +"Location:" = "المكان:"; +"Priority:" = "الأولوية:"; +"Privacy" = "الخصوصية"; +"Cycle" = "الدورة"; +"Cycle End" = "نهاية الدورة"; +"Categories" = "التصنيفات"; +"Classification" = "التصنيف"; +"Duration" = "المدة"; +"Attendees:" = "الحضور:"; +"Resources" = "الموارد"; +"Organizer:" = "المنظم:"; +"Description:" = "الوصف:"; +"Document:" = "المستند:"; +"Category:" = "التصنيف:"; +"Repeat:" = "التكرار:"; +"Reminder:" = "التنبيه:"; +"General:" = "العام:"; +"Reply:" = "الرد:"; + +"Target:" = "الهدف:"; + +"attributes" = "صفات"; +"attendees" = "حضور"; +"delegated from" = "مفوض من"; + +/* checkbox title */ +"is private" = "خاص؟"; +/* classification */ +"Public" = "عام"; +"Private" = "خاص"; +/* text used in overviews and tooltips */ +"empty title" = "عنوان فارغ"; +"private appointment" = "موعد خاص"; + +"Change..." = "غيِّر ..."; + +/* Appointments (participation state) */ + +"partStat_NEEDS-ACTION" = "سأؤكد الأمر لاحقًا"; +"partStat_ACCEPTED" = "سأحضُر"; +"partStat_DECLINED" = "لن أحضُر"; +"partStat_TENTATIVE" = "قد أحضُر"; +"partStat_DELEGATED" = "أفوِّض"; +"partStat_OTHER" = "أخرى"; + +/* Appointments (error messages) */ + +"Conflicts found!" = "هنالك تعارضات!"; +"Invalid iCal data!" = "بيانات iCal غير صالح!"; +"Could not create iCal data!" = "عاجِز عن إنشاء بيانات iCal!"; + +/* Searching */ + +"view_all" = "الكل"; +"view_today" = "اليوم"; +"view_next7" = "السبعة أيام القادمة"; +"view_next14" = "الأربعة عشر يومًا القادمة"; +"view_next31" = "الواحد وثلاثون يومًا القادمة"; +"view_thismonth" = "هذا الشهر"; +"view_future" = "جميع الأحداث المستقبلية"; +"view_selectedday" = "اليوم المحدد"; + +"View:" = "العرض:"; +"Title or Description" = "العنوان أو الوصف"; + +"Search" = "ابحث"; +"Search attendees" = "ابحث عن الحضور"; +"Search resources" = "ابحث عن الموارد"; +"Search appointments" = "ابحث عن المواعيد"; + +"All day Event" = "حدث طوال اليوم"; +"check for conflicts" = "افحص التعارضات"; + +"Browse URL" = "تصفح عنوان الويب"; + +"newAttendee" = "أضِف أحد الحضور"; + +/* calendar modes */ + +"Overview" = "رؤية عامة"; +"Chart" = "المخطط"; +"List" = "القائمة"; +"Columns" = "الأعمدة"; + +/* Priorities */ + +"prio_0" = "غير محدد"; +"prio_1" = "مرتفعة"; +"prio_2" = "مرتفعة"; +"prio_3" = "مرتفعة"; +"prio_4" = "مرتفعة"; +"prio_5" = "عادية"; +"prio_6" = "منخفضة"; +"prio_7" = "منخفضة"; +"prio_8" = "منخفضة"; +"prio_9" = "منخفضة"; + +/* access classes (privacy) */ +"PUBLIC_vevent" = "حدث عام"; +"CONFIDENTIAL_vevent" = "حدث سري"; +"PRIVATE_vevent" = "حدث خاص"; +"PUBLIC_vtodo" = "مهمة عامة"; +"CONFIDENTIAL_vtodo" = "مهمة سرية"; +"PRIVATE_vtodo" = "مهمة خاصة"; + +/* status type */ +"status_" = "غير محدد"; +"status_NOT-SPECIFIED" = "غير محدد"; +"status_TENTATIVE" = "مؤقت"; +"status_CONFIRMED" = "مؤكد"; +"status_CANCELLED" = "مُلغَى"; +"status_NEEDS-ACTION" = "يحتاجُ إجراءًا"; +"status_IN-PROCESS" = "يتم العمل فيه"; +"status_COMPLETED" = "اكتمل في"; + +/* Cycles */ + +"cycle_once" = "دورة واحدة"; +"cycle_daily" = "دورة يومية"; +"cycle_weekly" = "دورة أسبوعية"; +"cycle_2weeks" = "دورة كل أسبوعين"; +"cycle_4weeks" = "دورة كل 4 أسابيع"; +"cycle_monthly" = "دورة شهريّة"; +"cycle_weekday" = "دورة يومًا كل أسبوع"; +"cycle_yearly" = "دورة سنوية"; + +"cycle_end_never" = "دورة لا تنتهي"; +"cycle_end_until" = "دورة تنتهي في"; + +"Recurrence pattern" = "نمط التكرار"; +"Range of recurrence" = "نطاق التكرار"; + +"Repeat" = "التكرار"; +"Daily" = "يوميًا"; +"Weekly" = "أسبوعيًا"; +"Monthly" = "شهريًّا"; +"Yearly" = "سنويًّا"; +"Every" = "كل"; +"Days" = "أيام"; +"Week(s)" = "أسبوع (أسابيع)"; +"On" = "فعِّل"; +"Month(s)" = "شهر (شهور)"; +"The" = "الـ"; +"Recur on day(s)" = "يتكرر في يوم/أيام"; +"Year(s)" = "عام (أعوام)"; +"cycle_of" = "من"; +"No end date" = "لا يوجد تاريخ نهائي"; +"Create" = "أنشئ"; +"appointment(s)" = "موعد/مواعيد"; +"Repeat until" = "تكرار حتى"; + +"First" = "الأول"; +"Second" = "الثاني"; +"Third" = "الثالث"; +"Fourth" = "الرابع"; +"Fift" = "الخامس"; +"Last" = "الأخير"; + +/* Appointment categories */ + +"category_none" = "بلا"; +"category_labels" = "السنوية,يوم الميلاد,الأعمال,المكالمات,العملاء,المنافسة,العميل,المفضلات,المتابعة,الهدايا,العطلات،الأفكار,الاجتماع,المشاكل,منوعات,شخصي,المشاريع,العطلة العامة,الحالة,الموردون,السفر,الأجازة"; + +"repeat_NEVER" = "لا تكرِّر"; +"repeat_DAILY" = "يوميًا"; +"repeat_WEEKLY" = "أسبوعيًّا"; +"repeat_BI-WEEKLY" = "كل أسبوعين"; +"repeat_EVERY WEEKDAY" = "يوم كل أسبوع"; +"repeat_MONTHLY" = "شهريًّا"; +"repeat_YEARLY" = "سنويًّا"; +"repeat_CUSTOM" = "مخصص..."; + +"reminder_NONE" = "لا تنبيه"; +"reminder_5_MINUTES_BEFORE" = "5 دقائق قبل"; +"reminder_10_MINUTES_BEFORE" = "10 دقائق قبل"; +"reminder_15_MINUTES_BEFORE" = "15 دقيقة قبل"; +"reminder_30_MINUTES_BEFORE" = "30 دقيقة قبل"; +"reminder_45_MINUTES_BEFORE" = "45 دقيقة قبل"; +"reminder_1_HOUR_BEFORE" = "1 ساعة قبل"; +"reminder_2_HOURS_BEFORE" = "2 ساعتان قبل"; +"reminder_5_HOURS_BEFORE" = "5 ساعات قبل"; +"reminder_15_HOURS_BEFORE" = "15 ساعة قبل"; +"reminder_1_DAY_BEFORE" = "1 يوم قبل"; +"reminder_2_DAYS_BEFORE" = "2 يومان قبل"; +"reminder_1_WEEK_BEFORE" = "1 أسبوع قبل"; +"reminder_CUSTOM" = "مخصص..."; + +"reminder_MINUTES" = "دقائق"; +"reminder_HOURS" = "ساعات"; +"reminder_DAYS" = "أيام"; +"reminder_BEFORE" = "قبل"; +"reminder_AFTER" = "بعد"; +"reminder_START" = "يبدأ الحدث"; +"reminder_END" = "ينتهي الحدث"; +"Reminder Details" = "تفاصيل التنبيه"; + +"Choose a Reminder Action" = "اختر إجراءًا للتنبيه"; +"Show an Alert" = "اعرض تنبيهًا"; +"Send an E-mail" = "أرسِل رسالة إلكترونية"; +"Email Organizer" = "منظم البريد الإلكتروني"; +"Email Attendees" = "البريد الإلكتروني للحضور"; + +"zoom_400" = "400%"; +"zoom_200" = "200%"; +"zoom_100" = "100%"; +"zoom_50" = "50%"; +"zoom_25" = "25%"; + +/* transparency */ + +"Show Time as Free" = "اعرض الوقت كمتفرغ"; + +/* validation errors */ + +validate_notitle = "لم يضبط العنوان، استمرار؟"; +validate_invalid_startdate = "حقل تاريخ البدء غير صالح"; +validate_invalid_enddate = "حقل تاريخ الانتهاء غير صالح"; +validate_endbeforestart = "تاريخ الانتهاء الذي أدخلته يحدث قبل تاريخ البدء."; + +"Events" = "الأحداث"; +"Tasks" = "المهام"; +"Show completed tasks" = "اعرض المهام المكتملة"; + +/* tabs */ +"Task" = "المهمة"; +"Event" = "الحدث"; +"Recurrence" = "التكرار"; + +/* toolbar */ +"New Event" = "حدث جديد"; +"New Task" = "مهمة جديدة"; +"Edit" = "حرر"; +"Delete" = "احذف"; +"Go to Today" = "اذهب الي اليوم"; +"Day View" = "عرض اليوم"; +"Week View" = "عرض الاسبوع"; +"Month View" = "عرض الشهر"; +"Reload" = "تحديث"; + +"eventPartStatModificationError" = "حالة المشاركة الخاصة بك لا يمكن تعديلها."; + +/* menu */ +"New Event..." = "حدث جديد..."; +"New Task..." = "مهمة جديدة..."; +"Edit Selected Event..." = "حرر الحدث المحدد..."; +"Delete Selected Event" = "احذف الحدث المحدد"; +"Select All" = "اختر الكل"; +"Workweek days only" = "ايام العمل الأسبوعية فقط"; +"Tasks in View" = "المهمات في العرض"; + +"eventDeleteConfirmation" = "الحدث (الأحداث) الآتية ستُمحى: \n%{0}\nهل تريد المتابعة؟"; +"taskDeleteConfirmation" = "المهمة (المهام) التالية ستمحى: \n %{0}\n هل تريد المتابعة؟"; + +"You cannot remove nor unsubscribe from your personal calendar." += "لا يمكنك حذف أو إلغاء اشتراكك من تقويمك الشخصي."; +"Are you sure you want to delete the calendar \"%{0}\"?" += "هل انت متأكد من حذف التقويم \"%{0}\"؟"; + +/* Legend */ +"Participant" = "المشارك"; +"Optional Participant" = "المشارك الاختياري"; +"Non Participant" = "غير مشارك"; +"Chair" = "مقعد"; + +"Needs action" = "بحاجة إلى إجراء"; +"Accepted" = "مقبول"; +"Declined" = "مرفوض"; +"Tentative" = "مؤقت"; + +"Free" = "متاح"; +"Busy" = "مشغول"; +"Maybe busy" = "ربما يكون مشغولًا"; +"No free-busy information" = "لا معلومات عن حالة التوفر-الانشغال"; + +/* FreeBusy panel buttons and labels */ +"Suggest time slot:" = "اقترح فترة زمنية: "; +"Zoom:" = "تقريب:"; +"Previous slot" = "الفترة السابقة"; +"Next slot" = "الفترة التالية"; +"Previous hour" = "الساعة الماضية"; +"Next hour" = "الساعة التالية"; +"Work days only" = "أيام العمل فقط"; +"The whole day" = "اليوم المكتمل"; +"Between" = "بين"; +"and" = "و"; + +"A time conflict exists with one or more attendees.\nWould you like to keep the current settings anyway?" += "هنالك تعارض في الوقت مع أحد الحضور. \nهل تريد الابقاء على الإعدادات الحالية رغم ذلك؟"; + +/* apt list */ +"Title" = "العنوان"; +"Start" = "البداية"; +"End" = "النهاية"; +"Due Date" = "تاريخ الاستحقاق"; +"Location" = "المكان"; + +"(Private Event)" = "(الحدث الخاص)"; + +vevent_class0 = "(الحدث العام)"; +vevent_class1 = "(حدث خاص)"; +vevent_class2 = "(حدث سري)"; + +"Priority" = "الأولوية"; +"Category" = "التصنيفات"; + +vtodo_class0 = "(مهمة عامة)"; +vtodo_class1 = "(مهمة خاصة)"; +vtodo_class2 = "(مهمة سرية)"; + +"closeThisWindowMessage" = "شكرًا لك! يمكنك إغلاق هذه النافذة أو عرض الخاص بك"; +"Multicolumn Day View" = "عرض اليوم متعدد الأعمدة"; + +"Please select an event or a task." = "من فضلك اختر حدثًا أو مهمة."; + +"editRepeatingItem" = "العنصر الذي تُحرره هو عنصر متكرر. هل تريد تحرير جميع التكرارات أم هذا الحدث الواحد فقط؟"; +"button_thisOccurrenceOnly" = "هذا الحدث فقط"; +"button_allOccurrences" = "كل التكرارات"; + +/* Properties dialog */ +"Name:" = "الاسم:"; +"Color:" = "اللون:"; + +"Include in free-busy" = "ضمن حالة التوفر-الانشغال"; + +"Synchronization" = "المزامنة"; +"Synchronize" = "زامن"; +"Tag:" = "علامة:"; + +"Display" = "عرض"; +"Show alarms" = "إظهار الانذارات"; +"Show tasks" = "عرض المهام"; + +"Notifications" = "الإشعارات"; +"Receive a mail when I modify my calendar" = "تلقي البريد عندما أقوم بتعديل التقويم الخاص بي"; +"Receive a mail when someone else modifies my calendar" = "تلقي البريد عندما يقوم شخص آخر بتعديل التقويم الخاص بي"; +"When I modify my calendar, send a mail to:" = "عندما أقوم بتعديل التقويم الخاص بي، أرسل رسالة بريد إلكتروني إلى:"; + +"Links to this Calendar" = "روابط لهذا التقويم"; +"Authenticated User Access" = "مصادقة وصول المستخدم"; +"CalDAV URL" = "CalDAV URL"; +"WebDAV ICS URL" = "WebDAV ICS URL"; +"WebDAV XML URL" = "WebDAV XML URL"; + +/* Error messages */ +"dayFieldInvalid" = "يرجى تحديد قيمة رقمية في حقل الأيام أكبر من أو يساوي 1."; +"weekFieldInvalid" = "يرجى تحديد قيمة رقمية في حقل الأسبوع (الأسابيع) أكبر من أو يساوي 1."; +"monthFieldInvalid" = "يرجى تحديد قيمة رقمية في حقل الشهر (الشهور) أكبر من أو يساوي 1."; +"monthDayFieldInvalid" = "يرجى تحديد قيمة رقمية في حقل أيام الشهر أكبر من أو يساوي 1."; +"yearFieldInvalid" = "يرجى تحديد قيمة رقمية في حقل السنة (السنوات) أكبر من أو يساوي 1."; +"appointmentFieldInvalid" = "يرجى تحديد قيمة رقمية في مجال موعد (مواعيد) أكبر من أو يساوي 1."; +"recurrenceUnsupported" = "هذا النوع من التكرار غير معتمد."; +"Please specify a calendar name." = "الرجاء تحديد اسم التقويم."; +"tagNotDefined" = "يجب تحديد علامة إذا كنت تريد أن تزامن هذا التقويم."; +"tagAlreadyExists" = "العلامة التى حددتها يرتبط بالفعل بتقويم آخر."; +"tagHasChanged" = "إذا غيرت وسم تقويمك، ستحتاج إلى تحديث البيانات على هاتفك المحمول.\nهل تريد المتابعة؟"; +"tagWasAdded" = "إذا أردت مزامنة هذا التقويم، ستحتاج إلى تحديث البيانات على جهازك المحمول. \nهل تريد المتابعة؟"; +"tagWasRemoved" = "إذا حذفت التقويم من المزامنة، ستحتاج إلى تحديث البيانات على هاتفك المحمول.\nهل تريد المتابعة؟"; +"DestinationCalendarError" = "التقويم المصدر والتقويم الهدف متطابقان. من فضلك حاول النسخ إلى تقويم مختلف."; +"EventCopyError" = "فشل النسخ. من فضلك حاول النسخ من تقويم مختلف."; + +"Open Task..." = "افتح مهمة..."; +"Mark Completed" = "علم كمكتمل"; +"Delete Task" = "احذف المهمة"; +"Delete Event" = "احذف الحدث"; +"Copy event to my calendar" = "انسخ إلى تقويمي"; +"View Raw Source" = "عرض المصدر الخام"; + +"Subscribe to a web calendar..." = "اشترك في تقويم شابكة..."; +"URL of the Calendar" = "عنوان موقع التقويم"; +"Web Calendar" = "تقويم الشابكة"; +"Reload on login" = "حدث عند تسجيل الدخول"; +"Invalid number." = "عدد غير صحيح."; +"Please identify yourself to %{0}" = "من فضلك عرف نفسك لـ %{0}"; diff --git a/UI/Scheduler/BrazilianPortuguese.lproj/Localizable.strings b/UI/Scheduler/BrazilianPortuguese.lproj/Localizable.strings index 70e8115cd..4570f0b29 100644 --- a/UI/Scheduler/BrazilianPortuguese.lproj/Localizable.strings +++ b/UI/Scheduler/BrazilianPortuguese.lproj/Localizable.strings @@ -533,3 +533,4 @@ vtodo_class2 = "(Tarefa Confidencial)"; "Web Calendar" = "Calendário Web"; "Reload on login" = "Recarregar no login"; "Invalid number." = "Número inválido."; +"Please identify yourself to %{0}" = "Por favor, identifique-se para %{0}"; diff --git a/UI/Scheduler/Czech.lproj/Localizable.strings b/UI/Scheduler/Czech.lproj/Localizable.strings index d931c361b..4a0d83b91 100644 --- a/UI/Scheduler/Czech.lproj/Localizable.strings +++ b/UI/Scheduler/Czech.lproj/Localizable.strings @@ -533,3 +533,4 @@ vtodo_class2 = "(Důvěrný úkol)"; "Web Calendar" = "Vzdálený kalendář na webu"; "Reload on login" = "Aktualizovat při přihlášení"; "Invalid number." = "Invalid number."; +"Please identify yourself to %{0}" = "Identifikujte se na %{0}"; diff --git a/UI/Scheduler/Danish.lproj/Localizable.strings b/UI/Scheduler/Danish.lproj/Localizable.strings index db08c2085..6a70c7038 100644 --- a/UI/Scheduler/Danish.lproj/Localizable.strings +++ b/UI/Scheduler/Danish.lproj/Localizable.strings @@ -60,6 +60,7 @@ "Import Events" = "Importér begivenheder"; "Select an iCalendar file (.ics)." = "Vælg en iCalendar-fil (.ics)."; "Upload" = "Indlæs"; +"Uploading" = "Uploader"; "Publish Calendar..." = "Publicér kalender ..."; "Reload Remote Calendars" = "Opdatér kalendere"; "Properties" = "Egenskaber"; @@ -81,7 +82,8 @@ /* acls */ -"User rights for:" = "Brugerrettigheder:"; +"Access rights to" = "Adgangsrettigheder til"; +"For user" = "For bruger"; "Any Authenticated User" = "Enhver godkendt bruger"; "Public Access" = "Offentlig adgang"; @@ -109,7 +111,6 @@ /* Button Titles */ -"New Calendar..." = "Ny kalender ..."; "Subscribe to a Calendar..." = "Abonnér på en kalender ..."; "Remove the selected Calendar" = "Fjern den valgte kalender"; @@ -290,7 +291,7 @@ "cycle_end_until" = "cycle_end_until"; "Recurrence pattern" = "Gentagelsesmønster"; -"Range of recurrence" = "gentagelsesinterval"; +"Range of recurrence" = "Gentagelsesinterval"; "Repeat" = "Gentag"; "Daily" = "Dagligt"; @@ -379,6 +380,7 @@ validate_invalid_startdate = "Forkert startdato!"; validate_invalid_enddate = "Forkert slutdato!"; validate_endbeforestart = "Indtastet slutdato ligger før startdato."; +"Events" = "Opgaver"; "Tasks" = "Opgaver"; "Show completed tasks" = "Vis udførte opgaver"; @@ -409,12 +411,8 @@ validate_endbeforestart = "Indtastet slutdato ligger før startdato."; "Workweek days only" = "Arbejdsuge dage kun"; "Tasks in View" = "Opgaver i visning"; -"eventDeleteConfirmation" = "Følgende begivenhed er/bliver slettet: -%{0} -Fortsæt?"; -"taskDeleteConfirmation" = "Følgende opgave(r) bliver slettet: -%{0} -Fortsæt?"; +"eventDeleteConfirmation" = "Følgende begivenhed er/bliver slettet: \n%{0}\nFortsæt?"; +"taskDeleteConfirmation" = "Følgende opgave(r) bliver slettet: \n%{0}\nFortsæt?"; "You cannot remove nor unsubscribe from your personal calendar." = "Du kan ikke fjerne eller afmelde din personlige kalender."; @@ -450,8 +448,7 @@ Fortsæt?"; "and" = "og"; "A time conflict exists with one or more attendees.\nWould you like to keep the current settings anyway?" -= "En tidskonflikt med en eller flere deltagere. -Behold de aktuelle indstillinger alligevel?"; += "En tidskonflikt med en eller flere deltagere. \nBehold de aktuelle indstillinger alligevel?"; /* apt list */ "Title" = "Titel"; @@ -459,12 +456,16 @@ Behold de aktuelle indstillinger alligevel?"; "End" = "Slut"; "Due Date" = "Forfaldsdato"; "Location" = "Sted"; + "(Private Event)" = "(Privat begivenhed)"; vevent_class0 = "(Offentlig begivenhed)"; vevent_class1 = "(Privat begivenhed)"; vevent_class2 = "(Hemmelig begivenhed)"; +"Priority" = "Prioritet"; +"Category" = "Kategori"; + vtodo_class0 = "(Offentlig opgave)"; vtodo_class1 = "(Privat opgave)"; vtodo_class2 = "(Hemmelig opgave)"; @@ -492,6 +493,11 @@ vtodo_class2 = "(Hemmelig opgave)"; "Show alarms" = "Vis alarmer"; "Show tasks" = "Vis opgaver"; +"Notifications" = "Notifikationer"; +"Receive a mail when I modify my calendar" = "Modtag en mail, når jeg ændrer min kalender"; +"Receive a mail when someone else modifies my calendar" = "Modtag en mail, når andre ændrer min kalender"; +"When I modify my calendar, send a mail to:" = "Når jeg ændrer min kalender, så send en mail til:"; + "Links to this Calendar" = "Links til denne kalender"; "Authenticated User Access" = "Godkendt brugeradgang"; "CalDAV URL" = "CalDAV URL"; @@ -509,12 +515,9 @@ vtodo_class2 = "(Hemmelig opgave)"; "Please specify a calendar name." = "Angiv venligst et kalender navn."; "tagNotDefined" = "Du skal angive et mærkat, hvis du ønsker at synkronisere denne kalender."; "tagAlreadyExists" = "Mærkatet du har angivet er allerede knyttet til en anden kalender."; -"tagHasChanged" = "Hvis du ændrer din kalenders mærkat, skal du genindlæse data på din mobile enhed. -Fortsæt?"; -"tagWasAdded" = "Hvis du ønsker at synkronisere denne kalender, skal du genindlæse data på din mobile enhed. -Fortsæt?"; -"tagWasRemoved" = "Hvis du fjerner denne kalender fra synkronisering, skal du genindlæse data på din mobile enhed. -Fortsæt?"; +"tagHasChanged" = "Hvis du ændrer din kalenders mærkat, skal du genindlæse data på din mobile enhed.\nFortsæt?"; +"tagWasAdded" = "Hvis du ønsker at synkronisere denne kalender, skal du genindlæse data på din mobile enhed.\nFortsæt?"; +"tagWasRemoved" = "Hvis du fjerner denne kalender fra synkronisering, skal du genindlæse data på din mobile enhed.\nFortsæt?"; "DestinationCalendarError" = "Kilde og destination kalendere er de samme. Prøv at kopiere til en anden kalender."; "EventCopyError" = "Kopieringen mislykkedes. Prøv at kopiér til en anden kalender."; @@ -523,12 +526,11 @@ Fortsæt?"; "Delete Task" = "Slet opgave"; "Delete Event" = "Slet begivenhed"; "Copy event to my calendar" = "Kopiér begivenhed til min kalender"; +"View Raw Source" = "Vis kilde"; "Subscribe to a web calendar..." = "Abonnér på en online kalender ..."; "URL of the Calendar" = "Kalenderens URL"; "Web Calendar" = "Online kalender"; "Reload on login" = "Genindlæs ved login"; "Invalid number." = "Ugyldigt nummer."; - -"Category" = "Kategori"; -"Priority" = "Prioritet"; +"Please identify yourself to %{0}" = "Identificer dig selv til %{0}"; diff --git a/UI/Scheduler/Dutch.lproj/Localizable.strings b/UI/Scheduler/Dutch.lproj/Localizable.strings index 04d2f20fe..bfdaff361 100644 --- a/UI/Scheduler/Dutch.lproj/Localizable.strings +++ b/UI/Scheduler/Dutch.lproj/Localizable.strings @@ -533,3 +533,4 @@ vtodo_class2 = "(Vertrouwelijke taak)"; "Web Calendar" = "Web Agenda"; "Reload on login" = "Herladen bij inloggen"; "Invalid number." = "Ongeldig nummer."; +"Please identify yourself to %{0}" = "Identificeer u alstublieft tegenover %{0}"; diff --git a/UI/Scheduler/English.lproj/Localizable.strings b/UI/Scheduler/English.lproj/Localizable.strings index 6fe90daf0..7f6188e55 100644 --- a/UI/Scheduler/English.lproj/Localizable.strings +++ b/UI/Scheduler/English.lproj/Localizable.strings @@ -533,3 +533,4 @@ vtodo_class2 = "(Confidential task)"; "Web Calendar" = "Web Calendar"; "Reload on login" = "Reload on login"; "Invalid number." = "Invalid number."; +"Please identify yourself to %{0}" = "Please identify yourself to %{0}"; diff --git a/UI/Scheduler/Finnish.lproj/Localizable.strings b/UI/Scheduler/Finnish.lproj/Localizable.strings index c71440258..41c47154f 100644 --- a/UI/Scheduler/Finnish.lproj/Localizable.strings +++ b/UI/Scheduler/Finnish.lproj/Localizable.strings @@ -533,3 +533,4 @@ vtodo_class2 = "(Luottamuksellinen tehtävä)"; "Web Calendar" = "Web kalenteri"; "Reload on login" = "Päivitä kirjauduttaessa"; "Invalid number." = "Virheellinen numero."; +"Please identify yourself to %{0}" = "Ole hyvä ja tunnistaudu kohteeseen %{0}"; diff --git a/UI/Scheduler/French.lproj/Localizable.strings b/UI/Scheduler/French.lproj/Localizable.strings index f6fcbe825..6414e1f80 100644 --- a/UI/Scheduler/French.lproj/Localizable.strings +++ b/UI/Scheduler/French.lproj/Localizable.strings @@ -533,3 +533,4 @@ vtodo_class2 = "(Tâche confidentielle)"; "Web Calendar" = "Calendrier web"; "Reload on login" = "Rafraîchir à la connexion"; "Invalid number." = "Nombre invalide."; +"Please identify yourself to %{0}" = "Veuillez vous authentifier à %{0}"; diff --git a/UI/Scheduler/GNUmakefile b/UI/Scheduler/GNUmakefile index 6d58c48bd..2ade17522 100644 --- a/UI/Scheduler/GNUmakefile +++ b/UI/Scheduler/GNUmakefile @@ -6,7 +6,7 @@ BUNDLE_NAME = SchedulerUI SchedulerUI_PRINCIPAL_CLASS = SchedulerUIProduct -SchedulerUI_LANGUAGES = BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh +SchedulerUI_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh SchedulerUI_OBJC_FILES = \ SchedulerUIProduct.m \ diff --git a/UI/Scheduler/German.lproj/Localizable.strings b/UI/Scheduler/German.lproj/Localizable.strings index 5398716d2..4db805264 100644 --- a/UI/Scheduler/German.lproj/Localizable.strings +++ b/UI/Scheduler/German.lproj/Localizable.strings @@ -533,3 +533,4 @@ vtodo_class2 = "(Vertrauliche Aufgabe)"; "Web Calendar" = "Webkalender"; "Reload on login" = "Neu laden beim Anmelden"; "Invalid number." = "Ungültige Nummer."; +"Please identify yourself to %{0}" = "Bitte identifizieren Sie sich gegenüber %{0}"; diff --git a/UI/Scheduler/Hungarian.lproj/Localizable.strings b/UI/Scheduler/Hungarian.lproj/Localizable.strings index 0aaf22a76..ac80ad6b5 100644 --- a/UI/Scheduler/Hungarian.lproj/Localizable.strings +++ b/UI/Scheduler/Hungarian.lproj/Localizable.strings @@ -533,3 +533,4 @@ vtodo_class2 = "(Bizalmas feladat)"; "Web Calendar" = "Internetes naptár"; "Reload on login" = "Frissítés bejelentkezéskor"; "Invalid number." = "Érvénytelen szám"; +"Please identify yourself to %{0}" = "A %{0} kérésére adja meg azonosító adatait"; diff --git a/UI/Scheduler/Polish.lproj/Localizable.strings b/UI/Scheduler/Polish.lproj/Localizable.strings index e1af7dc11..3ebae4b95 100644 --- a/UI/Scheduler/Polish.lproj/Localizable.strings +++ b/UI/Scheduler/Polish.lproj/Localizable.strings @@ -533,3 +533,4 @@ vtodo_class2 = "(Zadanie poufne)"; "Web Calendar" = "Kalendarz sieciowy"; "Reload on login" = "Przeładuj przy logowaniu"; "Invalid number." = "Błędna liczba."; +"Please identify yourself to %{0}" = "Zaloguj się w %{0}"; diff --git a/UI/Scheduler/Russian.lproj/Localizable.strings b/UI/Scheduler/Russian.lproj/Localizable.strings index fb59cd83f..a3375a778 100644 --- a/UI/Scheduler/Russian.lproj/Localizable.strings +++ b/UI/Scheduler/Russian.lproj/Localizable.strings @@ -380,6 +380,7 @@ validate_invalid_startdate = "Неверное дата начала!"; validate_invalid_enddate = "Неверная дата конца!"; validate_endbeforestart = "Дата начала позже даты конца"; +"Events" = "События"; "Tasks" = "Задачи"; "Show completed tasks" = "Показать выполненные задачи"; @@ -455,12 +456,16 @@ validate_endbeforestart = "Дата начала позже даты конц "End" = "Конец"; "Due Date" = "К дате"; "Location" = "Место"; + "(Private Event)" = "(Приватное событие)"; vevent_class0 = "(Публичное событие)"; vevent_class1 = "(Приватное событие)"; vevent_class2 = "(Конфиденциальное событие)"; +"Priority" = "Важность"; +"Category" = "Категория"; + vtodo_class0 = "(Публичное задание)"; vtodo_class1 = "(Приватное задание)"; vtodo_class2 = "(Конфиденциальное задание)"; @@ -488,6 +493,7 @@ vtodo_class2 = "(Конфиденциальное задание)"; "Show alarms" = "Показать сигналы"; "Show tasks" = "Показать задания"; +"Notifications" = "Напоминания"; "Receive a mail when I modify my calendar" = "Получать письмо в случае если я изменю свой календарь"; "Receive a mail when someone else modifies my calendar" = "Получать письмо если кто-то изменит мой календарь"; "When I modify my calendar, send a mail to:" = "Если я изменю свой календарь, отправить письмо на адрес: "; @@ -527,6 +533,4 @@ vtodo_class2 = "(Конфиденциальное задание)"; "Web Calendar" = "Web Calendar"; "Reload on login" = "Перезагружать при входе"; "Invalid number." = "Число неверно."; - -"Category" = "Категория"; -"Priority" = "Приоритет"; +"Please identify yourself to %{0}" = "Пожалуйста, представьте себя %{0}"; diff --git a/UI/Scheduler/Slovak.lproj/Localizable.strings b/UI/Scheduler/Slovak.lproj/Localizable.strings index a4d3501ec..e69e9b461 100644 --- a/UI/Scheduler/Slovak.lproj/Localizable.strings +++ b/UI/Scheduler/Slovak.lproj/Localizable.strings @@ -533,3 +533,4 @@ vtodo_class2 = "(Dôverná úloha)"; "Web Calendar" = "Vzdialený kalendár na webe"; "Reload on login" = "Aktualizovať pri prihlásení"; "Invalid number." = "Neplatné číslo."; +"Please identify yourself to %{0}" = "Identifikujte sa na %{0}"; diff --git a/UI/Scheduler/SpanishArgentina.lproj/Localizable.strings b/UI/Scheduler/SpanishArgentina.lproj/Localizable.strings index 776c71ae6..8cd2657c9 100644 --- a/UI/Scheduler/SpanishArgentina.lproj/Localizable.strings +++ b/UI/Scheduler/SpanishArgentina.lproj/Localizable.strings @@ -533,3 +533,4 @@ vtodo_class2 = "(Tarea confidencial)"; "Web Calendar" = "Calendario Web"; "Reload on login" = "Recargar al reconectar"; "Invalid number." = "Número invalido."; +"Please identify yourself to %{0}" = "Por favor autentíquese en %{0}"; diff --git a/UI/Scheduler/SpanishSpain.lproj/Localizable.strings b/UI/Scheduler/SpanishSpain.lproj/Localizable.strings index aa16c2d5f..a04ec37ee 100644 --- a/UI/Scheduler/SpanishSpain.lproj/Localizable.strings +++ b/UI/Scheduler/SpanishSpain.lproj/Localizable.strings @@ -533,3 +533,4 @@ vtodo_class2 = "(Tarea confidencial)"; "Web Calendar" = "Calendario Web"; "Reload on login" = "Recargar al reconectar"; "Invalid number." = "número invalido."; +"Please identify yourself to %{0}" = "Por favor, identificase con %{0}"; diff --git a/UI/Templates/MailerUI/UIxMailMainFrame.wox b/UI/Templates/MailerUI/UIxMailMainFrame.wox index c0438bb64..858156769 100644 --- a/UI/Templates/MailerUI/UIxMailMainFrame.wox +++ b/UI/Templates/MailerUI/UIxMailMainFrame.wox @@ -54,7 +54,7 @@
  • -
  • +
  • @@ -70,7 +70,7 @@
  • -
  • +
  • @@ -87,7 +87,7 @@
  • -
  • +
  • diff --git a/UI/Templates/SOGoACLArabicAdditionAdvisory.wox b/UI/Templates/SOGoACLArabicAdditionAdvisory.wox new file mode 100644 index 000000000..ba141ab71 --- /dev/null +++ b/UI/Templates/SOGoACLArabicAdditionAdvisory.wox @@ -0,0 +1,28 @@ + + + + + + أضافك + + + + أضافك إلى قائمة الوصول لمجلد . + + + + diff --git a/UI/Templates/SOGoACLArabicModificationAdvisory.wox b/UI/Templates/SOGoACLArabicModificationAdvisory.wox new file mode 100644 index 000000000..0ad39888e --- /dev/null +++ b/UI/Templates/SOGoACLArabicModificationAdvisory.wox @@ -0,0 +1,28 @@ + + + + + + عدل تصاريح الوصول + + + + قام بتعديل تصاريح الوصول لمجلد folder. + + + + diff --git a/UI/Templates/SOGoACLArabicRemovalAdvisory.wox b/UI/Templates/SOGoACLArabicRemovalAdvisory.wox new file mode 100644 index 000000000..1439d5c47 --- /dev/null +++ b/UI/Templates/SOGoACLArabicRemovalAdvisory.wox @@ -0,0 +1,28 @@ + + + + + + ازالك + + + + ازالك من قائمة الوصول لمجلد . + + + + diff --git a/UI/Templates/SOGoFolderArabicAdditionAdvisory.wox b/UI/Templates/SOGoFolderArabicAdditionAdvisory.wox new file mode 100644 index 000000000..24ef681a8 --- /dev/null +++ b/UI/Templates/SOGoFolderArabicAdditionAdvisory.wox @@ -0,0 +1,23 @@ + + + + + + اُُنشِئ بنجاح + + + +The اُُنشِئ المجلد بنجاح. + + + + diff --git a/UI/Templates/SOGoFolderArabicRemovalAdvisory.wox b/UI/Templates/SOGoFolderArabicRemovalAdvisory.wox new file mode 100644 index 000000000..af580ede3 --- /dev/null +++ b/UI/Templates/SOGoFolderArabicRemovalAdvisory.wox @@ -0,0 +1,23 @@ + + + + + + حذف بنجاح + + + +The حذف المجلد بنجاح. + + + + diff --git a/UI/WebServerResources/MailerUI.js b/UI/WebServerResources/MailerUI.js index 3b0b381d0..99f646504 100644 --- a/UI/WebServerResources/MailerUI.js +++ b/UI/WebServerResources/MailerUI.js @@ -912,7 +912,7 @@ function refreshUnseenCounts() { } function getUnseenCountForFolder(mailbox) { - var url = ApplicationBaseURL + encodeURI(mailbox) + '/unseenCount'; + var url = URLForFolderID(mailbox) + '/unseenCount'; triggerAjaxRequest(url, unseenCountCallback, mailbox); } @@ -2353,17 +2353,37 @@ function onMenuRenameFolderConfirm() { } function onMenuDeleteFolder(event) { - showConfirmDialog(_("Confirmation"), - _("Do you really want to move this folder into the trash ?"), - onMenuDeleteFolderConfirm); -} - -function onMenuDeleteFolderConfirm() { var folderID = document.menuTarget.getAttribute("dataname"); var urlstr = URLForFolderID(folderID) + "/delete"; var errorLabel = _("The folder could not be deleted."); - triggerAjaxRequest(urlstr, folderOperationCallback, errorLabel); - disposeDialog(); + showConfirmDialog(_("Confirmation"), + _("Do you really want to move this folder into the trash ?"), + function(event) { + triggerAjaxRequest(urlstr, folderOperationCallback, errorLabel); + disposeDialog(); + }); +} + +function onMenuMarkFolderRead(event) { + var folderID = document.menuTarget.getAttribute("dataname"); + var urlstr = URLForFolderID(folderID) + "/markRead"; + + // Delete the associated data sources + deleteCachedMailbox(folderID); + + if (folderID == Mailer.currentMailbox) { + // Reset the data source so the message headers are reloaded in the callback function + Mailer.dataTable.dataSource.destroy(); + } + else { + // Reset the unseen count of the mailbox + var node = mailboxTree.getMailboxNode(folderID); + if (node) { + updateUnseenCount(node, 0, false); + } + } + + triggerAjaxRequest(urlstr, folderRefreshCallback, { "mailbox": folderID, "refresh": true }); } function onMenuExpungeFolder(event) { @@ -2767,22 +2787,19 @@ function onMenuAccountDelegation(event) { function getMenus() { var menus = { accountIconMenu: [ null, null, onMenuCreateFolder, null, null, onMenuAccountDelegation ], - inboxIconMenu: [ null, null, null, "-", null, + inboxIconMenu: [ null, null, null, "-", onMenuMarkFolderRead, onMenuCreateFolder, onMenuExpungeFolder, onMenuArchiveFolder, "-", null, onMenuSharing ], - trashIconMenu: [ null, null, null, "-", null, + trashIconMenu: [ null, null, null, "-", onMenuMarkFolderRead, onMenuCreateFolder, onMenuExpungeFolder, onMenuArchiveFolder, onMenuEmptyTrash, "-", null, onMenuSharing ], - mailboxIconMenu: [ null, null, null, "-", null, - onMenuCreateFolder, - onMenuRenameFolder, - onMenuExpungeFolder, - onMenuArchiveFolder, - onMenuDeleteFolder, - "folderTypeMenu", + mailboxIconMenu: [ null, null, null, "-", onMenuMarkFolderRead, + onMenuCreateFolder, onMenuRenameFolder, + onMenuExpungeFolder, onMenuArchiveFolder, + onMenuDeleteFolder, "folderTypeMenu", "-", null, onMenuSharing ], addressMenu: [ newContactFromEmail, newEmailTo ], diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js index 97eb6da88..30bb7355f 100644 --- a/UI/WebServerResources/SchedulerUI.js +++ b/UI/WebServerResources/SchedulerUI.js @@ -1441,7 +1441,7 @@ function reauthenticateWebCalendar(folderID, refreshCBData) { triggerAjaxRequest(url, authenticateWebCalendarCallback, refreshCBData, parameters, { "Content-type": "application/x-www-form-urlencoded" }); } - showAuthenticationDialog(_("Please identify yourself to \"%{0}\"...") + showAuthenticationDialog(_("Please identify yourself to %{0}") .formatted(hostname), authenticate); } diff --git a/Version b/Version index 0dc7bb82d..1217233bd 100644 --- a/Version +++ b/Version @@ -4,4 +4,4 @@ MAJOR_VERSION=2 MINOR_VERSION=0 -SUBMINOR_VERSION=4b +SUBMINOR_VERSION=5 diff --git a/packaging/debian-multiarch/rules b/packaging/debian-multiarch/rules index 120a7a3b7..688c6d399 100755 --- a/packaging/debian-multiarch/rules +++ b/packaging/debian-multiarch/rules @@ -41,8 +41,6 @@ clean: make clean; \ fi -rm -f OpenChange/MAPIStorePropertySelectors.* - -find OpenChange -type d -name "unrtf-*" -exec rm -rf {} \; - -rm -f OpenChange/unrtf*-stamp -rm -f config.make dh_clean @@ -73,14 +71,13 @@ install-arch: build-arch $(DESTDIR)/usr/lib/$(DEB_HOST_MULTIARCH)/mapistore_backends/SOGo.so; \ fi - mkdir -p debian/tmp/etc/default - cp Scripts/sogo-default debian/tmp/etc/default/sogo - mkdir -p debian/tmp/usr/share/lintian/overrides - cp debian/sogo.overrides debian/tmp/usr/share/lintian/overrides/sogo - mkdir -p debian/tmp/etc/apache2/conf.d - cp Apache/SOGo.conf debian/tmp/etc/apache2/conf.d/SOGo.conf + install -D Scripts/sogo-default debian/tmp/etc/default/sogo + install -D debian/sogo.overrides debian/tmp/usr/share/lintian/overrides/sogo + install -D Apache/SOGo.conf debian/tmp/etc/apache2/conf.d/SOGo.conf install -D -m 644 Scripts/sogo.cron debian/tmp/etc/cron.d/sogo install -D -m 644 Scripts/logrotate debian/tmp/etc/logrotate.d/sogo + install -d -m 750 debian/tmp/etc/sogo/ + install -D -m 640 Scripts/sogo.conf debian/tmp/etc/sogo/sogo.conf # Build architecture dependant packages using the common target. binary-arch: build-arch install-arch diff --git a/packaging/debian-multiarch/sogo.docs b/packaging/debian-multiarch/sogo.docs index ded20965f..781cb916d 100644 --- a/packaging/debian-multiarch/sogo.docs +++ b/packaging/debian-multiarch/sogo.docs @@ -3,3 +3,4 @@ TODO Scripts/*.sh Scripts/*.py Scripts/updates.php +Apache/SOGo-apple-ab.conf diff --git a/packaging/debian-multiarch/sogo.install b/packaging/debian-multiarch/sogo.install index 44d947d4f..5f22f31bc 100644 --- a/packaging/debian-multiarch/sogo.install +++ b/packaging/debian-multiarch/sogo.install @@ -1,7 +1,8 @@ -etc/default/sogo etc/apache2/conf.d/SOGo.conf etc/cron.d/sogo +etc/default/sogo etc/logrotate.d/sogo +etc/sogo/sogo.conf usr/sbin/* usr/lib/GNUstep/Frameworks/* usr/lib/GNUstep/Libraries/* diff --git a/packaging/debian-multiarch/sogo.postinst b/packaging/debian-multiarch/sogo.postinst index c4a7272fd..82cfa7d4e 100644 --- a/packaging/debian-multiarch/sogo.postinst +++ b/packaging/debian-multiarch/sogo.postinst @@ -20,6 +20,12 @@ case "$1" in configure) # update timestamp on imgs,css,js to let apache know the files changed find /usr/lib/GNUstep/SOGo/WebServerResources -exec touch {} \; + + # Enforce owner+mode on configuration + chmod 750 /etc/sogo + chown root:sogo /etc/sogo + chmod 640 /etc/sogo/sogo.conf + chown root:sogo /etc/sogo/sogo.conf ;; abort-upgrade|abort-remove|abort-deconfigure) diff --git a/packaging/debian-multiarch/sogo.preinst b/packaging/debian-multiarch/sogo.preinst index fc2d475bf..552628002 100644 --- a/packaging/debian-multiarch/sogo.preinst +++ b/packaging/debian-multiarch/sogo.preinst @@ -18,7 +18,7 @@ if [ "$1" == "install" ] || [ "$1" == "upgrade" ]; then useradd -d /var/lib/sogo -g sogo -c "SOGo daemon" -s /usr/sbin/nologin -M -r sogo fi - # create mandatory dirs and enforce owner/perms + # create mandatory dirs and enforce owner+mode for dir in lib log run spool; do install -m 750 -o sogo -g sogo -d /var/$dir/sogo done diff --git a/packaging/debian/rules b/packaging/debian/rules index 9e76c6c62..3fe7bd0c3 100755 --- a/packaging/debian/rules +++ b/packaging/debian/rules @@ -4,13 +4,19 @@ export DH_VERBOSE=1 # export DH_OPTIONS="-p sogo" DESTDIR=$(CURDIR)/debian/tmp +DIST_CODENAME=$(shell lsb_release -cs) + +# NOTYET +#ifeq ($(DIST_CODENAME), squeeze) +# SAML2_CONFIG=--enable-saml2 +#endif include /etc/GNUstep/GNUstep.conf include /usr/share/GNUstep/Makefiles/common.make config.make: configure dh_testdir - ./configure --prefix=$(GNUSTEP_SYSTEM_ROOT) + ./configure --prefix=$(GNUSTEP_SYSTEM_ROOT) $(SAML2_CONFIG) #Architecture build: build-arch @@ -40,8 +46,6 @@ clean: make clean; \ fi -rm -f OpenChange/MAPIStorePropertySelectors.* - -find OpenChange -type d -name "unrtf-*" -exec rm -rf {} \; - -rm -f OpenChange/unrtf*-stamp -rm -f config.make dh_clean @@ -72,14 +76,13 @@ install-arch: build-arch $(DESTDIR)/usr/lib/mapistore_backends/SOGo.so; \ fi - mkdir -p debian/tmp/etc/default - cp Scripts/sogo-default debian/tmp/etc/default/sogo - mkdir -p debian/tmp/usr/share/lintian/overrides - cp debian/sogo.overrides debian/tmp/usr/share/lintian/overrides/sogo - mkdir -p debian/tmp/etc/apache2/conf.d - cp Apache/SOGo.conf debian/tmp/etc/apache2/conf.d/SOGo.conf + install -D Scripts/sogo-default debian/tmp/etc/default/sogo + install -D debian/sogo.overrides debian/tmp/usr/share/lintian/overrides/sogo + install -D Apache/SOGo.conf debian/tmp/etc/apache2/conf.d/SOGo.conf install -D -m 644 Scripts/sogo.cron debian/tmp/etc/cron.d/sogo install -D -m 644 Scripts/logrotate debian/tmp/etc/logrotate.d/sogo + install -d -m 750 debian/tmp/etc/sogo + install -D -m 640 Scripts/sogo.conf debian/tmp/etc/sogo/sogo.conf # Build architecture dependant packages using the common target. binary-arch: build-arch install-arch diff --git a/packaging/debian/sogo.docs b/packaging/debian/sogo.docs index ded20965f..781cb916d 100644 --- a/packaging/debian/sogo.docs +++ b/packaging/debian/sogo.docs @@ -3,3 +3,4 @@ TODO Scripts/*.sh Scripts/*.py Scripts/updates.php +Apache/SOGo-apple-ab.conf diff --git a/packaging/debian/sogo.install b/packaging/debian/sogo.install index 44d947d4f..5f22f31bc 100644 --- a/packaging/debian/sogo.install +++ b/packaging/debian/sogo.install @@ -1,7 +1,8 @@ -etc/default/sogo etc/apache2/conf.d/SOGo.conf etc/cron.d/sogo +etc/default/sogo etc/logrotate.d/sogo +etc/sogo/sogo.conf usr/sbin/* usr/lib/GNUstep/Frameworks/* usr/lib/GNUstep/Libraries/* diff --git a/packaging/debian/sogo.postinst b/packaging/debian/sogo.postinst index c4a7272fd..82cfa7d4e 100644 --- a/packaging/debian/sogo.postinst +++ b/packaging/debian/sogo.postinst @@ -20,6 +20,12 @@ case "$1" in configure) # update timestamp on imgs,css,js to let apache know the files changed find /usr/lib/GNUstep/SOGo/WebServerResources -exec touch {} \; + + # Enforce owner+mode on configuration + chmod 750 /etc/sogo + chown root:sogo /etc/sogo + chmod 640 /etc/sogo/sogo.conf + chown root:sogo /etc/sogo/sogo.conf ;; abort-upgrade|abort-remove|abort-deconfigure) diff --git a/packaging/debian/sogo.preinst b/packaging/debian/sogo.preinst index fc2d475bf..552628002 100644 --- a/packaging/debian/sogo.preinst +++ b/packaging/debian/sogo.preinst @@ -18,7 +18,7 @@ if [ "$1" == "install" ] || [ "$1" == "upgrade" ]; then useradd -d /var/lib/sogo -g sogo -c "SOGo daemon" -s /usr/sbin/nologin -M -r sogo fi - # create mandatory dirs and enforce owner/perms + # create mandatory dirs and enforce owner+mode for dir in lib log run spool; do install -m 750 -o sogo -g sogo -d /var/$dir/sogo done diff --git a/packaging/rhel/sogo.spec b/packaging/rhel/sogo.spec index f283fd153..8cb0000f0 100644 --- a/packaging/rhel/sogo.spec +++ b/packaging/rhel/sogo.spec @@ -5,12 +5,14 @@ %{!?python_sys_pyver: %global python_sys_pyver %(/usr/bin/python -c "import sys; print sys.hexversion")} +%define sogo_user sogo + Summary: SOGo Name: sogo Version: %{sogo_version} Release: %{dist_suffix}%{?dist} Vendor: http://www.inverse.ca/ -Packager: Wolfgang Sourdeau +Packager: Wolfgang Sourdeau License: GPL URL: http://www.inverse.ca/contributions/sogo.html Group: Productivity/Groupware @@ -188,17 +190,19 @@ make DESTDIR=${RPM_BUILD_ROOT} \ GNUSTEP_INSTALLATION_DOMAIN=SYSTEM \ CC="$cc" LDFLAGS="$ldflags" \ install -mkdir -p ${RPM_BUILD_ROOT}/etc/init.d -mkdir -p ${RPM_BUILD_ROOT}/etc/cron.d -mkdir -p ${RPM_BUILD_ROOT}/etc/cron.daily -mkdir -p ${RPM_BUILD_ROOT}/etc/logrotate.d -mkdir -p ${RPM_BUILD_ROOT}/etc/sysconfig -mkdir -p ${RPM_BUILD_ROOT}/etc/httpd/conf.d -mkdir -p ${RPM_BUILD_ROOT}/usr/sbin -mkdir -p ${RPM_BUILD_ROOT}/var/lib/sogo -mkdir -p ${RPM_BUILD_ROOT}/var/log/sogo -mkdir -p ${RPM_BUILD_ROOT}/var/run/sogo -mkdir -p ${RPM_BUILD_ROOT}/var/spool/sogo +install -d ${RPM_BUILD_ROOT}/etc/init.d +install -d ${RPM_BUILD_ROOT}/etc/cron.d +install -d ${RPM_BUILD_ROOT}/etc/cron.daily +install -d ${RPM_BUILD_ROOT}/etc/logrotate.d +install -d ${RPM_BUILD_ROOT}/etc/sysconfig +install -d ${RPM_BUILD_ROOT}/etc/httpd/conf.d +install -d ${RPM_BUILD_ROOT}/usr/sbin +install -d ${RPM_BUILD_ROOT}/var/lib/sogo +install -d ${RPM_BUILD_ROOT}/var/log/sogo +install -d ${RPM_BUILD_ROOT}/var/run/sogo +install -d ${RPM_BUILD_ROOT}/var/spool/sogo +install -d -m 750 -o %sogo_user -g %sogo_user ${RPM_BUILD_ROOT}/etc/sogo +install -m 640 -o %sogo_user -g %sogo_user Scripts/sogo.conf ${RPM_BUILD_ROOT}/etc/sogo/ cat Apache/SOGo.conf | sed -e "s@/lib/@/%{_lib}/@g" > ${RPM_BUILD_ROOT}/etc/httpd/conf.d/SOGo.conf install -m 600 Scripts/sogo.cron ${RPM_BUILD_ROOT}/etc/cron.d/sogo cp Scripts/tmpwatch ${RPM_BUILD_ROOT}/etc/cron.daily/sogo-tmpwatch @@ -229,10 +233,11 @@ rm -fr ${RPM_BUILD_ROOT} /etc/init.d/sogod /etc/cron.daily/sogo-tmpwatch -%dir %attr(0700, sogo, sogo) %{_var}/lib/sogo -%dir %attr(0700, sogo, sogo) %{_var}/log/sogo -%dir %attr(0755, sogo, sogo) %{_var}/run/sogo -%dir %attr(0700, sogo, sogo) %{_var}/spool/sogo +%dir %attr(0700, %sogo_user, %sogo_user) %{_var}/lib/sogo +%dir %attr(0700, %sogo_user, %sogo_user) %{_var}/log/sogo +%dir %attr(0755, %sogo_user, %sogo_user) %{_var}/run/sogo +%dir %attr(0700, %sogo_user, %sogo_user) %{_var}/spool/sogo +%dir %attr(0750, root, %sogo_user) %{_sysconfdir}/sogo %{_sbindir}/sogod %{_libdir}/libSOGo.so.* %{_libdir}/libSOGoUI.so.* @@ -248,11 +253,12 @@ rm -fr ${RPM_BUILD_ROOT} %{_libdir}/GNUstep/OCSTypeModels %{_libdir}/GNUstep/WOxElemBuilders-* +%config(noreplace) %attr(0640, root, %sogo_user) %{_sysconfdir}/sogo/sogo.conf %config(noreplace) %{_sysconfdir}/logrotate.d/sogo %config(noreplace) %{_sysconfdir}/cron.d/sogo %config(noreplace) %{_sysconfdir}/httpd/conf.d/SOGo.conf %config(noreplace) %{_sysconfdir}/sysconfig/sogo -%doc ChangeLog NEWS Scripts/*sh Scripts/*py Scripts/updates.php +%doc ChangeLog NEWS Scripts/*sh Scripts/*py Scripts/updates.php Apache/SOGo-apple-ab.conf %files -n sogo-tool %{_sbindir}/sogo-tool @@ -302,8 +308,8 @@ rm -fr ${RPM_BUILD_ROOT} # **************************** pkgscripts ***************************** %pre -if ! id sogo >& /dev/null; then - /usr/sbin/useradd -d %{_var}/lib/sogo -c "SOGo daemon" -s /sbin/nologin -M -r sogo +if ! id %sogo_user >& /dev/null; then + /usr/sbin/useradd -d %{_var}/lib/sogo -c "SOGo daemon" -s /sbin/nologin -M -r %sogo_user fi %post @@ -322,8 +328,8 @@ fi %postun if test "$1" = "0" then - /usr/sbin/userdel sogo - /usr/sbin/groupdel sogo > /dev/null 2>&1 + /usr/sbin/userdel %sogo_user + /usr/sbin/groupdel %sogo_user > /dev/null 2>&1 /bin/rm -rf %{_var}/run/sogo /bin/rm -rf %{_var}/spool/sogo # not removing /var/lib/sogo to keep .GNUstepDefaults @@ -331,6 +337,10 @@ fi # ********************************* changelog ************************* %changelog +* Wed Apr 10 2013 Jean Raby +- use %sogo_user instead of 'sogo' +- install a sample sogo.conf in /etc/sogo + * Tue Jan 22 2013 Jean Raby - Create the sogo user as a system user - Use %attr() to set directory permissions instead of chown/chmod