aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/ChangeLog575
-rw-r--r--camel/camel-charset-map.c2
-rw-r--r--camel/camel-filter-driver.c26
-rw-r--r--camel/camel-filter-search.c15
-rw-r--r--camel/camel-folder-search.c18
-rw-r--r--camel/camel-folder-summary.c829
-rw-r--r--camel/camel-gpg-context.c4
-rw-r--r--camel/camel-http-stream.c1
-rw-r--r--camel/camel-mime-utils.c6
-rw-r--r--camel/camel-movemail.c3
-rw-r--r--camel/camel-multipart-signed.c195
-rw-r--r--camel/camel-operation.c2
-rw-r--r--camel/camel-sasl-digest-md5.c7
-rw-r--r--camel/camel-sasl-gssapi.c2
-rw-r--r--camel/camel-sasl-kerberos4.c1
-rw-r--r--camel/camel-service.c420
-rw-r--r--camel/camel-service.h66
-rw-r--r--camel/camel-smime-context.c32
-rw-r--r--camel/camel-tcp-stream-ssl.c3
-rw-r--r--camel/camel-vee-folder.c566
-rw-r--r--camel/camel-vee-folder.h28
-rw-r--r--camel/camel-vee-store.c7
-rw-r--r--camel/providers/groupwise/camel-gw-listener.c70
-rw-r--r--camel/providers/imap/camel-imap-command.c14
-rw-r--r--camel/providers/imap/camel-imap-folder.c123
-rw-r--r--camel/providers/imap/camel-imap-store.c232
-rw-r--r--camel/providers/imap4/camel-imap4-engine.c228
-rw-r--r--camel/providers/imap4/camel-imap4-store.c271
-rw-r--r--camel/providers/imapp/camel-imapp-store.c12
-rw-r--r--camel/providers/local/camel-local-folder.c2
-rw-r--r--camel/providers/local/camel-maildir-folder.c5
-rw-r--r--camel/providers/local/camel-mbox-folder.c81
-rw-r--r--camel/providers/local/camel-mbox-store.c3
-rw-r--r--camel/providers/local/camel-mh-folder.c5
-rw-r--r--camel/providers/local/camel-spool-folder.c4
-rw-r--r--camel/providers/local/camel-spool-store.c1
-rw-r--r--camel/providers/nntp/camel-nntp-folder.c3
-rw-r--r--camel/providers/nntp/camel-nntp-private.h2
-rw-r--r--camel/providers/nntp/camel-nntp-store.c155
-rw-r--r--camel/providers/nntp/camel-nntp-stream.c2
-rw-r--r--camel/providers/nntp/camel-nntp-summary.c37
-rw-r--r--camel/providers/pop3/camel-pop3-store.c199
-rw-r--r--camel/providers/smtp/camel-smtp-transport.c198
-rw-r--r--camel/providers/smtp/camel-smtp-transport.h8
-rw-r--r--camel/tests/data/messages/.cvsignore1
-rw-r--r--camel/tests/lib/folders.c18
46 files changed, 2263 insertions, 2219 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 68495b7d07..d7c203d0b0 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,6 +1,11 @@
-2004-12-01 Mengjie Yu <meng-jie.yu@sun.com>
+2004-12-02 Not Zed <NotZed@Ximian.com>
- * providers/imap/camel-imap-provider.c:add mnemonic for checkboxes.
+ ** See bug #69533.
+
+ * providers/imap/camel-imap-command.c (imap_read_untagged): gross
+ hack, if we get a blank line after a literal, assume the server
+ (read: groupwise) made a mistake. Given the complexity of this
+ code i'm not sure it is the server anyway but what can you do.
2004-12-01 Not Zed <NotZed@Ximian.com>
@@ -29,6 +34,8 @@
2004-11-30 Not Zed <NotZed@Ximian.com>
+ ** See bug #69982 (maybe).
+
* providers/nntp/camel-nntp-stream.c (CAMEL_NNTP_STREAM_LINE):
rename to STREAM_LINE_SIZE so it doesn't override the STREAM_LINE
enum. Sigh.
@@ -50,17 +57,12 @@
* evolution-2.0.2/camel/providers/imap/camel-imap-command.c (camel_imap_response_free)
* evolution-2.0.2/camel/providers/imap/camel-imap-folder.c (camel_imap_folder_new,camel_imap_folder_selected,imap_refresh_info,camel_imap_folder_new,camel_imap_folder_selected)
* evolution-2.0.2/camel/providers/imap/camel-imap-store.c (imap_get_capability,imap_connect_online,get_folder_online,get_folder_offline,get_subscribed_folders,folder_hash,get_folders)
+ * evolution-2.0.2/camel/providers/imap4/camel-imap4-engine.c (engine_parse_capability)
* evolution-2.0.2/camel/providers/pop3/camel-pop3-store.c (get_folder)
* evolution-2.0.2/camel/tests/lib/folders.c: (test_folder_message_ops)
some strcasecmp() calls changed with g_ascii_strcasecmp() for Turkish
character conversiton problems [ http://www.i18nguy.com/unicode/turkish-i18n.html ]
-2004-10-12 Radek Doulik <rodo@ximian.com>
-
- * camel-junk-plugin.c: new init method implementation
-
- * camel-junk-plugin.h: added junk plugin init declaration
-
2004-11-10 Not Zed <NotZed@Ximian.com>
** See bug #69109.
@@ -71,16 +73,11 @@
nameinfo flags a bit so we know when we got a numeric name and
need to wrap it in [].
-2004-11-21 Sivaiah Nallagatla <snallagatla@novell.com>
-
- * providers/groupwise/camel-groupwise-provider.c : added
- a setting to mark the account for offline usuage
+2004-11-19 Not Zed <NotZed@Ximian.com>
- * providers/groupwise/came-gw-listener.c
- (add_esource) (modify_esource) : changed the prototypes
- to pass CamelUrl instead of individual properties
- Add offline_sync property on e-sources if account is
- marked for offline
+ * providers/imap/camel-imap-store.c (connect_to_server): if we
+ have CAMEL_IMAP_BRAINDAMAGED set, then treat the server as
+ braindamaged ok. Testing for #69533.
2004-11-18 Not Zed <NotZed@Ximian.com>
@@ -89,10 +86,6 @@
* providers/nntp/camel-nntp-summary.c: Make debug run based on
'nntp' debug option.
- * providers/nntp/camel-nntp-stream.c (stream_fill): if we get a 0
- read, return ECONNRESET. This should really have been put on the
- stream for that imap hack fix.
-
* providers/nntp/camel-nntp-store.c (camel_nntp_try_authenticate):
retry if the password attempt failed.
@@ -103,140 +96,6 @@
(camel_nntp_command): if we continue, then set the return code to
-1, so we re-loop rather than abort.
-2004-11-15 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/pop3/camel-pop3-store.c (connect_to_server_wrapper):
- In the fallback cases, clear the exception first.
-
- * providers/imap/camel-imap-store.c (connect_to_server_wrapper):
- In the fallback cases, clear the exception first.
-
- * providers/imap4/camel-imap4-store.c (connect_to_server_wrapper):
- In the fallback cases, clear the exception first.
-
-2004-11-15 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/imap/camel-imap-store.c (connect_to_server): Use
- camel_tcp_stream_ssl_new_raw() for STARTTLS stream.
-
- * providers/imap4/camel-imap4-store.c (connect_to_server): Use
- camel_tcp_stream_ssl_new_raw() for STARTTLS stream.
-
- * providers/pop3/camel-pop3-store.c: Change default port numbers
- to be correct (they shouldn't all be the pop3s port).
- (connect_to_server): Moved the last tcp_stream unref to afetr the
- last fail-check so that we won't ever get a double-unref on
- something we only own one ref on.
- (connect_to_server): Unref the tcp_stream if we fail to create an
- engine object before returning fail.
- (connect_to_server): Use camel_tcp_stream_ssl_new_raw() for
- STARTTLS stream.
-
- * providers/imap4/camel-imap4-stream.c (camel_imap4_stream_line):
- Fix bug #69408 by filling our input buffer if inptr == inend.
-
-2004-11-13 Jeffrey Stedfast <fejj@ximian.com>
-
- * providers/imap4/camel-imap4-engine.c
- (camel_imap4_engine_parse_resp_code): Handle numeric tokens for
- the COPYUID set values as well.
-
-2004-11-12 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/imap4/camel-imap4-summary.c (camel_imap4_summary_new):
- Folder now gets set on the CamelFolderSummary object rather than
- the CamelIMAP4Summary.
- (imap4_fetch_all_update): Base summary class now has a folder
- member, use that instead.
- (imap4_fetch_all_add): Same.
- (imap4_summary_fetch_all): Same.
- (imap4_summary_fetch_flags): Same.
- (camel_imap4_summary_set_uidvalidity): Same.
- (camel_imap4_summary_expunge): Same.
- (camel_imap4_summary_flush_updates): Same.
-
- * providers/imap4/camel-imap4-folder.c (imap4_append_message):
- Init appended_uid value to NULL
-
- * providers/imap4/camel-imap4-engine.c (engine_parse_namespace):
- Properly handle NILs for the namespace separator (somehow I missed
- this, silly me).
-
-2004-11-16 Not Zed <NotZed@Ximian.com>
-
- * camel-lock-helper.c (g_strerror): have our own so we don't need
- to link with glib.
-
- * providers/*/Makefile.am: Do not install ANY provider header
- files. No providers are subclassable. No providers are directly
- linkable.
-
- * camel.pc.in: create package config file.
-
- * tests/lib/folders.c (test_folder_message_ops): updated counts for
- delete also marking unread.
-
- * tests/lib/camel-test.c (camel_test_provider_init): new api for
- initialising test system 'in-build'.
-
- * camel-provider.c: remove the assertions, init if we need to,k
- use pthread_once stuff to serialise it.
-
- * tests/folder/test3.c (main): remove gtk stuff (???).
-
- * tests/*: Fix all the makefiles. Made make-check work 'in-build'.
-
- * tests/lib/folders.c (test_folder_counts): update for api changes.
- (test_message_info): similar.
-
- * providers/Makefile.am: removed groupwise from the build, this
- can't go in here anymore, not in its current state.
-
- * camel-net-utils.c (camel_gethostbyaddr_r)
- (camel_gethostbyname_r): the old e_gethost* calls from
- e-host-utils.c.
-
-2004-11-15 Not Zed <NotZed@Ximian.com>
-
- * providers/imap/camel-imap-utils.c (imap_path_to_physical):
- copied from e-path.c.
- (imap_path_find_folders): copied from e-path.c.
-
- * camel.h: remove the provider stuff from the header.
-
- * camel-provider.c: globalise provider_init variable, and asserton
- it in all functions that rely on it.
-
- * camel-service.c: removed getaddrinfo/etc.
-
- * camel-net-utils.[ch]: separate out camel_getaddrinfo etc.
-
- * Makefile.am: split camel into 2 libraries, libcamel and
- libcamel-store.
-
- * camel-multipart-signed.c (camel_multipart_signed_sign)
- (camel_multipart_signed_verify, prepare_sign): remove old
- deprecated api.
-
- * camel-multipart-encrypted.c (camel_multipart_encrypted_encrypt)
- (camel_multipart_encrypted_decrypt): remove old deprecated api.
-
-2004-11-12 Not Zed <NotZed@Ximian.com>
-
- ** Merge in notzed-messageinfo-branch, fix some minor conflicts.
-
-2004-11-11 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/imap4/camel-imap4-store.c (imap4_reconnect): Free the
- passwd here if we need to retry to authenticate.
-
-2004-11-10 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/imap4/camel-imap4-summary.c (imap4_summary_fetch_all):
- Use the expanded ALL macro as on closer inspection of the RFC,
- we're not allowed to use macros in conjunction with other FETCH
- items (such as UID in our case).
-
2004-11-09 Not Zed <NotZed@Ximian.com>
* providers/imap/camel-imap-folder.c (imap_get_message): before
@@ -252,14 +111,6 @@
(content_info_incomplete): recursively check the content-info for
completeness, not just one level.
-2004-11-09 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/imap4/camel-imap4-provider.c: Updated the properties
- to include all the same settings as the old imap code.
-
- * providers/imap4/camel-imap4-folder.c (imap4_getv): Implemented.
- (imap4_setv): Implemented.
-
2004-11-08 Jeffrey Stedfast <fejj@novell.com>
Fix for bug #69241.
@@ -271,303 +122,11 @@
part, we need to use camel_data_wrapper_decode_to_stream() in case
the part was encoded in any way.
-2004-11-09 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/imap4/camel-imap4-stream.c (camel_imap4_stream_line):
- Handle not getting the CRLF pair together. Also don't require that
- we have at least 3 bytes in the read buffer as it is possible we
- don't have that much (see bug #69160).
-
-2004-11-08 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/imap4/camel-imap4-store.c (imap4_subscribe_folder):
- Note the folder-info just subscribed.
- (imap4_unsubscribe_folder): Unnote the folder-info.
-
-2004-11-04 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/imap4/camel-imap4-engine.c: Added much in-line
- documentation.
- (engine_parse_capability): Use g_ascii_str[n]casecmp().
- (camel_imap4_engine_nstring): New convenience function.
-
-2004-11-02 Not Zed <NotZed@Ximian.com>
-
- * camel-object.c (camel_object_hook_event): check interfaces for
- events too.
- (camel_object_trigger_event): check interfaces for events too.
- (camel_object_class_add_event): more checks for interfaces vs
- normal object classes.
- (camel_object_class_add_interface): add an interface to a class.
- (camel_object_get_interface): query for interfaces on an object.
- (camel_object_get_type): register the interface type.
-
-2004-11-02 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/imap4/camel-imap4-store.c (imap4_folder_utf7_name):
- Don't bother getting the folder delim if the name is "" since we
- don't need it in that case.
-
- * providers/imap4/camel-imap4-utils.c
- (camel_imap4_get_path_delim): add an assert that s->namespaces is
- non-NULL.
-
- * providers/imap4/camel-imap4-stream.c
- (camel_imap4_stream_literal): Update stream->inptr after fetching
- the literal chunk.
-
- * providers/imap4/camel-imap4-summary.c (envelope_decode_address):
- Do proper cleanup in case of error and also handle literals.
-
- * providers/imap4/camel-imap4-store.c (imap4_get_folder_info):
- Removed camel_service_connect() call which is no longer needed.
- (imap4_connect): If engine is already connected, shortcut to
- simply returning success.
- (imap4_disconnect): Check engine state rather than poking at
- stream state.
-
-2004-11-01 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/smtp/camel-smtp-transport.c
- (connect_to_server_wrapper): Do the same SSL->TLS and TLS->CLEAR
- fallbacks that the 2.0 (and older) code did.
-
- * providers/pop3/camel-pop3-store.c (connect_to_server_wrapper):
- Same.
-
- * providers/imap4/camel-imap4-store.c (connect_to_server_wrapper):
- Same.
-
- * providers/imap/camel-imap-store.c (connect_to_server_wrapper):
- Same.
-
-2004-11-01 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/imap4/camel-imap4-summary.c
- (camel_imap4_summary_expunge): Remove expunged messages from the
- cache.
- (camel_imap4_summary_set_uidvalidity): Clear the cache if the
- UIDVALIDITY has changed.
-
- * providers/imap4/camel-imap4-folder.c (imap4_get_message): If the
- message exists in the cache, use that rather than fetching it from
- the server and cache messages fetched from the server for later
- use.
- (camel_imap4_folder_finalize): Unref the cache if non-NULL.
- (camel_imap4_folder_new): Create the CamelDataCache.
-
- * providers/imap4/camel-imap4-store.c (imap4_create_folder): Cache
- the folder-info on the summary if successful.
- (imap4_delete_folder): Un-cache the folder-info from the summary.
-
- * providers/imap4/camel-imap4-store-summary.c (load_namespaces):
- Cleaned up a bit.
- (save_namespaces): Same.
- (camel_imap4_store_summary_unnote_info): New function.
- (camel_imap4_store_summary_get_folder_info): Fixed the logic a
- bit.
-
-2004-11-11 Not Zed <NotZed@Ximian.com>
-
- * providers/imap4/*: Update for folder-summary api changes.
-
- * providers/imap4/camel-imap4-store.c (imap4_build_folder_info):
- clean up the logic for getting counts from the folder, we have
- code to do this already. Also always run it against the selected
- folder, does'nt need to have FAST bit unset.
-
- * camel-folder-summary.c (camel_folder_summary_info_new): removed.
-
- * camel-string-utils.c (camel_pstring_strdup, camel_pstring_free):
- pooled string allocators. Oh so much easier than the poolv thing,
- and these refcount too.
-
- * camel-folder-summary.h: put message_id back into the summary.
-
-2004-11-08 Not Zed <NotZed@Ximian.com>
-
- * camel-folder.c (camel_folder_get_deleted_message_count): use
- getv method to get the deleted count.
- (get_deleted_message_count): removed.
-
- * camel-vtrash-folder.c (vtrash_getv): override the unread count
- to ignore junked or deleted.
-
- * camel-folder.c (folder_getv): ignore junked and deleted in the
- unread count.
-
- * camel-vee-folder.c (camel_vee_folder_finalise): changed the
- logic slightly not to call internal functions directly.
- (vee_delete): implement, remove all our folders when we're
- deleted, to give unmatched at least a snowflakes chance in hell of
- working.
-
- * camel-vtrash-folder.c (vtrash_search_by_expression)
- (vtrash_search_by_uids, vtrash_folder_changed, vtrash_add_folder)
- (vtrash_remove_folder, vtrash_rebuild_folder): implement
- vtrash-optimised versions. Much faster.
-
- * camel-vee-folder.c (camel_vee_folder_set_folders): don't rebuild
- the folder.
- (camel_vee_folder_add_folder): track folders here, but invoke
- virtual method to let subclasses know about it.
- (camel_vee_folder_remove_folder): similar.
- (vee_search_by_uids): free the folder_uids array with TRUE,
- plugging memory leak.
-
-2004-11-06 Not Zed <NotZed@Ximian.com>
-
- * camel-vee-folder.c: Removed vname, use Folder->full_name
- instead. Make add_folder/remove_folder/set_expression/set_folders
- virtual methods.
- (vee_add_folder): virtual implementation.
-
- * camel-vee-summary.c (camel_vee_summary_add): remove folder arg.
-
-2004-11-05 Not Zed <NotZed@Ximian.com>
-
- * camel-vee-summary.c (vee_info_set_flags): don't emit changed for
- ourselves, let it filter through the changed handler, otherwise we
- do it twice.
- (vee_info_set_user_tag, vee_info_set_user_flag): same.
-
- * camel-folder-summary.c (message_info_new_from_header): use the
- string pool for allocations.
- (message_info_load): same here.
- (camel_pstring_strdup): noop for NULL or ""
- (camel_pstring_free): same.
- (summary_assign_uid): don't always assing the flagged bit, der.
-
-2004-11-02 Not Zed <NotZed@Ximian.com>
-
- * camel-folder-summary.c (camel_pstring_strdup)
- (camel_pstring_free, message_info_free, message_info_clone):
- 'uniquify' the strings.
-
-2004-10-28 Jeffrey Stedfast <fejj@ximian.com>
-
- * providers/imap4/camel-imap4-summary.c (envelope_decode_nstring):
- Handle literal strings.
- (envelope_decode_date): Same. Fixes bug #68894.
-
- * providers/imap4/camel-imap4-stream.c
- (camel_imap4_stream_next_token): Properly tokenise "\*" as a flag
- token. Fixes bug #68869.
-
-2004-10-21 Björn Torkelsson <torkel@acc.umu.se>
-
- * camel-sasl-kerberos4.c: #include "camel-i18n.h"
-
2004-10-27 Julio M. Merino Vidal <jmmv@menta.net>
* camel-operation.c (camel_operation_shutdown): fix the arguments
to pthread_key_delete.
-2004-10-26 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/imap4/camel-imap4-store-summary.[c,h]: New files
- implementing a folder-info cache for offline mode (and faster
- startup I guess).
-
- * providers/imap4/camel-imap4-store.c (imap4_build_folder_info):
- Cache the folder-info for later use in offline mode.
-
- * providers/imap4/camel-imap4-utils.c
- (camel_imap4_get_path_delim): Instead of assigning top = "INBOX",
- do strcpy (top, "INBOX") so that we can later modify the
- string. Fixes bug #68814.
-
-2004-10-25 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/imap4/camel-imap4-engine.c (engine_parse_namespace):
- Updated to use the public function in camel-imap4-utils.c
- (camel_imap4_engine_finalize): Same.
-
- * providers/imap4/camel-imap4-store.c (imap4_construct): Setup and
- load the store summary.
- (camel_imap4_store_finalize): Unref the store summary.
- (imap4_get_folder): Implemented offline support.
- (imap4_folder_utf7_name): Pass the summary to get_delim rather
- than the engine.
- (imap4_create_folder): Same.
- (imap4_reconnect): Update the namespaces on the store summary.
- (connect_to_server): Update the store summary capabilities.
-
- * providers/imap4/camel-imap4-utils.c
- (camel_imap4_get_path_delim): Now takes a store-summary rather
- than an engine so that it will work in offline mode.
- (camel_imap4_namespace_clear): Moved here from
- camel-imap4-engine.c
- (camel_imap4_namespace_list_copy): New convenience function.
- (camel_imap4_namespace_list_free): New.
-
- * providers/imap4/camel-imap4-folder.c (camel_imap4_folder_new):
- Check the return value of summary loading in offline mode (if it
- fails, we can't get the folder).
-
-2004-10-21 Jeffrey Stedfast <fejj@novell.com>
-
- * camel-sasl-gssapi.c: #include "camel-i18n.h"
-
-2004-10-20 Jeffrey Stedfast <fejj@ximian.com>
-
- * providers/imap4/camel-imap4-store.c (imap4_get_folder): Don't
- allow users to create folders in offline mode. When in offline
- mode, use a different codepath to get a folder object.
- (imap4_noop): Handle offline mode.
- (imap4_unsubscribe_folder): Throw an exception if we are in
- offline mode.
- (imap4_subscribe_folder): Same.
- (imap4_get_folder_info): Started to implement offline
- support. Also, even if we are in online mode but the engine has
- not yet been connected, we should follow the "offline" code path
- and get the folder info's from the cache.
- (imap4_rename_folder): Disallow in offline mode.
- (imap4_delete_folder): Same.
- (imap4_connect): Handle offline mode.
- (imap4_disconnect): Handle offline mode and do proper locking.
- (imap4_query_auth_types): Same.
-
-2004-10-19 Jeffrey Stedfast <fejj@ximian.com>
-
- * providers/imap4/camel-imap4-summary.c (imap4_summary_fetch_all):
- Removed an already-fixed FIXME comment.
- (imap4_summary_fetch_flags): Same.
-
- * providers/imap4/camel-imap4-folder.c (imap4_get_path_delim):
- Removed. Use camel_imap4_get_path_delim() instead.
- (camel_imap4_folder_new): Updated.
- (imap4_sync): If we aren't online, we're done. nothing to do.
- (imap4_refresh_info): Same.
- (imap4_append_message): Same but set an exception.
- (imap4_transfer_messages_to): Same.
-
- * providers/imap4/camel-imap4-utils.c
- (camel_imap4_get_path_delim): Moved here from camel-imap4-store.c
-
- * providers/imap4/camel-imap4-store.c (imap4_try_authenticate):
- Change the service string for the sasl mechanism to"imap" rather
- than "imap4".
- (imap4_get_path_delim): Removed.
- (imap4_create_folder): Updated.
- (imap4_folder_utf7_name): Same.
-
-2004-10-13 Not Zed <NotZed@Ximian.com>
-
- * providers/imap4/camel-imap4-folder.c (camel_imap4_folder_new)
- (imap4_sync_changes, imap4_sync):
- * providers/imap4/camel-imap4-summary.c (untagged_fetch_all): kill
- cast as lvalue warning.
-
- * camel-string-utils.h: add prototype for camel_toupper.
-
- * providers/imap4/camel-imap4-utils.c:
- * providers/imap4/camel-imap4-summary.c:
- * providers/imap4/camel-imap4-folder.c:
- * providers/imap4/camel-imap4-engine.c:
- * providers/imap4/camel-imap4-command.c:
- * providers/imap4/camel-imap4-store.c: include camel-i18n.h.
-
2004-10-12 Not Zed <NotZed@Ximian.com>
** See bug ???
@@ -591,11 +150,11 @@
** See bug #67898 and probably others.
* providers/imapp/camel-imapp-store.c (connect_to_server):
- * providers/pop3/camel-pop3-store.c (connect_to_server_wrapper):
+ * providers/pop3/camel-pop3-store.c (connect_to_server):
* providers/imap4/camel-imap4-store.c (connect_to_server_wrapper):
- * providers/imap/camel-imap-store.c (connect_to_server_wrapper):
- * providers/nntp/camel-nntp-store.c (connect_to_server_wrapper):
- * providers/smtp/camel-smtp-transport.c (connect_to_server_wrapper):
+ * providers/imap/camel-imap-store.c (connect_to_server):
+ * providers/nntp/camel-nntp-store.c (connect_to_server):
+ * providers/smtp/camel-smtp-transport.c (connect_to_server):
Fallback to hard-coded port number if the name lookup fails and no
port was supplied.
@@ -609,11 +168,11 @@
2004-10-09 Sivaiah Nallagatla <snallagatla@novell.com>
- * providers/groupwise/camel-gw-listner.c (add_esource) : add the
- source uid to list of selected calendar and tasks so that
- groupwise calendar and tasks are automatically selected
+ * providers/groupwise/camel-gw-listner.c (add_esource) :
+ add the source uid to list of selected calendar and tasks
+ so that groupwise calendar and tasks are automatically selected
(remove_esource) : remove the uids from corresponding gconf keys
- Fixes #62053
+ Fixes #62053
2004-10-08 Not Zed <NotZed@Ximian.com>
@@ -643,16 +202,6 @@
EAI_AGAIN, it doesn't appear to mean the same as EAGAIN does with
system calls (i guess 'no shit sherlock' really).
-2004-10-04 JP Rosevear <jpr@novell.com>
-
- * providers/imap4/camel-imap4-provider.c: include camel-i18n.h
-
-2004-10-01 Jeffrey Stedfast <fejj@novell.com>
-
- * camel-service.c (camel_getaddrinfo): Avoid assigning a value to
- the member of a const struct (which newer gcc's apparently break
- over) by casting to non-const.
-
2004-09-28 Not Zed <NotZed@Ximian.com>
** See bug #66509.
@@ -696,7 +245,7 @@
* camel-vee-store.c:
* camel-vee-folder.c: move the unmatched
folder onto the camel-vee-store object. Removede the global
- unmatched folder and associated locks/etc, fixed all the code up
+ unmatched folder and associated locks/etc, fixed all the code up
to work with the new unmatched folder, if present.
2004-09-27 Not Zed <NotZed@Ximian.com>
@@ -722,24 +271,6 @@
(spool_get_meta_path): implement, this needs to work differnetly
to the parent classes implementations :-/.
-2004-09-22 Jeffrey Stedfast <fejj@novell.com>
-
- * providers/imap/camel-imap-store.c (connect_to_server): Instead
- of doing a host-lookup ourselves, get it passed in to us as an
- argument. Also simplified a bit (try_starttls is no longer an
- option).
- (connect_to_server_wrapper): Simplified (we no longer have
- fallback cases for SSL stuff). Also, perform host lookup here.
-
- * providers/imap4/camel-imap4-store.c: Same changes as above.
-
- * providers/pop3/camel-pop3-store.c: Same.
-
- * providers/smtp/camel-smtp-transport.c: Same. Other changes
- include making the code consistant with the other providers.
-
- * providers/nntp/camel-nntp-store.c: Same as pop/imap.
-
2004-09-21 Not Zed <NotZed@Ximian.com>
** See bug #63521.
@@ -824,12 +355,6 @@
* camel-http-stream.c: turn off debug.
-2004-09-08 Hannah & Fazlu <hannah_lins@yahoo.co.in>
-
- Fixes Bug#61088
-
- * camel/camel-smime-context.c: Change of strings.
-
2004-09-15 Not Zed <NotZed@Ximian.com>
** See bug #0xffff.
@@ -1150,60 +675,6 @@
CAMEL_GROUPWISE_CFLAGS.
(libcamelgroupwise_la_LIBADD): use CAMEL_GROUPWISE_LIBS.
-2004-09-07 Not Zed <NotZed@Ximian.com>
-
- * providers/groupwise/camel-groupwise-provider.c: put the options
- in their own section.
-
-2004-09-06 Not Zed <NotZed@Ximian.com>
-
- * camel-search-private.c (utf8_get): remove this, and make the
- code use camel_utf8_getc instead. Quite a bit faster esp if
- optimising with inlines.
-
- * camel-object.c (check_magic_fail): change the check_magic code
- to mostly run from a macro, its worth it.
-
-2004-09-04 Not Zed <NotZed@Ximian.com>
-
- * providers/local/camel-mbox-summary.c (message_info_new): fix
- cast issue.
-
- * providers/pop3/camel-pop3-engine.c (get_capabilities): remove
- some unused variables.
-
- * camel-object.h: remove camel-i18n.h, fixed all c files where
- appropriate.
-
-2004-08-25 Not Zed <NotZed@Ximian.com>
-
- * camel-list-utils.[ch]: Copied e_dlist* stuff to here, part of
- removing e-util dependency on camel.
-
-2004-08-05 Not Zed <NotZed@Ximian.com>
-
- * providers/local/camel-local-provider.c: same.
-
- * providers/imap/camel-imap-provider.c: put the extra stuff into a
- 'general' section.
-
- * providers/imapp/camel-imapp-provider.c: same.
-
- * providers/pop3/camel-pop3-provider.c: make sure each section
- start has a name.
-
-2004-08-03 Not Zed <NotZed@Ximian.com>
-
- * camel-url.c (camel_url_set_param): when clearing a param, use
- remove_data instead of set_data_full. craptatious glib at it
- again.
-
- * providers/nntp/camel-nntp-provider.c: turn on ssl option.
-
-2004-07-07 Not Zed <NotZed@Ximian.com>
-
- * camel-folder.c: removed filter-rule.h ugh.
-
2004-07-02 Christian Neumair <chris@gnome-de.org>
* camel-smime-context.c: s/Can't/Cannot/.
diff --git a/camel/camel-charset-map.c b/camel/camel-charset-map.c
index 74ab90bc5d..59f916c700 100644
--- a/camel/camel-charset-map.c
+++ b/camel/camel-charset-map.c
@@ -203,7 +203,7 @@ int main (void)
#include "camel-charset-map.h"
#include "camel-charset-map-private.h"
-#include <libedataserver/e-iconv.h>
+#include <gal/util/e-iconv.h>
#include <glib.h>
#include <locale.h>
diff --git a/camel/camel-filter-driver.c b/camel/camel-filter-driver.c
index ddc787b1e8..cd26c3c390 100644
--- a/camel/camel-filter-driver.c
+++ b/camel/camel-filter-driver.c
@@ -44,12 +44,12 @@
#include "camel-stream-fs.h"
#include "camel-stream-mem.h"
#include "camel-mime-message.h"
+
#include "camel-debug.h"
-#include "camel-i18n.h"
-#include "libedataserver/e-sexp.h"
-#include "libedataserver/e-memory.h"
-#include "libedataserver/e-msgport.h" /* for edlist */
+#include "e-util/e-sexp.h"
+#include "e-util/e-memory.h"
+#include "e-util/e-msgport.h" /* for edlist */
#define d(x)
@@ -575,7 +575,7 @@ do_colour (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDr
if (p->source && p->uid && camel_folder_has_summary_capability (p->source))
camel_folder_set_message_user_tag (p->source, p->uid, "colour", argv[0]->value.string);
else
- camel_message_info_set_user_tag(p->info, "colour", argv[0]->value.string);
+ camel_tag_set (&p->info->user_tags, "colour", argv[0]->value.string);
camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Set colour to %s", argv[0]->value.string);
}
@@ -595,7 +595,7 @@ do_score (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDri
if (p->source && p->uid && camel_folder_has_summary_capability (p->source))
camel_folder_set_message_user_tag (p->source, p->uid, "score", value);
else
- camel_message_info_set_user_tag(p->info, "score", value);
+ camel_tag_set (&p->info->user_tags, "score", value);
camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Set score to %d", argv[0]->value.number);
g_free (value);
}
@@ -615,7 +615,7 @@ set_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDri
if (p->source && p->uid && camel_folder_has_summary_capability (p->source))
camel_folder_set_message_flags (p->source, p->uid, flags, ~0);
else
- camel_message_info_set_flags(p->info, flags | CAMEL_MESSAGE_FOLDER_FLAGGED, ~0);
+ p->info->flags |= flags | CAMEL_MESSAGE_FOLDER_FLAGGED;
camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Set %s flag", argv[0]->value.string);
}
@@ -634,7 +634,7 @@ unset_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterD
if (p->source && p->uid && camel_folder_has_summary_capability (p->source))
camel_folder_set_message_flags (p->source, p->uid, flags, 0);
else
- camel_message_info_set_flags(p->info, flags | CAMEL_MESSAGE_FOLDER_FLAGGED, 0);
+ p->info->flags = (p->info->flags & ~flags) | CAMEL_MESSAGE_FOLDER_FLAGGED;
camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Unset %s flag", argv[0]->value.string);
}
@@ -1150,8 +1150,8 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver, const char *mbox, co
goto fail;
}
- info = camel_message_info_new_from_header(NULL, ((CamelMimePart *)msg)->headers);
- ((CamelMessageInfoBase *)info)->size = camel_mime_parser_tell(mp) - last;
+ info = camel_message_info_new_from_header(((CamelMimePart *)msg)->headers);
+ info->size = camel_mime_parser_tell(mp) - last;
last = camel_mime_parser_tell(mp);
status = camel_filter_driver_filter_message (driver, msg, info, NULL, NULL, source_url,
original_source_url ? original_source_url : source_url, ex);
@@ -1365,10 +1365,10 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage
}
h = CAMEL_MIME_PART (message)->headers;
- info = camel_message_info_new_from_header (NULL, h);
+ info = camel_message_info_new_from_header (h);
freeinfo = TRUE;
} else {
- if (camel_message_info_flags(info) & CAMEL_MESSAGE_DELETED)
+ if (info->flags & CAMEL_MESSAGE_DELETED)
return 0;
uid = camel_message_info_uid (info);
@@ -1443,7 +1443,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage
if (p->source && p->uid && camel_folder_has_summary_capability (p->source))
camel_folder_set_message_flags(p->source, p->uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, ~0);
else
- camel_message_info_set_flags(info, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FOLDER_FLAGGED, ~0);
+ info->flags |= CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FOLDER_FLAGGED;
}
/* Logic: if !Moved and there exists a default folder... */
diff --git a/camel/camel-filter-search.c b/camel/camel-filter-search.c
index 2e35cb5e0d..9999b0ad2c 100644
--- a/camel/camel-filter-search.c
+++ b/camel/camel-filter-search.c
@@ -42,8 +42,9 @@
#include <signal.h>
#include <sys/wait.h>
-#include <libedataserver/e-sexp.h>
-#include <libedataserver/e-iconv.h>
+#include <e-util/e-sexp.h>
+
+#include <gal/util/e-iconv.h>
#include "camel-mime-message.h"
#include "camel-provider.h"
@@ -54,7 +55,7 @@
#include "camel-stream-mem.h"
#include "camel-stream-fs.h"
#include "camel-search-private.h"
-#include "camel-i18n.h"
+
#include "camel-url.h"
#define d(x)
@@ -364,7 +365,7 @@ user_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessage
/* performs an OR of all words */
for (i = 0; i < argc && !truth; i++) {
if (argv[i]->type == ESEXP_RES_STRING
- && camel_message_info_user_flag(fms->info, argv[i]->value.string)) {
+ && camel_flag_get (&fms->info->user_flags, argv[i]->value.string)) {
truth = TRUE;
break;
}
@@ -385,7 +386,7 @@ system_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessa
e_sexp_fatal_error(f, _("Invalid arguments to (system-flag)"));
r = e_sexp_result_new (f, ESEXP_RES_BOOL);
- r->value.bool = camel_system_flag_get (camel_message_info_flags(fms->info), argv[0]->value.string);
+ r->value.bool = camel_system_flag_get (fms->info->flags, argv[0]->value.string);
return r;
}
@@ -399,7 +400,7 @@ user_tag (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageS
if (argc != 1 || argv[0]->type != ESEXP_RES_STRING)
e_sexp_fatal_error(f, _("Invalid arguments to (user-tag)"));
- tag = camel_message_info_user_tag(fms->info, argv[0]->value.string);
+ tag = camel_tag_get (&fms->info->user_tags, argv[0]->value.string);
r = e_sexp_result_new (f, ESEXP_RES_STRING);
r->value.string = g_strdup (tag ? tag : "");
@@ -490,7 +491,7 @@ get_size (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageS
ESExpResult *r;
r = e_sexp_result_new(f, ESEXP_RES_INT);
- r->value.number = camel_message_info_size(fms->info) / 1024;
+ r->value.number = fms->info->size / 1024;
return r;
}
diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c
index 51597ee0c7..db7e6076fe 100644
--- a/camel/camel-folder-search.c
+++ b/camel/camel-folder-search.c
@@ -35,8 +35,6 @@
#include <glib.h>
-#include "libedataserver/e-memory.h"
-
#include "camel-folder-search.h"
#include "camel-folder-thread.h"
@@ -45,8 +43,8 @@
#include "camel-multipart.h"
#include "camel-mime-message.h"
#include "camel-stream-mem.h"
+#include "e-util/e-memory.h"
#include "camel-search-private.h"
-#include "camel-i18n.h"
#define d(x)
#define r(x)
@@ -862,7 +860,7 @@ check_header(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolder
header = camel_message_info_subject(search->current);
} else if (!strcasecmp(headername, "date")) {
/* FIXME: not a very useful form of the date */
- sprintf(strbuf, "%d", (int)camel_message_info_date_sent(search->current));
+ sprintf(strbuf, "%d", (int)search->current->date_sent);
header = strbuf;
} else if (!strcasecmp(headername, "from")) {
header = camel_message_info_from(search->current);
@@ -1248,7 +1246,7 @@ search_user_flag(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFo
/* performs an OR of all words */
for (i=0;i<argc && !truth;i++) {
if (argv[i]->type == ESEXP_RES_STRING
- && camel_message_info_user_flag(search->current, argv[i]->value.string)) {
+ && camel_flag_get(&search->current->user_flags, argv[i]->value.string)) {
truth = TRUE;
break;
}
@@ -1274,7 +1272,7 @@ search_system_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, Came
gboolean truth = FALSE;
if (argc == 1)
- truth = camel_system_flag_get (camel_message_info_flags(search->current), argv[0]->value.string);
+ truth = camel_system_flag_get (search->current->flags, argv[0]->value.string);
r = e_sexp_result_new(f, ESEXP_RES_BOOL);
r->value.bool = truth;
@@ -1295,7 +1293,7 @@ search_user_tag(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFol
r(printf("executing user-tag\n"));
if (argc == 1)
- value = camel_message_info_user_tag(search->current, argv[0]->value.string);
+ value = camel_tag_get (&search->current->user_tags, argv[0]->value.string);
r = e_sexp_result_new(f, ESEXP_RES_STRING);
r->value.string = g_strdup (value ? value : "");
@@ -1314,7 +1312,7 @@ search_get_sent_date(struct _ESExp *f, int argc, struct _ESExpResult **argv, Cam
if (s->current) {
r = e_sexp_result_new(f, ESEXP_RES_INT);
- r->value.number = camel_message_info_date_sent(s->current);
+ r->value.number = s->current->date_sent;
} else {
r = e_sexp_result_new(f, ESEXP_RES_ARRAY_PTR);
r->value.ptrarray = g_ptr_array_new ();
@@ -1334,7 +1332,7 @@ search_get_received_date(struct _ESExp *f, int argc, struct _ESExpResult **argv,
if (s->current) {
r = e_sexp_result_new(f, ESEXP_RES_INT);
- r->value.number = camel_message_info_date_received(s->current);
+ r->value.number = s->current->date_received;
} else {
r = e_sexp_result_new(f, ESEXP_RES_ARRAY_PTR);
r->value.ptrarray = g_ptr_array_new ();
@@ -1365,7 +1363,7 @@ search_get_size (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFo
/* are we inside a match-all? */
if (s->current) {
r = e_sexp_result_new (f, ESEXP_RES_INT);
- r->value.number = camel_message_info_size(s->current) / 1024;
+ r->value.number = s->current->size / 1024;
} else {
r = e_sexp_result_new (f, ESEXP_RES_ARRAY_PTR);
r->value.ptrarray = g_ptr_array_new ();
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index d4d99b7cfe..bf58f4a47e 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -33,13 +33,10 @@
#include <errno.h>
#include <ctype.h>
-#include <libedataserver/e-iconv.h>
+#include <gal/util/e-iconv.h>
#include "camel-folder-summary.h"
-/* for change events, perhaps we should just do them ourselves */
-#include "camel-folder.h"
-
#include <camel/camel-file-utils.h>
#include <camel/camel-mime-filter.h>
#include <camel/camel-mime-filter-index.h>
@@ -55,8 +52,8 @@
#include <camel/camel-string-utils.h>
-#include "libedataserver/md5-utils.h"
-#include "libedataserver/e-memory.h"
+#include "e-util/md5-utils.h"
+#include "e-util/e-memory.h"
#include "camel-private.h"
@@ -93,14 +90,14 @@ static int my_list_size(struct _node **list);
static int summary_header_load(CamelFolderSummary *, FILE *);
static int summary_header_save(CamelFolderSummary *, FILE *);
-static CamelMessageInfo * message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageInfo * message_info_new(CamelFolderSummary *, struct _camel_header_raw *);
static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
static CamelMessageInfo * message_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg);
static CamelMessageInfo * message_info_load(CamelFolderSummary *, FILE *);
static int message_info_save(CamelFolderSummary *, FILE *, CamelMessageInfo *);
static void message_info_free(CamelFolderSummary *, CamelMessageInfo *);
-static CamelMessageContentInfo * content_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageContentInfo * content_info_new(CamelFolderSummary *, struct _camel_header_raw *);
static CamelMessageContentInfo * content_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
static CamelMessageContentInfo * content_info_new_from_message(CamelFolderSummary *s, CamelMimePart *mp);
static CamelMessageContentInfo * content_info_load(CamelFolderSummary *, FILE *);
@@ -119,6 +116,31 @@ static void camel_folder_summary_finalize (CamelObject *obj);
static CamelObjectClass *camel_folder_summary_parent;
static void
+camel_folder_summary_class_init (CamelFolderSummaryClass *klass)
+{
+ camel_folder_summary_parent = camel_type_get_global_classfuncs (camel_object_get_type ());
+
+ klass->summary_header_load = summary_header_load;
+ klass->summary_header_save = summary_header_save;
+
+ klass->message_info_new = message_info_new;
+ klass->message_info_new_from_parser = message_info_new_from_parser;
+ klass->message_info_new_from_message = message_info_new_from_message;
+ klass->message_info_load = message_info_load;
+ klass->message_info_save = message_info_save;
+ klass->message_info_free = message_info_free;
+
+ klass->content_info_new = content_info_new;
+ klass->content_info_new_from_parser = content_info_new_from_parser;
+ klass->content_info_new_from_message = content_info_new_from_message;
+ klass->content_info_load = content_info_load;
+ klass->content_info_save = content_info_save;
+ klass->content_info_free = content_info_free;
+
+ klass->next_uid_string = next_uid_string;
+}
+
+static void
camel_folder_summary_init (CamelFolderSummary *s)
{
struct _CamelFolderSummaryPrivate *p;
@@ -127,7 +149,7 @@ camel_folder_summary_init (CamelFolderSummary *s)
p->filter_charset = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
- s->message_info_size = sizeof(CamelMessageInfoBase);
+ s->message_info_size = sizeof(CamelMessageInfo);
s->content_info_size = sizeof(CamelMessageContentInfo);
s->message_info_chunks = NULL;
@@ -227,22 +249,18 @@ camel_folder_summary_get_type (void)
/**
* camel_folder_summary_new:
- * @folder: Parent folder. It will hold a ref to us, not the other way around.
*
* Create a new CamelFolderSummary object.
*
* Return value: A new CamelFolderSummary widget.
**/
CamelFolderSummary *
-camel_folder_summary_new (struct _CamelFolder *folder)
+camel_folder_summary_new (void)
{
- CamelFolderSummary *new = CAMEL_FOLDER_SUMMARY ( camel_object_new (camel_folder_summary_get_type ()));
-
- new->folder = folder;
-
- return new;
+ CamelFolderSummary *new = CAMEL_FOLDER_SUMMARY ( camel_object_new (camel_folder_summary_get_type ())); return new;
}
+
/**
* camel_folder_summary_set_filename:
* @s:
@@ -322,6 +340,7 @@ camel_folder_summary_count(CamelFolderSummary *s)
*
* Return value: The summary item, or NULL if the index @i is out
* of range.
+ * It must be freed using camel_folder_summary_info_free().
**/
CamelMessageInfo *
camel_folder_summary_index(CamelFolderSummary *s, int i)
@@ -387,9 +406,8 @@ camel_folder_summary_array_free(CamelFolderSummary *s, GPtrArray *array)
{
int i;
- /* FIXME: do the locking around the whole lot to make it faster */
for (i=0;i<array->len;i++)
- camel_message_info_free(array->pdata[i]);
+ camel_folder_summary_info_free(s, array->pdata[i]);
g_ptr_array_free(array, TRUE);
}
@@ -406,6 +424,7 @@ camel_folder_summary_array_free(CamelFolderSummary *s, GPtrArray *array)
*
* Return value: The summary item, or NULL if the uid @uid
* is not available.
+ * It must be freed using camel_folder_summary_info_free().
**/
CamelMessageInfo *
camel_folder_summary_uid(CamelFolderSummary *s, const char *uid)
@@ -541,11 +560,10 @@ camel_folder_summary_load(CamelFolderSummary *s)
if (mi == NULL)
goto error;
- /* FIXME: this should be done differently, how i don't know */
if (s->build_content) {
- ((CamelMessageInfoBase *)mi)->content = perform_content_info_load(s, in);
- if (((CamelMessageInfoBase *)mi)->content == NULL) {
- camel_message_info_free(mi);
+ mi->content = perform_content_info_load(s, in);
+ if (mi->content == NULL) {
+ camel_folder_summary_info_free(s, mi);
goto error;
}
}
@@ -613,8 +631,6 @@ camel_folder_summary_save(CamelFolderSummary *s)
CamelMessageInfo *mi;
char *path;
- g_assert(s->message_info_size >= sizeof(CamelMessageInfoBase));
-
if (s->summary_path == NULL
|| (s->flags & CAMEL_SUMMARY_DIRTY) == 0)
return 0;
@@ -649,7 +665,7 @@ camel_folder_summary_save(CamelFolderSummary *s)
goto exception;
if (s->build_content) {
- if (perform_content_info_save (s, out, ((CamelMessageInfoBase *)mi)->content) == -1)
+ if (perform_content_info_save (s, out, mi->content) == -1)
goto exception;
}
}
@@ -724,8 +740,8 @@ summary_assign_uid(CamelFolderSummary *s, CamelMessageInfo *info)
uid = camel_message_info_uid(info);
if (uid == NULL || uid[0] == 0) {
- g_free(info->uid);
- uid = info->uid = camel_folder_summary_next_uid_string(s);
+ camel_message_info_set_uid(info, camel_folder_summary_next_uid_string(s));
+ uid = camel_message_info_uid(info);
}
CAMEL_SUMMARY_LOCK(s, summary_lock);
@@ -735,14 +751,13 @@ summary_assign_uid(CamelFolderSummary *s, CamelMessageInfo *info)
if (mi == info)
return 0;
d(printf ("Trying to insert message with clashing uid (%s). new uid re-assigned", camel_message_info_uid(info)));
- g_free(info->uid);
- uid = info->uid = camel_folder_summary_next_uid_string(s);
- camel_message_info_set_flags(info, CAMEL_MESSAGE_FOLDER_FLAGGED, CAMEL_MESSAGE_FOLDER_FLAGGED);
+ camel_message_info_set_uid(info, camel_folder_summary_next_uid_string(s));
+ uid = camel_message_info_uid(info);
+ info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
CAMEL_SUMMARY_LOCK(s, summary_lock);
}
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
-
return 1;
}
@@ -851,11 +866,12 @@ CamelMessageInfo *camel_folder_summary_add_from_message(CamelFolderSummary *s, C
*
* Create a new info record from a header.
*
- * Return value: Guess? Free using camel_message_info_free().
+ * Return value: Guess? This info record MUST be freed using
+ * camel_folder_summary_info_free(), camel_message_info_free() will not work.
**/
CamelMessageInfo *camel_folder_summary_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
{
- return ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s))) -> message_info_new_from_header(s, h);
+ return ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s))) -> message_info_new(s, h);
}
/**
@@ -876,7 +892,8 @@ CamelMessageInfo *camel_folder_summary_info_new_from_header(CamelFolderSummary *
* Once complete, the parser will be positioned at the end of
* the message.
*
- * Return value: Guess?
+ * Return value: Guess? This info record MUST be freed using
+ * camel_folder_summary_info_free(), camel_message_info_free() will not work.
**/
CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser *mp)
{
@@ -911,7 +928,7 @@ CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary *
}
/* always scan the content info, even if we dont save it */
- ((CamelMessageInfoBase *)info)->content = summary_build_content_info(s, info, mp);
+ info->content = summary_build_content_info(s, info, mp);
if (name) {
camel_index_write_name(p->index, name);
@@ -921,7 +938,7 @@ CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary *
CAMEL_SUMMARY_UNLOCK(s, filter_lock);
- ((CamelMessageInfoBase *)info)->size = camel_mime_parser_tell(mp) - start;
+ info->size = camel_mime_parser_tell(mp) - start;
}
return info;
}
@@ -965,7 +982,7 @@ CamelMessageInfo *camel_folder_summary_info_new_from_message(CamelFolderSummary
}
}
- ((CamelMessageInfoBase *)info)->content = summary_build_content_info_message(s, info, (CamelMimePart *)msg);
+ info->content = summary_build_content_info_message(s, info, (CamelMimePart *)msg);
if (name) {
camel_index_write_name(p->index, name);
@@ -1000,6 +1017,58 @@ camel_folder_summary_content_info_free(CamelFolderSummary *s, CamelMessageConten
}
/**
+ * camel_folder_summary_info_free:
+ * @s:
+ * @mi:
+ *
+ * Unref and potentially free the message info @mi, and all associated memory.
+ **/
+void camel_folder_summary_info_free(CamelFolderSummary *s, CamelMessageInfo *mi)
+{
+ CamelMessageContentInfo *ci;
+
+ g_assert(mi);
+ g_assert(s);
+
+ CAMEL_SUMMARY_LOCK(s, ref_lock);
+
+ g_assert(mi->refcount >= 1);
+
+ mi->refcount--;
+ if (mi->refcount > 0) {
+ CAMEL_SUMMARY_UNLOCK(s, ref_lock);
+ return;
+ }
+
+ CAMEL_SUMMARY_UNLOCK(s, ref_lock);
+
+ ci = mi->content;
+
+ ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_free(s, mi);
+ if (s->build_content && ci) {
+ camel_folder_summary_content_info_free(s, ci);
+ }
+}
+
+/**
+ * camel_folder_summary_info_ref:
+ * @s:
+ * @mi:
+ *
+ * Add an extra reference to @mi.
+ **/
+void camel_folder_summary_info_ref(CamelFolderSummary *s, CamelMessageInfo *mi)
+{
+ g_assert(mi);
+ g_assert(s);
+
+ CAMEL_SUMMARY_LOCK(s, ref_lock);
+ g_assert(mi->refcount >= 1);
+ mi->refcount++;
+ CAMEL_SUMMARY_UNLOCK(s, ref_lock);
+}
+
+/**
* camel_folder_summary_touch:
* @s:
*
@@ -1031,7 +1100,7 @@ camel_folder_summary_clear(CamelFolderSummary *s)
}
for (i=0;i<s->messages->len;i++)
- camel_message_info_free(s->messages->pdata[i]);
+ camel_folder_summary_info_free(s, s->messages->pdata[i]);
g_ptr_array_set_size(s->messages, 0);
g_hash_table_destroy(s->messages_uid);
@@ -1055,7 +1124,7 @@ void camel_folder_summary_remove(CamelFolderSummary *s, CamelMessageInfo *info)
s->flags |= CAMEL_SUMMARY_DIRTY;
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
- camel_message_info_free(info);
+ camel_folder_summary_info_free(s, info);
}
/**
@@ -1078,7 +1147,7 @@ void camel_folder_summary_remove_uid(CamelFolderSummary *s, const char *uid)
CAMEL_SUMMARY_UNLOCK(s, ref_lock);
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
camel_folder_summary_remove(s, oldinfo);
- camel_message_info_free(oldinfo);
+ camel_folder_summary_info_free(s, oldinfo);
} else {
CAMEL_SUMMARY_UNLOCK(s, ref_lock);
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
@@ -1103,7 +1172,7 @@ void camel_folder_summary_remove_index(CamelFolderSummary *s, int index)
s->flags |= CAMEL_SUMMARY_DIRTY;
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
- camel_message_info_free(info);
+ camel_folder_summary_info_free(s, info);
} else {
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
}
@@ -1144,7 +1213,7 @@ void camel_folder_summary_remove_range(CamelFolderSummary *s, int start, int end
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
for (i=start;i<end;i++)
- camel_message_info_free(infos[i-start]);
+ camel_folder_summary_info_free(s, infos[i-start]);
g_free(infos);
} else {
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
@@ -1390,20 +1459,18 @@ summary_header_save(CamelFolderSummary *s, FILE *out)
count = camel_folder_summary_count(s);
for (i=0; i<count; i++) {
CamelMessageInfo *info = camel_folder_summary_index(s, i);
- guint32 flags;
if (info == NULL)
continue;
- flags = camel_message_info_flags(info);
- if ((flags & CAMEL_MESSAGE_SEEN) == 0)
+ if ((info->flags & CAMEL_MESSAGE_SEEN) == 0)
unread++;
- if ((flags & CAMEL_MESSAGE_DELETED) != 0)
+ if ((info->flags & CAMEL_MESSAGE_DELETED) != 0)
deleted++;
- if ((flags & CAMEL_MESSAGE_JUNK) != 0)
+ if ((info->flags & CAMEL_MESSAGE_JUNK) != 0)
junk++;
- camel_message_info_free(info);
+ camel_folder_summary_info_free(s, info);
}
camel_file_util_encode_fixed_int32(out, count);
@@ -1424,7 +1491,7 @@ static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *s, Ca
case CAMEL_MIME_PARSER_STATE_HEADER:
case CAMEL_MIME_PARSER_STATE_MESSAGE:
case CAMEL_MIME_PARSER_STATE_MULTIPART:
- mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_header(s, camel_mime_parser_headers_raw(mp));
+ mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new(s, camel_mime_parser_headers_raw(mp));
break;
default:
g_error("Invalid parser state");
@@ -1441,7 +1508,7 @@ static CamelMessageContentInfo * content_info_new_from_parser(CamelFolderSummary
case CAMEL_MIME_PARSER_STATE_HEADER:
case CAMEL_MIME_PARSER_STATE_MESSAGE:
case CAMEL_MIME_PARSER_STATE_MULTIPART:
- ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new_from_header(s, camel_mime_parser_headers_raw(mp));
+ ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new(s, camel_mime_parser_headers_raw(mp));
if (ci) {
ci->type = camel_mime_parser_content_type(mp);
camel_content_type_ref(ci->type);
@@ -1458,7 +1525,7 @@ static CamelMessageInfo * message_info_new_from_message(CamelFolderSummary *s, C
{
CamelMessageInfo *mi;
- mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_header(s, ((CamelMimePart *)msg)->headers);
+ mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new(s, ((CamelMimePart *)msg)->headers);
return mi;
}
@@ -1467,7 +1534,7 @@ static CamelMessageContentInfo * content_info_new_from_message(CamelFolderSummar
{
CamelMessageContentInfo *ci;
- ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new_from_header(s, mp->headers);
+ ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new(s, mp->headers);
return ci;
}
@@ -1507,6 +1574,37 @@ summary_format_string (struct _camel_header_raw *h, const char *name, const char
}
/**
+ * camel_folder_summary_info_new:
+ * @s:
+ *
+ * Allocate a new camel message info, suitable for adding
+ * to this summary.
+ *
+ * Return value:
+ **/
+CamelMessageInfo *
+camel_folder_summary_info_new(CamelFolderSummary *s)
+{
+ CamelMessageInfo *mi;
+
+ CAMEL_SUMMARY_LOCK(s, alloc_lock);
+ if (s->message_info_chunks == NULL)
+ s->message_info_chunks = e_memchunk_new(32, s->message_info_size);
+ mi = e_memchunk_alloc(s->message_info_chunks);
+ CAMEL_SUMMARY_UNLOCK(s, alloc_lock);
+
+ memset(mi, 0, s->message_info_size);
+#ifdef DOEPOOLV
+ mi->strings = e_poolv_new (s->message_info_strings);
+#endif
+#ifdef DOESTRV
+ mi->strings = e_strv_new(s->message_info_strings);
+#endif
+ mi->refcount = 1;
+ return mi;
+}
+
+/**
* camel_folder_summary_content_info_new:
* @s:
*
@@ -1531,9 +1629,9 @@ camel_folder_summary_content_info_new(CamelFolderSummary *s)
}
static CamelMessageInfo *
-message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
+message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
{
- CamelMessageInfoBase *mi;
+ CamelMessageInfo *mi;
const char *received;
guchar digest[16];
struct _camel_header_references *refs, *irt, *scan;
@@ -1543,7 +1641,7 @@ message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
CamelContentType *ct = NULL;
const char *content, *charset = NULL;
- mi = (CamelMessageInfoBase *)camel_message_info_new(s);
+ mi = camel_folder_summary_info_new(s);
if ((content = camel_header_raw_find(&h, "Content-Type", NULL))
&& (ct = camel_content_type_decode(content))
@@ -1562,17 +1660,25 @@ message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
if (ct)
camel_content_type_unref(ct);
- mi->subject = camel_pstring_strdup(subject);
- mi->from = camel_pstring_strdup(from);
- mi->to = camel_pstring_strdup(to);
- mi->cc = camel_pstring_strdup(cc);
- mi->mlist = camel_pstring_strdup(mlist);
-
- g_free(subject);
- g_free(from);
- g_free(to);
- g_free(cc);
- g_free(mlist);
+#ifdef DOEPOOLV
+ e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_SUBJECT, subject, TRUE);
+ e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_FROM, from, TRUE);
+ e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_TO, to, TRUE);
+ e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_CC, cc, TRUE);
+ e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_MLIST, mlist, TRUE);
+#elif defined (DOESTRV)
+ e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_SUBJECT, subject);
+ e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_FROM, from);
+ e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_TO, to);
+ e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_CC, cc);
+ e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_MLIST, mlist);
+#else
+ mi->subject = subject;
+ mi->from = from;
+ mi->to = to;
+ mi->cc = cc;
+ mi->mlist = mlist;
+#endif
mi->user_flags = NULL;
mi->user_tags = NULL;
@@ -1621,18 +1727,19 @@ message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
camel_header_references_list_clear(&refs);
}
- return (CamelMessageInfo *)mi;
+ return mi;
}
+
static CamelMessageInfo *
message_info_load(CamelFolderSummary *s, FILE *in)
{
- CamelMessageInfoBase *mi;
+ CamelMessageInfo *mi;
guint count;
int i;
char *subject, *from, *to, *cc, *mlist, *uid;;
- mi = (CamelMessageInfoBase *)camel_message_info_new(s);
+ mi = camel_folder_summary_info_new(s);
io(printf("Loading message info\n"));
@@ -1647,18 +1754,28 @@ message_info_load(CamelFolderSummary *s, FILE *in)
camel_file_util_decode_string(in, &cc);
camel_file_util_decode_string(in, &mlist);
+#ifdef DOEPOOLV
+ e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_UID, uid, TRUE);
+ e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_SUBJECT, subject, TRUE);
+ e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_FROM, from, TRUE);
+ e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_TO, to, TRUE);
+ e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_CC, cc, TRUE);
+ e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_MLIST, mlist, TRUE);
+#elif defined (DOESTRV)
+ e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_UID, uid);
+ e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_SUBJECT, subject);
+ e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_FROM, from);
+ e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_TO, to);
+ e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_CC, cc);
+ e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_MLIST, mlist);
+#else
mi->uid = uid;
- mi->subject = camel_pstring_strdup(subject);
- mi->from = camel_pstring_strdup(from);
- mi->to = camel_pstring_strdup(to);
- mi->cc = camel_pstring_strdup(cc);
- mi->mlist = camel_pstring_strdup(mlist);
-
- g_free(subject);
- g_free(from);
- g_free(to);
- g_free(cc);
- g_free(mlist);
+ mi->subject = subject;
+ mi->from = from;
+ mi->to = to;
+ mi->cc = cc;
+ mi->mlist = mlist;
+#endif
mi->content = NULL;
@@ -1702,22 +1819,21 @@ message_info_load(CamelFolderSummary *s, FILE *in)
}
if (!ferror(in))
- return (CamelMessageInfo *)mi;
+ return mi;
error:
- camel_message_info_free((CamelMessageInfo *)mi);
+ camel_folder_summary_info_free(s, mi);
return NULL;
}
static int
-message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *info)
+message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi)
{
guint32 count;
CamelFlag *flag;
CamelTag *tag;
int i;
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
io(printf("Saving message info\n"));
@@ -1766,27 +1882,28 @@ message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *info)
}
static void
-message_info_free(CamelFolderSummary *s, CamelMessageInfo *info)
+message_info_free(CamelFolderSummary *s, CamelMessageInfo *mi)
{
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
-
+#ifdef DOEPOOLV
+ e_poolv_destroy(mi->strings);
+#elif defined (DOESTRV)
+ e_strv_destroy(mi->strings);
+#else
g_free(mi->uid);
- camel_pstring_free(mi->subject);
- camel_pstring_free(mi->from);
- camel_pstring_free(mi->to);
- camel_pstring_free(mi->cc);
- camel_pstring_free(mi->mlist);
+ g_free(mi->subject);
+ g_free(mi->from);
+ g_free(mi->to);
+ g_free(mi->cc);
+ g_free(mi->mlist);
+#endif
g_free(mi->references);
camel_flag_list_free(&mi->user_flags);
camel_tag_list_free(&mi->user_tags);
- if (s)
- e_memchunk_free(s->message_info_chunks, mi);
- else
- g_free(mi);
+ e_memchunk_free(s->message_info_chunks, mi);
}
static CamelMessageContentInfo *
-content_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
+content_info_new (CamelFolderSummary *s, struct _camel_header_raw *h)
{
CamelMessageContentInfo *ci;
const char *charset;
@@ -1939,7 +2056,7 @@ summary_build_content_info(CamelFolderSummary *s, CamelMessageInfo *msginfo, Cam
|| camel_content_type_is(ct, "application", "pkcs7-signature")
#endif
)
- camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE);
+ msginfo->flags |= CAMEL_MESSAGE_SECURE;
if (p->index && camel_content_type_is(ct, "text", "*")) {
char *encoding;
@@ -1949,7 +2066,7 @@ summary_build_content_info(CamelFolderSummary *s, CamelMessageInfo *msginfo, Cam
encoding = camel_content_transfer_encoding_decode(camel_mime_parser_header(mp, "content-transfer-encoding", NULL));
if (encoding) {
- if (!g_ascii_strcasecmp(encoding, "base64")) {
+ if (!strcasecmp(encoding, "base64")) {
d(printf(" decoding base64\n"));
if (p->filter_64 == NULL)
p->filter_64 = camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
@@ -1963,7 +2080,7 @@ summary_build_content_info(CamelFolderSummary *s, CamelMessageInfo *msginfo, Cam
else
camel_mime_filter_reset((CamelMimeFilter *)p->filter_qp);
enc_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)p->filter_qp);
- } else if (!g_ascii_strcasecmp (encoding, "x-uuencode")) {
+ } else if (!strcasecmp (encoding, "x-uuencode")) {
d(printf(" decoding x-uuencode\n"));
if (p->filter_uu == NULL)
p->filter_uu = camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_UU_DEC);
@@ -1979,7 +2096,7 @@ summary_build_content_info(CamelFolderSummary *s, CamelMessageInfo *msginfo, Cam
charset = camel_content_type_param(ct, "charset");
if (charset!=NULL
&& !(g_ascii_strcasecmp(charset, "us-ascii")==0
- || g_ascii_strcasecmp(charset, "utf-8")==0)) {
+ || strcasecmp(charset, "utf-8")==0)) {
d(printf(" Adding conversion filter from %s to UTF-8\n", charset));
mfc = g_hash_table_lookup(p->filter_charset, charset);
if (mfc == NULL) {
@@ -2023,10 +2140,10 @@ summary_build_content_info(CamelFolderSummary *s, CamelMessageInfo *msginfo, Cam
/* update attachments flag as we go */
ct = camel_mime_parser_content_type(mp);
if (camel_content_type_is(ct, "multipart", "mixed"))
- camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_ATTACHMENTS, CAMEL_MESSAGE_ATTACHMENTS);
+ msginfo->flags |= CAMEL_MESSAGE_ATTACHMENTS;
if (camel_content_type_is(ct, "multipart", "signed")
|| camel_content_type_is(ct, "multipart", "encrypted"))
- camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE);
+ msginfo->flags |= CAMEL_MESSAGE_SECURE;
while (camel_mime_parser_step(mp, &buffer, &len) != CAMEL_MIME_PARSER_STATE_MULTIPART_END) {
camel_mime_parser_unstep(mp);
@@ -2040,7 +2157,7 @@ summary_build_content_info(CamelFolderSummary *s, CamelMessageInfo *msginfo, Cam
case CAMEL_MIME_PARSER_STATE_MESSAGE:
d(printf("Summarising message\n"));
/* update attachments flag as we go */
- camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_ATTACHMENTS, CAMEL_MESSAGE_ATTACHMENTS);
+ msginfo->flags |= CAMEL_MESSAGE_ATTACHMENTS;
part = summary_build_content_info(s, msginfo, mp);
if (part) {
@@ -2086,17 +2203,17 @@ summary_build_content_info_message(CamelFolderSummary *s, CamelMessageInfo *msgi
ct = ((CamelDataWrapper *)containee)->mime_type;
if (camel_content_type_is(ct, "multipart", "*")) {
if (camel_content_type_is(ct, "multipart", "mixed"))
- camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_ATTACHMENTS, CAMEL_MESSAGE_ATTACHMENTS);
+ msginfo->flags |= CAMEL_MESSAGE_ATTACHMENTS;
if (camel_content_type_is(ct, "multipart", "signed")
|| camel_content_type_is(ct, "multipart", "encrypted"))
- camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE);
+ msginfo->flags |= CAMEL_MESSAGE_SECURE;
} else if (camel_content_type_is(ct, "application", "pgp-signature")
#ifdef ENABLE_SMIME
|| camel_content_type_is(ct, "application", "x-pkcs7-signature")
|| camel_content_type_is(ct, "application", "pkcs7-signature")
#endif
) {
- camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE);
+ msginfo->flags |= CAMEL_MESSAGE_SECURE;
}
/* using the object types is more accurate than using the mime/types */
@@ -2490,23 +2607,19 @@ camel_system_flag_get (guint32 flags, const char *name)
*
* Returns a new CamelMessageInfo structure.
**/
-void *
-camel_message_info_new (CamelFolderSummary *s)
+CamelMessageInfo *
+camel_message_info_new (void)
{
CamelMessageInfo *info;
-
- if (s) {
- CAMEL_SUMMARY_LOCK(s, alloc_lock);
- if (s->message_info_chunks == NULL)
- s->message_info_chunks = e_memchunk_new(32, s->message_info_size);
- info = e_memchunk_alloc0(s->message_info_chunks);
- CAMEL_SUMMARY_UNLOCK(s, alloc_lock);
- } else {
- info = g_malloc0(sizeof(CamelMessageInfoBase));
- }
-
+
+ info = g_malloc0(sizeof(*info));
+#ifdef DOEPOOLV
+ info->strings = e_poolv_new(CAMEL_MESSAGE_INFO_LAST);
+#endif
+#ifdef DOESTRV
+ info->strings = e_strv_new (CAMEL_MESSAGE_INFO_LAST);
+#endif
info->refcount = 1;
- info->summary = s;
return info;
}
@@ -2516,22 +2629,14 @@ camel_message_info_new (CamelFolderSummary *s)
* @info:
*
* Reference an info.
+ *
+ * NOTE: This interface is not MT-SAFE, like the others.
**/
-void camel_message_info_ref(void *o)
+void camel_message_info_ref(CamelMessageInfo *info)
{
- CamelMessageInfo *mi = o;
-
- if (mi->summary) {
- CAMEL_SUMMARY_LOCK(mi->summary, ref_lock);
- g_assert(mi->refcount >= 1);
- mi->refcount++;
- CAMEL_SUMMARY_UNLOCK(mi->summary, ref_lock);
- } else {
- GLOBAL_INFO_LOCK(info);
- g_assert(mi->refcount >= 1);
- mi->refcount++;
- GLOBAL_INFO_UNLOCK(info);
- }
+ GLOBAL_INFO_LOCK(info);
+ info->refcount++;
+ GLOBAL_INFO_UNLOCK(info);
}
/**
@@ -2541,89 +2646,108 @@ void camel_message_info_ref(void *o)
* Returns a new CamelMessageInfo structure populated by the header.
**/
CamelMessageInfo *
-camel_message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *header)
+camel_message_info_new_from_header (struct _camel_header_raw *header)
{
- if (s)
- return ((CamelFolderSummaryClass *)((CamelObject *)s)->klass)->message_info_new_from_header(s, header);
+ CamelMessageInfo *info;
+ char *subject, *from, *to, *cc, *mlist;
+ CamelContentType *ct = NULL;
+ const char *content, *date, *charset = NULL;
+
+ if ((content = camel_header_raw_find(&header, "Content-Type", NULL))
+ && (ct = camel_content_type_decode(content))
+ && (charset = camel_content_type_param(ct, "charset"))
+ && (g_ascii_strcasecmp(charset, "us-ascii") == 0))
+ charset = NULL;
+
+ charset = charset ? e_iconv_charset_name (charset) : NULL;
+
+ subject = summary_format_string(header, "subject", charset);
+ from = summary_format_address(header, "from", charset);
+ to = summary_format_address(header, "to", charset);
+ cc = summary_format_address(header, "cc", charset);
+ date = camel_header_raw_find(&header, "date", NULL);
+ mlist = camel_header_raw_check_mailing_list(&header);
+
+ if (ct)
+ camel_content_type_unref(ct);
+
+ info = camel_message_info_new();
+
+ camel_message_info_set_subject(info, subject);
+ camel_message_info_set_from(info, from);
+ camel_message_info_set_to(info, to);
+ camel_message_info_set_cc(info, cc);
+ camel_message_info_set_mlist(info, mlist);
+
+ if (date)
+ info->date_sent = camel_header_decode_date (date, NULL);
+ else
+ info->date_sent = time (NULL);
+
+ date = camel_header_raw_find (&header, "received", NULL);
+ if (date && (date = strrchr (date, ';')))
+ date++;
+
+ if (date)
+ info->date_received = camel_header_decode_date (date, NULL);
else
- return message_info_new_from_header(NULL, header);
+ info->date_received = time (NULL);
+
+ return info;
}
/**
- * camel_message_info_free:
- * @mi: the message info
- *
- * Unref's and potentially frees a CamelMessageInfo and its contents.
+ * camel_message_info_dup_to:
+ * @from: source message info
+ * @to: destination message info
*
+ * Duplicates the contents of one CamelMessageInfo structure into another.
+ * (The destination is assumed to be empty: its contents are not freed.)
+ * The slightly odd interface is to allow this to be used to initialize
+ * "subclasses" of CamelMessageInfo.
**/
void
-camel_message_info_free(void *o)
-{
- CamelMessageInfo *mi = o;
-
- g_return_if_fail(mi != NULL);
-
- if (mi->summary) {
- CAMEL_SUMMARY_LOCK(mi->summary, ref_lock);
-
- g_assert(mi->refcount >= 1);
- mi->refcount--;
- if (mi->refcount > 0) {
- CAMEL_SUMMARY_UNLOCK(mi->summary, ref_lock);
- return;
- }
-
- CAMEL_SUMMARY_UNLOCK(mi->summary, ref_lock);
-
- /* FIXME: this is kinda busted, should really be handled by message info free */
- if (mi->summary->build_content
- && ((CamelMessageInfoBase *)mi)->content) {
- camel_folder_summary_content_info_free(mi->summary, ((CamelMessageInfoBase *)mi)->content);
- }
-
- ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(mi->summary)))->message_info_free(mi->summary, mi);
- } else {
- GLOBAL_INFO_LOCK(info);
- mi->refcount--;
- if (mi->refcount > 0) {
- GLOBAL_INFO_UNLOCK(info);
- return;
- }
- GLOBAL_INFO_UNLOCK(info);
-
- message_info_free(NULL, mi);
- }
-}
-
-static CamelMessageInfo *
-message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi)
+camel_message_info_dup_to(const CamelMessageInfo *from, CamelMessageInfo *to)
{
- CamelMessageInfoBase *to, *from = (CamelMessageInfoBase *)mi;
CamelFlag *flag;
CamelTag *tag;
- to = (CamelMessageInfoBase *)camel_message_info_new(s);
-
+ /* Copy numbers */
to->flags = from->flags;
to->size = from->size;
to->date_sent = from->date_sent;
to->date_received = from->date_received;
to->refcount = 1;
- /* NB: We don't clone the uid */
-
- to->subject = camel_pstring_strdup(from->subject);
- to->from = camel_pstring_strdup(from->from);
- to->to = camel_pstring_strdup(from->to);
- to->cc = camel_pstring_strdup(from->cc);
- to->mlist = camel_pstring_strdup(from->mlist);
- memcpy(&to->message_id, &from->message_id, sizeof(to->message_id));
+ /* Copy strings */
+#ifdef DOEPOOLV
+ to->strings = e_poolv_cpy (to->strings, from->strings);
+#elif defined (DOESTRV)
+ /* to->strings = e_strv_new(CAMEL_MESSAGE_INFO_LAST); */
+ e_strv_set(to->strings, CAMEL_MESSAGE_INFO_SUBJECT, camel_message_info_subject(from));
+ e_strv_set(to->strings, CAMEL_MESSAGE_INFO_FROM, camel_message_info_from(from));
+ e_strv_set(to->strings, CAMEL_MESSAGE_INFO_TO, camel_message_info_to(from));
+ e_strv_set(to->strings, CAMEL_MESSAGE_INFO_CC, camel_message_info_cc(from));
+ e_strv_set(to->strings, CAMEL_MESSAGE_INFO_UID, camel_message_info_uid(from));
+ e_strv_set(to->strings, CAMEL_MESSAGE_INFO_UID, camel_message_info_mlist(from));
+#else
+ to->subject = g_strdup(from->subject);
+ to->from = g_strdup(from->from);
+ to->to = g_strdup(from->to);
+ to->cc = g_strdup(from->cc);
+ to->uid = g_strdup(from->uid);
+ to->mlist = g_strdup(from->mlist);
+#endif
+ memcpy(&to->message_id, &from->message_id, sizeof(from->message_id));
+ /* Copy structures */
if (from->references) {
int len = sizeof(*from->references) + ((from->references->size-1) * sizeof(from->references->references[0]));
to->references = g_malloc(len);
memcpy(to->references, from->references, len);
+ } else {
+ to->references = NULL;
}
flag = from->user_flags;
@@ -2638,226 +2762,83 @@ message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi)
tag = tag->next;
}
- if (from->content) {
- /* FIXME: copy content-infos */
- }
-
- return (CamelMessageInfo *)to;
-}
-
-void *
-camel_message_info_clone(const void *o)
-{
- const CamelMessageInfo *mi = o;
-
- if (mi->summary)
- return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->message_info_clone(mi->summary, mi);
- else
- return message_info_clone(NULL, mi);
-}
-
-static const void *
-info_ptr(const CamelMessageInfo *mi, int id)
-{
- switch (id) {
- case CAMEL_MESSAGE_INFO_SUBJECT:
- return ((const CamelMessageInfoBase *)mi)->subject;
- case CAMEL_MESSAGE_INFO_FROM:
- return ((const CamelMessageInfoBase *)mi)->from;
- case CAMEL_MESSAGE_INFO_TO:
- return ((const CamelMessageInfoBase *)mi)->to;
- case CAMEL_MESSAGE_INFO_CC:
- return ((const CamelMessageInfoBase *)mi)->cc;
- case CAMEL_MESSAGE_INFO_MLIST:
- return ((const CamelMessageInfoBase *)mi)->mlist;
- case CAMEL_MESSAGE_INFO_MESSAGE_ID:
- return &((const CamelMessageInfoBase *)mi)->message_id;
- case CAMEL_MESSAGE_INFO_REFERENCES:
- return ((const CamelMessageInfoBase *)mi)->references;
- case CAMEL_MESSAGE_INFO_USER_FLAGS:
- return ((const CamelMessageInfoBase *)mi)->user_flags;
- case CAMEL_MESSAGE_INFO_USER_TAGS:
- return ((const CamelMessageInfoBase *)mi)->user_tags;
- default:
- abort();
- }
-}
-
-static guint32
-info_uint32(const CamelMessageInfo *mi, int id)
-{
- switch (id) {
- case CAMEL_MESSAGE_INFO_FLAGS:
- return ((const CamelMessageInfoBase *)mi)->flags;
- case CAMEL_MESSAGE_INFO_SIZE:
- return ((const CamelMessageInfoBase *)mi)->size;
- default:
- abort();
- }
-}
-
-static time_t
-info_time(const CamelMessageInfo *mi, int id)
-{
- switch (id) {
- case CAMEL_MESSAGE_INFO_DATE_SENT:
- return ((const CamelMessageInfoBase *)mi)->date_sent;
- case CAMEL_MESSAGE_INFO_DATE_RECEIVED:
- return ((const CamelMessageInfoBase *)mi)->date_received;
- default:
- abort();
- }
-}
-
-static gboolean
-info_user_flag(const CamelMessageInfo *mi, const char *id)
-{
- return camel_flag_get(&((CamelMessageInfoBase *)mi)->user_flags, id);
-}
-
-static const char *
-info_user_tag(const CamelMessageInfo *mi, const char *id)
-{
- return camel_tag_get(&((CamelMessageInfoBase *)mi)->user_tags, id);
-}
-
-const void *
-camel_message_info_ptr(const CamelMessageInfo *mi, int id)
-{
- if (mi->summary)
- return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_ptr(mi, id);
- else
- return info_ptr(mi, id);
-}
-
-guint32 camel_message_info_uint32(const CamelMessageInfo *mi, int id)
-{
- if (mi->summary)
- return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_uint32(mi, id);
- else
- return info_uint32(mi, id);
-}
-
-time_t camel_message_info_time(const CamelMessageInfo *mi, int id)
-{
- if (mi->summary)
- return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_time(mi, id);
- else
- return info_time(mi, id);
-}
-
-gboolean camel_message_info_user_flag(const CamelMessageInfo *mi, const char *id)
-{
- if (mi->summary)
- return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_user_flag(mi, id);
- else
- return info_user_flag(mi, id);
-}
-
-const char *camel_message_info_user_tag(const CamelMessageInfo *mi, const char *id)
-{
- if (mi->summary)
- return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_user_tag(mi, id);
- else
- return info_user_tag(mi, id);
-}
-
-static gboolean
-info_set_flags(CamelMessageInfo *info, guint32 flags, guint32 set)
-{
- guint32 old;
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
-
- /* TODO: locking? */
-
- old = mi->flags;
- mi->flags = (old & ~flags) | (set & flags);
- if (old != mi->flags) {
- mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
- if (mi->summary)
- camel_folder_summary_touch(mi->summary);
- }
-
- if ((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (mi->flags & ~CAMEL_MESSAGE_SYSTEM_MASK))
- return FALSE;
-
- if (mi->summary && mi->summary->folder && mi->uid) {
- CamelFolderChangeInfo *changes = camel_folder_change_info_new();
-
- camel_folder_change_info_change_uid(changes, camel_message_info_uid(info));
- camel_object_trigger_event(mi->summary->folder, "folder_changed", changes);
- camel_folder_change_info_free(changes);
- }
-
- return TRUE;
-}
-
-gboolean camel_message_info_set_flags(CamelMessageInfo *mi, guint32 flags, guint32 set)
-{
- if (mi->summary)
- return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_flags(mi, flags, set);
- else
- return info_set_flags(mi, flags, set);
+ /* No, this is impossible without knowing the class of summary we came from */
+ /* FIXME some day */
+ to->content = NULL;
}
-static gboolean
-info_set_user_flag(CamelMessageInfo *info, const char *name, gboolean value)
+/**
+ * camel_message_info_free:
+ * @mi: the message info
+ *
+ * Unref's and potentially frees a CamelMessageInfo and its contents.
+ *
+ * Can only be used to free CamelMessageInfo's created with
+ * camel_message_info_dup_to.
+ *
+ * NOTE: This interface is not MT-SAFE, like the others.
+ *
+ **/
+void
+camel_message_info_free(CamelMessageInfo *mi)
{
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
- int res;
-
- res = camel_flag_set(&mi->user_flags, name, value);
-
- /* TODO: check this item is still in the summary first */
- if (mi->summary && res && mi->summary->folder && mi->uid) {
- CamelFolderChangeInfo *changes = camel_folder_change_info_new();
+ g_return_if_fail(mi != NULL);
- mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
- camel_folder_summary_touch(mi->summary);
- camel_folder_change_info_change_uid(changes, camel_message_info_uid(info));
- camel_object_trigger_event(mi->summary->folder, "folder_changed", changes);
- camel_folder_change_info_free(changes);
+ GLOBAL_INFO_LOCK(info);
+ mi->refcount--;
+ if (mi->refcount > 0) {
+ GLOBAL_INFO_UNLOCK(info);
+ return;
}
+ GLOBAL_INFO_UNLOCK(info);
- return res;
+#ifdef DOEPOOLV
+ e_poolv_destroy(mi->strings);
+#elif defined (DOESTRV)
+ e_strv_destroy(mi->strings);
+#else
+ g_free(mi->uid);
+ g_free(mi->subject);
+ g_free(mi->from);
+ g_free(mi->to);
+ g_free(mi->cc);
+ g_free(mi->mlist);
+#endif
+ g_free(mi->references);
+ camel_flag_list_free(&mi->user_flags);
+ camel_tag_list_free(&mi->user_tags);
+ /* FIXME: content info? */
+ g_free(mi);
}
-gboolean camel_message_info_set_user_flag(CamelMessageInfo *mi, const char *id, gboolean state)
+#if defined (DOEPOOLV) || defined (DOESTRV)
+const char *
+camel_message_info_string (const CamelMessageInfo *mi, int type)
{
- if (mi->summary)
- return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_user_flag(mi, id, state);
- else
- return info_set_user_flag(mi, id, state);
+ g_assert (mi != NULL);
+
+ if (mi->strings == NULL)
+ return "";
+#ifdef DOEPOOLV
+ return e_poolv_get (mi->strings, type);
+#else
+ return e_strv_get (mi->strings, type);
+#endif
}
-static gboolean
-info_set_user_tag(CamelMessageInfo *info, const char *name, const char *value)
+void
+camel_message_info_set_string (CamelMessageInfo *mi, int type, char *str)
{
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
- int res;
-
- res = camel_tag_set(&mi->user_tags, name, value);
-
- if (mi->summary && res && mi->summary->folder && mi->uid) {
- CamelFolderChangeInfo *changes = camel_folder_change_info_new();
-
- mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
- camel_folder_summary_touch(mi->summary);
- camel_folder_change_info_change_uid(changes, camel_message_info_uid(info));
- camel_object_trigger_event(mi->summary->folder, "folder_changed", changes);
- camel_folder_change_info_free(changes);
- }
-
- return res;
+ g_assert (mi != NULL);
+ g_assert (mi->strings != NULL);
+#ifdef DOEPOOLV
+ e_poolv_set (mi->strings, type, str, TRUE);
+#else
+ mi->strings = e_strv_set_ref_free (mi->strings, type, str);
+#endif
}
+#endif
-gboolean camel_message_info_set_user_tag(CamelMessageInfo *mi, const char *id, const char *val)
-{
- if (mi->summary)
- return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_user_tag(mi, id, val);
- else
- return info_set_user_tag(mi, id, val);
-}
void
camel_content_info_dump (CamelMessageContentInfo *ci, int depth)
@@ -2902,50 +2883,6 @@ camel_message_info_dump (CamelMessageInfo *mi)
printf("mailing list: %s\n", camel_message_info_mlist(mi));
printf("From: %s\n", camel_message_info_from(mi));
printf("UID: %s\n", camel_message_info_uid(mi));
- printf("Flags: %04x\n", camel_message_info_flags(mi));
- /*camel_content_info_dump(mi->content, 0);*/
-}
-
-
-static void
-camel_folder_summary_class_init (CamelFolderSummaryClass *klass)
-{
- camel_folder_summary_parent = camel_type_get_global_classfuncs (camel_object_get_type ());
-
- klass->summary_header_load = summary_header_load;
- klass->summary_header_save = summary_header_save;
-
- klass->message_info_new_from_header = message_info_new_from_header;
- klass->message_info_new_from_parser = message_info_new_from_parser;
- klass->message_info_new_from_message = message_info_new_from_message;
- klass->message_info_load = message_info_load;
- klass->message_info_save = message_info_save;
- klass->message_info_free = message_info_free;
- klass->message_info_clone = message_info_clone;
-
- klass->content_info_new_from_header = content_info_new_from_header;
- klass->content_info_new_from_parser = content_info_new_from_parser;
- klass->content_info_new_from_message = content_info_new_from_message;
- klass->content_info_load = content_info_load;
- klass->content_info_save = content_info_save;
- klass->content_info_free = content_info_free;
-
- klass->next_uid_string = next_uid_string;
-
- klass->info_ptr = info_ptr;
- klass->info_uint32 = info_uint32;
- klass->info_time = info_time;
- klass->info_user_flag = info_user_flag;
- klass->info_user_tag = info_user_tag;
-
-#if 0
- klass->info_set_string = info_set_string;
- klass->info_set_uint32 = info_set_uint32;
- klass->info_set_time = info_set_time;
- klass->info_set_ptr = info_set_ptr;
-#endif
- klass->info_set_user_flag = info_set_user_flag;
- klass->info_set_user_tag = info_set_user_tag;
-
- klass->info_set_flags = info_set_flags;
+ printf("Flags: %04x\n", mi->flags & 0xffff);
+ camel_content_info_dump(mi->content, 0);
}
diff --git a/camel/camel-gpg-context.c b/camel/camel-gpg-context.c
index 928b4ed4be..b52f6feb6b 100644
--- a/camel/camel-gpg-context.c
+++ b/camel/camel-gpg-context.c
@@ -46,7 +46,7 @@
#include <errno.h>
#include <ctype.h>
-#include "libedataserver/e-iconv.h"
+#include "gal/util/e-iconv.h"
#include "camel-gpg-context.h"
#include "camel-mime-filter-charset.h"
@@ -56,9 +56,9 @@
#include "camel-operation.h"
#include "camel-mime-part.h"
#include "camel-mime-filter-canon.h"
+
#include "camel-multipart-signed.h"
#include "camel-multipart-encrypted.h"
-#include "camel-i18n.h"
#define d(x)
diff --git a/camel/camel-http-stream.c b/camel/camel-http-stream.c
index e9bad5d1a4..53c0241a2b 100644
--- a/camel/camel-http-stream.c
+++ b/camel/camel-http-stream.c
@@ -30,7 +30,6 @@
#include <ctype.h>
#include <errno.h>
-#include "camel-net-utils.h"
#include "camel-http-stream.h"
#include "camel-mime-utils.h"
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c
index 510d07f019..8fe1cc240f 100644
--- a/camel/camel-mime-utils.c
+++ b/camel/camel-mime-utils.c
@@ -45,12 +45,12 @@
#endif
#include <glib.h>
-#include <libedataserver/e-iconv.h>
-#include <libedataserver/e-time-utils.h>
+#include <gal/util/e-iconv.h>
+#include <e-util/e-time-utils.h>
#include "camel-mime-utils.h"
#include "camel-charset-map.h"
-#include "camel-net-utils.h"
+#include "camel-service.h" /* for camel_gethostbyname() */
#include "camel-utf8.h"
#ifndef CLEAN_DATE
diff --git a/camel/camel-movemail.c b/camel/camel-movemail.c
index 619d3dc33a..9684bf25e6 100644
--- a/camel/camel-movemail.c
+++ b/camel/camel-movemail.c
@@ -42,11 +42,12 @@
#include "camel-movemail.h"
#include "camel-exception.h"
+
#include "camel-mime-parser.h"
#include "camel-mime-filter.h"
#include "camel-mime-filter-from.h"
+
#include "camel-lock-client.h"
-#include "camel-i18n.h"
#define d(x)
diff --git a/camel/camel-multipart-signed.c b/camel/camel-multipart-signed.c
index ebd5d275e4..26d3b04993 100644
--- a/camel/camel-multipart-signed.c
+++ b/camel/camel-multipart-signed.c
@@ -43,13 +43,12 @@
#include "camel-multipart-signed.h"
#include "camel-mime-part.h"
#include "camel-exception.h"
-#include "libedataserver/md5-utils.h"
+#include "md5-utils.h"
#include "camel-stream-filter.h"
#include "camel-seekable-substream.h"
#include "camel-mime-filter-crlf.h"
#include "camel-mime-filter-canon.h"
-#include "camel-i18n.h"
#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))
#include <stdio.h>;*/
@@ -541,6 +540,124 @@ write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
return total;
}
+/* See rfc3156, section 2 and others */
+/* We do this simply: Anything not base64 must be qp
+ This is so that we can safely translate any occurance of "From "
+ into the quoted-printable escaped version safely. */
+static void
+prepare_sign(CamelMimePart *mime_part)
+{
+ CamelDataWrapper *wrapper;
+ CamelTransferEncoding encoding;
+ int parts, i;
+
+ wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part));
+ if (!wrapper)
+ return;
+
+ if (CAMEL_IS_MULTIPART (wrapper)) {
+ parts = camel_multipart_get_number((CamelMultipart *)wrapper);
+ for (i = 0; i < parts; i++)
+ prepare_sign(camel_multipart_get_part((CamelMultipart *)wrapper, i));
+ } else if (CAMEL_IS_MIME_MESSAGE (wrapper)) {
+ prepare_sign((CamelMimePart *)wrapper);
+ } else {
+ encoding = camel_mime_part_get_encoding(mime_part);
+
+ if (encoding != CAMEL_TRANSFER_ENCODING_BASE64
+ && encoding != CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE) {
+ camel_mime_part_set_encoding(mime_part, CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE);
+ }
+ }
+}
+
+/**
+ * camel_multipart_signed_sign:
+ * @mps:
+ * @context: The CipherContext to use for signing.
+ * @content: CamelMimePart content you wish to sign/transport.
+ * @userid: The id of the signing key to use.
+ * @hash: The algorithm to use.
+ * @ex:
+ *
+ * Sign the part @content, and attach it as the first part
+ * (CAMEL_MULTIPART_SIGNED_CONTENT) of the multipart @mps. A
+ * signature object will be created and setup as the second part
+ * (CAMEL_MULTIPART_SIGNED_SIGNATURE) of the object. Once a part has
+ * been successfully signed the mutlipart is ready for transmission.
+ *
+ * This method should be used to create multipart/signed objects
+ * which are properly canoncalised before signing, etc.
+ *
+ * Return value: -1 on error, setting @ex appropriately. On error
+ * neither the content or signature parts will be setup.
+ **/
+int
+camel_multipart_signed_sign(CamelMultipartSigned *mps, CamelCipherContext *context, CamelMimePart *content, const char *userid, CamelCipherHash hash, CamelException *ex)
+{
+ abort();
+#if 0
+ CamelMimeFilter *canon_filter;
+ CamelStream *mem;
+ CamelStreamFilter *filter;
+ CamelContentType *mime_type;
+ CamelMimePart *sigpart;
+
+ /* this needs to be set */
+ g_return_val_if_fail(context->sign_protocol != NULL, -1);
+
+ prepare_sign(content);
+
+ mem = camel_stream_mem_new();
+ filter = camel_stream_filter_new_with_stream(mem);
+
+ /* Note: see rfc2015 or rfc3156, section 5 */
+ canon_filter = camel_mime_filter_canon_new(CAMEL_MIME_FILTER_CANON_STRIP|CAMEL_MIME_FILTER_CANON_CRLF|CAMEL_MIME_FILTER_CANON_FROM);
+ camel_stream_filter_add(filter, (CamelMimeFilter *)canon_filter);
+ camel_object_unref((CamelObject *)canon_filter);
+
+ camel_data_wrapper_write_to_stream((CamelDataWrapper *)content, (CamelStream *)filter);
+ camel_stream_flush((CamelStream *)filter);
+ camel_object_unref((CamelObject *)filter);
+ camel_stream_reset(mem);
+
+#if 0
+ printf("-- Signing:\n");
+ fwrite(((CamelStreamMem *)mem)->buffer->data, ((CamelStreamMem *)mem)->buffer->len, 1, stdout);
+ printf("-- end\n");
+#endif
+
+ sigpart = camel_mime_part_new();
+
+ if (camel_cipher_sign(context, userid, hash, mem, sigpart, ex) == -1) {
+ camel_object_unref(mem);
+ camel_object_unref(sigpart);
+ return -1;
+ }
+
+ /* setup our mime type and boundary */
+ mime_type = camel_content_type_new("multipart", "signed");
+ camel_content_type_set_param(mime_type, "micalg", camel_cipher_hash_to_id(context, hash));
+ camel_content_type_set_param(mime_type, "protocol", context->sign_protocol);
+ camel_data_wrapper_set_mime_type_field(CAMEL_DATA_WRAPPER (mps), mime_type);
+ camel_content_type_unref(mime_type);
+ camel_multipart_set_boundary((CamelMultipart *)mps, NULL);
+
+ /* just keep the whole raw content. We dont *really* need to do this because
+ we know how we just proccessed it, but, well, better to be safe than sorry */
+ mps->signature = sigpart;
+ mps->contentraw = mem;
+ camel_stream_reset(mem);
+
+ /* clear the data-wrapper stream - tells write_to_stream to use the right object */
+ if (((CamelDataWrapper *)mps)->stream) {
+ camel_object_unref((CamelObject *) ((CamelDataWrapper *)mps)->stream);
+ ((CamelDataWrapper *)mps)->stream = NULL;
+ }
+#endif
+ return 0;
+}
+
CamelStream *
camel_multipart_signed_get_content_stream(CamelMultipartSigned *mps, CamelException *ex)
{
@@ -573,3 +690,77 @@ camel_multipart_signed_get_content_stream(CamelMultipartSigned *mps, CamelExcept
return constream;
}
+
+/**
+ * camel_multipart_signed_verify:
+ * @mps:
+ * @context:
+ * @ex:
+ *
+ * Verify a signed object. This may be used to verify newly signed
+ * objects as well as those created from external streams or parsers.
+ *
+ * Return value: A validity value, or NULL on error, setting @ex
+ * appropriately.
+ **/
+CamelCipherValidity *
+camel_multipart_signed_verify(CamelMultipartSigned *mps, CamelCipherContext *context, CamelException *ex)
+{
+ abort();
+
+ return NULL;
+#if 0
+ CamelCipherValidity *valid;
+ CamelMimePart *sigpart;
+ CamelStream *constream;
+
+ /* we need to be able to verify stuff we just signed as well as stuff we loaded from a stream/parser */
+
+ if (mps->contentraw) {
+ constream = mps->contentraw;
+ camel_object_ref((CamelObject *)constream);
+ } else {
+ CamelStream *sub;
+ CamelMimeFilter *canon_filter;
+
+ if (mps->start1 == -1 && parse_content(mps) == -1) {
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("parse error"));
+ return NULL;
+ }
+
+ /* first, prepare our parts */
+ sub = camel_seekable_substream_new((CamelSeekableStream *)((CamelDataWrapper *)mps)->stream, mps->start1, mps->end1);
+ constream = (CamelStream *)camel_stream_filter_new_with_stream(sub);
+ camel_object_unref((CamelObject *)sub);
+
+ /* Note: see rfc2015 or rfc3156, section 5 */
+ canon_filter = camel_mime_filter_canon_new (CAMEL_MIME_FILTER_CANON_CRLF);
+ camel_stream_filter_add((CamelStreamFilter *)constream, (CamelMimeFilter *)canon_filter);
+ camel_object_unref((CamelObject *)canon_filter);
+ }
+
+ /* we do this as a normal mime part so we can have it handle transfer encoding etc */
+ sigpart = camel_multipart_get_part((CamelMultipart *)mps, CAMEL_MULTIPART_SIGNED_SIGNATURE);
+
+ /* do the magic, the caller must supply the right context for this kind of object */
+ valid = camel_cipher_verify(context, camel_cipher_id_to_hash(context, mps->micalg), constream, sigpart, ex);
+
+#if 0
+ {
+ CamelStream *sout = camel_stream_fs_new_with_fd(dup(0));
+
+ camel_stream_printf(sout, "-- Verifying:\n");
+ camel_stream_reset(constream);
+ camel_stream_write_to_stream(constream, sout);
+ camel_stream_printf(sout, "-- end\n");
+ camel_object_unref((CamelObject *)sout);
+ }
+#endif
+
+ camel_object_unref(constream);
+
+ return valid;
+#endif
+}
+
+
diff --git a/camel/camel-operation.c b/camel/camel-operation.c
index 1234163eef..406d576597 100644
--- a/camel/camel-operation.c
+++ b/camel/camel-operation.c
@@ -36,7 +36,7 @@
#endif
#include "camel-operation.h"
-#include "libedataserver/e-msgport.h"
+#include "e-util/e-msgport.h"
#define d(x)
diff --git a/camel/camel-sasl-digest-md5.c b/camel/camel-sasl-digest-md5.c
index 2a38858dd4..47b3339520 100644
--- a/camel/camel-sasl-digest-md5.c
+++ b/camel/camel-sasl-digest-md5.c
@@ -20,6 +20,7 @@
*
*/
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -29,15 +30,13 @@
#include <ctype.h>
#include <unistd.h>
-#include <libedataserver/md5-utils.h>
+#include <e-util/md5-utils.h>
-#include <libedataserver/e-iconv.h>
+#include <gal/util/e-iconv.h>
#include "camel-charset-map.h"
#include "camel-mime-utils.h"
#include "camel-sasl-digest-md5.h"
-#include "camel-i18n.h"
-#include "camel-net-utils.h"
#define d(x)
diff --git a/camel/camel-sasl-gssapi.c b/camel/camel-sasl-gssapi.c
index e4fa002d5c..1efbefee16 100644
--- a/camel/camel-sasl-gssapi.c
+++ b/camel/camel-sasl-gssapi.c
@@ -46,7 +46,6 @@
#define GSS_C_OID_KRBV5_DES GSS_C_NO_OID
#endif
-#include "camel-i18n.h"
#include "camel-sasl-gssapi.h"
CamelServiceAuthType camel_sasl_gssapi_authtype = {
@@ -205,6 +204,7 @@ gssapi_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex)
gss_buffer_desc inbuf, outbuf;
GByteArray *challenge = NULL;
gss_buffer_t input_token;
+ struct hostent *h;
int conf_state;
gss_qop_t qop;
gss_OID mech;
diff --git a/camel/camel-sasl-kerberos4.c b/camel/camel-sasl-kerberos4.c
index 457f3e9afd..fd366e61db 100644
--- a/camel/camel-sasl-kerberos4.c
+++ b/camel/camel-sasl-kerberos4.c
@@ -33,7 +33,6 @@
#undef _
#include <string.h>
-#include "camel-i18n.h"
#include "camel-string-utils.h"
#include "camel-sasl-kerberos4.h"
#include "camel-service.h"
diff --git a/camel/camel-service.c b/camel/camel-service.c
index 6e79a86363..13190844e6 100644
--- a/camel/camel-service.c
+++ b/camel/camel-service.c
@@ -32,18 +32,20 @@
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
+#include <netdb.h>
#include <errno.h>
#include <sys/poll.h>
-#include "libedataserver/e-msgport.h"
+#include "e-util/e-msgport.h"
+
+#include "e-util/e-host-utils.h"
#include "camel-service.h"
#include "camel-session.h"
#include "camel-exception.h"
#include "camel-operation.h"
#include "camel-private.h"
-#include "camel-i18n.h"
#define d(x)
#define w(x)
@@ -642,3 +644,417 @@ camel_service_query_auth_types (CamelService *service, CamelException *ex)
return ret;
}
+
+/* ********************************************************************** */
+struct _addrinfo_msg {
+ EMsg msg;
+ unsigned int cancelled:1;
+
+ /* for host lookup */
+ const char *name;
+ const char *service;
+ int result;
+ const struct addrinfo *hints;
+ struct addrinfo **res;
+
+ /* for host lookup emulation */
+#ifdef NEED_ADDRINFO
+ struct hostent hostbuf;
+ int hostbuflen;
+ char *hostbufmem;
+#endif
+
+ /* for name lookup */
+ const struct sockaddr *addr;
+ socklen_t addrlen;
+ char *host;
+ int hostlen;
+ char *serv;
+ int servlen;
+ int flags;
+};
+
+static void
+cs_freeinfo(struct _addrinfo_msg *msg)
+{
+ g_free(msg->host);
+ g_free(msg->serv);
+#ifdef NEED_ADDRINFO
+ g_free(msg->hostbufmem);
+#endif
+ g_free(msg);
+}
+
+/* returns -1 if cancelled */
+static int
+cs_waitinfo(void *(worker)(void *), struct _addrinfo_msg *msg, const char *error, CamelException *ex)
+{
+ EMsgPort *reply_port;
+ pthread_t id;
+ int err, cancel_fd, cancel = 0, fd;
+
+ cancel_fd = camel_operation_cancel_fd(NULL);
+ if (cancel_fd == -1) {
+ worker(msg);
+ return 0;
+ }
+
+ reply_port = msg->msg.reply_port = e_msgport_new();
+ fd = e_msgport_fd(msg->msg.reply_port);
+ if ((err = pthread_create(&id, NULL, worker, msg)) == 0) {
+ struct pollfd polls[2];
+ int status;
+
+ polls[0].fd = fd;
+ polls[0].events = POLLIN;
+ polls[1].fd = cancel_fd;
+ polls[1].events = POLLIN;
+
+ d(printf("waiting for name return/cancellation in main process\n"));
+ do {
+ polls[0].revents = 0;
+ polls[1].revents = 0;
+ status = poll(polls, 2, -1);
+ } while (status == -1 && errno == EINTR);
+
+ if (status == -1 || (polls[1].revents & POLLIN)) {
+ if (status == -1)
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, "%s: %s", error, g_strerror(errno));
+ else
+ camel_exception_setv(ex, CAMEL_EXCEPTION_USER_CANCEL, _("Cancelled"));
+
+ /* We cancel so if the thread impl is decent it causes immediate exit.
+ We detach so we dont need to wait for it to exit if it isn't.
+ We check the reply port incase we had a reply in the mean time, which we free later */
+ d(printf("Cancelling lookup thread and leaving it\n"));
+ msg->cancelled = 1;
+ pthread_detach(id);
+ pthread_cancel(id);
+ cancel = 1;
+ } else {
+ struct _addrinfo_msg *reply = (struct _addrinfo_msg *)e_msgport_get(reply_port);
+
+ g_assert(reply == msg);
+ d(printf("waiting for child to exit\n"));
+ pthread_join(id, NULL);
+ d(printf("child done\n"));
+ }
+ } else {
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, "%s: %s: %s", error, _("cannot create thread"), g_strerror(err));
+ }
+ e_msgport_destroy(reply_port);
+
+ return cancel;
+}
+
+#ifdef NEED_ADDRINFO
+static void *
+cs_getaddrinfo(void *data)
+{
+ struct _addrinfo_msg *msg = data;
+ int herr;
+ struct hostent h;
+ struct addrinfo *res, *last = NULL;
+ struct sockaddr_in *sin;
+ in_port_t port = 0;
+ int i;
+
+ /* This is a pretty simplistic emulation of getaddrinfo */
+
+ while ((msg->result = e_gethostbyname_r(msg->name, &h, msg->hostbufmem, msg->hostbuflen, &herr)) == ERANGE) {
+ pthread_testcancel();
+ msg->hostbuflen *= 2;
+ msg->hostbufmem = g_realloc(msg->hostbufmem, msg->hostbuflen);
+ }
+
+ /* If we got cancelled, dont reply, just free it */
+ if (msg->cancelled)
+ goto cancel;
+
+ /* FIXME: map error numbers across */
+ if (msg->result != 0)
+ goto reply;
+
+ /* check hints matched */
+ if (msg->hints && msg->hints->ai_family && msg->hints->ai_family != h.h_addrtype) {
+ msg->result = EAI_FAMILY;
+ goto reply;
+ }
+
+ /* we only support ipv4 for this interface, even if it could supply ipv6 */
+ if (h.h_addrtype != AF_INET) {
+ msg->result = EAI_FAMILY;
+ goto reply;
+ }
+
+ /* check service mapping */
+ if (msg->service) {
+ const char *p = msg->service;
+
+ while (*p) {
+ if (*p < '0' || *p > '9')
+ break;
+ p++;
+ }
+
+ if (*p) {
+ const char *socktype = NULL;
+ struct servent *serv;
+
+ if (msg->hints && msg->hints->ai_socktype) {
+ if (msg->hints->ai_socktype == SOCK_STREAM)
+ socktype = "tcp";
+ else if (msg->hints->ai_socktype == SOCK_DGRAM)
+ socktype = "udp";
+ }
+
+ serv = getservbyname(msg->service, socktype);
+ if (serv == NULL) {
+ msg->result = EAI_NONAME;
+ goto reply;
+ }
+ port = serv->s_port;
+ } else {
+ port = htons(strtoul(msg->service, NULL, 10));
+ }
+ }
+
+ for (i=0;h.h_addr_list[i];i++) {
+ res = g_malloc0(sizeof(*res));
+ if (msg->hints) {
+ res->ai_flags = msg->hints->ai_flags;
+ if (msg->hints->ai_flags & AI_CANONNAME)
+ res->ai_canonname = g_strdup(h.h_name);
+ res->ai_socktype = msg->hints->ai_socktype;
+ res->ai_protocol = msg->hints->ai_protocol;
+ } else {
+ res->ai_flags = 0;
+ res->ai_socktype = SOCK_STREAM; /* fudge */
+ res->ai_protocol = 0; /* fudge */
+ }
+ res->ai_family = AF_INET;
+ res->ai_addrlen = sizeof(*sin);
+ res->ai_addr = g_malloc(sizeof(*sin));
+ sin = (struct sockaddr_in *)res->ai_addr;
+ sin->sin_family = AF_INET;
+ sin->sin_port = port;
+ memcpy(&sin->sin_addr, h.h_addr_list[i], sizeof(sin->sin_addr));
+
+ if (last == NULL) {
+ *msg->res = last = res;
+ } else {
+ last->ai_next = res;
+ last = res;
+ }
+ }
+reply:
+ e_msgport_reply((EMsg *)msg);
+ return NULL;
+cancel:
+ cs_freeinfo(msg);
+ return NULL;
+}
+#else
+static void *
+cs_getaddrinfo(void *data)
+{
+ struct _addrinfo_msg *info = data;
+
+ info->result = getaddrinfo(info->name, info->service, info->hints, info->res);
+
+ if (info->cancelled) {
+ g_free(info);
+ } else {
+ e_msgport_reply((EMsg *)info);
+ }
+
+ return NULL;
+}
+#endif /* NEED_ADDRINFO */
+
+struct addrinfo *
+camel_getaddrinfo(const char *name, const char *service, const struct addrinfo *hints, CamelException *ex)
+{
+ struct _addrinfo_msg *msg;
+ struct addrinfo *res = NULL;
+#ifndef ENABLE_IPv6
+ struct addrinfo myhints;
+#endif
+ g_return_val_if_fail(name != NULL, NULL);
+
+ if (camel_operation_cancel_check(NULL)) {
+ camel_exception_set(ex, CAMEL_EXCEPTION_USER_CANCEL, _("Cancelled"));
+ return NULL;
+ }
+
+ camel_operation_start_transient(NULL, _("Resolving: %s"), name);
+
+ /* force ipv4 addresses only */
+#ifndef ENABLE_IPv6
+ if (hints == NULL)
+ memset(&myhints, 0, sizeof(myhints));
+ else
+ memcpy (&myhints, hints, sizeof (myhints));
+
+ myhints.ai_family = AF_INET;
+ hints = &myhints;
+#endif
+
+ msg = g_malloc0(sizeof(*msg));
+ msg->name = name;
+ msg->service = service;
+ msg->hints = hints;
+ msg->res = &res;
+#ifdef NEED_ADDRINFO
+ msg->hostbuflen = 1024;
+ msg->hostbufmem = g_malloc(msg->hostbuflen);
+#endif
+ if (cs_waitinfo(cs_getaddrinfo, msg, _("Host lookup failed"), ex) == 0) {
+ if (msg->result != 0)
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Host lookup failed: %s: %s"),
+ name, gai_strerror (msg->result));
+
+ cs_freeinfo(msg);
+ } else
+ res = NULL;
+
+ camel_operation_end(NULL);
+
+ return res;
+}
+
+void
+camel_freeaddrinfo(struct addrinfo *host)
+{
+#ifdef NEED_ADDRINFO
+ while (host) {
+ struct addrinfo *next = host->ai_next;
+
+ g_free(host->ai_canonname);
+ g_free(host->ai_addr);
+ g_free(host);
+ host = next;
+ }
+#else
+ freeaddrinfo(host);
+#endif
+}
+
+#ifdef NEED_ADDRINFO
+static void *
+cs_getnameinfo(void *data)
+{
+ struct _addrinfo_msg *msg = data;
+ int herr;
+ struct hostent h;
+ struct sockaddr_in *sin = (struct sockaddr_in *)msg->addr;
+
+ /* FIXME: error code */
+ if (msg->addr->sa_family != AF_INET) {
+ msg->result = -1;
+ return NULL;
+ }
+
+ /* FIXME: honour getnameinfo flags: do we care, not really */
+
+ while ((msg->result = e_gethostbyaddr_r((const char *)&sin->sin_addr, sizeof(sin->sin_addr), AF_INET, &h,
+ msg->hostbufmem, msg->hostbuflen, &herr)) == ERANGE) {
+ pthread_testcancel ();
+ msg->hostbuflen *= 2;
+ msg->hostbufmem = g_realloc(msg->hostbufmem, msg->hostbuflen);
+ }
+
+ if (msg->cancelled)
+ goto cancel;
+
+ if (msg->host) {
+ g_free(msg->host);
+ if (msg->result == 0 && h.h_name && h.h_name[0]) {
+ msg->host = g_strdup(h.h_name);
+ } else {
+ unsigned char *in = (unsigned char *)&sin->sin_addr;
+
+ /* sin_addr is always network order which is big-endian */
+ msg->host = g_strdup_printf("%u.%u.%u.%u", in[0], in[1], in[2], in[3]);
+ }
+ }
+
+ /* we never actually use this anyway */
+ if (msg->serv)
+ sprintf(msg->serv, "%d", sin->sin_port);
+
+ e_msgport_reply((EMsg *)msg);
+ return NULL;
+cancel:
+ cs_freeinfo(msg);
+ return NULL;
+}
+#else
+static void *
+cs_getnameinfo(void *data)
+{
+ struct _addrinfo_msg *msg = data;
+
+ /* there doens't appear to be a return code which says host or serv buffers are too short, lengthen them */
+ msg->result = getnameinfo(msg->addr, msg->addrlen, msg->host, msg->hostlen, msg->serv, msg->servlen, msg->flags);
+
+ if (msg->cancelled)
+ cs_freeinfo(msg);
+ else
+ e_msgport_reply((EMsg *)msg);
+
+ return NULL;
+}
+#endif
+
+int
+camel_getnameinfo(const struct sockaddr *sa, socklen_t salen, char **host, char **serv, int flags, CamelException *ex)
+{
+ struct _addrinfo_msg *msg;
+ int result;
+
+ if (camel_operation_cancel_check(NULL)) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, _("Cancelled"));
+ return -1;
+ }
+
+ camel_operation_start_transient(NULL, _("Resolving address"));
+
+ msg = g_malloc0(sizeof(*msg));
+ msg->addr = sa;
+ msg->addrlen = salen;
+ if (host) {
+ msg->hostlen = NI_MAXHOST;
+ msg->host = g_malloc(msg->hostlen);
+ msg->host[0] = 0;
+ }
+ if (serv) {
+ msg->servlen = NI_MAXSERV;
+ msg->serv = g_malloc(msg->servlen);
+ msg->serv[0] = 0;
+ }
+ msg->flags = flags;
+#ifdef NEED_ADDRINFO
+ msg->hostbuflen = 1024;
+ msg->hostbufmem = g_malloc(msg->hostbuflen);
+#endif
+ cs_waitinfo(cs_getnameinfo, msg, _("Name lookup failed"), ex);
+
+ if ((result = msg->result) != 0)
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Name lookup failed: %s"),
+ gai_strerror (result));
+
+ if (host)
+ *host = g_strdup(msg->host);
+ if (serv)
+ *serv = g_strdup(msg->serv);
+
+ g_free(msg->host);
+ g_free(msg->serv);
+ g_free(msg);
+
+ camel_operation_end(NULL);
+
+ return result;
+}
+
diff --git a/camel/camel-service.h b/camel/camel-service.h
index 8180b2a05e..f49472cc5a 100644
--- a/camel/camel-service.h
+++ b/camel/camel-service.h
@@ -1,9 +1,10 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* camel-service.h : Abstract class for an email service */
+
/*
*
- * Authors: Bertrand Guiheneuf <bertrand@helixcode.com>
- * Michael Zucchi <notzed@ximian.com>
+ * Author :
+ * Bertrand Guiheneuf <bertrand@helixcode.com>
*
* Copyright 1999, 2000 Ximian, Inc. (www.ximian.com)
*
@@ -22,6 +23,7 @@
* USA
*/
+
#ifndef CAMEL_SERVICE_H
#define CAMEL_SERVICE_H 1
@@ -31,6 +33,7 @@ extern "C" {
#pragma }
#endif /* __cplusplus }*/
+#include <netdb.h>
#include <camel/camel-object.h>
#include <camel/camel-url.h>
#include <camel/camel-provider.h>
@@ -74,6 +77,7 @@ struct _CamelService {
CamelURL *url;
};
+
typedef struct {
CamelObjectClass parent_class;
@@ -99,6 +103,7 @@ typedef struct {
} CamelServiceClass;
+
/* query_auth_types returns a GList of these */
typedef struct {
char *name; /* user-friendly name */
@@ -108,6 +113,7 @@ typedef struct {
gboolean need_password; /* needs a password to authenticate */
} CamelServiceAuthType;
+
/* public methods */
void camel_service_construct (CamelService *service,
CamelSession *session,
@@ -129,6 +135,62 @@ CamelProvider * camel_service_get_provider (CamelService *service);
GList * camel_service_query_auth_types (CamelService *service,
CamelException *ex);
+#ifdef NEED_ADDRINFO
+/* Some of this is copied from GNU's netdb.h
+
+ Copyright (C) 1996-2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library 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.1 of the License, or (at your option) any later version.
+*/
+struct addrinfo {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ size_t ai_addrlen;
+ struct sockaddr *ai_addr;
+ char *ai_canonname;
+ struct addrinfo *ai_next;
+};
+
+#define AI_CANONNAME 0x0002 /* Request for canonical name. */
+#define AI_NUMERICHOST 0x0004 /* Don't use name resolution. */
+
+/* Error values for `getaddrinfo' function. */
+#define EAI_BADFLAGS -1 /* Invalid value for `ai_flags' field. */
+#define EAI_NONAME -2 /* NAME or SERVICE is unknown. */
+#define EAI_AGAIN -3 /* Temporary failure in name resolution. */
+#define EAI_FAIL -4 /* Non-recoverable failure in name res. */
+#define EAI_NODATA -5 /* No address associated with NAME. */
+#define EAI_FAMILY -6 /* `ai_family' not supported. */
+#define EAI_SOCKTYPE -7 /* `ai_socktype' not supported. */
+#define EAI_SERVICE -8 /* SERVICE not supported for `ai_socktype'. */
+#define EAI_ADDRFAMILY -9 /* Address family for NAME not supported. */
+#define EAI_MEMORY -10 /* Memory allocation failure. */
+#define EAI_SYSTEM -11 /* System error returned in `errno'. */
+#define EAI_OVERFLOW -12 /* Argument buffer overflow. */
+
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
+
+#define NI_NUMERICHOST 1 /* Don't try to look up hostname. */
+#define NI_NUMERICSERV 2 /* Don't convert port number to name. */
+#define NI_NOFQDN 4 /* Only return nodename portion. */
+#define NI_NAMEREQD 8 /* Don't return numeric addresses. */
+#define NI_DGRAM 16 /* Look up UDP service rather than TCP. */
+#endif
+
+/* new hostname interfaces */
+struct addrinfo *camel_getaddrinfo(const char *name, const char *service,
+ const struct addrinfo *hints, CamelException *ex);
+void camel_freeaddrinfo(struct addrinfo *host);
+int camel_getnameinfo(const struct sockaddr *sa, socklen_t salen, char **host, char **serv,
+ int flags, CamelException *ex);
+
/* Standard Camel function */
CamelType camel_service_get_type (void);
diff --git a/camel/camel-smime-context.c b/camel/camel-smime-context.c
index 9e5cc241dc..80b10081a5 100644
--- a/camel/camel-smime-context.c
+++ b/camel/camel-smime-context.c
@@ -56,7 +56,6 @@
#include "camel-smime-context.h"
#include "camel-operation.h"
-#include "camel-i18n.h"
#define d(x)
@@ -239,13 +238,13 @@ sm_signing_cmsmessage(CamelSMIMEContext *context, const char *nick, SECOidTag ha
}
if ((sigd = NSS_CMSSignedData_Create(cmsg)) == NULL) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create CMS signed data"));
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create CMS signedData"));
goto fail;
}
cinfo = NSS_CMSMessage_GetContentInfo(cmsg);
if (NSS_CMSContentInfo_SetContent_SignedData(cmsg, cinfo, sigd) != SECSuccess) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach CMS signed data"));
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach CMS signedData"));
goto fail;
}
@@ -258,19 +257,19 @@ sm_signing_cmsmessage(CamelSMIMEContext *context, const char *nick, SECOidTag ha
signerinfo = NSS_CMSSignerInfo_Create(cmsg, cert, hash);
if (signerinfo == NULL) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create CMS Signer information"));
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create CMS SignerInfo"));
goto fail;
}
/* we want the cert chain included for this one */
if (NSS_CMSSignerInfo_IncludeCerts(signerinfo, NSSCMSCM_CertChain, certUsageEmailSigner) != SECSuccess) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot find certificate chain"));
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot find cert chain"));
goto fail;
}
/* SMIME RFC says signing time should always be added */
if (NSS_CMSSignerInfo_AddSigningTime(signerinfo, PR_Now()) != SECSuccess) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot add CMS Signing time"));
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot add CMS SigningTime"));
goto fail;
}
@@ -292,7 +291,7 @@ sm_signing_cmsmessage(CamelSMIMEContext *context, const char *nick, SECOidTag ha
p->certdb,
p->encrypt_key,
certUsageEmailRecipient, PR_FALSE, NULL)) == NULL) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Encryption certificate for '%s' does not exist"), p->encrypt_key);
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Encryption cert for '%s' does not exist"), p->encrypt_key);
goto fail;
}
enccert = ekpcert;
@@ -304,7 +303,7 @@ sm_signing_cmsmessage(CamelSMIMEContext *context, const char *nick, SECOidTag ha
if ((ekpcert = CERT_FindUserCertByUsage(
p->certdb, (char *)nick,
certUsageEmailRecipient, PR_FALSE, NULL)) == NULL) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Encryption certificate for '%s' does not exist"), nick);
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Encryption cert for '%s' does not exist"), nick);
goto fail;
}
enccert = ekpcert;
@@ -327,7 +326,7 @@ sm_signing_cmsmessage(CamelSMIMEContext *context, const char *nick, SECOidTag ha
}
if (NSS_CMSSignedData_AddSignerInfo(sigd, signerinfo) != SECSuccess) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot add CMS Signer information"));
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot add CMS SignerInfo"));
goto fail;
}
@@ -536,7 +535,7 @@ sm_verify_cmsg(CamelCipherContext *context, NSSCMSMessage *cmsg, CamelStream *ex
case SEC_OID_PKCS7_SIGNED_DATA:
sigd = (NSSCMSSignedData *)NSS_CMSContentInfo_GetContent(cinfo);
if (sigd == NULL) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("No signed data in signature"));
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("No signedData in signature"));
goto fail;
}
@@ -593,13 +592,12 @@ sm_verify_cmsg(CamelCipherContext *context, NSSCMSMessage *cmsg, CamelStream *ex
/* check for certs-only message */
nsigners = NSS_CMSSignedData_SignerInfoCount(sigd);
if (nsigners == 0) {
-
/* already imported certs above, not sure what usage we should use here or if this isn't handled above */
if (NSS_CMSSignedData_VerifyCertsOnly(sigd, p->certdb, certUsageEmailSigner) != SECSuccess) {
- g_string_printf(description, _("Certificate is the only message, cannot verify certificates"));
+ g_string_printf(description, _("Certificate only message, cannot verify certificates"));
} else {
status = NSSCMSVS_GoodSignature;
- g_string_printf(description, _("Certificate is the only message, certificates imported and verified"));
+ g_string_printf(description, _("Certificate only message, certificates imported and verified"));
}
} else {
if (!NSS_CMSSignedData_HasDigests(sigd)) {
@@ -805,13 +803,13 @@ sm_encrypt(CamelCipherContext *context, const char *userid, GPtrArray *recipient
envd = NSS_CMSEnvelopedData_Create(cmsg, bulkalgtag, bulkkeysize);
if (envd == NULL) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create CMS Enveloped data"));
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create CMS EnvelopedData"));
goto fail;
}
cinfo = NSS_CMSMessage_GetContentInfo(cmsg);
if (NSS_CMSContentInfo_SetContent_EnvelopedData(cmsg, cinfo, envd) != SECSuccess) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach CMS Enveloped data"));
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach CMS EnvelopedData"));
goto fail;
}
@@ -826,12 +824,12 @@ sm_encrypt(CamelCipherContext *context, const char *userid, GPtrArray *recipient
NSSCMSRecipientInfo *ri = NSS_CMSRecipientInfo_Create(cmsg, recipient_certs[i]);
if (ri == NULL) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create CMS Recipient information"));
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create CMS RecipientInfo"));
goto fail;
}
if (NSS_CMSEnvelopedData_AddRecipient(envd, ri) != SECSuccess) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot add CMS Recipient information"));
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot add CMS RecipientInfo"));
goto fail;
}
}
diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c
index a818fbc8b4..39bf89d468 100644
--- a/camel/camel-tcp-stream-ssl.c
+++ b/camel/camel-tcp-stream-ssl.c
@@ -54,14 +54,13 @@
/* this is commented because otherwise we get an error about the
redefinition of MD5Context...yay */
-/*#include <libedataserver/md5-utils.h>*/
+/*#include <e-util/md5-utils.h>*/
#include "camel-tcp-stream-ssl.h"
#include "camel-stream-fs.h"
#include "camel-session.h"
#include "camel-certdb.h"
#include "camel-operation.h"
-#include "camel-i18n.h"
/* from md5-utils.h */
void md5_get_digest (const char *buffer, int buffer_size, unsigned char digest[16]);
diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c
index 47d0331be5..d7c29eefb4 100644
--- a/camel/camel-vee-folder.c
+++ b/camel/camel-vee-folder.c
@@ -30,20 +30,19 @@
#include "camel-exception.h"
#include "camel-vee-folder.h"
#include "camel-store.h"
+#include "camel-folder-summary.h"
#include "camel-mime-message.h"
#include "camel-folder-search.h"
-#include "camel-vee-summary.h"
#include "camel-session.h"
#include "camel-vee-store.h" /* for open flags */
#include "camel-private.h"
#include "camel-debug.h"
-#include "camel-i18n.h"
-#include "libedataserver/md5-utils.h"
+#include "e-util/md5-utils.h"
#if defined (DOEPOOLV) || defined (DOESTRV)
-#include "libedataserver/e-memory.h"
+#include "e-util/e-memory.h"
#endif
#define d(x)
@@ -51,7 +50,6 @@
#define _PRIVATE(o) (((CamelVeeFolder *)(o))->priv)
-#if 0
static void vee_refresh_info(CamelFolder *folder, CamelException *ex);
static void vee_sync (CamelFolder *folder, gboolean expunge, CamelException *ex);
@@ -67,19 +65,21 @@ static void vee_transfer_messages_to(CamelFolder *source, GPtrArray *uids, Camel
static GPtrArray *vee_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex);
static GPtrArray *vee_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex);
+static gboolean vee_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set);
+static void vee_set_message_user_flag (CamelFolder *folder, const char *uid, const char *name, gboolean value);
+static void vee_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value);
static void vee_rename(CamelFolder *folder, const char *new);
-#endif
static void camel_vee_folder_class_init (CamelVeeFolderClass *klass);
static void camel_vee_folder_init (CamelVeeFolder *obj);
static void camel_vee_folder_finalise (CamelObject *obj);
-static int vee_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex);
-static void vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source);
+static int vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex);
+static void vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun);
static void folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder *vf);
static void subfolder_deleted(CamelFolder *f, void *event_data, CamelVeeFolder *vf);
-static void folder_renamed(CamelFolder *f, const char *old, CamelVeeFolder *vf);
+static void subfolder_renamed(CamelFolder *f, void *event_data, CamelVeeFolder *vf);
static void folder_changed_remove_uid(CamelFolder *sub, const char *uid, const char hash[8], int keep, CamelVeeFolder *vf);
@@ -103,21 +103,120 @@ camel_vee_folder_get_type (void)
return type;
}
+static void
+camel_vee_folder_class_init (CamelVeeFolderClass *klass)
+{
+ CamelFolderClass *folder_class = (CamelFolderClass *) klass;
+
+ camel_vee_folder_parent = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs (camel_folder_get_type ()));
+
+ folder_class->refresh_info = vee_refresh_info;
+ folder_class->sync = vee_sync;
+ folder_class->expunge = vee_expunge;
+
+ folder_class->get_message = vee_get_message;
+ folder_class->append_message = vee_append_message;
+ folder_class->transfer_messages_to = vee_transfer_messages_to;
+
+ folder_class->search_by_expression = vee_search_by_expression;
+ folder_class->search_by_uids = vee_search_by_uids;
+
+ folder_class->set_message_flags = vee_set_message_flags;
+ folder_class->set_message_user_flag = vee_set_message_user_flag;
+ folder_class->set_message_user_tag = vee_set_message_user_tag;
+
+ folder_class->rename = vee_rename;
+
+ folder_class->freeze = vee_freeze;
+ folder_class->thaw = vee_thaw;
+}
+
+static void
+camel_vee_folder_init (CamelVeeFolder *obj)
+{
+ struct _CamelVeeFolderPrivate *p;
+ CamelFolder *folder = (CamelFolder *)obj;
+
+ p = _PRIVATE(obj) = g_malloc0(sizeof(*p));
+
+ folder->folder_flags |= (CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY |
+ CAMEL_FOLDER_HAS_SEARCH_CAPABILITY);
+
+ /* FIXME: what to do about user flags if the subfolder doesn't support them? */
+ folder->permanent_flags = CAMEL_MESSAGE_ANSWERED |
+ CAMEL_MESSAGE_DELETED |
+ CAMEL_MESSAGE_DRAFT |
+ CAMEL_MESSAGE_FLAGGED |
+ CAMEL_MESSAGE_SEEN;
+
+ obj->changes = camel_folder_change_info_new();
+ obj->search = camel_folder_search_new();
+
+ p->summary_lock = g_mutex_new();
+ p->subfolder_lock = g_mutex_new();
+ p->changed_lock = g_mutex_new();
+}
+
+static void
+camel_vee_folder_finalise (CamelObject *obj)
+{
+ CamelVeeFolder *vf = (CamelVeeFolder *)obj;
+ struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
+ GList *node;
+ CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
+
+ /* FIXME: check leaks */
+ node = p->folders;
+ while (node) {
+ CamelFolder *f = node->data;
+
+ if (vf != folder_unmatched) {
+ camel_object_unhook_event((CamelObject *)f, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf);
+ camel_object_unhook_event((CamelObject *)f, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf);
+ camel_object_unhook_event((CamelObject *)f, "renamed", (CamelObjectEventHookFunc) subfolder_renamed, vf);
+ /* this updates the vfolder */
+ if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0)
+ vee_folder_remove_folder(vf, f, FALSE);
+ }
+ camel_object_unref((CamelObject *)f);
+
+ node = g_list_next(node);
+ }
+
+ g_free(vf->expression);
+ g_free(vf->vname);
+
+ g_list_free(p->folders);
+ g_list_free(p->folders_changed);
+
+ camel_folder_change_info_free(vf->changes);
+ camel_object_unref((CamelObject *)vf->search);
+
+ g_mutex_free(p->summary_lock);
+ g_mutex_free(p->subfolder_lock);
+ g_mutex_free(p->changed_lock);
+
+ g_free(p);
+}
+
void
camel_vee_folder_construct (CamelVeeFolder *vf, CamelStore *parent_store, const char *name, guint32 flags)
{
CamelFolder *folder = (CamelFolder *)vf;
- const char *tmp;
+ char *tmp;
vf->flags = flags;
- tmp = strrchr(name, '/');
+ vf->vname = g_strdup(name);
+ tmp = strrchr(vf->vname, '/');
if (tmp)
tmp++;
else
- tmp = name;
- camel_folder_construct(folder, parent_store, name, tmp);
+ tmp = vf->vname;
+ camel_folder_construct(folder, parent_store, vf->vname, tmp);
- folder->summary = camel_vee_summary_new(folder);
+ /* should CamelVeeMessageInfo be subclassable ..? */
+ folder->summary = camel_folder_summary_new();
+ folder->summary->message_info_size = sizeof(CamelVeeMessageInfo);
if (CAMEL_IS_VEE_STORE(parent_store))
vf->parent_vee_store = (CamelVeeStore *)parent_store;
@@ -162,7 +261,38 @@ camel_vee_folder_new(CamelStore *parent_store, const char *name, guint32 flags)
void
camel_vee_folder_set_expression(CamelVeeFolder *vf, const char *query)
{
- ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->set_expression(vf, query);
+ struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
+ GList *node;
+
+ CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
+
+ /* no change, do nothing */
+ if ((vf->expression && query && strcmp(vf->expression, query) == 0)
+ || (vf->expression == NULL && query == NULL)) {
+ CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
+ return;
+ }
+
+ g_free(vf->expression);
+ if (query)
+ vf->expression = g_strdup(query);
+
+ node = p->folders;
+ while (node) {
+ CamelFolder *f = node->data;
+
+ if (vee_folder_build_folder(vf, f, NULL) == -1)
+ break;
+
+ node = node->next;
+ }
+
+ CAMEL_VEE_FOLDER_LOCK(vf, changed_lock);
+ g_list_free(p->folders_changed);
+ p->folders_changed = NULL;
+ CAMEL_VEE_FOLDER_UNLOCK(vf, changed_lock);
+
+ CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
}
/**
@@ -219,9 +349,9 @@ camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
camel_object_hook_event((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc)folder_changed, vf);
camel_object_hook_event((CamelObject *)sub, "deleted", (CamelObjectEventHookFunc)subfolder_deleted, vf);
- camel_object_hook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc)folder_renamed, vf);
+ camel_object_hook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc)subfolder_renamed, vf);
- ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->add_folder(vf, sub);
+ vee_folder_build_folder(vf, sub, NULL);
}
/**
@@ -235,6 +365,7 @@ void
camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
{
struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
+ int killun = FALSE;
int i;
CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
@@ -251,7 +382,7 @@ camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
camel_object_unhook_event((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf);
camel_object_unhook_event((CamelObject *)sub, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf);
- camel_object_unhook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc) folder_renamed, vf);
+ camel_object_unhook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc) subfolder_renamed, vf);
p->folders = g_list_remove(p->folders, sub);
@@ -270,6 +401,7 @@ camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
/* if folder deleted, then blow it away from unmatched always, and remove all refs to it */
if (sub->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED) {
while (g_list_find(up->folders, sub)) {
+ killun = TRUE;
up->folders = g_list_remove(up->folders, sub);
camel_object_unref((CamelObject *)sub);
@@ -290,29 +422,18 @@ camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
camel_folder_thaw(sub);
CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
}
+ if (g_list_find(up->folders, sub) == NULL) {
+ killun = TRUE;
+ }
}
CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, subfolder_lock);
}
- ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->remove_folder(vf, sub);
+ vee_folder_remove_folder(vf, sub, killun);
camel_object_unref((CamelObject *)sub);
}
-/**
- * camel_vee_folder_rebuild_folder:
- * @vf: Virtual Folder object
- * @sub: source CamelFolder to add to @vf
- * @ex: Exception.
- *
- * Rebuild the folder @sub, if it should be.
- **/
-int
-camel_vee_folder_rebuild_folder(CamelVeeFolder *vf, CamelFolder *sub, CamelException *ex)
-{
- return ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->rebuild_folder(vf, sub, ex);
-}
-
static void
remove_folders(CamelFolder *folder, CamelFolder *foldercopy, CamelVeeFolder *vf)
{
@@ -334,6 +455,7 @@ camel_vee_folder_set_folders(CamelVeeFolder *vf, GList *folders)
GHashTable *remove = g_hash_table_new(NULL, NULL);
GList *l;
CamelFolder *folder;
+ int changed;
/* setup a table of all folders we have currently */
CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
@@ -351,6 +473,15 @@ camel_vee_folder_set_folders(CamelVeeFolder *vf, GList *folders)
if ((folder = g_hash_table_lookup(remove, l->data))) {
g_hash_table_remove(remove, folder);
camel_object_unref((CamelObject *)folder);
+
+ /* if this was a changed folder, re-update it while we're here */
+ CAMEL_VEE_FOLDER_LOCK(vf, changed_lock);
+ changed = g_list_find(p->folders_changed, folder) != NULL;
+ if (changed)
+ p->folders_changed = g_list_remove(p->folders_changed, folder);
+ CAMEL_VEE_FOLDER_UNLOCK(vf, changed_lock);
+ if (changed)
+ vee_folder_build_folder(vf, folder, NULL);
} else {
camel_vee_folder_add_folder(vf, l->data);
}
@@ -409,25 +540,21 @@ camel_vee_folder_hash_folder(CamelFolder *folder, char buffer[8])
CamelFolder *
camel_vee_folder_get_location(CamelVeeFolder *vf, const CamelVeeMessageInfo *vinfo, char **realuid)
{
- CamelFolder *folder;
-
- folder = vinfo->real->summary->folder;
-
/* locking? yes? no? although the vfolderinfo is valid when obtained
the folder in it might not necessarily be so ...? */
- if (CAMEL_IS_VEE_FOLDER(folder)) {
- CamelFolder *res;
+ if (CAMEL_IS_VEE_FOLDER(vinfo->folder)) {
+ CamelFolder *folder;
const CamelVeeMessageInfo *vfinfo;
- vfinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info(folder, camel_message_info_uid(vinfo)+8);
- res = camel_vee_folder_get_location((CamelVeeFolder *)folder, vfinfo, realuid);
- camel_folder_free_message_info(folder, (CamelMessageInfo *)vfinfo);
- return res;
+ vfinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info(vinfo->folder, camel_message_info_uid(vinfo)+8);
+ folder = camel_vee_folder_get_location((CamelVeeFolder *)vinfo->folder, vfinfo, realuid);
+ camel_folder_free_message_info(vinfo->folder, (CamelMessageInfo *)vfinfo);
+ return folder;
} else {
if (realuid)
*realuid = g_strdup(camel_message_info_uid(vinfo)+8);
- return folder;
+ return vinfo->folder;
}
}
@@ -446,7 +573,7 @@ static void vee_refresh_info(CamelFolder *folder, CamelException *ex)
while (node) {
CamelFolder *f = node->data;
- if (camel_vee_folder_rebuild_folder(vf, f, ex) == -1)
+ if (vee_folder_build_folder(vf, f, ex) == -1)
break;
node = node->next;
@@ -479,7 +606,7 @@ vee_sync(CamelFolder *folder, gboolean expunge, CamelException *ex)
/* auto update vfolders shouldn't need a rebuild */
if ((vf->flags & CAMEL_STORE_VEE_FOLDER_AUTO) == 0
- && camel_vee_folder_rebuild_folder(vf, f, ex) == -1)
+ && vee_folder_build_folder(vf, f, ex) == -1)
break;
node = node->next;
@@ -511,8 +638,8 @@ vee_get_message(CamelFolder *folder, const char *uid, CamelException *ex)
mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
if (mi) {
- msg = camel_folder_get_message(mi->real->summary->folder, camel_message_info_uid(mi)+8, ex);
- camel_message_info_free((CamelMessageInfo *)mi);
+ msg = camel_folder_get_message(mi->folder, camel_message_info_uid(mi)+8, ex);
+ camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi);
} else {
camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
_("No such message %s in %s"), uid,
@@ -632,11 +759,53 @@ vee_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids,
CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
g_hash_table_destroy(searched);
- g_ptr_array_free(folder_uids, TRUE);
+ g_ptr_array_free(folder_uids, 0);
return result;
}
+static gboolean
+vee_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set)
+{
+ CamelVeeMessageInfo *mi;
+ int res = FALSE;
+
+ mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
+ if (mi) {
+ res = camel_folder_set_message_flags(mi->folder, camel_message_info_uid(mi) + 8, flags, set);
+ camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi);
+ res = res || ((CamelFolderClass *)camel_vee_folder_parent)->set_message_flags(folder, uid, flags, set);
+ }
+
+ return res;
+}
+
+static void
+vee_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value)
+{
+ CamelVeeMessageInfo *mi;
+
+ mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
+ if (mi) {
+ camel_folder_set_message_user_flag(mi->folder, camel_message_info_uid(mi) + 8, name, value);
+ camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi);
+ ((CamelFolderClass *)camel_vee_folder_parent)->set_message_user_flag(folder, uid, name, value);
+ }
+}
+
+static void
+vee_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value)
+{
+ CamelVeeMessageInfo *mi;
+
+ mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
+ if (mi) {
+ camel_folder_set_message_user_tag(mi->folder, camel_message_info_uid(mi) + 8, name, value);
+ camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi);
+ ((CamelFolderClass *)camel_vee_folder_parent)->set_message_user_tag(folder, uid, name, value);
+ }
+}
+
static void
vee_append_message(CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, char **appended_uid, CamelException *ex)
{
@@ -651,35 +820,56 @@ vee_transfer_messages_to (CamelFolder *folder, GPtrArray *uids, CamelFolder *des
static void vee_rename(CamelFolder *folder, const char *new)
{
- /*CamelVeeFolder *vf = (CamelVeeFolder *)folder;*/
+ CamelVeeFolder *vf = (CamelVeeFolder *)folder;
+
+ g_free(vf->vname);
+ vf->vname = g_strdup(new);
((CamelFolderClass *)camel_vee_folder_parent)->rename(folder, new);
}
-static void vee_delete(CamelFolder *folder)
-{
- struct _CamelVeeFolderPrivate *p = _PRIVATE(folder);
-
- /* NB: this is never called on UNMTACHED */
-
- CAMEL_VEE_FOLDER_LOCK(folder, subfolder_lock);
- while (p->folders) {
- CamelFolder *f = p->folders->data;
+/* ********************************************************************** *
+ utility functions */
- camel_object_ref(f);
- CAMEL_VEE_FOLDER_UNLOCK(folder, subfolder_lock);
+/* must be called with summary_lock held */
+static CamelVeeMessageInfo *
+vee_folder_add_info(CamelVeeFolder *vf, CamelFolder *f, CamelMessageInfo *info, const char hash[8])
+{
+ CamelVeeMessageInfo *mi;
+ char *vuid;
+ const char *uid;
+ CamelFolder *folder = (CamelFolder *)vf;
+ CamelMessageInfo *dinfo;
- camel_vee_folder_remove_folder((CamelVeeFolder *)folder, f);
- camel_object_unref(f);
- CAMEL_VEE_FOLDER_LOCK(folder, subfolder_lock);
+ uid = camel_message_info_uid(info);
+ vuid = alloca(strlen(uid)+9);
+ memcpy(vuid, hash, 8);
+ strcpy(vuid+8, uid);
+ dinfo = camel_folder_summary_uid(folder->summary, vuid);
+ if (dinfo) {
+ d(printf("w:clash, we already have '%s' in summary\n", vuid));
+ camel_folder_summary_info_free(folder->summary, dinfo);
+ return NULL;
}
- CAMEL_VEE_FOLDER_LOCK(folder, subfolder_lock);
- ((CamelFolderClass *)camel_vee_folder_parent)->delete(folder);
-}
+ d(printf("adding vuid %s to %s\n", vuid, vf->vname));
+
+ mi = (CamelVeeMessageInfo *)camel_folder_summary_info_new(folder->summary);
+ camel_message_info_dup_to(info, (CamelMessageInfo *)mi);
+#ifdef DOEPOOLV
+ mi->info.strings = e_poolv_set(mi->info.strings, CAMEL_MESSAGE_INFO_UID, vuid, FALSE);
+#elif defined (DOESTRV)
+ mi->info.strings = e_strv_set_ref(mi->info.strings, CAMEL_MESSAGE_INFO_UID, vuid);
+ mi->info.strings = e_strv_pack(mi->info.strings);
+#else
+ g_free(mi->info.uid);
+ mi->info.uid = g_strdup(vuid);
+#endif
+ mi->folder = f;
+ camel_folder_summary_add(folder->summary, (CamelMessageInfo *)mi);
-/* ********************************************************************** *
- utility functions */
+ return mi;
+}
/* must be called with summary_lock held */
static CamelVeeMessageInfo *
@@ -690,14 +880,14 @@ vee_folder_add_uid(CamelVeeFolder *vf, CamelFolder *f, const char *inuid, const
info = camel_folder_get_message_info(f, inuid);
if (info) {
- mi = camel_vee_summary_add((CamelVeeSummary *)((CamelFolder *)vf)->summary, info, hash);
+ mi = vee_folder_add_info(vf, f, info, hash);
camel_folder_free_message_info(f, info);
}
return mi;
}
static void
-vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source)
+vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
{
int i, count, n, still = FALSE, start, last;
char *oldkey;
@@ -708,15 +898,10 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source)
void *oldval;
CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
- CamelFolderSummary *ssummary = source->summary;
- int killun = FALSE;
-
+
if (vf == folder_unmatched)
return;
- if ((source->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED))
- killun = TRUE;
-
CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
if (folder_unmatched != NULL) {
@@ -739,7 +924,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source)
CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i);
if (mi) {
- if (mi->real->summary == ssummary) {
+ if (mi->folder == source) {
camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi));
if (last == -1) {
last = start = i;
@@ -751,7 +936,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source)
start = last = i;
}
}
- camel_message_info_free((CamelMessageInfo *)mi);
+ camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
}
}
if (last != -1)
@@ -765,7 +950,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source)
for (i=0;i<count;i++) {
CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(folder->summary, i);
if (mi) {
- if (mi->real->summary == ssummary) {
+ if (mi->folder == source) {
const char *uid = camel_message_info_uid(mi);
camel_folder_change_info_remove_uid(vf->changes, uid);
@@ -800,7 +985,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source)
}
}
}
- camel_message_info_free((CamelMessageInfo *)mi);
+ camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi);
}
}
@@ -860,7 +1045,7 @@ unmatched_check_uid(char *uidin, void *value, struct _update_data *u)
if (mi) {
camel_folder_summary_remove(((CamelFolder *)u->folder_unmatched)->summary, (CamelMessageInfo *)mi);
camel_folder_change_info_remove_uid(u->folder_unmatched->changes, uid);
- camel_message_info_free((CamelMessageInfo *)mi);
+ camel_folder_summary_info_free(((CamelFolder *)u->folder_unmatched)->summary, (CamelMessageInfo *)mi);
}
}
}
@@ -889,7 +1074,7 @@ folder_added_uid(char *uidin, void *value, struct _update_data *u)
/* build query contents for a single folder */
static int
-vee_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex)
+vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex)
{
GPtrArray *match, *all;
GHashTable *allhash, *matchhash;
@@ -900,7 +1085,6 @@ vee_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex)
CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
- CamelFolderSummary *ssummary = source->summary;
if (vf == folder_unmatched)
return 0;
@@ -945,7 +1129,7 @@ vee_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex)
CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(folder->summary, i);
if (mi) {
- if (mi->real->summary == ssummary) {
+ if (mi->folder == source) {
char *uid = (char *)camel_message_info_uid(mi), *oldkey;
void *oldval;
@@ -975,7 +1159,7 @@ vee_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex)
g_hash_table_remove(matchhash, uid+8);
}
}
- camel_message_info_free((CamelMessageInfo *)mi);
+ camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi);
}
}
if (last != -1)
@@ -991,7 +1175,7 @@ vee_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex)
CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i);
if (mi) {
- if (mi->real->summary == ssummary) {
+ if (mi->folder == source) {
char *uid = (char *)camel_message_info_uid(mi);
if (g_hash_table_lookup(allhash, uid+8) == NULL) {
@@ -1003,7 +1187,7 @@ vee_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex)
g_hash_table_remove(allhash, uid+8);
}
}
- camel_message_info_free((CamelMessageInfo *)mi);
+ camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
}
}
@@ -1110,7 +1294,7 @@ folder_changed_remove_uid(CamelFolder *sub, const char *uid, const char hash[8],
if (vinfo) {
camel_folder_change_info_remove_uid(vf->changes, vuid);
camel_folder_summary_remove(folder->summary, (CamelMessageInfo *)vinfo);
- camel_message_info_free((CamelMessageInfo *)vinfo);
+ camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
}
if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && folder_unmatched != NULL) {
@@ -1165,23 +1349,45 @@ folder_changed_change_uid(CamelFolder *sub, const char *uid, const char hash[8],
info = camel_folder_get_message_info(sub, uid);
if (info) {
if (vinfo) {
- camel_folder_change_info_change_uid(vf->changes, vuid);
- camel_message_info_free((CamelMessageInfo *)vinfo);
+ int changed = FALSE;
+
+ if (vinfo->info.flags != info->flags){
+ vinfo->info.flags = info->flags;
+ changed = TRUE;
+ }
+
+ changed |= camel_flag_list_copy(&vinfo->info.user_flags, &info->user_flags);
+ changed |= camel_tag_list_copy(&vinfo->info.user_tags, &info->user_tags);
+ if (changed)
+ camel_folder_change_info_change_uid(vf->changes, vuid);
+
+ camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
}
if (uinfo) {
- camel_folder_change_info_change_uid(folder_unmatched->changes, vuid);
- camel_message_info_free((CamelMessageInfo *)uinfo);
+ int changed = FALSE;
+
+ if (uinfo->info.flags != info->flags){
+ uinfo->info.flags = info->flags;
+ changed = TRUE;
+ }
+
+ changed |= camel_flag_list_copy(&uinfo->info.user_flags, &info->user_flags);
+ changed |= camel_tag_list_copy(&uinfo->info.user_tags, &info->user_tags);
+ if (changed)
+ camel_folder_change_info_change_uid(folder_unmatched->changes, vuid);
+
+ camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)uinfo);
}
camel_folder_free_message_info(sub, info);
} else {
if (vinfo) {
folder_changed_remove_uid(sub, uid, hash, FALSE, vf);
- camel_message_info_free((CamelMessageInfo *)vinfo);
+ camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
}
if (uinfo)
- camel_message_info_free((CamelMessageInfo *)uinfo);
+ camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)uinfo);
}
}
}
@@ -1257,7 +1463,7 @@ folder_changed_change(CamelSession *session, CamelSessionThreadMsg *msg)
g_ptr_array_add(newchanged, (char *)uid);
} else {
g_ptr_array_add(always_changed, (char *)uid);
- camel_message_info_free((CamelMessageInfo *)vinfo);
+ camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
}
}
changed = newchanged;
@@ -1361,7 +1567,7 @@ folder_changed_change(CamelSession *session, CamelSessionThreadMsg *msg)
dd(printf(" removing uid '%s' [did match]\n", uid));
folder_changed_remove_uid(sub, uid, hash, TRUE, vf);
}
- camel_message_info_free((CamelMessageInfo *)vinfo);
+ camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
}
}
g_hash_table_destroy(matches_hash);
@@ -1437,7 +1643,7 @@ static CamelSessionThreadOps folder_changed_ops = {
};
static void
-folder_changed_base(CamelVeeFolder *vf, CamelFolder *sub, CamelFolderChangeInfo *changes)
+folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder *vf)
{
struct _folder_changed_msg *m;
CamelSession *session = ((CamelService *)((CamelFolder *)vf)->parent_store)->session;
@@ -1452,12 +1658,6 @@ folder_changed_base(CamelVeeFolder *vf, CamelFolder *sub, CamelFolderChangeInfo
camel_session_thread_queue(session, &m->msg, 0);
}
-static void
-folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder *vf)
-{
- ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->folder_changed(vf, sub, changes);
-}
-
/* track vanishing folders */
static void
subfolder_deleted(CamelFolder *f, void *event_data, CamelVeeFolder *vf)
@@ -1472,7 +1672,6 @@ subfolder_renamed_update(CamelVeeFolder *vf, CamelFolder *sub, char hash[8])
CamelFolderChangeInfo *changes = NULL;
CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
- CamelFolderSummary *ssummary = sub->summary;
CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
@@ -1484,7 +1683,7 @@ subfolder_renamed_update(CamelVeeFolder *vf, CamelFolder *sub, char hash[8])
if (mi == NULL)
continue;
- if (mi->real->summary == ssummary) {
+ if (mi->folder == sub) {
char *uid = (char *)camel_message_info_uid(mi);
char *oldkey;
void *oldval;
@@ -1509,7 +1708,7 @@ subfolder_renamed_update(CamelVeeFolder *vf, CamelFolder *sub, char hash[8])
}
}
- camel_message_info_free((CamelMessageInfo *)mi);
+ camel_folder_summary_info_free(((CamelFolder *)vf)->summary, (CamelMessageInfo *)mi);
}
if (camel_folder_change_info_changed(vf->changes)) {
@@ -1526,7 +1725,7 @@ subfolder_renamed_update(CamelVeeFolder *vf, CamelFolder *sub, char hash[8])
}
static void
-folder_renamed_base(CamelVeeFolder *vf, CamelFolder *f, const char *old)
+subfolder_renamed(CamelFolder *f, void *event_data, CamelVeeFolder *vf)
{
char hash[8];
CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
@@ -1544,12 +1743,6 @@ folder_renamed_base(CamelVeeFolder *vf, CamelFolder *f, const char *old)
}
static void
-folder_renamed(CamelFolder *sub, const char *old, CamelVeeFolder *vf)
-{
- ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->folder_renamed(vf, sub, old);
-}
-
-static void
vee_freeze (CamelFolder *folder)
{
CamelVeeFolder *vfolder = (CamelVeeFolder *)folder;
@@ -1594,148 +1787,3 @@ vee_thaw(CamelFolder *folder)
/* call parent implementation */
CAMEL_FOLDER_CLASS (camel_vee_folder_parent)->thaw(folder);
}
-
-/* vfolder base implementaitons */
-static void
-vee_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
-{
- vee_rebuild_folder(vf, sub, NULL);
-}
-
-static void
-vee_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
-{
- vee_folder_remove_folder(vf, sub);
-}
-
-static void
-vee_set_expression(CamelVeeFolder *vf, const char *query)
-{
- struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
- GList *node;
-
- CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
-
- /* no change, do nothing */
- if ((vf->expression && query && strcmp(vf->expression, query) == 0)
- || (vf->expression == NULL && query == NULL)) {
- CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
- return;
- }
-
- g_free(vf->expression);
- if (query)
- vf->expression = g_strdup(query);
-
- node = p->folders;
- while (node) {
- CamelFolder *f = node->data;
-
- if (camel_vee_folder_rebuild_folder(vf, f, NULL) == -1)
- break;
-
- node = node->next;
- }
-
- CAMEL_VEE_FOLDER_LOCK(vf, changed_lock);
- g_list_free(p->folders_changed);
- p->folders_changed = NULL;
- CAMEL_VEE_FOLDER_UNLOCK(vf, changed_lock);
-
- CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
-}
-
-static void
-camel_vee_folder_class_init (CamelVeeFolderClass *klass)
-{
- CamelFolderClass *folder_class = (CamelFolderClass *) klass;
-
- camel_vee_folder_parent = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs (camel_folder_get_type ()));
-
- folder_class->refresh_info = vee_refresh_info;
- folder_class->sync = vee_sync;
- folder_class->expunge = vee_expunge;
-
- folder_class->get_message = vee_get_message;
- folder_class->append_message = vee_append_message;
- folder_class->transfer_messages_to = vee_transfer_messages_to;
-
- folder_class->search_by_expression = vee_search_by_expression;
- folder_class->search_by_uids = vee_search_by_uids;
-
- folder_class->rename = vee_rename;
- folder_class->delete = vee_delete;
-
- folder_class->freeze = vee_freeze;
- folder_class->thaw = vee_thaw;
-
- klass->set_expression = vee_set_expression;
- klass->add_folder = vee_add_folder;
- klass->remove_folder = vee_remove_folder;
- klass->rebuild_folder = vee_rebuild_folder;
- klass->folder_changed = folder_changed_base;
- klass->folder_renamed = folder_renamed_base;
-}
-
-static void
-camel_vee_folder_init (CamelVeeFolder *obj)
-{
- struct _CamelVeeFolderPrivate *p;
- CamelFolder *folder = (CamelFolder *)obj;
-
- p = _PRIVATE(obj) = g_malloc0(sizeof(*p));
-
- folder->folder_flags |= (CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY |
- CAMEL_FOLDER_HAS_SEARCH_CAPABILITY);
-
- /* FIXME: what to do about user flags if the subfolder doesn't support them? */
- folder->permanent_flags = CAMEL_MESSAGE_ANSWERED |
- CAMEL_MESSAGE_DELETED |
- CAMEL_MESSAGE_DRAFT |
- CAMEL_MESSAGE_FLAGGED |
- CAMEL_MESSAGE_SEEN;
-
- obj->changes = camel_folder_change_info_new();
- obj->search = camel_folder_search_new();
-
- p->summary_lock = g_mutex_new();
- p->subfolder_lock = g_mutex_new();
- p->changed_lock = g_mutex_new();
-}
-
-static void
-camel_vee_folder_finalise (CamelObject *obj)
-{
- CamelVeeFolder *vf = (CamelVeeFolder *)obj;
- struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
- CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
- GList *node;
-
- /* TODO: there may be other leaks? */
-
- /* This may invoke sub-classes with partially destroyed state, they must deal with this */
- if (vf == folder_unmatched) {
- for (node = p->folders;node;node = g_list_next(node))
- camel_object_unref(node->data);
- } else {
- while (p->folders) {
- CamelFolder *f = p->folders->data;
-
- camel_vee_folder_remove_folder(vf, f);
- }
- }
-
- g_free(vf->expression);
-
- g_list_free(p->folders);
- g_list_free(p->folders_changed);
-
- camel_folder_change_info_free(vf->changes);
- camel_object_unref((CamelObject *)vf->search);
-
- g_mutex_free(p->summary_lock);
- g_mutex_free(p->subfolder_lock);
- g_mutex_free(p->changed_lock);
-
- g_free(p);
-}
diff --git a/camel/camel-vee-folder.h b/camel/camel-vee-folder.h
index bccdf2c7ab..79f13a7280 100644
--- a/camel/camel-vee-folder.h
+++ b/camel/camel-vee-folder.h
@@ -1,8 +1,8 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * Copyright (C) 2000 Ximian Inc.
+ * Copyright (C) 2000 Ximian Inc.
*
- * Authors: Michael Zucchi <notzed@ximian.com>
+ * Authors: Michael Zucchi <notzed@ximian.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -30,7 +30,6 @@ extern "C" {
#include <glib.h>
#include <camel/camel-folder.h>
-#include <camel/camel-vee-summary.h>
#define CAMEL_VEE_FOLDER(obj) CAMEL_CHECK_CAST (obj, camel_vee_folder_get_type (), CamelVeeFolder)
#define CAMEL_VEE_FOLDER_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_vee_folder_get_type (), CamelVeeFolderClass)
@@ -39,12 +38,19 @@ extern "C" {
typedef struct _CamelVeeFolder CamelVeeFolder;
typedef struct _CamelVeeFolderClass CamelVeeFolderClass;
+/* our message info includes the parent folder */
+typedef struct _CamelVeeMessageInfo {
+ CamelMessageInfo info;
+ CamelFolder *folder;
+} CamelVeeMessageInfo;
+
struct _CamelVeeFolder {
CamelFolder parent;
struct _CamelVeeFolderPrivate *priv;
char *expression; /* query expression */
+ char *vname; /* local name */
guint32 flags; /* folder open flags */
@@ -58,19 +64,6 @@ struct _CamelVeeFolder {
struct _CamelVeeFolderClass {
CamelFolderClass parent_class;
-
- /* TODO: Some of this may need some additional work/thinking through, it works for now*/
-
- void (*add_folder)(CamelVeeFolder *, CamelFolder *);
- void (*remove_folder)(CamelVeeFolder *, CamelFolder *);
- int (*rebuild_folder)(CamelVeeFolder *, CamelFolder *, CamelException *);
-
- void (*set_expression)(CamelVeeFolder *, const char *);
-
- /* Called for a folder-changed event on a source folder */
- void (*folder_changed)(CamelVeeFolder *, CamelFolder *sub, CamelFolderChangeInfo *changes);
- /* Called for a folder-renamed event on a source folder */
- void (*folder_renamed)(CamelVeeFolder *, CamelFolder *sub, const char *old);
};
#define CAMEL_UNMATCHED_NAME "UNMATCHED"
@@ -79,12 +72,11 @@ CamelType camel_vee_folder_get_type (void);
CamelFolder *camel_vee_folder_new (CamelStore *parent_store, const char *name, guint32 flags);
void camel_vee_folder_construct (CamelVeeFolder *vf, CamelStore *parent_store, const char *name, guint32 flags);
-CamelFolder *camel_vee_folder_get_location(CamelVeeFolder *vf, const struct _CamelVeeMessageInfo *vinfo, char **realuid);
+CamelFolder *camel_vee_folder_get_location(CamelVeeFolder *vf, const CamelVeeMessageInfo *vinfo, char **realuid);
void camel_vee_folder_add_folder (CamelVeeFolder *vf, CamelFolder *sub);
void camel_vee_folder_remove_folder (CamelVeeFolder *vf, CamelFolder *sub);
void camel_vee_folder_set_folders (CamelVeeFolder *vf, GList *folders);
-int camel_vee_folder_rebuild_folder(CamelVeeFolder *vf, CamelFolder *sub, CamelException *ex);
void camel_vee_folder_set_expression (CamelVeeFolder *vf, const char *expr);
void camel_vee_folder_hash_folder (CamelFolder *folder, char buffer[8]);
diff --git a/camel/camel-vee-store.c b/camel/camel-vee-store.c
index 8068339f28..b562ad4a60 100644
--- a/camel/camel-vee-store.c
+++ b/camel/camel-vee-store.c
@@ -27,7 +27,6 @@
#include "camel-vee-folder.h"
#include "camel-private.h"
-#include "camel-i18n.h"
#include <string.h>
@@ -179,8 +178,8 @@ vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, Camel
vf = (CamelVeeFolder *)camel_vee_folder_new(store, folder_name, flags);
if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
/* Check that parents exist, if not, create dummy ones */
- name = alloca(strlen(((CamelFolder *)vf)->full_name)+1);
- strcpy(name, ((CamelFolder *)vf)->full_name);
+ name = alloca(strlen(vf->vname)+1);
+ strcpy(name, vf->vname);
p = name;
while ( (p = strchr(p, '/'))) {
*p = 0;
@@ -198,7 +197,7 @@ vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, Camel
*p++='/';
}
- change_folder(store, ((CamelFolder *)vf)->full_name, CHANGE_ADD, camel_folder_get_message_count((CamelFolder *)vf));
+ change_folder(store, vf->vname, CHANGE_ADD, camel_folder_get_message_count((CamelFolder *)vf));
}
return (CamelFolder *)vf;
diff --git a/camel/providers/groupwise/camel-gw-listener.c b/camel/providers/groupwise/camel-gw-listener.c
index 1f6eaf6267..9da66d6b6d 100644
--- a/camel/providers/groupwise/camel-gw-listener.c
+++ b/camel/providers/groupwise/camel-gw-listener.c
@@ -162,7 +162,7 @@ lookup_account_info (const char *key)
#define SELECTED_TASKS "/apps/evolution/calendar/tasks/selected_tasks"
static void
-add_esource (const char *conf_key, const char *group_name, const char *source_name, CamelURL *url)
+add_esource (const char *conf_key, const char *group_name, const char* source_name, const char *username, const char* relative_uri, const char *soap_port, const char *use_ssl)
{
ESourceList *source_list;
ESourceGroup *group;
@@ -170,45 +170,20 @@ add_esource (const char *conf_key, const char *group_name, const char *source_n
GConfClient* client;
GSList *ids, *temp ;
char *source_selection_key;
- char *relative_uri;
- const char *soap_port;
- const char * use_ssl;
- const char *poa_address;
- const char *offline_sync;
-
-
- poa_address = camel_url_get_param (url, "poa");
- if (!poa_address || strlen (poa_address) ==0)
- return;
- soap_port = camel_url_get_param (url, "soap_port");
-
- if (!soap_port || strlen (soap_port) == 0)
- soap_port = "7181";
- use_ssl = camel_url_get_param (url, "soap_ssl");
- if (use_ssl)
- use_ssl = "always";
- else
- use_ssl = NULL;
-
- offline_sync = camel_url_get_param (url, "offline_sync");
-
client = gconf_client_get_default();
source_list = e_source_list_new_for_gconf (client, conf_key);
group = e_source_group_new (group_name, GROUPWISE_URI_PREFIX);
- if (!e_source_list_add_group (source_list, group, -1))
+ if ( !e_source_list_add_group (source_list, group, -1))
return;
- relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address);
-
+
source = e_source_new (source_name, relative_uri);
e_source_set_property (source, "auth", "1");
- e_source_set_property (source, "username", url->user);
- e_source_set_property (source, "port", camel_url_get_param (url, "soap_port"));
+ e_source_set_property (source, "username", username);
+ e_source_set_property (source, "port", soap_port);
e_source_set_property (source, "auth-domain", "Groupwise");
- e_source_set_property (source, "use_ssl", camel_url_get_param (url, "use_ssl"));
- e_source_set_property (source, "offline_sync", offline_sync);
- // e_source_set_property (source, "offline_sync", );
+ e_source_set_property (source, "use_ssl", use_ssl);
e_source_group_add_source (group, source, -1);
e_source_list_sync (source_list, NULL);
@@ -231,7 +206,6 @@ add_esource (const char *conf_key, const char *group_name, const char *source_n
g_object_unref (group);
g_object_unref (source_list);
g_object_unref (client);
- g_free (relative_uri);
}
@@ -308,7 +282,7 @@ remove_esource (const char *conf_key, const char *group_name, char* source_name,
/* looks up for e-source with having same info as old_account_info and changes its values passed in new values */
static void
-modify_esource (const char* conf_key, GwAccountInfo *old_account_info, const char* new_group_name, CamelURL *new_url)
+modify_esource (const char* conf_key, GwAccountInfo *old_account_info, const char* new_group_name, const char *username, const char* new_relative_uri, const char *soap_port, const char *use_ssl)
{
ESourceList *list;
ESourceGroup *group;
@@ -320,15 +294,11 @@ modify_esource (const char* conf_key, GwAccountInfo *old_account_info, const cha
gboolean found_group;
GConfClient* client;
const char *poa_address;
- char *new_relative_uri;
- const char *new_poa_address;
-
+
url = camel_url_new (old_account_info->source_url, NULL);
poa_address = camel_url_get_param (url, "poa");
if (!poa_address || strlen (poa_address) ==0)
return;
- new_poa_address = camel_url_get_param (new_url, "poa");
-
old_relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address);
client = gconf_client_get_default ();
list = e_source_list_new_for_gconf (client, conf_key);
@@ -351,16 +321,13 @@ modify_esource (const char* conf_key, GwAccountInfo *old_account_info, const cha
if (strcmp (e_source_peek_relative_uri (source), old_relative_uri) == 0) {
- new_relative_uri = g_strdup_printf ("%s@%s/", new_url->user, new_poa_address);
e_source_group_set_name (group, new_group_name);
e_source_set_relative_uri (source, new_relative_uri);
- e_source_set_property (source, "username", new_url->user);
- e_source_set_property (source, "port", camel_url_get_param (new_url,"soap_port"));
- e_source_set_property (source, "use_ssl", camel_url_get_param (url, "soap_ssl"));
- e_source_set_property (source, "offline_sync", camel_url_get_param (url, "offline_sync"));
+ e_source_set_property (source, "username", username);
+ e_source_set_property (source, "port", soap_port);
+ e_source_set_property (source, "use_ssl", use_ssl);
e_source_list_sync (list, NULL);
found_group = TRUE;
- g_free (new_relative_uri);
break;
}
}
@@ -371,7 +338,6 @@ modify_esource (const char* conf_key, GwAccountInfo *old_account_info, const cha
g_object_unref (client);
camel_url_free (url);
g_free (old_relative_uri);
-
}
/* add sources for calendar and tasks if the account added is groupwise account
@@ -402,8 +368,8 @@ add_calendar_tasks_sources (GwAccountInfo *info)
use_ssl = NULL;
relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address);
- add_esource ("/apps/evolution/calendar/sources", info->name, _("Calendar"), url);
- add_esource ("/apps/evolution/tasks/sources", info->name, _("Tasks"), url);
+ add_esource ("/apps/evolution/calendar/sources", info->name, _("Calendar"), url->user, relative_uri, soap_port, use_ssl);
+ add_esource ("/apps/evolution/tasks/sources", info->name, _("Tasks"), url->user, relative_uri, soap_port, use_ssl);
camel_url_free (url);
g_free (relative_uri);
@@ -551,7 +517,7 @@ add_addressbook_sources (EAccount *account)
e_source_set_property (source, "auth-domain", "Groupwise");
e_source_set_property (source, "port", soap_port);
e_source_set_property(source, "user", url->user);
- e_source_set_property (source, "offline_sync", camel_url_get_param (url, "offline_sync"));
+
if (!e_gw_container_get_is_writable (E_GW_CONTAINER(temp_list->data)))
e_source_set_property (source, "completion", "true");
if (e_gw_container_get_is_frequent_contacts (E_GW_CONTAINER(temp_list->data)))
@@ -593,7 +559,6 @@ modify_addressbook_sources ( EAccount *account, GwAccountInfo *existing_account_
ESource *source;
GConfClient *client;
const char *poa_address;
-
url = camel_url_new (existing_account_info->source_url, NULL);
if (url == NULL) {
@@ -766,6 +731,7 @@ account_changed (EAccountList *account_listener, EAccount *account)
{
gboolean is_gw_account;
CamelURL *old_url, *new_url;
+ char *relative_uri;
const char *old_soap_port, *new_soap_port;
GwAccountInfo *existing_account_info;
const char *old_use_ssl, *new_use_ssl;
@@ -833,9 +799,11 @@ account_changed (EAccountList *account_listener, EAccount *account)
account_added (account_listener, account);
} else if (strcmp (existing_account_info->name, account->name)) {
- modify_esource ("/apps/evolution/calendar/sources", existing_account_info, account->name, new_url);
- modify_esource ("/apps/evolution/tasks/sources", existing_account_info, account->name, new_url);
+ relative_uri = g_strdup_printf ("%s@%s/", new_url->user, new_poa_address);
+ modify_esource ("/apps/evolution/calendar/sources", existing_account_info, account->name, new_url->user, relative_uri, new_soap_port, new_use_ssl);
+ modify_esource ("/apps/evolution/tasks/sources", existing_account_info, account->name, new_url->user, relative_uri, new_soap_port, new_use_ssl);
modify_addressbook_sources (account, existing_account_info);
+ g_free (relative_uri);
}
diff --git a/camel/providers/imap/camel-imap-command.c b/camel/providers/imap/camel-imap-command.c
index eeb3ecd302..fdba581fbb 100644
--- a/camel/providers/imap/camel-imap-command.c
+++ b/camel/providers/imap/camel-imap-command.c
@@ -43,7 +43,7 @@
#include <camel/camel-private.h>
#include <camel/camel-utf8.h>
#include <camel/camel-session.h>
-#include "camel-i18n.h"
+
extern int camel_verbose_debug;
@@ -499,10 +499,16 @@ imap_read_untagged (CamelImapStore *store, char *line, CamelException *ex)
fulllen += str->len;
g_ptr_array_add (data, str);
-
+
/* Read the next line. */
- if (camel_imap_store_readline (store, &line, ex) < 0)
- goto lose;
+ do {
+ if (camel_imap_store_readline (store, &line, ex) < 0)
+ goto lose;
+
+ /* MAJOR HACK ALERT, gropuwise sometimes sends an extra blank line after literals, check that here */
+ if (line[0] == 0)
+ g_warning("Server sent empty line after a literal, assuming in error");
+ } while (line[0] == 0);
}
/* Now reassemble the data. */
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index 6cdd96bcf7..d592b819f1 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -23,6 +23,7 @@
* USA
*/
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -37,8 +38,8 @@
#include <fcntl.h>
#include <ctype.h>
-/*#include "libedataserver/e-path.h"*/
-#include "libedataserver/e-time-utils.h"
+#include "e-util/e-path.h"
+#include "e-util/e-time-utils.h"
#include "camel-imap-folder.h"
#include "camel-imap-command.h"
@@ -69,7 +70,6 @@
#include "camel-string-utils.h"
#include "camel-file-utils.h"
#include "camel-debug.h"
-#include "camel-i18n.h"
#define d(x)
@@ -237,7 +237,7 @@ camel_imap_folder_new (CamelStore *parent, const char *folder_name,
camel_folder_construct (folder, parent, folder_name, short_name);
summary_file = g_strdup_printf ("%s/summary", folder_dir);
- folder->summary = camel_imap_summary_new (folder, summary_file);
+ folder->summary = camel_imap_summary_new (summary_file);
g_free (summary_file);
if (!folder->summary) {
camel_object_unref (CAMEL_OBJECT (folder));
@@ -387,7 +387,7 @@ camel_imap_folder_selected (CamelFolder *folder, CamelImapResponse *response,
info = camel_folder_summary_index (folder->summary, count - 1);
val = strtoul (camel_message_info_uid (info), NULL, 10);
- camel_message_info_free(info);
+ camel_folder_summary_info_free (folder->summary, info);
if (uid == 0 || uid != val)
imap_folder->need_rescan = TRUE;
}
@@ -470,7 +470,7 @@ imap_rename (CamelFolder *folder, const char *new)
char *folders;
folders = g_strconcat (imap_store->storage_path, "/folders", NULL);
- folder_dir = imap_path_to_physical (folders, new);
+ folder_dir = e_path_to_physical (folders, new);
g_free (folders);
summary_path = g_strdup_printf("%s/summary", folder_dir);
@@ -575,7 +575,7 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
ok = camel_imap_command_start (store, folder, ex,
"UID FETCH 1:%s (FLAGS)",
camel_message_info_uid (info));
- camel_message_info_free(info);
+ camel_folder_summary_info_free (folder->summary, info);
if (!ok) {
camel_operation_end (NULL);
return;
@@ -632,7 +632,7 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
iinfo = (CamelImapMessageInfo *)info;
if (strcmp (camel_message_info_uid (info), new[i].uid) != 0) {
- camel_message_info_free(info);
+ camel_folder_summary_info_free(folder->summary, info);
seq = i + 1;
g_array_append_val (removed, seq);
i--;
@@ -646,8 +646,8 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
server_set = new[i].flags & ~iinfo->server_flags;
server_cleared = iinfo->server_flags & ~new[i].flags;
-
- iinfo->info.flags = (iinfo->info.flags | server_set) & ~server_cleared;
+
+ info->flags = (info->flags | server_set) & ~server_cleared;
iinfo->server_flags = new[i].flags;
if (changes == NULL)
@@ -655,7 +655,7 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
camel_folder_change_info_change_uid(changes, new[i].uid);
}
- camel_message_info_free(info);
+ camel_folder_summary_info_free (folder->summary, info);
g_free (new[i].uid);
}
@@ -697,7 +697,7 @@ static GPtrArray *
get_matching (CamelFolder *folder, guint32 flags, guint32 mask, char **set)
{
GPtrArray *matches;
- CamelImapMessageInfo *info;
+ CamelMessageInfo *info;
int i, max, range;
GString *gset;
@@ -706,11 +706,11 @@ get_matching (CamelFolder *folder, guint32 flags, guint32 mask, char **set)
max = camel_folder_summary_count (folder->summary);
range = -1;
for (i = 0; i < max && !UID_SET_FULL (gset->len, UID_SET_LIMIT); i++) {
- info = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, i);
+ info = camel_folder_summary_index (folder->summary, i);
if (!info)
continue;
- if ((info->info.flags & mask) != flags) {
- camel_message_info_free((CamelMessageInfo *)info);
+ if ((info->flags & mask) != flags) {
+ camel_folder_summary_info_free (folder->summary, info);
if (range != -1) {
if (range != i - 1) {
info = matches->pdata[matches->len - 1];
@@ -758,7 +758,7 @@ imap_sync_online (CamelFolder *folder, CamelException *ex)
{
CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
CamelImapResponse *response = NULL;
- CamelImapMessageInfo *info;
+ CamelMessageInfo *info;
CamelException local_ex;
GPtrArray *matches;
char *set, *flaglist;
@@ -779,33 +779,33 @@ imap_sync_online (CamelFolder *folder, CamelException *ex)
*/
max = camel_folder_summary_count (folder->summary);
for (i = 0; i < max; i++) {
- if (!(info = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, i)))
+ if (!(info = camel_folder_summary_index (folder->summary, i)))
continue;
- if (!(info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- camel_message_info_free((CamelMessageInfo *)info);
+ if (!(info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
+ camel_folder_summary_info_free (folder->summary, info);
continue;
}
/* Note: Cyrus is broken and will not accept an
empty-set of flags so... if this is true then we
want to unset the previously set flags.*/
- unset = !(info->info.flags & folder->permanent_flags);
+ unset = !(info->flags & folder->permanent_flags);
/* Note: get_matching() uses UID_SET_LIMIT to limit
the size of the uid-set string. We don't have to
loop here to flush all the matching uids because
they will be scooped up later by our parent loop (I
think?). -- Jeff */
- matches = get_matching (folder, info->info.flags & (folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED),
+ matches = get_matching (folder, info->flags & (folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED),
folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED, &set);
- camel_message_info_free(info);
+ camel_folder_summary_info_free (folder->summary, info);
if (matches == NULL)
continue;
/* FIXME: since we don't know the previously set flags,
if unset is TRUE then just unset all the flags? */
- flaglist = imap_create_flag_list (unset ? folder->permanent_flags : info->info.flags & folder->permanent_flags);
+ flaglist = imap_create_flag_list (unset ? folder->permanent_flags : info->flags & folder->permanent_flags);
/* Note: to `unset' flags, use -FLAGS.SILENT (<flag list>) */
response = camel_imap_command (store, folder, &local_ex,
@@ -820,15 +820,16 @@ imap_sync_online (CamelFolder *folder, CamelException *ex)
if (!camel_exception_is_set (&local_ex)) {
for (j = 0; j < matches->len; j++) {
info = matches->pdata[j];
- info->info.flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
- ((CamelImapMessageInfo *) info)->server_flags = info->info.flags & CAMEL_IMAP_SERVER_FLAGS;
+ info->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
+ ((CamelImapMessageInfo *) info)->server_flags =
+ info->flags & CAMEL_IMAP_SERVER_FLAGS;
}
camel_folder_summary_touch (folder->summary);
}
for (j = 0; j < matches->len; j++) {
info = matches->pdata[j];
- camel_message_info_free(&info->info);
+ camel_folder_summary_info_free (folder->summary, info);
}
g_ptr_array_free (matches, TRUE);
@@ -1166,11 +1167,10 @@ do_append (CamelFolder *folder, CamelMimeMessage *message,
CamelStreamFilter *streamfilter;
GByteArray *ba;
char *flagstr, *end;
- guint32 flags;
-
- flags = camel_message_info_flags(info);
- if (flags)
- flagstr = imap_create_flag_list (flags);
+
+ /* create flag string param */
+ if (info && info->flags)
+ flagstr = imap_create_flag_list (info->flags);
else
flagstr = NULL;
@@ -1357,7 +1357,7 @@ imap_transfer_offline (CamelFolder *source, GPtrArray *uids,
camel_imap_summary_add_offline_uncached (dest->summary, destuid, mi);
camel_imap_message_cache_copy (sc, uid, dc, destuid, ex);
- camel_message_info_free(mi);
+ camel_folder_summary_info_free (source->summary, mi);
camel_folder_change_info_add_uid (changes, destuid);
if (transferred_uids)
@@ -1968,12 +1968,12 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
{
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapMessageInfo *mi;
+ CamelMessageInfo *mi;
CamelMimeMessage *msg = NULL;
CamelStream *stream = NULL;
int retry;
- mi = (CamelImapMessageInfo *)camel_folder_summary_uid (folder->summary, uid);
+ mi = camel_folder_summary_uid (folder->summary, uid);
if (mi == NULL) {
camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
_("Cannot get message: %s\n %s"), uid, _("No such message"));
@@ -2001,11 +2001,11 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
/* If the message is small or only 1 part, or server doesn't do 4v1 (properly) fetch it in one piece. */
if (store->server_level < IMAP_LEVEL_IMAP4REV1
|| store->braindamaged
- || mi->info.size < IMAP_SMALL_BODY_SIZE
- || (!content_info_incomplete(mi->info.content) && !mi->info.content->childs)) {
+ || mi->size < IMAP_SMALL_BODY_SIZE
+ || (!content_info_incomplete(mi->content) && !mi->content->childs)) {
msg = get_message_simple (imap_folder, uid, NULL, ex);
} else {
- if (content_info_incomplete (mi->info.content)) {
+ if (content_info_incomplete (mi->content)) {
/* For larger messages, fetch the structure and build a message
* with offline parts. (We check mi->content->type rather than
* mi->content because camel_folder_summary_info_new always creates
@@ -2038,7 +2038,7 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
}
if (body)
- imap_parse_body ((const char **) &body, folder, mi->info.content);
+ imap_parse_body ((const char **) &body, folder, mi->content);
if (fetch_data)
g_datalist_clear (&fetch_data);
@@ -2049,7 +2049,7 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
if (camel_debug_start("imap:folder")) {
printf("Folder get message '%s' folder info ->\n", uid);
- camel_message_info_dump((CamelMessageInfo *)mi);
+ camel_message_info_dump(mi);
camel_debug_end();
}
@@ -2059,10 +2059,10 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
* fall back to fetching the entire thing and
* let the mailer's "bad MIME" code handle it.
*/
- if (content_info_incomplete (mi->info.content))
+ if (content_info_incomplete (mi->content))
msg = get_message_simple (imap_folder, uid, NULL, ex);
else
- msg = get_message (imap_folder, uid, mi->info.content, ex);
+ msg = get_message (imap_folder, uid, mi->content, ex);
}
} while (msg == NULL
&& retry < 2
@@ -2072,7 +2072,7 @@ done: /* FIXME, this shouldn't be done this way. */
if (msg)
camel_medium_set_header (CAMEL_MEDIUM (msg), "X-Evolution-Source", store->base_url);
fail:
- camel_message_info_free(&mi->info);
+ camel_folder_summary_info_free (folder->summary, mi);
return msg;
}
@@ -2201,7 +2201,7 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages,
{
CamelMimeMessage *msg;
CamelStream *stream;
- CamelImapMessageInfo *mi;
+ CamelMessageInfo *mi;
const char *idate;
int seq;
@@ -2221,14 +2221,14 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages,
return;
}
- mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (folder->summary, msg);
+ mi = camel_folder_summary_info_new_from_message (folder->summary, msg);
camel_object_unref (CAMEL_OBJECT (msg));
if ((idate = g_datalist_get_data (&data, "INTERNALDATE")))
- mi->info.date_received = decode_internaldate (idate);
+ mi->date_received = decode_internaldate (idate);
- if (mi->info.date_received == -1)
- mi->info.date_received = mi->info.date_sent;
+ if (mi->date_received == -1)
+ mi->date_received = mi->date_sent;
messages->pdata[seq - first] = mi;
}
@@ -2253,7 +2253,7 @@ imap_update_summary (CamelFolder *folder, int exists,
int i, seq, first, size, got;
CamelImapResponseType type;
const char *header_spec;
- CamelImapMessageInfo *mi, *info;
+ CamelMessageInfo *mi, *info;
CamelStream *stream;
char *uid, *resp;
GData *data;
@@ -2272,9 +2272,9 @@ imap_update_summary (CamelFolder *folder, int exists,
seq = camel_folder_summary_count (folder->summary);
first = seq + 1;
if (seq > 0) {
- mi = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, seq - 1);
+ mi = camel_folder_summary_index (folder->summary, seq - 1);
uidval = strtoul(camel_message_info_uid (mi), NULL, 10);
- camel_message_info_free(&mi->info);
+ camel_folder_summary_info_free (folder->summary, mi);
} else
uidval = 0;
@@ -2433,23 +2433,24 @@ imap_update_summary (CamelFolder *folder, int exists,
continue;
}
- mi = (CamelImapMessageInfo *)camel_message_info_clone(pmi);
+ mi = camel_message_info_new ();
+ camel_message_info_dup_to (pmi, mi);
}
uid = g_datalist_get_data (&data, "UID");
if (uid)
- mi->info.uid = g_strdup (uid);
+ camel_message_info_set_uid (mi, g_strdup (uid));
flags = GPOINTER_TO_INT (g_datalist_get_data (&data, "FLAGS"));
if (flags) {
((CamelImapMessageInfo *)mi)->server_flags = flags;
/* "or" them in with the existing flags that may
* have been set by summary_info_new_from_message.
*/
- mi->info.flags |= flags;
+ mi->flags |= flags;
}
size = GPOINTER_TO_INT (g_datalist_get_data (&data, "RFC822.SIZE"));
if (size)
- mi->info.size = size;
+ mi->size = size;
g_datalist_clear (&data);
}
@@ -2473,7 +2474,7 @@ imap_update_summary (CamelFolder *folder, int exists,
i + first);
break;
}
- info = (CamelImapMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
+ info = camel_folder_summary_uid(folder->summary, uid);
if (info) {
for (seq = 0; seq < camel_folder_summary_count (folder->summary); seq++) {
if (folder->summary->messages->pdata[seq] == info)
@@ -2485,20 +2486,20 @@ imap_update_summary (CamelFolder *folder, int exists,
_("Unexpected server response: Identical UIDs provided for messages %d and %d"),
seq + 1, i + first);
- camel_message_info_free(&info->info);
+ camel_folder_summary_info_free(folder->summary, info);
break;
}
- camel_folder_summary_add (folder->summary, (CamelMessageInfo *)mi);
+ camel_folder_summary_add (folder->summary, mi);
camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi));
- if ((mi->info.flags & CAMEL_IMAP_MESSAGE_RECENT))
+ if ((mi->flags & CAMEL_IMAP_MESSAGE_RECENT))
camel_folder_change_info_recent_uid(changes, camel_message_info_uid (mi));
}
for ( ; i < messages->len; i++) {
if ((mi = messages->pdata[i]))
- camel_message_info_free(&mi->info);
+ camel_folder_summary_info_free(folder->summary, mi);
}
g_ptr_array_free (messages, TRUE);
@@ -2516,7 +2517,7 @@ imap_update_summary (CamelFolder *folder, int exists,
if (messages) {
for (i = 0; i < messages->len; i++) {
if (messages->pdata[i])
- camel_message_info_free(messages->pdata[i]);
+ camel_folder_summary_info_free (folder->summary, messages->pdata[i]);
}
g_ptr_array_free (messages, TRUE);
}
@@ -2552,7 +2553,7 @@ camel_imap_folder_changed (CamelFolder *folder, int exists,
camel_imap_message_cache_remove (imap_folder->cache, camel_message_info_uid (info));
CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock);
camel_folder_summary_remove (folder->summary, info);
- camel_message_info_free(info);
+ camel_folder_summary_info_free(folder->summary, info);
}
}
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index 5811b0f691..3f92c2f40a 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -24,6 +24,7 @@
*
*/
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -34,6 +35,8 @@
#include <unistd.h>
#include <errno.h>
+#include "e-util/e-path.h"
+
#include "camel-imap-store.h"
#include "camel-imap-store-summary.h"
#include "camel-imap-folder.h"
@@ -56,11 +59,11 @@
#include "camel-sasl.h"
#include "camel-utf8.h"
#include "camel-string-utils.h"
+
#include "camel-imap-private.h"
#include "camel-private.h"
+
#include "camel-debug.h"
-#include "camel-i18n.h"
-#include "camel-net-utils.h"
#define d(x)
@@ -502,52 +505,87 @@ imap_get_capability (CamelService *service, CamelException *ex)
}
enum {
- MODE_CLEAR,
- MODE_SSL,
- MODE_TLS,
+ USE_SSL_NEVER,
+ USE_SSL_ALWAYS,
+ USE_SSL_WHEN_POSSIBLE
};
#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
static gboolean
-connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, CamelException *ex)
+connect_to_server (CamelService *service, int ssl_mode, int try_starttls, CamelException *ex)
{
CamelImapStore *store = (CamelImapStore *) service;
CamelImapResponse *response;
CamelStream *tcp_stream;
CamelSockOptData sockopt;
gboolean force_imap4 = FALSE;
- int clean_quit, ret;
+ int clean_quit;
+ int ret;
char *buf;
+ struct addrinfo *ai, hints = { 0 };
+ char *serv;
+ const char *port = NULL;
+
+ /* FIXME: this connect stuff is duplicated everywhere */
+
+ if (service->url->port) {
+ serv = g_alloca(16);
+ sprintf(serv, "%d", service->url->port);
+ } else {
+ serv = "imap";
+ port = IMAP_PORT;
+ }
- if (ssl_mode != MODE_CLEAR) {
+ if (ssl_mode != USE_SSL_NEVER) {
#ifdef HAVE_SSL
- if (ssl_mode == MODE_TLS) {
+ if (try_starttls) {
tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
} else {
+ if (service->url->port == 0) {
+ serv = "imaps";
+ port = IMAPS_PORT;
+ }
tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
}
#else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, _("SSL unavailable"));
+ if (!try_starttls && service->url->port == 0) {
+ serv = "imaps";
+ port = IMAPS_PORT;
+ }
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ _("Could not connect to %s (port %s): %s"),
+ service->url->host, serv,
+ _("SSL unavailable"));
return FALSE;
#endif /* HAVE_SSL */
} else {
tcp_stream = camel_tcp_stream_raw_new ();
}
+
+ hints.ai_socktype = SOCK_STREAM;
+ ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
+ if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
+ camel_exception_clear(ex);
+ ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
+ }
+ if (ai == NULL) {
+ camel_object_unref(tcp_stream);
+ return FALSE;
+ }
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -1) {
+ ret = camel_tcp_stream_connect(CAMEL_TCP_STREAM(tcp_stream), ai);
+ camel_freeaddrinfo(ai);
+ if (ret == -1) {
if (errno == EINTR)
camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
_("Connection cancelled"));
else
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host,
- g_strerror (errno));
+ _("Could not connect to %s (port %s): %s"),
+ service->url->host, serv, g_strerror (errno));
camel_object_unref (tcp_stream);
@@ -591,7 +629,7 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
if (!strncmp(buf, "* PREAUTH", 9))
store->preauthed = TRUE;
- if (strstr (buf, "Courier-IMAP")) {
+ if (strstr (buf, "Courier-IMAP") || getenv("CAMEL_IMAP_BRAINDAMAGED")) {
/* Courier-IMAP is braindamaged. So far this flag only
* works around the fact that Courier-IMAP is known to
* give invalid BODY responses seemingly because its
@@ -642,18 +680,32 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
store->server_level = IMAP_LEVEL_IMAP4;
}
- if (ssl_mode != MODE_TLS) {
- /* we're done */
- return TRUE;
+#ifdef HAVE_SSL
+ if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
+ if (store->capabilities & IMAP_CAPABILITY_STARTTLS)
+ goto starttls;
+ } else if (ssl_mode == USE_SSL_ALWAYS) {
+ if (try_starttls) {
+ if (store->capabilities & IMAP_CAPABILITY_STARTTLS) {
+ /* attempt to toggle STARTTLS mode */
+ goto starttls;
+ } else {
+ /* server doesn't support STARTTLS, abort */
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to connect to IMAP server %s in secure mode: %s"),
+ service->url->host, _("SSL/TLS extension not supported."));
+ /* we have the possibility of quitting cleanly here */
+ clean_quit = TRUE;
+ goto exception;
+ }
+ }
}
+#endif /* HAVE_SSL */
- if (!(store->capabilities & IMAP_CAPABILITY_STARTTLS)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to IMAP server %s in secure mode: %s"),
- service->url->host, _("STARTTLS not supported"));
-
- goto exception;
- }
+ return TRUE;
+
+#ifdef HAVE_SSL
+ starttls:
/* as soon as we send a STARTTLS command, all hope is lost of a clean QUIT if problems arise */
clean_quit = FALSE;
@@ -718,6 +770,7 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
store->connected = FALSE;
return FALSE;
+#endif /* HAVE_SSL */
}
static gboolean
@@ -865,70 +918,60 @@ connect_to_server_process (CamelService *service, const char *cmd, CamelExceptio
static struct {
char *value;
- char *serv;
- char *port;
int mode;
} ssl_options[] = {
- { "", "imaps", IMAPS_PORT, MODE_SSL }, /* really old (1.x) */
- { "always", "imaps", IMAPS_PORT, MODE_SSL },
- { "when-possible", "imap", IMAP_PORT, MODE_TLS },
- { "never", "imap", IMAP_PORT, MODE_CLEAR },
- { NULL, "imap", IMAP_PORT, MODE_CLEAR },
+ { "", USE_SSL_ALWAYS },
+ { "always", USE_SSL_ALWAYS },
+ { "when-possible", USE_SSL_WHEN_POSSIBLE },
+ { "never", USE_SSL_NEVER },
+ { NULL, USE_SSL_NEVER },
};
static gboolean
connect_to_server_wrapper (CamelService *service, CamelException *ex)
{
- const char *command, *ssl_mode;
- struct addrinfo hints, *ai;
- int mode, ret, i;
- char *serv;
- const char *port;
-
- if ((command = camel_url_get_param (service->url, "command")))
+ const char *command;
+#ifdef HAVE_SSL
+ const char *use_ssl;
+ int i, ssl_mode;
+#endif
+ command = camel_url_get_param (service->url, "command");
+ if (command)
return connect_to_server_process (service, command, ex);
-
- if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
+
+#ifdef HAVE_SSL
+ use_ssl = camel_url_get_param (service->url, "use_ssl");
+ if (use_ssl) {
for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, ssl_mode))
+ if (!strcmp (ssl_options[i].value, use_ssl))
break;
- mode = ssl_options[i].mode;
- serv = ssl_options[i].serv;
- port = ssl_options[i].port;
+ ssl_mode = ssl_options[i].mode;
+ } else
+ ssl_mode = USE_SSL_NEVER;
+
+ if (ssl_mode == USE_SSL_ALWAYS) {
+ /* First try the ssl port */
+ if (!connect_to_server (service, ssl_mode, FALSE, ex)) {
+ if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE) {
+ /* The ssl port seems to be unavailable, lets try STARTTLS */
+ camel_exception_clear (ex);
+ return connect_to_server (service, ssl_mode, TRUE, ex);
+ } else {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ } else if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
+ /* If the server supports STARTTLS, use it */
+ return connect_to_server (service, ssl_mode, TRUE, ex);
} else {
- mode = MODE_CLEAR;
- serv = "imap";
- port = IMAP_PORT;
- }
-
- if (service->url->port) {
- serv = g_alloca (16);
- sprintf (serv, "%d", service->url->port);
- port = NULL;
- }
-
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
- ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
- if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
- camel_exception_clear (ex);
- ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
- }
- if (ai == NULL)
- return FALSE;
-
- if (!(ret = connect_to_server (service, ai, mode, ex)) && mode == MODE_SSL) {
- camel_exception_clear (ex);
- ret = connect_to_server (service, ai, MODE_TLS, ex);
- } else if (!ret && mode == MODE_TLS) {
- camel_exception_clear (ex);
- ret = connect_to_server (service, ai, MODE_CLEAR, ex);
+ /* User doesn't care about SSL */
+ return connect_to_server (service, ssl_mode, FALSE, ex);
}
-
- camel_freeaddrinfo (ai);
-
- return ret;
+#else
+ return connect_to_server (service, USE_SSL_NEVER, FALSE, ex);
+#endif
}
extern CamelServiceAuthType camel_imap_password_authtype;
@@ -1041,7 +1084,7 @@ imap_forget_folder (CamelImapStore *imap_store, const char *folder_name, CamelEx
name = folder_name;
storage_path = g_strdup_printf ("%s/folders", imap_store->storage_path);
- folder_dir = imap_path_to_physical (storage_path, folder_name);
+ folder_dir = e_path_to_physical (storage_path, folder_name);
g_free (storage_path);
if (access (folder_dir, F_OK) != 0) {
g_free (folder_dir);
@@ -1049,7 +1092,7 @@ imap_forget_folder (CamelImapStore *imap_store, const char *folder_name, CamelEx
}
summary_file = g_strdup_printf ("%s/summary", folder_dir);
- summary = camel_imap_summary_new (NULL, summary_file);
+ summary = camel_imap_summary_new (summary_file);
if (!summary) {
g_free (summary_file);
g_free (folder_dir);
@@ -1599,17 +1642,14 @@ imap_disconnect_online (CamelService *service, gboolean clean, CamelException *e
static gboolean
imap_summary_is_dirty (CamelFolderSummary *summary)
{
- CamelImapMessageInfo *info;
+ CamelMessageInfo *info;
int max, i;
- int found = FALSE;
-
+
max = camel_folder_summary_count (summary);
- for (i = 0; i < max && !found; i++) {
- info = (CamelImapMessageInfo *)camel_folder_summary_index (summary, i);
- if (info) {
- found = info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED;
- camel_message_info_free(info);
- }
+ for (i = 0; i < max; i++) {
+ info = camel_folder_summary_index (summary, i);
+ if (info && (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED))
+ return TRUE;
}
return FALSE;
@@ -1982,7 +2022,7 @@ get_folder_online (CamelStore *store, const char *folder_name, guint32 flags, Ca
}
storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
- folder_dir = imap_path_to_physical (storage_path, folder_name);
+ folder_dir = e_path_to_physical (storage_path, folder_name);
g_free(storage_path);
new_folder = camel_imap_folder_new (store, folder_name, folder_dir, ex);
g_free (folder_dir);
@@ -2025,7 +2065,7 @@ get_folder_offline (CamelStore *store, const char *folder_name,
folder_name = "INBOX";
storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
- folder_dir = imap_path_to_physical (storage_path, folder_name);
+ folder_dir = e_path_to_physical (storage_path, folder_name);
g_free(storage_path);
if (!folder_dir || access (folder_dir, F_OK) != 0) {
g_free (folder_dir);
@@ -2195,8 +2235,8 @@ rename_folder (CamelStore *store, const char *old_name, const char *new_name_in,
manage_subscriptions(store, new_name_in, TRUE);
storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
- oldpath = imap_path_to_physical (storage_path, old_name);
- newpath = imap_path_to_physical (storage_path, new_name_in);
+ oldpath = e_path_to_physical (storage_path, old_name);
+ newpath = e_path_to_physical (storage_path, new_name_in);
g_free(storage_path);
/* So do we care if this didn't work? Its just a cache? */
@@ -2631,7 +2671,7 @@ fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags)
/* This is a lot of work for one path! */
storage_path = g_strdup_printf("%s/folders", ((CamelImapStore *)store)->storage_path);
- folder_dir = imap_path_to_physical(storage_path, fi->full_name);
+ folder_dir = e_path_to_physical(storage_path, fi->full_name);
path = g_strdup_printf("%s/summary", folder_dir);
s = (CamelFolderSummary *)camel_object_new(camel_imap_summary_get_type());
camel_folder_summary_set_build_content(s, TRUE);
@@ -3037,7 +3077,7 @@ get_folder_info_offline (CamelStore *store, const char *top,
/* A kludge to avoid having to pass a struct to the callback */
g_ptr_array_add (folders, imap_store);
storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
- if (!imap_path_find_folders (storage_path, get_one_folder_offline, folders)) {
+ if (!e_path_find_folders (storage_path, get_one_folder_offline, folders)) {
camel_disco_store_check_online (CAMEL_DISCO_STORE (imap_store), ex);
fi = NULL;
} else {
diff --git a/camel/providers/imap4/camel-imap4-engine.c b/camel/providers/imap4/camel-imap4-engine.c
index d6f17532ee..adbf862747 100644
--- a/camel/providers/imap4/camel-imap4-engine.c
+++ b/camel/providers/imap4/camel-imap4-engine.c
@@ -28,7 +28,6 @@
#include <camel/camel-sasl.h>
#include <camel/camel-stream-buffer.h>
-#include <camel/camel-i18n.h>
#include "camel-imap4-summary.h"
#include "camel-imap4-command.h"
@@ -115,6 +114,22 @@ camel_imap4_engine_init (CamelIMAP4Engine *engine, CamelIMAP4EngineClass *klass)
}
static void
+imap4_namespace_clear (CamelIMAP4Namespace **namespace)
+{
+ CamelIMAP4Namespace *node, *next;
+
+ node = *namespace;
+ while (node != NULL) {
+ next = node->next;
+ g_free (node->path);
+ g_free (node);
+ node = next;
+ }
+
+ *namespace = NULL;
+}
+
+static void
camel_imap4_engine_finalize (CamelObject *object)
{
CamelIMAP4Engine *engine = (CamelIMAP4Engine *) object;
@@ -129,9 +144,9 @@ camel_imap4_engine_finalize (CamelObject *object)
g_hash_table_foreach (engine->authtypes, (GHFunc) g_free, NULL);
g_hash_table_destroy (engine->authtypes);
- camel_imap4_namespace_clear (&engine->namespaces.personal);
- camel_imap4_namespace_clear (&engine->namespaces.other);
- camel_imap4_namespace_clear (&engine->namespaces.shared);
+ imap4_namespace_clear (&engine->namespaces.personal);
+ imap4_namespace_clear (&engine->namespaces.other);
+ imap4_namespace_clear (&engine->namespaces.shared);
if (engine->folder)
camel_object_unref (engine->folder);
@@ -148,7 +163,6 @@ camel_imap4_engine_finalize (CamelObject *object)
/**
* camel_imap4_engine_new:
* @service: service
- * @reconnect: reconnect callback function
*
* Returns a new imap4 engine
**/
@@ -334,16 +348,6 @@ camel_imap4_engine_namespace (CamelIMAP4Engine *engine, CamelException *ex)
}
-/**
- * camel_imap4_engine_select_folder:
- * @engine: IMAP4 engine
- * @folder: folder to select
- * @ex: exception
- *
- * Convenience function to select @folder.
- *
- * Returns 0 on success or -1 on fail.
- **/
int
camel_imap4_engine_select_folder (CamelIMAP4Engine *engine, CamelFolder *folder, CamelException *ex)
{
@@ -435,15 +439,11 @@ static struct {
{ "IMAP4", CAMEL_IMAP4_CAPABILITY_IMAP4 },
{ "IMAP4REV1", CAMEL_IMAP4_CAPABILITY_IMAP4REV1 },
{ "STATUS", CAMEL_IMAP4_CAPABILITY_STATUS },
- { "NAMESPACE", CAMEL_IMAP4_CAPABILITY_NAMESPACE }, /* rfc2342 */
- { "UIDPLUS", CAMEL_IMAP4_CAPABILITY_UIDPLUS }, /* rfc2359 */
- { "LITERAL+", CAMEL_IMAP4_CAPABILITY_LITERALPLUS }, /* rfc2088 */
+ { "NAMESPACE", CAMEL_IMAP4_CAPABILITY_NAMESPACE },
+ { "UIDPLUS", CAMEL_IMAP4_CAPABILITY_UIDPLUS },
+ { "LITERAL+", CAMEL_IMAP4_CAPABILITY_LITERALPLUS },
{ "LOGINDISABLED", CAMEL_IMAP4_CAPABILITY_LOGINDISABLED },
{ "STARTTLS", CAMEL_IMAP4_CAPABILITY_STARTTLS },
- { "QUOTA", CAMEL_IMAP4_CAPABILITY_QUOTA }, /* rfc2087 */
- { "ACL", CAMEL_IMAP4_CAPABILITY_ACL }, /* rfc2086 */
- { "IDLE", CAMEL_IMAP4_CAPABILITY_IDLE }, /* rfc2177 */
- { "MULTIAPPEND", CAMEL_IMAP4_CAPABILITY_MULTIAPPEND }, /* rfc3502 */
{ NULL, 0 }
};
@@ -469,7 +469,7 @@ engine_parse_capability (CamelIMAP4Engine *engine, int sentinel, CamelException
return -1;
while (token.token == CAMEL_IMAP4_TOKEN_ATOM) {
- if (!g_ascii_strncasecmp ("AUTH=", token.v.atom, 5)) {
+ if (!strncasecmp ("AUTH=", token.v.atom, 5)) {
CamelServiceAuthType *auth;
if ((auth = camel_sasl_authtype (token.v.atom + 5)) != NULL)
@@ -563,9 +563,9 @@ engine_parse_namespace (CamelIMAP4Engine *engine, CamelException *ex)
camel_imap4_token_t token;
int i, n = 0;
- camel_imap4_namespace_clear (&engine->namespaces.personal);
- camel_imap4_namespace_clear (&engine->namespaces.other);
- camel_imap4_namespace_clear (&engine->namespaces.shared);
+ imap4_namespace_clear (&engine->namespaces.personal);
+ imap4_namespace_clear (&engine->namespaces.other);
+ imap4_namespace_clear (&engine->namespaces.shared);
if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
return -1;
@@ -604,19 +604,8 @@ engine_parse_namespace (CamelIMAP4Engine *engine, CamelException *ex)
goto exception;
}
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- node->sep = '\0';
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- if (strlen (token.v.qstring) == 1) {
- node->sep = *token.v.qstring;
- break;
- } else {
- /* invalid, fall thru */
- }
- default:
- d(fprintf (stderr, "Expected to find a nil or a valid qstring token as second element in NAMESPACE pair\n"));
+ if (token.token != CAMEL_IMAP4_TOKEN_QSTRING || strlen (token.v.qstring) > 1) {
+ d(fprintf (stderr, "Expected to find a qstring token as second element in NAMESPACE pair\n"));
camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
g_free (node->path);
g_free (node);
@@ -624,6 +613,7 @@ engine_parse_namespace (CamelIMAP4Engine *engine, CamelException *ex)
goto exception;
}
+ node->sep = *token.v.qstring;
tail->next = node;
tail = node;
@@ -682,7 +672,7 @@ engine_parse_namespace (CamelIMAP4Engine *engine, CamelException *ex)
exception:
for (i = 0; i <= n; i++)
- camel_imap4_namespace_clear (&namespaces[i]);
+ imap4_namespace_clear (&namespaces[i]);
return -1;
}
@@ -723,15 +713,6 @@ static struct {
};
-/**
- * camel_imap4_engine_parse_resp_code:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Parses a RESP-CODE
- *
- * Returns 0 on success or -1 on fail.
- **/
int
camel_imap4_engine_parse_resp_code (CamelIMAP4Engine *engine, CamelException *ex)
{
@@ -900,34 +881,26 @@ camel_imap4_engine_parse_resp_code (CamelIMAP4Engine *engine, CamelException *ex
if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
return -1;
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM && token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an atom or numeric token as the second argument to the COPYUID RESP-CODE\n"));
+ if (token.token != CAMEL_IMAP4_TOKEN_ATOM) {
+ d(fprintf (stderr, "Expected an atom token as the second argument to the COPYUID RESP-CODE\n"));
camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
goto exception;
}
- if (resp != NULL) {
- if (token.token == CAMEL_IMAP4_TOKEN_NUMBER)
- resp->v.copyuid.srcset = g_strdup_printf ("%u", token.v.number);
- else
- resp->v.copyuid.srcset = g_strdup (token.v.atom);
- }
+ if (resp != NULL)
+ resp->v.copyuid.srcset = g_strdup (token.v.atom);
if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
return -1;
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM && token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an atom or numeric token as the third argument to the APPENDUID RESP-CODE\n"));
+ if (token.token != CAMEL_IMAP4_TOKEN_ATOM) {
+ d(fprintf (stderr, "Expected an atom token as the third argument to the APPENDUID RESP-CODE\n"));
camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
goto exception;
}
- if (resp != NULL) {
- if (token.token == CAMEL_IMAP4_TOKEN_NUMBER)
- resp->v.copyuid.destset = g_strdup_printf ("%u", token.v.number);
- else
- resp->v.copyuid.destset = g_strdup (token.v.atom);
- }
+ if (resp != NULL)
+ resp->v.copyuid.destset = g_strdup (token.v.atom);
break;
default:
@@ -986,17 +959,8 @@ camel_imap4_engine_parse_resp_code (CamelIMAP4Engine *engine, CamelException *ex
}
-/**
- * camel_imap4_engine_handle_untagged_1:
- * @engine: IMAP4 engine
- * @token: IMAP4 token
- * @ex: exception
- *
- * Handles a single untagged response
- *
- * Returns -1 on error or one of
- * CAMEL_IMAP4_UNTAGGED_[OK,NO,BAD,PREAUTH,HANDLED] on success
- **/
+
+/* returns -1 on error, or one of CAMEL_IMAP4_UNTAGGED_[OK,NO,BAD,PREAUTH,HANDLED] on success */
int
camel_imap4_engine_handle_untagged_1 (CamelIMAP4Engine *engine, camel_imap4_token_t *token, CamelException *ex)
{
@@ -1149,13 +1113,6 @@ camel_imap4_engine_handle_untagged_1 (CamelIMAP4Engine *engine, camel_imap4_toke
}
-/**
- * camel_imap4_engine_handle_untagged:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Handle a stream of untagged responses.
- **/
void
camel_imap4_engine_handle_untagged (CamelIMAP4Engine *engine, CamelException *ex)
{
@@ -1254,7 +1211,6 @@ engine_state_change (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
return retval;
}
-
/**
* camel_imap4_engine_iterate:
* @engine: IMAP4 engine
@@ -1421,13 +1377,6 @@ camel_imap4_engine_prequeue (CamelIMAP4Engine *engine, CamelFolder *folder, cons
}
-/**
- * camel_imap4_engine_dequeue:
- * @engine: IMAP4 engine
- * @ic: IMAP4 command
- *
- * Removes @ic from the processing queue.
- **/
void
camel_imap4_engine_dequeue (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
{
@@ -1444,18 +1393,6 @@ camel_imap4_engine_dequeue (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
}
-/**
- * camel_imap4_engine_next_token:
- * @engine: IMAP4 engine
- * @token: IMAP4 token
- * @ex: exception
- *
- * Wraps camel_imap4_stream_next_token() to set an exception on
- * failure and updates the engine state to DISCONNECTED if the stream
- * gets disconencted.
- *
- * Returns 0 on success or -1 on fail.
- **/
int
camel_imap4_engine_next_token (CamelIMAP4Engine *engine, camel_imap4_token_t *token, CamelException *ex)
{
@@ -1473,15 +1410,6 @@ camel_imap4_engine_next_token (CamelIMAP4Engine *engine, camel_imap4_token_t *to
}
-/**
- * camel_imap4_engine_eat_line:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Gobbles up the remainder of the response line.
- *
- * Returns 0 on success or -1 on fail
- **/
int
camel_imap4_engine_eat_line (CamelIMAP4Engine *engine, CamelException *ex)
{
@@ -1514,19 +1442,6 @@ camel_imap4_engine_eat_line (CamelIMAP4Engine *engine, CamelException *ex)
}
-/**
- * camel_imap4_engine_line:
- * @engine: IMAP4 engine
- * @line: line pointer
- * @len: length pointer
- * @ex: exception
- *
- * Reads in a single line of input from the IMAP4 server and updates
- * @line to point to the line buffer. @len is set to the length of the
- * line buffer. @line must be free'd using g_free().
- *
- * Returns 0 on success or -1 on fail
- **/
int
camel_imap4_engine_line (CamelIMAP4Engine *engine, unsigned char **line, size_t *len, CamelException *ex)
{
@@ -1569,20 +1484,6 @@ camel_imap4_engine_line (CamelIMAP4Engine *engine, unsigned char **line, size_t
}
-/**
- * camel_imap4_engine_literal:
- * @engine: IMAP4 engine
- * @literal: literal pointer
- * @len: len pointer
- * @ex: exception
- *
- * Reads in an entire literal string and updates @literal to point to
- * it. @len is set to the length of the literal. @literal will also
- * conveniently be terminated with a nul-byte. @literal must be free'd
- * using g_free().
- *
- * Returns 0 on success or -1 on fail.
- **/
int
camel_imap4_engine_literal (CamelIMAP4Engine *engine, unsigned char **literal, size_t *len, CamelException *ex)
{
@@ -1626,55 +1527,6 @@ camel_imap4_engine_literal (CamelIMAP4Engine *engine, unsigned char **literal, s
}
-/**
- * camel_imap4_engine_nstring:
- * @engine: IMAP4 engine
- * @nstring: nstring pointer
- * @ex: exception
- *
- * Reads in an nstring (NIL, atom, qstring or literal) and updates
- * @nstring to point to it. @nstring must be free'd using g_free().
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_engine_nstring (CamelIMAP4Engine *engine, unsigned char **nstring, CamelException *ex)
-{
- camel_imap4_token_t token;
- size_t n;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- *nstring = NULL;
- break;
- case CAMEL_IMAP4_TOKEN_ATOM:
- *nstring = g_strdup (token.v.atom);
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- *nstring = g_strdup (token.v.qstring);
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- if (camel_imap4_engine_literal (engine, nstring, &n, ex) == -1)
- return -1;
- break;
- default:
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- return 0;
-}
-
-
-/**
- * camel_imap4_resp_code_free:
- * @rcode: RESP-CODE
- *
- * Free's the RESP-CODE
- **/
void
camel_imap4_resp_code_free (CamelIMAP4RespCode *rcode)
{
diff --git a/camel/providers/imap4/camel-imap4-store.c b/camel/providers/imap4/camel-imap4-store.c
index 2e7308d75d..0d33f43c5d 100644
--- a/camel/providers/imap4/camel-imap4-store.c
+++ b/camel/providers/imap4/camel-imap4-store.c
@@ -34,9 +34,6 @@
#include <camel/camel-private.h>
-#include <camel/camel-i18n.h>
-#include <camel/camel-net-utils.h>
-
#include "camel-imap4-store.h"
#include "camel-imap4-engine.h"
#include "camel-imap4-folder.h"
@@ -44,9 +41,7 @@
#include "camel-imap4-command.h"
#include "camel-imap4-utils.h"
#include "camel-imap4-summary.h"
-#include "camel-imap4-store-summary.h"
-#define d(x) x
static void camel_imap4_store_class_init (CamelIMAP4StoreClass *klass);
static void camel_imap4_store_init (CamelIMAP4Store *store, CamelIMAP4StoreClass *klass);
@@ -148,7 +143,6 @@ static void
camel_imap4_store_init (CamelIMAP4Store *store, CamelIMAP4StoreClass *klass)
{
store->engine = NULL;
- store->summary = NULL;
}
static void
@@ -156,11 +150,6 @@ camel_imap4_store_finalize (CamelObject *object)
{
CamelIMAP4Store *store = (CamelIMAP4Store *) object;
- if (store->summary) {
- camel_store_summary_save ((CamelStoreSummary *) store->summary);
- camel_object_unref (store->summary);
- }
-
if (store->engine)
camel_object_unref (store->engine);
@@ -172,7 +161,6 @@ static void
imap4_construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex)
{
CamelIMAP4Store *store = (CamelIMAP4Store *) service;
- char *buf;
CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
if (camel_exception_is_set (ex))
@@ -180,20 +168,6 @@ imap4_construct (CamelService *service, CamelSession *session, CamelProvider *pr
store->storage_path = camel_session_get_storage_path (session, service, ex);
store->engine = camel_imap4_engine_new (service, imap4_reconnect);
-
- /* setup/load the summary */
- buf = g_alloca (strlen (store->storage_path) + 32);
- sprintf (buf, "%s/.summary", store->storage_path);
- store->summary = camel_imap4_store_summary_new ();
- camel_store_summary_set_filename ((CamelStoreSummary *) store->summary, buf);
-
- buf = camel_url_to_string (service->url, CAMEL_URL_HIDE_ALL);
- url = camel_url_new (buf, NULL);
- g_free (buf);
- camel_store_summary_set_uri_base ((CamelStoreSummary *) store->summary, url);
- camel_url_free (url);
-
- camel_store_summary_load ((CamelStoreSummary *) store->summary);
}
static char *
@@ -226,7 +200,7 @@ connect_to_server (CamelIMAP4Engine *engine, struct addrinfo *ai, int ssl_mode,
if (ssl_mode != MODE_CLEAR) {
#ifdef HAVE_SSL
if (ssl_mode == MODE_TLS) {
- tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
+ tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, STARTTLS_FLAGS);
} else {
tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
}
@@ -262,8 +236,6 @@ connect_to_server (CamelIMAP4Engine *engine, struct addrinfo *ai, int ssl_mode,
if (camel_imap4_engine_capability (engine, ex) == -1)
return FALSE;
- camel_imap4_store_summary_set_capabilities (((CamelIMAP4Store *) service)->summary, engine->capa);
-
if (ssl_mode != MODE_TLS) {
/* we're done */
return TRUE;
@@ -320,9 +292,9 @@ connect_to_server_wrapper (CamelIMAP4Engine *engine, CamelException *ex)
struct addrinfo *ai, hints;
const char *ssl_mode;
int mode, ret, i;
- const char *port;
char *serv;
-
+ const char *port;
+
if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
for (i = 0; ssl_options[i].value; i++)
if (!strcmp (ssl_options[i].value, ssl_mode))
@@ -353,13 +325,7 @@ connect_to_server_wrapper (CamelIMAP4Engine *engine, CamelException *ex)
if (ai == NULL)
return FALSE;
- if (!(ret = connect_to_server (engine, ai, mode, ex)) && mode == MODE_SSL) {
- camel_exception_clear (ex);
- ret = connect_to_server (engine, ai, MODE_TLS, ex);
- } else if (!ret && mode == MODE_TLS) {
- camel_exception_clear (ex);
- ret = connect_to_server (engine, ai, MODE_CLEAR, ex);
- }
+ ret = connect_to_server (engine, ai, mode, ex);
camel_freeaddrinfo (ai);
@@ -389,7 +355,7 @@ sasl_auth (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, const unsigned char
if (!(challenge = camel_sasl_challenge_base64 (sasl, (const char *) linebuf, ex)))
return -1;
- d(fprintf (stderr, "sending : %s\r\n", challenge));
+ fprintf (stderr, "sending : %s\r\n", challenge);
if (camel_stream_printf (engine->ostream, "%s\r\n", challenge) == -1) {
g_free (challenge);
@@ -437,7 +403,7 @@ imap4_try_authenticate (CamelIMAP4Engine *engine, gboolean reprompt, const char
CamelServiceAuthType *mech;
mech = g_hash_table_lookup (engine->authtypes, service->url->authmech);
- sasl = camel_sasl_new ("imap", mech->authproto, service);
+ sasl = camel_sasl_new ("imap4", mech->authproto, service);
ic = camel_imap4_engine_prequeue (engine, NULL, "AUTHENTICATE %s\r\n", service->url->authmech);
ic->plus = sasl_auth;
@@ -501,8 +467,6 @@ imap4_reconnect (CamelIMAP4Engine *engine, CamelException *ex)
g_free (errmsg);
errmsg = g_strdup (lex.desc);
camel_exception_clear (&lex);
- g_free (service->url->passwd);
- service->url->passwd = NULL;
reprompt = TRUE;
}
g_free (errmsg);
@@ -515,25 +479,16 @@ imap4_reconnect (CamelIMAP4Engine *engine, CamelException *ex)
if (camel_imap4_engine_namespace (engine, ex) == -1)
return FALSE;
- camel_imap4_store_summary_set_namespaces (((CamelIMAP4Store *) service)->summary, &engine->namespaces);
-
return TRUE;
}
static gboolean
imap4_connect (CamelService *service, CamelException *ex)
{
- CamelIMAP4Store *store = (CamelIMAP4Store *) service;
gboolean retval;
- if (!camel_session_is_online (service->session))
- return TRUE;
-
CAMEL_SERVICE_LOCK (service, connect_lock);
- if (store->engine->state == CAMEL_IMAP4_ENGINE_DISCONNECTED)
- retval = imap4_reconnect (store->engine, ex);
- else
- retval = TRUE;
+ retval = imap4_reconnect (((CamelIMAP4Store *) service)->engine, ex);
CAMEL_SERVICE_UNLOCK (service, connect_lock);
return retval;
@@ -546,18 +501,13 @@ imap4_disconnect (CamelService *service, gboolean clean, CamelException *ex)
CamelIMAP4Command *ic;
int id;
- if (!camel_session_is_online (service->session))
- return TRUE;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
- if (clean && store->engine->state != CAMEL_IMAP4_ENGINE_DISCONNECTED) {
+ if (clean && !store->engine->istream->disconnected) {
ic = camel_imap4_engine_queue (store->engine, NULL, "LOGOUT\r\n");
while ((id = camel_imap4_engine_iterate (store->engine)) < ic->id && id != -1)
;
camel_imap4_command_unref (ic);
}
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
return 0;
}
@@ -572,9 +522,6 @@ imap4_query_auth_types (CamelService *service, CamelException *ex)
GList *sasl_types, *t, *next;
gboolean connected;
- if (!camel_session_is_online (service->session))
- return NULL;
-
CAMEL_SERVICE_LOCK (store, connect_lock);
connected = connect_to_server_wrapper (store->engine, ex);
CAMEL_SERVICE_UNLOCK (store, connect_lock);
@@ -595,30 +542,83 @@ imap4_query_auth_types (CamelService *service, CamelException *ex)
return g_list_prepend (sasl_types, &camel_imap4_password_authtype);
}
+
+static char
+imap4_get_path_delim (CamelIMAP4Engine *engine, const char *full_name)
+{
+ /* FIXME: move this to utils so imap4-folder.c can share */
+ CamelIMAP4Namespace *namespace;
+ const char *slash;
+ size_t len;
+ char *top;
+
+ if ((slash = strchr (full_name, '/')))
+ len = (slash - full_name);
+ else
+ len = strlen (full_name);
+
+ top = g_alloca (len + 1);
+ memcpy (top, full_name, len);
+ top[len] = '\0';
+
+ if (!g_ascii_strcasecmp (top, "INBOX"))
+ top = "INBOX";
+
+ retry:
+ namespace = engine->namespaces.personal;
+ while (namespace != NULL) {
+ if (!strcmp (namespace->path, top))
+ return namespace->sep;
+ namespace = namespace->next;
+ }
+
+ namespace = engine->namespaces.other;
+ while (namespace != NULL) {
+ if (!strcmp (namespace->path, top))
+ return namespace->sep;
+ namespace = namespace->next;
+ }
+
+ namespace = engine->namespaces.shared;
+ while (namespace != NULL) {
+ if (!strcmp (namespace->path, top))
+ return namespace->sep;
+ namespace = namespace->next;
+ }
+
+ if (top[0] != '\0') {
+ /* look for a default namespace? */
+ top[0] = '\0';
+ goto retry;
+ }
+
+ return '/';
+}
+
static char *
imap4_folder_utf7_name (CamelStore *store, const char *folder_name, char wildcard)
{
char *real_name, *p;
- char sep = '\0';
+ char sep;
int len;
- if (*folder_name) {
- sep = camel_imap4_get_path_delim (((CamelIMAP4Store *) store)->summary, folder_name);
-
- if (sep != '/') {
- p = real_name = g_alloca (strlen (folder_name) + 1);
- strcpy (real_name, folder_name);
- while (*p != '\0') {
- if (*p == '/')
- *p = sep;
- p++;
- }
-
- folder_name = real_name;
+ sep = imap4_get_path_delim (((CamelIMAP4Store *) store)->engine, folder_name);
+
+ if (sep != '/') {
+ p = real_name = g_alloca (strlen (folder_name) + 1);
+ strcpy (real_name, folder_name);
+ while (*p != '\0') {
+ if (*p == '/')
+ *p = sep;
+ p++;
}
+ folder_name = real_name;
+ }
+
+ if (*folder_name)
real_name = camel_utf8_utf7 (folder_name);
- } else
+ else
real_name = g_strdup ("");
if (wildcard) {
@@ -639,7 +639,6 @@ static CamelFolder *
imap4_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelFolder *folder = NULL;
camel_imap4_list_t *list;
CamelIMAP4Command *ic;
@@ -651,18 +650,6 @@ imap4_get_folder (CamelStore *store, const char *folder_name, guint32 flags, Cam
CAMEL_SERVICE_LOCK (store, connect_lock);
- if (!camel_session_is_online (session)) {
- if ((flags & CAMEL_STORE_FOLDER_CREATE) != 0) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create IMAP folders in offline mode."));
- } else {
- folder = camel_imap4_folder_new (store, folder_name, ex);
- }
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return folder;
- }
-
/* make sure the folder exists - try LISTing it? */
utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
ic = camel_imap4_engine_queue (engine, NULL, "LIST \"\" %S\r\n", utf7_name);
@@ -740,7 +727,6 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
* contain subfolders - delete them and re-create with the
* proper hint */
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelFolderInfo *fi = NULL;
CamelIMAP4Command *ic;
char *utf7_name;
@@ -750,7 +736,7 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
char sep;
int id;
- sep = camel_imap4_get_path_delim (((CamelIMAP4Store *) store)->summary, parent_name);
+ sep = imap4_get_path_delim (engine, parent_name);
c = folder_name;
while (*c != '\0') {
@@ -765,11 +751,6 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
c++;
}
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create IMAP folders in offline mode."));
- return NULL;
- }
-
if (parent_name != NULL && *parent_name)
name = g_strdup_printf ("%s/%s", parent_name, folder_name);
else
@@ -807,8 +788,6 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
fi->unread = -1;
fi->total = -1;
- camel_imap4_store_summary_note_info (((CamelIMAP4Store *) store)->summary, fi);
-
camel_object_trigger_event (store, "folder_created", fi);
break;
case CAMEL_IMAP4_RESULT_NO:
@@ -841,7 +820,6 @@ static void
imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelFolder *selected = (CamelFolder *) engine->folder;
CamelIMAP4Command *ic, *ic0 = NULL;
CamelFolderInfo *fi;
@@ -858,11 +836,6 @@ imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException
return;
}
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot delete IMAP folders in offline mode."));
- return;
- }
-
CAMEL_SERVICE_LOCK (store, connect_lock);
if (selected && !strcmp (folder_name, selected->full_name))
@@ -909,8 +882,6 @@ imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException
fi->unread = -1;
fi->total = -1;
- camel_imap4_store_summary_unnote_info (((CamelIMAP4Store *) store)->summary, fi);
-
camel_object_trigger_event (store, "folder_deleted", fi);
camel_folder_info_free (fi);
@@ -937,7 +908,6 @@ static void
imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
char *old_uname, *new_uname;
CamelIMAP4Command *ic;
int id;
@@ -950,11 +920,6 @@ imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_na
return;
}
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot rename IMAP folders in offline mode."));
- return;
- }
-
CAMEL_SERVICE_LOCK (store, connect_lock);
old_uname = imap4_folder_utf7_name (store, old_name, '\0');
@@ -977,7 +942,6 @@ imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_na
switch (ic->result) {
case CAMEL_IMAP4_RESULT_OK:
/* FIXME: need to update state on the renamed folder object */
- /* FIXME: need to update cached summary info too */
break;
case CAMEL_IMAP4_RESULT_NO:
/* FIXME: would be good to save the NO reason into the err message */
@@ -1091,11 +1055,6 @@ imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtr
url = camel_url_copy (engine->url);
- if (!strcmp (top, "") && (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE)) {
- /* clear the folder-info cache */
- camel_store_summary_clear ((CamelStoreSummary *) ((CamelIMAP4Store *) store)->summary);
- }
-
for (i = 0; i < array->len; i++) {
list = array->pdata[i];
fi = g_malloc0 (sizeof (CamelFolderInfo));
@@ -1116,20 +1075,34 @@ imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtr
fi->flags = list->flags;
fi->unread = -1;
fi->total = -1;
-
- /* SELECTED folder, just get it from the folder */
- if (folder && !strcmp (folder->full_name, fi->full_name)) {
- camel_object_get(folder, NULL, CAMEL_FOLDER_TOTAL, &fi->total, CAMEL_FOLDER_UNREAD, &fi->unread, 0);
- } else if (!(flags & CAMEL_STORE_FOLDER_INFO_FAST)) {
- imap4_status (store, fi);
+
+ if (!(flags & CAMEL_STORE_FOLDER_INFO_FAST)) {
+ if (folder && !strcmp (folder->full_name, fi->full_name)) {
+ /* can't STATUS this folder since it is SELECTED, besides - it would be wasteful */
+ CamelMessageInfo *info;
+ int index;
+
+ fi->total = camel_folder_summary_count (folder->summary);
+
+ fi->unread = 0;
+ for (index = 0; index < fi->total; index++) {
+ if (!(info = camel_folder_summary_index (folder->summary, index)))
+ continue;
+
+ if ((info->flags & CAMEL_MESSAGE_SEEN) == 0)
+ fi->unread++;
+
+ camel_folder_summary_info_free (folder->summary, info);
+ }
+ } else {
+ imap4_status (store, fi);
+ }
}
g_free (list->name);
g_free (list);
array->pdata[i] = fi;
-
- camel_imap4_store_summary_note_info (((CamelIMAP4Store *) store)->summary, fi);
}
fi = camel_folder_info_build (array, top, '/', TRUE);
@@ -1138,8 +1111,6 @@ imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtr
g_ptr_array_free (array, TRUE);
- camel_store_summary_save ((CamelStoreSummary *) ((CamelIMAP4Store *) store)->summary);
-
return fi;
}
@@ -1147,7 +1118,6 @@ static CamelFolderInfo *
imap4_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelIMAP4Command *ic, *ic0 = NULL;
CamelFolderInfo *fi = NULL;
camel_imap4_list_t *list;
@@ -1157,30 +1127,23 @@ imap4_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelE
char wildcard;
int id, i;
- if (top == NULL)
- top = "";
-
CAMEL_SERVICE_LOCK (store, connect_lock);
- if (!camel_session_is_online (session) || engine->state == CAMEL_IMAP4_ENGINE_DISCONNECTED) {
- fi = camel_imap4_store_summary_get_folder_info (((CamelIMAP4Store *) store)->summary, top, flags);
- if (fi == NULL && camel_session_is_online (session)) {
- /* folder info hasn't yet been cached and the store hasn't been
- * connected yet, but the network is available so we can connect
- * and query the server. */
- goto check_online;
- }
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return fi;
+ if (engine->state == CAMEL_IMAP4_ENGINE_DISCONNECTED) {
+ if (!camel_service_connect ((CamelService *) store, ex))
+ return NULL;
+
+ engine = ((CamelIMAP4Store *) store)->engine;
}
- check_online:
-
if (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)
cmd = "LSUB";
else
cmd = "LIST";
+ if (top == NULL)
+ top = "";
+
wildcard = (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) ? '*' : '%';
pattern = imap4_folder_utf7_name (store, top, wildcard);
array = g_ptr_array_new ();
@@ -1268,7 +1231,6 @@ static void
imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelIMAP4Command *ic;
CamelFolderInfo *fi;
char *utf7_name;
@@ -1276,11 +1238,6 @@ imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelExcepti
const char *p;
int id;
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot subscribe to IMAP folders in offline mode."));
- return;
- }
-
CAMEL_SERVICE_LOCK (store, connect_lock);
utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
@@ -1314,8 +1271,6 @@ imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelExcepti
fi->unread = -1;
fi->total = -1;
- camel_imap4_store_summary_note_info (((CamelIMAP4Store *) store)->summary, fi);
-
camel_object_trigger_event (store, "folder_subscribed", fi);
camel_folder_info_free (fi);
break;
@@ -1341,7 +1296,6 @@ static void
imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelIMAP4Command *ic;
CamelFolderInfo *fi;
char *utf7_name;
@@ -1349,11 +1303,6 @@ imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelExcep
const char *p;
int id;
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot unsubscribe from IMAP folders in offline mode."));
- return;
- }
-
CAMEL_SERVICE_LOCK (store, connect_lock);
utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
@@ -1387,8 +1336,6 @@ imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelExcep
fi->unread = -1;
fi->total = -1;
- camel_imap4_store_summary_unnote_info (((CamelIMAP4Store *) store)->summary, fi);
-
camel_object_trigger_event (store, "folder_unsubscribed", fi);
camel_folder_info_free (fi);
break;
@@ -1414,14 +1361,10 @@ static void
imap4_noop (CamelStore *store, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelFolder *folder = (CamelFolder *) engine->folder;
CamelIMAP4Command *ic;
int id;
- if (!camel_session_is_online (session))
- return;
-
CAMEL_SERVICE_LOCK (store, connect_lock);
if (folder) {
diff --git a/camel/providers/imapp/camel-imapp-store.c b/camel/providers/imapp/camel-imapp-store.c
index 03f835da7a..c1c9f50649 100644
--- a/camel/providers/imapp/camel-imapp-store.c
+++ b/camel/providers/imapp/camel-imapp-store.c
@@ -48,7 +48,6 @@
#ifdef HAVE_SSL
#include "camel/camel-tcp-stream-ssl.h"
#endif
-#include "camel/camel-i18n.h"
#include "camel-imapp-store-summary.h"
#include "camel-imapp-store.h"
@@ -57,7 +56,6 @@
#include "camel-imapp-exception.h"
#include "camel-imapp-utils.h"
#include "camel-imapp-driver.h"
-#include "camel-net-utils.h"
/* Specified in RFC 2060 section 2.1 */
#define IMAP_PORT 143
@@ -811,7 +809,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data)
if (strcmp(finfo->uid, camel_message_info_uid(info)) != 0) {
printf("summary at index %d has uid %s expected %s\n", id, camel_message_info_uid(info), finfo->uid);
/* uid mismatch??? try do it based on uid instead? try to reorder? i dont know? */
- camel_message_info_free(info);
+ camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
info = camel_folder_summary_uid(((CamelFolder *)istore->selected)->summary, finfo->uid);
}
}
@@ -860,7 +858,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data)
CamelMimeParser *mp;
if (pending == NULL)
- camel_message_info_free(info);
+ camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
mp = camel_mime_parser_new();
camel_mime_parser_init_with_stream(mp, finfo->header);
info = camel_folder_summary_info_new_from_parser(((CamelFolder *)istore->selected)->summary, mp);
@@ -873,7 +871,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data)
/* FIXME: use a dlist */
e_dlist_remove((EDListNode *)pending);
g_hash_table_remove(istore->pending_fetch_table, camel_message_info_uid(pending->info));
- camel_message_info_free(pending->info);
+ camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, pending->info);
/*e_memchunk_free(istore->pending_fetch_chunks, pending);*/
}
} else if (finfo->got & FETCH_FLAGS) {
@@ -885,7 +883,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data)
}
} else {
if (pending == NULL)
- camel_message_info_free(info);
+ camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
printf("got unexpected fetch response?\n");
imap_dump_fetch(finfo);
}
@@ -975,7 +973,7 @@ camel_imapp_store_folder_selected(CamelIMAPPStore *store, CamelIMAPPFolder *fold
if (info) {
printf("message info [%d] =\n", i);
camel_message_info_dump(info);
- camel_message_info_free(info);
+ camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
}
}
} CAMEL_CATCH (e) {
diff --git a/camel/providers/local/camel-local-folder.c b/camel/providers/local/camel-local-folder.c
index 70673d9687..b86d23221a 100644
--- a/camel/providers/local/camel-local-folder.c
+++ b/camel/providers/local/camel-local-folder.c
@@ -20,6 +20,7 @@
*
*/
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -47,7 +48,6 @@
#include "camel-stream-filter.h"
#include "camel-mime-filter-from.h"
#include "camel-exception.h"
-#include "camel-i18n.h"
#include "camel-local-private.h"
diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c
index b74f6e5ace..ba42b75f28 100644
--- a/camel/providers/local/camel-maildir-folder.c
+++ b/camel/providers/local/camel-maildir-folder.c
@@ -39,7 +39,6 @@
#include "camel-data-wrapper.h"
#include "camel-mime-message.h"
#include "camel-exception.h"
-#include "camel-i18n.h"
#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
@@ -153,7 +152,7 @@ camel_maildir_folder_new(CamelStore *parent_store, const char *full_name, guint3
static CamelLocalSummary *maildir_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
{
- return (CamelLocalSummary *)camel_maildir_summary_new((CamelFolder *)lf, path, folder, index);
+ return (CamelLocalSummary *)camel_maildir_summary_new(path, folder, index);
}
static void
@@ -251,7 +250,7 @@ static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar *
/* what do we do if the message flags (and :info data) changes? filename mismatch - need to recheck I guess */
name = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename(mdi));
- camel_message_info_free(info);
+ camel_folder_summary_info_free(folder->summary, info);
if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) {
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
diff --git a/camel/providers/local/camel-mbox-folder.c b/camel/providers/local/camel-mbox-folder.c
index d213b444fc..fa8f0b645d 100644
--- a/camel/providers/local/camel-mbox-folder.c
+++ b/camel/providers/local/camel-mbox-folder.c
@@ -42,7 +42,6 @@
#include "camel-stream-filter.h"
#include "camel-mime-filter-from.h"
#include "camel-exception.h"
-#include "camel-i18n.h"
#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
@@ -56,6 +55,13 @@ static CamelLocalFolderClass *parent_class = NULL;
static int mbox_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex);
static void mbox_unlock(CamelLocalFolder *lf);
+#ifdef STATUS_PINE
+static gboolean mbox_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set);
+#endif
+
+static void mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value);
+static void mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value);
+
static void mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info, char **appended_uid, CamelException *ex);
static CamelMimeMessage *mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex);
static CamelLocalSummary *mbox_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index);
@@ -76,6 +82,12 @@ camel_mbox_folder_class_init(CamelMboxFolderClass * camel_mbox_folder_class)
camel_folder_class->append_message = mbox_append_message;
camel_folder_class->get_message = mbox_get_message;
+#ifdef STATUS_PINE
+ camel_folder_class->set_message_flags = mbox_set_message_flags;
+#endif
+ camel_folder_class->set_message_user_flag = mbox_set_message_user_flag;
+ camel_folder_class->set_message_user_tag = mbox_set_message_user_tag;
+
lclass->get_full_path = camel_mbox_folder_get_full_path;
lclass->get_meta_path = camel_mbox_folder_get_meta_path;
lclass->create_summary = mbox_create_summary;
@@ -194,7 +206,7 @@ camel_mbox_folder_get_meta_path (CamelLocalFolder *lf, const char *toplevel_dir,
static CamelLocalSummary *mbox_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
{
- return (CamelLocalSummary *)camel_mbox_summary_new((CamelFolder *)lf, path, folder, index);
+ return (CamelLocalSummary *)camel_mbox_summary_new(path, folder, index);
}
static int mbox_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex)
@@ -408,7 +420,7 @@ retry:
g_assert(info->frompos != -1);
frompos = info->frompos;
- camel_message_info_free((CamelMessageInfo *)info);
+ camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)info);
/* we use an fd instead of a normal stream here - the reason is subtle, camel_mime_part will cache
the whole message in memory if the stream is non-seekable (which it is when built from a parser
@@ -480,3 +492,66 @@ fail:
return message;
}
+
+#ifdef STATUS_PINE
+static gboolean
+mbox_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set)
+{
+ /* Basically, if anything could change the Status line, presume it does */
+ if (((CamelMboxSummary *)folder->summary)->xstatus
+ && (flags & (CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_ANSWERED|CAMEL_MESSAGE_DELETED))) {
+ flags |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED;
+ set |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED;
+ }
+
+ return ((CamelFolderClass *)parent_class)->set_message_flags(folder, uid, flags, set);
+}
+#endif
+
+static void
+mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value)
+{
+ CamelMessageInfo *info;
+
+ g_return_if_fail(folder->summary != NULL);
+
+ info = camel_folder_summary_uid(folder->summary, uid);
+ if (info == NULL)
+ return;
+
+ if (camel_flag_set(&info->user_flags, name, value)) {
+ CamelFolderChangeInfo *changes = camel_folder_change_info_new();
+
+ info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE;
+ camel_folder_summary_touch(folder->summary);
+
+ camel_folder_change_info_change_uid(changes, uid);
+ camel_object_trigger_event(folder, "folder_changed", changes);
+ camel_folder_change_info_free(changes);
+ }
+ camel_folder_summary_info_free(folder->summary, info);
+}
+
+static void
+mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value)
+{
+ CamelMessageInfo *info;
+
+ g_return_if_fail(folder->summary != NULL);
+
+ info = camel_folder_summary_uid(folder->summary, uid);
+ if (info == NULL)
+ return;
+
+ if (camel_tag_set(&info->user_tags, name, value)) {
+ CamelFolderChangeInfo *changes = camel_folder_change_info_new();
+
+ info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE;
+ camel_folder_summary_touch(folder->summary);
+
+ camel_folder_change_info_change_uid(changes, uid);
+ camel_object_trigger_event (folder, "folder_changed", changes);
+ camel_folder_change_info_free(changes);
+ }
+ camel_folder_summary_info_free(folder->summary, info);
+}
diff --git a/camel/providers/local/camel-mbox-store.c b/camel/providers/local/camel-mbox-store.c
index a9e581cdd7..1277407dbb 100644
--- a/camel/providers/local/camel-mbox-store.c
+++ b/camel/providers/local/camel-mbox-store.c
@@ -37,7 +37,6 @@
#include "camel-text-index.h"
#include "camel-exception.h"
#include "camel-url.h"
-#include "camel-i18n.h"
#define d(x)
@@ -618,7 +617,7 @@ fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags)
path = camel_mbox_folder_get_meta_path(NULL, root, fi->full_name, ".ev-summary");
folderpath = camel_mbox_folder_get_full_path(NULL, root, fi->full_name);
- mbs = (CamelMboxSummary *)camel_mbox_summary_new(NULL, path, folderpath, NULL);
+ mbs = (CamelMboxSummary *)camel_mbox_summary_new(path, folderpath, NULL);
if (camel_folder_summary_header_load((CamelFolderSummary *)mbs) != -1) {
fi->unread = ((CamelFolderSummary *)mbs)->unread_count;
fi->total = ((CamelFolderSummary *)mbs)->saved_count;
diff --git a/camel/providers/local/camel-mh-folder.c b/camel/providers/local/camel-mh-folder.c
index 1b054a4547..78456b6daf 100644
--- a/camel/providers/local/camel-mh-folder.c
+++ b/camel/providers/local/camel-mh-folder.c
@@ -39,7 +39,6 @@
#include "camel-data-wrapper.h"
#include "camel-mime-message.h"
#include "camel-exception.h"
-#include "camel-i18n.h"
#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
@@ -117,7 +116,7 @@ camel_mh_folder_new(CamelStore *parent_store, const char *full_name, guint32 fla
static CamelLocalSummary *mh_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
{
- return (CamelLocalSummary *)camel_mh_summary_new((CamelFolder *)lf, path, folder, index);
+ return (CamelLocalSummary *)camel_mh_summary_new(path, folder, index);
}
static void
@@ -205,7 +204,7 @@ static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid,
}
/* we only need it to check the message exists */
- camel_message_info_free(info);
+ camel_folder_summary_info_free(folder->summary, info);
name = g_strdup_printf("%s/%s", lf->folder_path, uid);
if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) {
diff --git a/camel/providers/local/camel-spool-folder.c b/camel/providers/local/camel-spool-folder.c
index c4c7da91b6..6a1bbf798a 100644
--- a/camel/providers/local/camel-spool-folder.c
+++ b/camel/providers/local/camel-spool-folder.c
@@ -44,8 +44,8 @@
#include "camel-session.h"
#include "camel-file-utils.h"
#include "camel-lock-client.h"
+
#include "camel-local-private.h"
-#include "camel-i18n.h"
#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
@@ -160,7 +160,7 @@ spool_get_meta_path(CamelLocalFolder *lf, const char *toplevel_dir, const char *
static CamelLocalSummary *
spool_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
{
- return (CamelLocalSummary *)camel_spool_summary_new((CamelFolder *)lf, folder);
+ return (CamelLocalSummary *)camel_spool_summary_new(folder);
}
static int
diff --git a/camel/providers/local/camel-spool-store.c b/camel/providers/local/camel-spool-store.c
index 3dc21886c8..2e3d9ea777 100644
--- a/camel/providers/local/camel-spool-store.c
+++ b/camel/providers/local/camel-spool-store.c
@@ -41,7 +41,6 @@
#include "camel-exception.h"
#include "camel-url.h"
#include "camel-private.h"
-#include "camel-i18n.h"
#define d(x)
diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c
index de0f4cd222..ffb1b29742 100644
--- a/camel/providers/nntp/camel-nntp-folder.c
+++ b/camel/providers/nntp/camel-nntp-folder.c
@@ -49,7 +49,6 @@
#include "camel/camel-multipart.h"
#include "camel/camel-mime-part.h"
#include "camel/camel-stream-buffer.h"
-#include "camel/camel-i18n.h"
#include "camel/camel-private.h"
#include "camel-nntp-summary.h"
@@ -511,7 +510,7 @@ camel_nntp_folder_new (CamelStore *parent, const char *folder_name, CamelExcepti
g_free(root);
root = g_strdup_printf("%s.ev-summary", nntp_folder->storage_path);
- folder->summary = (CamelFolderSummary *) camel_nntp_summary_new (folder, root);
+ folder->summary = (CamelFolderSummary *) camel_nntp_summary_new (root);
g_free(root);
camel_folder_summary_load (folder->summary);
diff --git a/camel/providers/nntp/camel-nntp-private.h b/camel/providers/nntp/camel-nntp-private.h
index 520c9db134..253d4e2031 100644
--- a/camel/providers/nntp/camel-nntp-private.h
+++ b/camel/providers/nntp/camel-nntp-private.h
@@ -35,7 +35,7 @@ extern "C" {
#include <config.h>
#endif
-#include "libedataserver/e-msgport.h"
+#include "e-util/e-msgport.h"
struct _CamelNNTPStorePrivate {
int dummy;
diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c
index f9daad8515..3e911ec1c5 100644
--- a/camel/providers/nntp/camel-nntp-store.c
+++ b/camel/providers/nntp/camel-nntp-store.c
@@ -53,8 +53,6 @@
#include "camel-nntp-folder.h"
#include "camel-nntp-private.h"
#include "camel-nntp-resp-codes.h"
-#include "camel-i18n.h"
-#include "camel-net-utils.h"
#define w(x)
#define dd(x) (camel_debug("nntp")?(x):0)
@@ -85,6 +83,12 @@ nntp_can_work_offline(CamelDiscoStore *store)
return TRUE;
}
+enum {
+ USE_SSL_NEVER,
+ USE_SSL_ALWAYS,
+ USE_SSL_WHEN_POSSIBLE
+};
+
static struct {
const char *name;
int type;
@@ -149,17 +153,8 @@ xover_setup(CamelNNTPStore *store, CamelException *ex)
return ret;
}
-enum {
- MODE_CLEAR,
- MODE_SSL,
- MODE_TLS,
-};
-
-#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
-#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
-
static gboolean
-connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, CamelException *ex)
+connect_to_server (CamelService *service, int ssl_mode, CamelException *ex)
{
CamelNNTPStore *store = (CamelNNTPStore *) service;
CamelDiscoStore *disco_store = (CamelDiscoStore*) service;
@@ -169,6 +164,9 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
unsigned int len;
int ret;
char *path;
+ struct addrinfo *ai, hints = { 0 };
+ char *serv;
+ const char *port = NULL;
CAMEL_SERVICE_LOCK(store, connect_lock);
@@ -185,34 +183,50 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
camel_data_cache_set_expire_age (store->cache, 60*60*24*14);
camel_data_cache_set_expire_access (store->cache, 60*60*24*5);
}
+
+ if (service->url->port) {
+ serv = g_alloca(16);
+ sprintf(serv, "%d", service->url->port);
+ } else {
+ serv = "nntp";
+ port = NNTP_PORT;
+ }
- if (ssl_mode != MODE_CLEAR) {
#ifdef HAVE_SSL
- if (ssl_mode == MODE_TLS) {
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, STARTTLS_FLAGS);
- } else {
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
+ if (ssl_mode != USE_SSL_NEVER) {
+ if (service->url->port == 0) {
+ serv = "nntps";
+ port = NNTPS_PORT;
}
-#else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, _("SSL unavailable"));
-
- goto fail;
-#endif /* HAVE_SSL */
+ tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3);
} else {
tcp_stream = camel_tcp_stream_raw_new ();
}
+#else
+ tcp_stream = camel_tcp_stream_raw_new ();
+#endif /* HAVE_SSL */
+
+ hints.ai_socktype = SOCK_STREAM;
+ ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
+ if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
+ camel_exception_clear(ex);
+ ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
+ }
+ if (ai == NULL) {
+ camel_object_unref(tcp_stream);
+ goto fail;
+ }
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -1) {
+ ret = camel_tcp_stream_connect(CAMEL_TCP_STREAM(tcp_stream), ai);
+ camel_freeaddrinfo(ai);
+ if (ret == -1) {
if (errno == EINTR)
camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
_("Connection cancelled"));
else
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host,
- g_strerror (errno));
+ _("Could not connect to %s (port %s): %s"),
+ service->url->host, serv, g_strerror (errno));
camel_object_unref (tcp_stream);
@@ -254,11 +268,11 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
if (service->url->user != NULL
&& camel_nntp_try_authenticate(store, ex) != NNTP_AUTH_ACCEPTED)
goto fail;
-
- /* set 'reader' mode & ignore return code, also ping the server, inn goes offline very quickly otherwise */
+
+ /* set 'reader' mode & ignore return code, also ping the server, inn goes offline very quickly otherwise */
if (camel_nntp_raw_command_auth (store, ex, (char **) &buf, "mode reader") == -1
|| camel_nntp_raw_command_auth (store, ex, (char **) &buf, "date") == -1)
- goto fail;
+ goto fail;
if (xover_setup(store, ex) == -1)
goto fail;
@@ -279,61 +293,54 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
static struct {
char *value;
- char *serv;
- char *port;
int mode;
} ssl_options[] = {
- { "", "nntps", NNTPS_PORT, MODE_SSL }, /* really old (1.x) */
- { "always", "nntps", NNTPS_PORT, MODE_SSL },
- { "when-possible", "nntp", NNTP_PORT, MODE_TLS },
- { "never", "nntp", NNTP_PORT, MODE_CLEAR },
- { NULL, "nntp", NNTP_PORT, MODE_CLEAR },
+ { "", USE_SSL_ALWAYS },
+ { "always", USE_SSL_ALWAYS },
+ { "when-possible", USE_SSL_WHEN_POSSIBLE },
+ { "never", USE_SSL_NEVER },
+ { NULL, USE_SSL_NEVER },
};
static gboolean
nntp_connect_online (CamelService *service, CamelException *ex)
{
- struct addrinfo hints, *ai;
- const char *ssl_mode;
- int mode, ret, i;
- char *serv;
- const char *port;
+#ifdef HAVE_SSL
+ const char *use_ssl;
+ int i, ssl_mode;
- if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
+ use_ssl = camel_url_get_param (service->url, "use_ssl");
+ if (use_ssl) {
for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, ssl_mode))
+ if (!strcmp (ssl_options[i].value, use_ssl))
break;
- mode = ssl_options[i].mode;
- serv = ssl_options[i].serv;
- port = ssl_options[i].port;
+ ssl_mode = ssl_options[i].mode;
+ } else
+ ssl_mode = USE_SSL_NEVER;
+
+ if (ssl_mode == USE_SSL_ALWAYS) {
+ /* Connect via SSL */
+ return connect_to_server (service, ssl_mode, ex);
+ } else if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
+ /* If the server supports SSL, use it */
+ if (!connect_to_server (service, ssl_mode, ex)) {
+ if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE) {
+ /* The ssl port seems to be unavailable, fall back to plain NNTP */
+ camel_exception_clear (ex);
+ return connect_to_server (service, USE_SSL_NEVER, ex);
+ } else {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
} else {
- mode = MODE_CLEAR;
- serv = "nntp";
- port = NNTP_PORT;
+ /* User doesn't care about SSL */
+ return connect_to_server (service, ssl_mode, ex);
}
-
- if (service->url->port) {
- serv = g_alloca (16);
- sprintf (serv, "%d", service->url->port);
- port = NULL;
- }
-
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
- ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
- if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
- camel_exception_clear (ex);
- ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
- }
- if (ai == NULL)
- return FALSE;
-
- ret = connect_to_server (service, ai, mode, ex);
-
- camel_freeaddrinfo (ai);
-
- return ret;
+#else
+ return connect_to_server (service, USE_SSL_NEVER, ex);
+#endif
}
static gboolean
diff --git a/camel/providers/nntp/camel-nntp-stream.c b/camel/providers/nntp/camel-nntp-stream.c
index 244b67acb1..74bee9ced5 100644
--- a/camel/providers/nntp/camel-nntp-stream.c
+++ b/camel/providers/nntp/camel-nntp-stream.c
@@ -60,8 +60,6 @@ stream_fill(CamelNNTPStream *is)
is->end[0] = '\n';
return is->end - is->ptr;
} else {
- if (left == 0)
- errno = ECONNRESET;
dd(printf("NNTP_STREAM_FILL(ERROR): %d - '%s'\n", left, strerror(errno)));
return -1;
}
diff --git a/camel/providers/nntp/camel-nntp-summary.c b/camel/providers/nntp/camel-nntp-summary.c
index e6c02b95af..02589e632e 100644
--- a/camel/providers/nntp/camel-nntp-summary.c
+++ b/camel/providers/nntp/camel-nntp-summary.c
@@ -36,7 +36,6 @@
#include "camel/camel-stream-null.h"
#include "camel/camel-operation.h"
#include "camel/camel-data-cache.h"
-#include "camel/camel-i18n.h"
#include "camel/camel-debug.h"
#include "camel-nntp-summary.h"
@@ -60,7 +59,7 @@ struct _CamelNNTPSummaryPrivate {
#define _PRIVATE(o) (((CamelNNTPSummary *)(o))->priv)
-static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _camel_header_raw *);
static int summary_header_load(CamelFolderSummary *, FILE *);
static int summary_header_save(CamelFolderSummary *, FILE *);
@@ -94,7 +93,7 @@ camel_nntp_summary_class_init(CamelNNTPSummaryClass *klass)
camel_nntp_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_type_get_global_classfuncs(camel_folder_summary_get_type()));
- sklass->message_info_new_from_header = message_info_new_from_header;
+ sklass->message_info_new = message_info_new;
sklass->summary_header_load = summary_header_load;
sklass->summary_header_save = summary_header_save;
}
@@ -108,7 +107,7 @@ camel_nntp_summary_init(CamelNNTPSummary *obj)
p = _PRIVATE(obj) = g_malloc0(sizeof(*p));
/* subclasses need to set the right instance data sizes */
- s->message_info_size = sizeof(CamelMessageInfoBase);
+ s->message_info_size = sizeof(CamelMessageInfo);
s->content_info_size = sizeof(CamelMessageContentInfo);
/* and a unique file version */
@@ -124,12 +123,10 @@ camel_nntp_summary_finalise(CamelObject *obj)
}
CamelNNTPSummary *
-camel_nntp_summary_new(struct _CamelFolder *folder, const char *path)
+camel_nntp_summary_new(const char *path)
{
CamelNNTPSummary *cns = (CamelNNTPSummary *)camel_object_new(camel_nntp_summary_get_type());
- ((CamelFolderSummary *)cns)->folder = folder;
-
camel_folder_summary_set_filename((CamelFolderSummary *)cns, path);
camel_folder_summary_set_build_content((CamelFolderSummary *)cns, FALSE);
@@ -137,9 +134,9 @@ camel_nntp_summary_new(struct _CamelFolder *folder, const char *path)
}
static CamelMessageInfo *
-message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
+message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
{
- CamelMessageInfoBase *mi;
+ CamelMessageInfo *mi;
CamelNNTPSummary *cns = (CamelNNTPSummary *)s;
/* error to call without this setup */
@@ -149,13 +146,13 @@ message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
/* we shouldn't be here if we already have this uid */
g_assert(camel_folder_summary_uid(s, cns->priv->uid) == NULL);
- mi = (CamelMessageInfoBase *)((CamelFolderSummaryClass *)camel_nntp_summary_parent)->message_info_new_from_header(s, h);
+ mi = ((CamelFolderSummaryClass *)camel_nntp_summary_parent)->message_info_new(s, h);
if (mi) {
- mi->uid = g_strdup(cns->priv->uid);
+ camel_message_info_set_uid(mi, cns->priv->uid);
cns->priv->uid = NULL;
}
- return (CamelMessageInfo *)mi;
+ return mi;
}
static int
@@ -209,7 +206,7 @@ static int
add_range_xover(CamelNNTPSummary *cns, CamelNNTPStore *store, unsigned int high, unsigned int low, CamelFolderChangeInfo *changes, CamelException *ex)
{
CamelFolderSummary *s;
- CamelMessageInfoBase *mi;
+ CamelMessageInfo *mi;
struct _camel_header_raw *headers = NULL;
char *line, *tab;
int len, ret;
@@ -273,16 +270,16 @@ add_range_xover(CamelNNTPSummary *cns, CamelNNTPStore *store, unsigned int high,
/* truncated line? ignore? */
if (xover == NULL) {
- mi = (CamelMessageInfoBase *)camel_folder_summary_uid(s, cns->priv->uid);
+ mi = camel_folder_summary_uid(s, cns->priv->uid);
if (mi == NULL) {
- mi = (CamelMessageInfoBase *)camel_folder_summary_add_from_header(s, headers);
+ mi = camel_folder_summary_add_from_header(s, headers);
if (mi) {
mi->size = size;
cns->high = n;
camel_folder_change_info_add_uid(changes, camel_message_info_uid(mi));
}
} else {
- camel_message_info_free(mi);
+ camel_folder_summary_info_free(s, mi);
}
}
@@ -354,7 +351,7 @@ add_range_head(CamelNNTPSummary *cns, CamelNNTPStore *store, unsigned int high,
camel_folder_change_info_add_uid(changes, camel_message_info_uid(mi));
} else {
/* already have, ignore */
- camel_message_info_free(mi);
+ camel_folder_summary_info_free(s, mi);
}
if (cns->priv->uid) {
g_free(cns->priv->uid);
@@ -447,7 +444,7 @@ camel_nntp_summary_check(CamelNNTPSummary *cns, CamelNNTPStore *store, char *lin
i--;
}
- camel_message_info_free(mi);
+ camel_folder_summary_info_free(s, mi);
}
}
cns->low = f;
@@ -475,12 +472,12 @@ update:
count = camel_folder_summary_count(s);
for (i = 0; i < count; i++) {
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *)camel_folder_summary_index(s, i);
+ CamelMessageInfo *mi = camel_folder_summary_index(s, i);
if (mi) {
if ((mi->flags & CAMEL_MESSAGE_SEEN) == 0)
unread++;
- camel_message_info_free(mi);
+ camel_folder_summary_info_free(s, mi);
}
}
diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c
index 46a1fd3fe6..f7117b1b31 100644
--- a/camel/providers/pop3/camel-pop3-store.c
+++ b/camel/providers/pop3/camel-pop3-store.c
@@ -45,7 +45,7 @@
#include "camel-session.h"
#include "camel-exception.h"
#include "camel-url.h"
-#include "libedataserver/md5-utils.h"
+#include "e-util/md5-utils.h"
#include "camel-pop3-engine.h"
#include "camel-sasl.h"
#include "camel-data-cache.h"
@@ -54,12 +54,9 @@
#ifdef HAVE_SSL
#include "camel-tcp-stream-ssl.h"
#endif
-#include "camel-i18n.h"
-#include "camel-net-utils.h"
/* Specified in RFC 1939 */
-#define POP3_PORT "110"
-#define POP3S_PORT "995"
+#define POP3_PORT 110
static CamelStoreClass *parent_class = NULL;
@@ -137,16 +134,16 @@ finalize (CamelObject *object)
}
enum {
- MODE_CLEAR,
- MODE_SSL,
- MODE_TLS,
+ USE_SSL_NEVER,
+ USE_SSL_ALWAYS,
+ USE_SSL_WHEN_POSSIBLE
};
#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
static gboolean
-connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, CamelException *ex)
+connect_to_server (CamelService *service, int ssl_mode, int try_starttls, CamelException *ex)
{
CamelPOP3Store *store = CAMEL_POP3_STORE (service);
CamelStream *tcp_stream;
@@ -154,34 +151,67 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
guint32 flags = 0;
int clean_quit;
int ret;
-
- if (ssl_mode != MODE_CLEAR) {
+ struct addrinfo *ai, hints = { 0 };
+ char *serv;
+ const char *port = NULL;
+
+ if (service->url->port) {
+ serv = g_alloca(16);
+ sprintf(serv, "%d", service->url->port);
+ } else {
+ serv = "pop3";
+ port = "110";
+ }
+
+ if (ssl_mode != USE_SSL_NEVER) {
#ifdef HAVE_SSL
- if (ssl_mode == MODE_TLS) {
+ if (try_starttls) {
tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
} else {
+ if (service->url->port == 0) {
+ serv = "pop3s";
+ port = "995";
+ }
tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
}
#else
+ if (!try_starttls && service->url->port == 0) {
+ serv = "pop3s";
+ port = "995";
+ }
+
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, _("SSL unavailable"));
+ _("Could not connect to %s (port %s): %s"),
+ service->url->host, serv,
+ _("SSL unavailable"));
return FALSE;
#endif /* HAVE_SSL */
} else {
tcp_stream = camel_tcp_stream_raw_new ();
}
+
+ hints.ai_socktype = SOCK_STREAM;
+ ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
+ if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
+ camel_exception_clear(ex);
+ ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
+ }
+ if (ai == NULL) {
+ camel_object_unref(tcp_stream);
+ return FALSE;
+ }
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -1) {
+ ret = camel_tcp_stream_connect(CAMEL_TCP_STREAM(tcp_stream), ai);
+ camel_freeaddrinfo(ai);
+ if (ret == -1) {
if (errno == EINTR)
camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
_("Connection cancelled"));
else
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host,
- g_strerror (errno));
+ _("Could not connect to POP server %s (port %s): %s"),
+ service->url->host, serv, g_strerror (errno));
camel_object_unref (tcp_stream);
@@ -199,24 +229,41 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
if (!(store->engine = camel_pop3_engine_new (tcp_stream, flags))) {
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to read a valid greeting from POP server %s"),
- service->url->host);
- camel_object_unref (tcp_stream);
+ _("Failed to read a valid greeting from POP server %s (port %s)"),
+ service->url->host, serv);
return FALSE;
}
- if (ssl_mode != MODE_TLS) {
- camel_object_unref (tcp_stream);
- return TRUE;
+#ifdef HAVE_SSL
+ if (store->engine) {
+ if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
+ if (store->engine->capa & CAMEL_POP3_CAP_STLS)
+ goto starttls;
+ } else if (ssl_mode == USE_SSL_ALWAYS) {
+ if (try_starttls) {
+ if (store->engine->capa & CAMEL_POP3_CAP_STLS) {
+ /* attempt to toggle STARTTLS mode */
+ goto starttls;
+ } else {
+ /* server doesn't support STARTTLS, abort */
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to connect to POP server %s in secure mode: %s"),
+ service->url->host, _("SSL/TLS extension not supported."));
+ /* we have the possibility of quitting cleanly here */
+ clean_quit = TRUE;
+ goto stls_exception;
+ }
+ }
+ }
}
+#endif /* HAVE_SSL */
- if (!(store->engine->capa & CAMEL_POP3_CAP_STLS)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to POP server %s in secure mode: %s"),
- service->url->host, _("STLS not supported"));
- goto stls_exception;
- }
+ camel_object_unref (tcp_stream);
+ return store->engine != NULL;
+
+#ifdef HAVE_SSL
+ starttls:
/* as soon as we send a STLS command, all hope is lost of a clean QUIT if problems arise */
clean_quit = FALSE;
@@ -237,6 +284,8 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
/* Okay, now toggle SSL/TLS mode */
ret = camel_tcp_stream_ssl_enable_ssl (CAMEL_TCP_STREAM_SSL (tcp_stream));
+ camel_object_unref (CAMEL_OBJECT (tcp_stream));
+
if (ret == -1) {
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
_("Failed to connect to POP server %s in secure mode: %s"),
@@ -244,8 +293,6 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
goto stls_exception;
}
- camel_object_unref (tcp_stream);
-
/* rfc2595, section 4 states that after a successful STLS
command, the client MUST discard prior CAPA responses */
camel_pop3_engine_reget_capabilities (store->engine);
@@ -266,71 +313,59 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
store->engine = NULL;
return FALSE;
+#endif /* HAVE_SSL */
}
static struct {
char *value;
- char *serv;
- char *port;
int mode;
} ssl_options[] = {
- { "", "pop3s", POP3S_PORT, MODE_SSL }, /* really old (1.x) */
- { "always", "pop3s", POP3S_PORT, MODE_SSL },
- { "when-possible", "pop3", POP3_PORT, MODE_TLS },
- { "never", "pop3", POP3_PORT, MODE_CLEAR },
- { NULL, "pop3", POP3_PORT, MODE_CLEAR },
+ { "", USE_SSL_ALWAYS },
+ { "always", USE_SSL_ALWAYS },
+ { "when-possible", USE_SSL_WHEN_POSSIBLE },
+ { "never", USE_SSL_NEVER },
+ { NULL, USE_SSL_NEVER },
};
static gboolean
connect_to_server_wrapper (CamelService *service, CamelException *ex)
{
- struct addrinfo hints, *ai;
- const char *ssl_mode;
- int mode, ret, i;
- char *serv;
- const char *port;
-
- if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
+#ifdef HAVE_SSL
+ const char *use_ssl;
+ int i, ssl_mode;
+
+ use_ssl = camel_url_get_param (service->url, "use_ssl");
+ if (use_ssl) {
for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, ssl_mode))
+ if (!strcmp (ssl_options[i].value, use_ssl))
break;
- mode = ssl_options[i].mode;
- serv = ssl_options[i].serv;
- port = ssl_options[i].port;
+ ssl_mode = ssl_options[i].mode;
+ } else
+ ssl_mode = USE_SSL_NEVER;
+
+ if (ssl_mode == USE_SSL_ALWAYS) {
+ /* First try the ssl port */
+ if (!connect_to_server (service, ssl_mode, FALSE, ex)) {
+ if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE) {
+ /* The ssl port seems to be unavailable, lets try STARTTLS */
+ camel_exception_clear (ex);
+ return connect_to_server (service, ssl_mode, TRUE, ex);
+ } else {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ } else if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
+ /* If the server supports STARTTLS, use it */
+ return connect_to_server (service, ssl_mode, TRUE, ex);
} else {
- mode = MODE_CLEAR;
- serv = "pop3";
- port = POP3S_PORT;
+ /* User doesn't care about SSL */
+ return connect_to_server (service, ssl_mode, FALSE, ex);
}
-
- if (service->url->port) {
- serv = g_alloca (16);
- sprintf (serv, "%d", service->url->port);
- port = NULL;
- }
-
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
- ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
- if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
- camel_exception_clear (ex);
- ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
- }
- if (ai == NULL)
- return FALSE;
-
- if (!(ret = connect_to_server (service, ai, mode, ex)) && mode == MODE_SSL) {
- camel_exception_clear (ex);
- ret = connect_to_server (service, ai, MODE_TLS, ex);
- } else if (!ret && mode == MODE_TLS) {
- camel_exception_clear (ex);
- ret = connect_to_server (service, ai, MODE_CLEAR, ex);
- }
-
- camel_freeaddrinfo (ai);
-
- return ret;
+#else
+ return connect_to_server (service, USE_SSL_NEVER, FALSE, ex);
+#endif
}
extern CamelServiceAuthType camel_pop3_password_authtype;
diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c
index 065d79fdac..ea8ca26e49 100644
--- a/camel/providers/smtp/camel-smtp-transport.c
+++ b/camel/providers/smtp/camel-smtp-transport.c
@@ -55,15 +55,13 @@
#include "camel-session.h"
#include "camel-exception.h"
#include "camel-sasl.h"
-#include "camel-i18n.h"
-#include "camel-net-utils.h"
+
extern int camel_verbose_debug;
#define d(x) (camel_verbose_debug ? (x) : 0)
/* Specified in RFC 821 */
-#define SMTP_PORT "25"
-#define SMTPS_PORT "465"
+#define SMTP_PORT 25
/* camel smtp transport class prototypes */
static gboolean smtp_send_to (CamelTransport *transport, CamelMimeMessage *message,
@@ -147,7 +145,18 @@ smtp_construct (CamelService *service, CamelSession *session,
CamelProvider *provider, CamelURL *url,
CamelException *ex)
{
+ CamelSmtpTransport *smtp_transport = CAMEL_SMTP_TRANSPORT (service);
+ const char *use_ssl;
+
CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
+
+ if ((use_ssl = camel_url_get_param (url, "use_ssl"))) {
+ /* Note: previous versions would use "" to toggle use_ssl to 'on' */
+ if (!*use_ssl || !strcmp (use_ssl, "always"))
+ smtp_transport->flags |= CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS;
+ else if (!strcmp (use_ssl, "when-possible"))
+ smtp_transport->flags |= CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE;
+ }
}
static const char *
@@ -219,56 +228,82 @@ smtp_error_string (int error)
}
}
-enum {
- MODE_CLEAR,
- MODE_SSL,
- MODE_TLS,
-};
-
#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
static gboolean
-connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, CamelException *ex)
+connect_to_server (CamelService *service, int try_starttls, CamelException *ex)
{
CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service);
CamelStream *tcp_stream;
char *respbuf = NULL;
int ret;
+ struct addrinfo *ai, hints = { 0 };
+ char *serv;
+ const char *port = NULL;
if (!CAMEL_SERVICE_CLASS (parent_class)->connect (service, ex))
return FALSE;
/* set some smtp transport defaults */
- transport->flags = 0;
+ transport->flags &= CAMEL_SMTP_TRANSPORT_USE_SSL; /* reset all but ssl flags */
transport->authtypes = NULL;
+
+ if (service->url->port) {
+ serv = g_alloca(16);
+ sprintf(serv, "%d", service->url->port);
+ } else {
+ serv = "smtp";
+ port = "25";
+ }
- if (ssl_mode != MODE_CLEAR) {
+ if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL) {
#ifdef HAVE_SSL
- if (ssl_mode == MODE_TLS) {
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, STARTTLS_FLAGS);
+ if (try_starttls) {
+ tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
} else {
+ if (service->url->port == 0) {
+ serv = "smtps";
+ port = "465";
+ }
tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
}
#else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, _("SSL unavailable"));
+ if (!try_starttls && service->url->port == 0) {
+ serv = "smtps";
+ port = "465";
+ }
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ _("Could not connect to %s (port %s): %s"),
+ service->url->host, serv,
+ _("SSL unavailable"));
+
return FALSE;
#endif /* HAVE_SSL */
} else {
tcp_stream = camel_tcp_stream_raw_new ();
}
+
+ hints.ai_socktype = SOCK_STREAM;
+ ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
+ /* fallback to numerical port if the system is misconfigured */
+ if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
+ camel_exception_clear(ex);
+ ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
+ }
+ if (ai == NULL) {
+ camel_object_unref(tcp_stream);
+ return FALSE;
+ }
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -1) {
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("Connection cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, g_strerror (errno));
+ ret = camel_tcp_stream_connect(CAMEL_TCP_STREAM(tcp_stream), ai);
+ camel_freeaddrinfo(ai);
+ if (ret == -1) {
+ camel_exception_setv (ex, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ _("Could not connect to %s (port %s): %s"),
+ service->url->host, serv,
+ g_strerror (errno));
camel_object_unref (tcp_stream);
@@ -312,19 +347,30 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
/* clear any EHLO/HELO exception and assume that any SMTP errors encountered were non-fatal */
camel_exception_clear (ex);
- if (ssl_mode != MODE_TLS) {
- /* we're done */
- return TRUE;
+#ifdef HAVE_SSL
+ if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE) {
+ /* try_starttls is always TRUE here */
+ if (transport->flags & CAMEL_SMTP_TRANSPORT_STARTTLS)
+ goto starttls;
+ } else if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS) {
+ if (try_starttls) {
+ if (transport->flags & CAMEL_SMTP_TRANSPORT_STARTTLS) {
+ goto starttls;
+ } else {
+ /* server doesn't support STARTTLS, abort */
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to connect to SMTP server %s in secure mode: %s"),
+ service->url->host, _("server does not appear to support SSL"));
+ goto exception_cleanup;
+ }
+ }
}
+#endif /* HAVE_SSL */
- if (!(transport->flags & CAMEL_SMTP_TRANSPORT_STARTTLS)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to SMTP server %s in secure mode: %s"),
- service->url->host, _("STARTTLS not supported"));
-
- goto exception_cleanup;
- }
+ return TRUE;
+#ifdef HAVE_SSL
+ starttls:
d(fprintf (stderr, "sending : STARTTLS\r\n"));
if (camel_stream_write (tcp_stream, "STARTTLS\r\n", 10) == -1) {
camel_exception_setv (ex, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SYSTEM,
@@ -374,68 +420,38 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
transport->connected = FALSE;
return FALSE;
+#endif /* HAVE_SSL */
}
-static struct {
- char *value;
- char *serv;
- char *port;
- int mode;
-} ssl_options[] = {
- { "", "smtps", SMTPS_PORT, MODE_SSL }, /* really old (1.x) */
- { "always", "smtps", SMTPS_PORT, MODE_SSL },
- { "when-possible", "smtp", SMTP_PORT, MODE_TLS },
- { "never", "smtp", SMTP_PORT, MODE_CLEAR },
- { NULL, "smtp", SMTP_PORT, MODE_CLEAR },
-};
-
static gboolean
connect_to_server_wrapper (CamelService *service, CamelException *ex)
{
- struct addrinfo hints, *ai;
- const char *ssl_mode;
- int mode, ret, i;
- char *serv;
- const char *port;
-
- if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
- for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, ssl_mode))
- break;
- mode = ssl_options[i].mode;
- serv = ssl_options[i].serv;
- port = ssl_options[i].port;
- } else {
- mode = MODE_CLEAR;
- serv = "smtp";
- port = SMTP_PORT;
- }
-
- if (service->url->port) {
- serv = g_alloca (16);
- sprintf (serv, "%d", service->url->port);
- port = NULL;
- }
+#ifdef HAVE_SSL
+ CamelSmtpTransport *transport = (CamelSmtpTransport *) service;
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
- ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
- if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
- camel_exception_clear (ex);
- ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
+ if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS) {
+ /* First try connecting to the SSL port */
+ if (!connect_to_server (service, FALSE, ex)) {
+ if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE) {
+ /* Seems the SSL port is unavailable, lets try STARTTLS */
+ camel_exception_clear (ex);
+ return connect_to_server (service, TRUE, ex);
+ } else {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ } else if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE) {
+ /* If the server supports STARTTLS, use it */
+ return connect_to_server (service, TRUE, ex);
+ } else {
+ /* User doesn't care about SSL */
+ return connect_to_server (service, FALSE, ex);
}
- if (ai == NULL)
- return FALSE;
-
- if (!(ret = connect_to_server (service, ai, mode, ex)) && mode == MODE_SSL)
- ret = connect_to_server (service, ai, MODE_TLS, ex);
- else if (!ret && mode == MODE_TLS)
- ret = connect_to_server (service, ai, MODE_CLEAR, ex);
-
- camel_freeaddrinfo (ai);
-
- return ret;
+#else
+ return connect_to_server (service, FALSE, ex);
+#endif
}
static gboolean
diff --git a/camel/providers/smtp/camel-smtp-transport.h b/camel/providers/smtp/camel-smtp-transport.h
index 7b5ad88f12..87fcafb58b 100644
--- a/camel/providers/smtp/camel-smtp-transport.h
+++ b/camel/providers/smtp/camel-smtp-transport.h
@@ -43,7 +43,13 @@ extern "C" {
#define CAMEL_SMTP_TRANSPORT_ENHANCEDSTATUSCODES (1 << 2)
#define CAMEL_SMTP_TRANSPORT_STARTTLS (1 << 3)
-#define CAMEL_SMTP_TRANSPORT_AUTH_EQUAL (1 << 4) /* set if we are using authtypes from a broken AUTH= */
+#define CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS (1 << 4)
+#define CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE (1 << 5)
+
+#define CAMEL_SMTP_TRANSPORT_USE_SSL (CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS | \
+ CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE)
+
+#define CAMEL_SMTP_TRANSPORT_AUTH_EQUAL (1 << 6) /* set if we are using authtypes from a broken AUTH= */
typedef struct {
CamelTransport parent_object;
diff --git a/camel/tests/data/messages/.cvsignore b/camel/tests/data/messages/.cvsignore
deleted file mode 100644
index e358dd1903..0000000000
--- a/camel/tests/data/messages/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-*.msg
diff --git a/camel/tests/lib/folders.c b/camel/tests/lib/folders.c
index 5104da6c12..e93d8caf2e 100644
--- a/camel/tests/lib/folders.c
+++ b/camel/tests/lib/folders.c
@@ -12,15 +12,13 @@ test_folder_counts(CamelFolder *folder, int total, int unread)
{
GPtrArray *s;
int i, myunread;
- int gettotal, getunread;
CamelMessageInfo *info;
push("test folder counts %d total %d unread", total, unread);
/* first, use the standard functions */
- camel_object_get(folder, NULL, CAMEL_FOLDER_TOTAL, &gettotal, CAMEL_FOLDER_UNREAD, &getunread, 0);
- check(gettotal == total);
- check(getunread == unread);
+ check(camel_folder_get_message_count(folder) == total);
+ check(camel_folder_get_unread_message_count(folder) == total);
/* next, use the summary */
s = camel_folder_get_summary(folder);
@@ -29,7 +27,7 @@ test_folder_counts(CamelFolder *folder, int total, int unread)
myunread = s->len;
for (i=0;i<s->len;i++) {
info = s->pdata[i];
- if (camel_message_info_flags(info) & CAMEL_MESSAGE_SEEN)
+ if (info->flags & CAMEL_MESSAGE_SEEN)
myunread--;
}
check(unread == myunread);
@@ -42,7 +40,7 @@ test_folder_counts(CamelFolder *folder, int total, int unread)
myunread = s->len;
for (i=0;i<s->len;i++) {
info = camel_folder_get_message_info(folder, s->pdata[i]);
- if (camel_message_info_flags(info) & CAMEL_MESSAGE_SEEN)
+ if (info->flags & CAMEL_MESSAGE_SEEN)
myunread--;
camel_folder_free_message_info(folder, info);
}
@@ -72,7 +70,7 @@ test_message_info(CamelMimeMessage *msg, const CamelMessageInfo *info)
/* FIXME: testing from/cc/to, etc is more tricky */
- check(camel_message_info_date_sent(info) == camel_mime_message_get_date(msg, NULL));
+ check(info->date_sent == camel_mime_message_get_date(msg, NULL));
/* date received isn't set for messages that haven't been sent anywhere ... */
/*check(info->date_received == camel_mime_message_get_date_received(msg, NULL));*/
@@ -471,7 +469,7 @@ test_folder_message_ops(CamelSession *session, const char *name, int local, cons
push("deleting first message & expunging");
camel_folder_delete_message(folder, uids->pdata[0]);
- test_folder_counts(folder, 10, 9);
+ test_folder_counts(folder, 10, 10);
camel_folder_expunge(folder, ex);
check_msg(!camel_exception_is_set(ex), "%s", camel_exception_get_description(ex));
test_folder_not_message(folder, uids->pdata[0]);
@@ -500,7 +498,7 @@ test_folder_message_ops(CamelSession *session, const char *name, int local, cons
push("deleting last message & expunging");
camel_folder_delete_message(folder, uids->pdata[8]);
/* sync? */
- test_folder_counts(folder, 9, 8);
+ test_folder_counts(folder, 9, 9);
camel_folder_expunge(folder, ex);
check_msg(!camel_exception_is_set(ex), "%s", camel_exception_get_description(ex));
test_folder_not_message(folder, uids->pdata[8]);
@@ -531,7 +529,7 @@ test_folder_message_ops(CamelSession *session, const char *name, int local, cons
camel_folder_delete_message(folder, uids->pdata[j]);
}
/* sync? */
- test_folder_counts(folder, 8, 0);
+ test_folder_counts(folder, 8, 8);
camel_folder_expunge(folder, ex);
check_msg(!camel_exception_is_set(ex), "%s", camel_exception_get_description(ex));
for (j=0;j<8;j++) {