static CamelStream * insert_setup (CamelImapMessageCache *cache, const char *uid, const char *part_spec, char **path, char **key, CamelException *ex) { CamelStream *stream; int fd; #ifdef G_OS_WIN32 /* Trailing periods in file names are silently dropped on * Win32, argh. The code in this file requires the period to * be there. So in case part_spec is empty, use a tilde (just * a random choice) instead. */ if (!*part_spec) part_spec = "~"; #endif *path = g_strdup_printf ("%s/%s.%s", cache->path, uid, part_spec); *key = strrchr (*path, '/') + 1; stream = g_hash_table_lookup (cache->parts, *key); if (stream) camel_object_unref (CAMEL_OBJECT (stream)); fd = g_open (*path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0600); if (fd == -1) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Failed to cache message %s: %s"), uid, g_strerror (errno)); g_free (*path); return NULL; } return camel_stream_fs_new_with_fd (fd); }
/** * camel_imap_message_cache_copy: * @source: the source message cache * @source_uid: UID of a message in @source * @dest: the destination message cache * @dest_uid: UID of the message in @dest * * Copies all cached parts from @source_uid in @source to @dest_uid in * @destination. **/ void camel_imap_message_cache_copy (CamelImapMessageCache *source, const char *source_uid, CamelImapMessageCache *dest, const char *dest_uid, CamelException *ex) { GPtrArray *subparts; CamelStream *stream; char *part; int i; subparts = g_hash_table_lookup (source->parts, source_uid); if (!subparts || !subparts->len) return; for (i = 0; i < subparts->len; i++) { part = strchr (subparts->pdata[i], '.'); if (!part++) continue; if ((stream = camel_imap_message_cache_get (source, source_uid, part, ex))) { camel_imap_message_cache_insert_stream (dest, dest_uid, part, stream, ex); camel_object_unref (CAMEL_OBJECT (stream)); } } }
static void exchange_get_folder (char *uri, CamelFolder *folder, void *data) { CamelStore *store; CamelException ex; CamelFolderInfo *info; gchar *name = NULL; gchar *stored_name = NULL; gchar *target_uri = (gchar *)data; ExchangeAccount *account = NULL; account = exchange_operations_get_exchange_account (); if (!account) return; /* Get the subscribed folder name. */ name = target_uri + strlen ("exchange://") + strlen (account->account_filename); stored_name = strrchr (name + 1, '/'); if (stored_name) name[stored_name - name] = '\0'; camel_exception_init (&ex); store = camel_folder_get_parent_store (folder); /* Construct the CamelFolderInfo */ info = ex_create_folder_info (store, name, target_uri, -1, 0); camel_object_trigger_event (CAMEL_OBJECT (store), "folder_unsubscribed", info); g_free (target_uri); }
static CamelStream * insert_abort (char *path, CamelStream *stream) { g_unlink (path); g_free (path); camel_object_unref (CAMEL_OBJECT (stream)); return NULL; }
static TnyMsg * tny_camel_partial_msg_receive_strategy_perform_get_msg_default (TnyMsgReceiveStrategy *self, TnyFolder *folder, TnyHeader *header, GError **err) { TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (folder); TnyMsg *message = NULL; CamelMimeMessage *camel_message = NULL; gchar *id; CamelException ex = CAMEL_EXCEPTION_INITIALISER; CamelFolderReceiveType mtype = CAMEL_FOLDER_RECEIVE_PARTIAL; g_assert (TNY_IS_HEADER (header)); if (!priv->strict_retrieval) mtype = CAMEL_FOLDER_RECEIVE_ANY_OR_PARTIAL; id = tny_header_dup_uid (TNY_HEADER (header)); message = NULL; camel_message = camel_folder_get_message (priv->folder, (const char *) id, mtype, -1, &ex); g_free (id); if (camel_exception_is_set (&ex)) { _tny_camel_exception_to_tny_error (&ex, err); camel_exception_clear (&ex); } else { if (camel_message && CAMEL_IS_OBJECT (camel_message)) { TnyHeader *nheader = NULL; nheader = _tny_camel_msg_header_new (CAMEL_MIME_MESSAGE (camel_message), folder, tny_header_get_date_received (header)); _tny_camel_msg_header_set_decorated (TNY_CAMEL_MSG_HEADER (nheader), header, FALSE); message = tny_camel_msg_new (); _tny_camel_msg_set_received (TNY_CAMEL_MSG (message), tny_header_get_date_received (header)); _tny_camel_msg_set_folder (TNY_CAMEL_MSG (message), folder); TNY_CAMEL_MSG_HEADER (nheader)->old_uid = tny_header_dup_uid (header); _tny_camel_msg_set_header (TNY_CAMEL_MSG (message), nheader); _tny_camel_mime_part_set_part (TNY_CAMEL_MIME_PART (message), CAMEL_MIME_PART (camel_message)); tny_header_set_flag (nheader, TNY_HEADER_FLAG_CACHED); tny_header_set_flag (nheader, TNY_HEADER_FLAG_PARTIAL); g_object_unref (nheader); tny_header_set_flag (header, TNY_HEADER_FLAG_CACHED); tny_header_set_flag (header, TNY_HEADER_FLAG_PARTIAL); } } if (camel_message && CAMEL_IS_OBJECT (camel_message)) camel_object_unref (CAMEL_OBJECT (camel_message)); return message; }
/** * camel_imap_response_free_without_processing: * @store: the CamelImapStore the response is from. * @response: a CamelImapResponse: * * Frees all of the data in @response without processing any untagged * responses. Releases @store's command lock. **/ void camel_imap_response_free_without_processing (CamelImapStore *store, CamelImapResponse *response) { if (!response) return; if (response->folder) { camel_object_unref (CAMEL_OBJECT (response->folder)); response->folder = NULL; } camel_imap_response_free (store, response); }
/** * camel_imap_response_free: * @store: the CamelImapStore the response is from * @response: a CamelImapResponse * * Frees all of the data in @response and processes any untagged * EXPUNGE and EXISTS responses in it. Releases @store's connect_lock. **/ void camel_imap_response_free (CamelImapStore *store, CamelImapResponse *response) { int i, number, exists = 0; GArray *expunged = NULL; char *resp, *p; if (!response) return; for (i = 0; i < response->untagged->len; i++) { resp = response->untagged->pdata[i]; if (response->folder) { /* Check if it's something we need to handle. */ number = strtoul (resp + 2, &p, 10); if (!g_ascii_strcasecmp (p, " EXISTS")) { exists = number; } else if (!g_ascii_strcasecmp (p, " EXPUNGE") || !g_ascii_strcasecmp(p, " XGWMOVE")) { /* XGWMOVE response is the same as an EXPUNGE response */ if (!expunged) { expunged = g_array_new (FALSE, FALSE, sizeof (int)); } g_array_append_val (expunged, number); } } g_free (resp); } g_ptr_array_free (response->untagged, TRUE); g_free (response->status); if (response->folder) { if (exists > 0 || expunged) { /* Update the summary */ camel_imap_folder_changed (response->folder, exists, expunged, NULL); if (expunged) g_array_free (expunged, TRUE); } camel_object_unref (CAMEL_OBJECT (response->folder)); } g_free (response); CAMEL_SERVICE_REC_UNLOCK (store, connect_lock); }
static void groupwise_forget_folder (CamelGroupwiseStore *gw_store, const char *folder_name, CamelException *ex) { CamelFolderSummary *summary; CamelGroupwiseStorePrivate *priv = gw_store->priv; char *summary_file, *state_file; char *folder_dir, *storage_path; CamelFolderInfo *fi; const char *name; name = folder_name; storage_path = g_strdup_printf ("%s/folders", priv->storage_path); folder_dir = e_path_to_physical (storage_path,folder_name); if (g_access(folder_dir, F_OK) != 0) { g_free(folder_dir); return; } summary_file = g_strdup_printf ("%s/summary", folder_dir); summary = camel_groupwise_summary_new(NULL,summary_file); if(!summary) { g_free(summary_file); g_free(folder_dir); return; } camel_object_unref (summary); g_unlink (summary_file); g_free (summary_file); state_file = g_strdup_printf ("%s/cmeta", folder_dir); g_unlink (state_file); g_free (state_file); g_rmdir (folder_dir); g_free (folder_dir); camel_store_summary_remove_path ( (CamelStoreSummary *)gw_store->summary, folder_name); camel_store_summary_save ( (CamelStoreSummary *)gw_store->summary); fi = groupwise_build_folder_info(gw_store, NULL, folder_name); camel_object_trigger_event (CAMEL_OBJECT (gw_store), "folder_deleted", fi); camel_folder_info_free (fi); }
static gboolean vee_store_delete_folder_sync (CamelStore *store, const gchar *folder_name, GCancellable *cancellable, GError **error) { CamelFolder *folder; if (strcmp (folder_name, CAMEL_UNMATCHED_NAME) == 0) { g_set_error ( error, CAMEL_STORE_ERROR, CAMEL_STORE_ERROR_NO_FOLDER, _("Cannot delete folder: %s: Invalid operation"), folder_name); return FALSE; } folder = camel_object_bag_get (store->folders, folder_name); if (folder) { CamelObject *object = CAMEL_OBJECT (folder); const gchar *state_filename; state_filename = camel_object_get_state_filename (object); if (state_filename != NULL) { g_unlink (state_filename); camel_object_set_state_filename (object, NULL); } if ((((CamelVeeFolder *) folder)->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) { /* what about now-empty parents? ignore? */ change_folder (store, folder_name, CHANGE_DELETE, -1); } g_object_unref (folder); } else { g_set_error ( error, CAMEL_STORE_ERROR, CAMEL_STORE_ERROR_NO_FOLDER, _("Cannot delete folder: %s: No such folder"), folder_name); return FALSE; } return TRUE; }
static void cache_put (CamelImapMessageCache *cache, const char *uid, const char *key, CamelStream *stream) { char *hash_key; GPtrArray *subparts; gpointer okey, ostream; guint32 uidval; uidval = strtoul (uid, NULL, 10); if (uidval > cache->max_uid) cache->max_uid = uidval; subparts = g_hash_table_lookup (cache->parts, uid); if (!subparts) { subparts = g_ptr_array_new (); g_hash_table_insert (cache->parts, g_strdup (uid), subparts); } if (g_hash_table_lookup_extended (cache->parts, key, &okey, &ostream)) { if (ostream) { camel_object_unhook_event (ostream, "finalize", stream_finalize, cache); g_hash_table_remove (cache->cached, ostream); camel_object_unref (ostream); } hash_key = okey; } else { hash_key = g_strdup (key); g_ptr_array_add (subparts, hash_key); } g_hash_table_insert (cache->parts, hash_key, stream); g_hash_table_insert (cache->cached, stream, hash_key); if (stream) { camel_object_hook_event (CAMEL_OBJECT (stream), "finalize", stream_finalize, cache); } }
/** * camel_imap_message_cache_get: * @cache: the cache * @uid: the UID of the data to get * @part_spec: the part_spec of the data to get * @ex: exception * * Return value: a CamelStream containing the cached data (which the * caller must unref), or %NULL if that data is not cached. **/ CamelStream * camel_imap_message_cache_get (CamelImapMessageCache *cache, const char *uid, const char *part_spec, CamelException *ex) { CamelStream *stream; char *path, *key; if (uid[0] == 0) return NULL; #ifdef G_OS_WIN32 /* See comment in insert_setup() */ if (!*part_spec) part_spec = "~"; #endif path = g_strdup_printf ("%s/%s.%s", cache->path, uid, part_spec); key = strrchr (path, '/') + 1; stream = g_hash_table_lookup (cache->parts, key); if (stream) { camel_stream_reset (CAMEL_STREAM (stream)); camel_object_ref (CAMEL_OBJECT (stream)); g_free (path); return stream; } stream = camel_stream_fs_new_with_name (path, O_RDONLY, 0); if (stream) { cache_put (cache, uid, key, stream); } else { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Failed to cache %s: %s"), part_spec, g_strerror (errno)); } g_free (path); return stream; }
/** * camel_imap_message_cache_insert_wrapper: * @cache: the cache * @uid: UID of the message data to cache * @part_spec: the IMAP part_spec of the data * @wrapper: the wrapper to cache * * Caches the provided data into @cache. **/ void camel_imap_message_cache_insert_wrapper (CamelImapMessageCache *cache, const char *uid, const char *part_spec, CamelDataWrapper *wrapper, CamelException *ex) { char *path, *key; CamelStream *stream; stream = insert_setup (cache, uid, part_spec, &path, &key, ex); if (!stream) return; if (camel_data_wrapper_write_to_stream (wrapper, stream) == -1) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Failed to cache message %s: %s"), uid, g_strerror (errno)); insert_abort (path, stream); } else { insert_finish (cache, uid, path, key, stream); camel_object_unref (CAMEL_OBJECT (stream)); } }
static gboolean maildir_folder_append_message_sync (CamelFolder *folder, CamelMimeMessage *message, CamelMessageInfo *info, gchar **appended_uid, GCancellable *cancellable, GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *)folder; CamelStream *output_stream; CamelMessageInfo *mi; CamelMaildirMessageInfo *mdi; gchar *name, *dest = NULL; gboolean success = TRUE; d(printf("Appending message\n")); /* If we can't lock, don't do anything */ if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) return FALSE; /* add it to the summary/assign the uid, etc */ mi = camel_local_summary_add ( CAMEL_LOCAL_SUMMARY (folder->summary), message, info, lf->changes, error); if (mi == NULL) goto check_changed; if ((camel_message_info_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) && !camel_mime_message_has_attachment (message)) camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, 0); mdi = (CamelMaildirMessageInfo *)mi; d(printf("Appending message: uid is %s filename is %s\n", camel_message_info_uid(mi), mdi->filename)); /* write it out to tmp, use the uid we got from the summary */ name = g_strdup_printf ("%s/tmp/%s", lf->folder_path, camel_message_info_uid(mi)); output_stream = camel_stream_fs_new_with_name ( name, O_WRONLY|O_CREAT, 0600, error); if (output_stream == NULL) goto fail_write; if (camel_data_wrapper_write_to_stream_sync ( (CamelDataWrapper *)message, output_stream, cancellable, error) == -1 || camel_stream_close (output_stream, cancellable, error) == -1) goto fail_write; /* now move from tmp to cur (bypass new, does it matter?) */ dest = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi)); if (g_rename (name, dest) == -1) { g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), "%s", g_strerror (errno)); goto fail_write; } g_free (dest); g_free (name); if (appended_uid) *appended_uid = g_strdup(camel_message_info_uid(mi)); if (output_stream) g_object_unref (output_stream); goto check_changed; fail_write: /* remove the summary info so we are not out-of-sync with the mh folder */ camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (folder->summary), camel_message_info_uid (mi)); g_prefix_error ( error, _("Cannot append message to maildir folder: %s: "), name); if (output_stream) { g_object_unref (CAMEL_OBJECT (output_stream)); unlink (name); } g_free (name); g_free (dest); success = FALSE; check_changed: camel_local_folder_unlock (lf); if (lf && camel_folder_change_info_changed (lf->changes)) { camel_folder_changed (folder, lf->changes); camel_folder_change_info_clear (lf->changes); } return success; }
CamelImapResponse * imap_read_response (CamelImapStore *store, CamelException *ex) { CamelImapResponse *response; CamelImapResponseType type; char *respbuf, *p; /* Get another lock so that when we reach the tagged * response and camel_imap_command_response unlocks, * we're still locked. This lock is owned by response * and gets unlocked when response is freed. */ CAMEL_SERVICE_REC_LOCK (store, connect_lock); response = g_new0 (CamelImapResponse, 1); if (store->current_folder && camel_disco_store_status (CAMEL_DISCO_STORE (store)) != CAMEL_DISCO_STORE_RESYNCING) { response->folder = store->current_folder; camel_object_ref (CAMEL_OBJECT (response->folder)); } response->untagged = g_ptr_array_new (); while ((type = camel_imap_command_response (store, &respbuf, ex)) == CAMEL_IMAP_RESPONSE_UNTAGGED) g_ptr_array_add (response->untagged, respbuf); if (type == CAMEL_IMAP_RESPONSE_ERROR) { camel_imap_response_free_without_processing (store, response); return NULL; } response->status = respbuf; /* Check for OK or continuation response. */ if (*respbuf == '+') return response; p = strchr (respbuf, ' '); if (p && !g_ascii_strncasecmp (p, " OK", 3)) return response; /* We should never get BAD, or anything else but +, OK, or NO * for that matter. Well, we could get BAD, treat as NO. */ if (!p || (g_ascii_strncasecmp(p, " NO", 3) != 0 && g_ascii_strncasecmp(p, " BAD", 4)) ) { g_warning ("Unexpected response from IMAP server: %s", respbuf); camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, _("Unexpected response from IMAP " "server: %s"), respbuf); camel_imap_response_free_without_processing (store, response); return NULL; } p += 3; if (!*p++) p = NULL; camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_INVALID, _("IMAP command failed: %s"), p ? p : _("Unknown error")); camel_imap_response_free_without_processing (store, response); return NULL; }
int main (int argc, char **argv) { CamelSession *session; CamelCipherContext *ctx; CamelException *ex; CamelCipherValidity *valid; CamelStream *stream1, *stream2; struct _CamelMimePart *sigpart, *conpart, *encpart, *outpart; CamelDataWrapper *dw; GPtrArray *recipients; GByteArray *buf; char *before, *after; int ret; if (getenv("CAMEL_TEST_GPG") == NULL) return 77; camel_test_init (argc, argv); /* clear out any camel-test data */ system ("/bin/rm -rf /tmp/camel-test"); system ("/bin/mkdir /tmp/camel-test"); setenv ("GNUPGHOME", "/tmp/camel-test/.gnupg", 1); /* import the gpg keys */ if ((ret = system ("gpg < /dev/null > /dev/null 2>&1")) == -1) return 77; else if (WEXITSTATUS (ret) == 127) return 77; g_message ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.pub > /dev/null 2>&1"); system ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.pub > /dev/null 2>&1"); g_message ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.sec > /dev/null 2>&1"); system ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.sec > /dev/null 2>&1"); session = camel_pgp_session_new ("/tmp/camel-test"); ex = camel_exception_new (); ctx = camel_gpg_context_new (session); camel_gpg_context_set_always_trust (CAMEL_GPG_CONTEXT (ctx), TRUE); camel_test_start ("Test of PGP functions"); stream1 = camel_stream_mem_new (); camel_stream_write (stream1, "Hello, I am a test stream.\n", 27); camel_stream_reset (stream1); conpart = camel_mime_part_new(); dw = camel_data_wrapper_new(); camel_data_wrapper_construct_from_stream(dw, stream1); camel_medium_set_content_object((CamelMedium *)conpart, dw); camel_object_unref(stream1); camel_object_unref(dw); sigpart = camel_mime_part_new(); camel_test_push ("PGP signing"); camel_cipher_sign (ctx, "*****@*****.**", CAMEL_CIPHER_HASH_SHA1, conpart, sigpart, ex); if (camel_exception_is_set(ex)) { printf("PGP signing failed assuming non-functional environment\n%s", camel_exception_get_description (ex)); camel_test_pull(); return 77; } camel_test_pull (); camel_exception_clear (ex); camel_test_push ("PGP verify"); valid = camel_cipher_verify (ctx, sigpart, ex); check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex)); check_msg (camel_cipher_validity_get_valid (valid), "%s", camel_cipher_validity_get_description (valid)); camel_cipher_validity_free (valid); camel_test_pull (); camel_object_unref(conpart); camel_object_unref(sigpart); stream1 = camel_stream_mem_new (); camel_stream_write (stream1, "Hello, I am a test of encryption/decryption.", 44); camel_stream_reset (stream1); conpart = camel_mime_part_new(); dw = camel_data_wrapper_new(); camel_stream_reset(stream1); camel_data_wrapper_construct_from_stream(dw, stream1); camel_medium_set_content_object((CamelMedium *)conpart, dw); camel_object_unref(stream1); camel_object_unref(dw); encpart = camel_mime_part_new(); camel_exception_clear (ex); camel_test_push ("PGP encrypt"); recipients = g_ptr_array_new (); g_ptr_array_add (recipients, "*****@*****.**"); camel_cipher_encrypt (ctx, "*****@*****.**", recipients, conpart, encpart, ex); check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex)); g_ptr_array_free (recipients, TRUE); camel_test_pull (); camel_exception_clear (ex); camel_test_push ("PGP decrypt"); outpart = camel_mime_part_new(); valid = camel_cipher_decrypt (ctx, encpart, outpart, ex); check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex)); check_msg (valid->encrypt.status == CAMEL_CIPHER_VALIDITY_ENCRYPT_ENCRYPTED, "%s", valid->encrypt.description); stream1 = camel_stream_mem_new(); stream2 = camel_stream_mem_new(); camel_data_wrapper_write_to_stream((CamelDataWrapper *)conpart, stream1); camel_data_wrapper_write_to_stream((CamelDataWrapper *)outpart, stream2); buf = CAMEL_STREAM_MEM (stream1)->buffer; before = g_strndup (buf->data, buf->len); buf = CAMEL_STREAM_MEM (stream2)->buffer; after = g_strndup (buf->data, buf->len); check_msg (string_equal (before, after), "before = '%s', after = '%s'", before, after); g_free (before); g_free (after); camel_object_unref(stream1); camel_object_unref(stream2); camel_object_unref(conpart); camel_object_unref(encpart); camel_object_unref(outpart); camel_test_pull (); camel_object_unref (CAMEL_OBJECT (ctx)); camel_object_unref (CAMEL_OBJECT (session)); camel_test_end (); return 0; }