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; }
static guint32 imap4_fetch_all_update (struct imap4_fetch_all_t *fetch) { CamelIMAP4MessageInfo *iinfo, *new_iinfo; CamelFolderChangeInfo *changes = NULL; struct imap4_envelope_t *envelope; CamelMessageInfo *info; guint32 first = 0; guint32 flags; int total, i; changes = fetch->changes; total = camel_folder_summary_count (fetch->summary); for (i = 0; i < total; i++) { info = camel_folder_summary_index (fetch->summary, i); if (!(envelope = g_hash_table_lookup (fetch->uid_hash, camel_message_info_uid (info)))) { /* remove it */ camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info)); camel_folder_summary_remove (fetch->summary, info); total--; i--; } else if (envelope->changed & IMAP4_FETCH_FLAGS) { /* update it with the new flags */ new_iinfo = (CamelIMAP4MessageInfo *) envelope->info; iinfo = (CamelIMAP4MessageInfo *) info; flags = iinfo->info.flags; iinfo->info.flags = camel_imap4_merge_flags (iinfo->server_flags, iinfo->info.flags, new_iinfo->server_flags); iinfo->server_flags = new_iinfo->server_flags; if (iinfo->info.flags != flags) camel_folder_change_info_change_uid (changes, camel_message_info_uid (info)); } camel_message_info_free (info); } for (i = 0; i < fetch->added->len; i++) { if (!(envelope = fetch->added->pdata[i])) { courier_imap_is_a_piece_of_shit (fetch->summary, i + fetch->first); break; } info = envelope->info; if (!first && camel_message_info_uid (info)) { if ((info = camel_folder_summary_uid (fetch->summary, camel_message_info_uid (info)))) { camel_message_info_free(info); } else { first = i + fetch->first; } } camel_message_info_free(envelope->info); g_free (envelope); } g_ptr_array_free (fetch->added, TRUE); g_hash_table_destroy (fetch->uid_hash); if (camel_folder_change_info_changed (changes)) camel_object_trigger_event (fetch->summary->folder, "folder_changed", changes); camel_folder_change_info_free (changes); g_free (fetch); return first; }
static CamelMimeMessage * mbox_folder_get_message_sync (CamelFolder *folder, const gchar *uid, GCancellable *cancellable, GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *) folder; CamelMimeMessage *message = NULL; CamelMboxMessageInfo *info; CamelMimeParser *parser = NULL; gint fd, retval; gint retried = FALSE; goffset frompos; d (printf ("Getting message %s\n", uid)); /* lock the folder first, burn if we can't, need write lock for summary check */ if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) return NULL; /* check for new messages always */ if (camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, cancellable, error) == -1) { camel_local_folder_unlock (lf); return NULL; } retry: /* get the message summary info */ info = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid); if (info == NULL) { set_cannot_get_message_ex ( error, CAMEL_FOLDER_ERROR_INVALID_UID, uid, lf->folder_path, _("No such message")); goto fail; } if (info->frompos == -1) { camel_message_info_unref (info); goto fail; } frompos = info->frompos; camel_message_info_unref (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 * with no stream). This means we dont have to lock the mbox for the life of the message, but only * while it is being created. */ fd = g_open (lf->folder_path, O_LARGEFILE | O_RDONLY | O_BINARY, 0); if (fd == -1) { set_cannot_get_message_ex ( error, CAMEL_ERROR_GENERIC, uid, lf->folder_path, g_strerror (errno)); goto fail; } /* we use a parser to verify the message is correct, and in the correct position */ parser = camel_mime_parser_new (); camel_mime_parser_init_with_fd (parser, fd); camel_mime_parser_scan_from (parser, TRUE); camel_mime_parser_seek (parser, frompos, SEEK_SET); if (camel_mime_parser_step (parser, NULL, NULL) != CAMEL_MIME_PARSER_STATE_FROM || camel_mime_parser_tell_start_from (parser) != frompos) { g_warning ("Summary doesn't match the folder contents! eek!\n" " expecting offset %ld got %ld, state = %d", (glong) frompos, (glong) camel_mime_parser_tell_start_from (parser), camel_mime_parser_state (parser)); g_object_unref (parser); parser = NULL; if (!retried) { retried = TRUE; camel_local_summary_check_force ((CamelLocalSummary *) folder->summary); retval = camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, cancellable, error); if (retval != -1) goto retry; } set_cannot_get_message_ex ( error, CAMEL_FOLDER_ERROR_INVALID, uid, lf->folder_path, _("The folder appears to be irrecoverably corrupted.")); goto fail; } message = camel_mime_message_new (); if (!camel_mime_part_construct_from_parser_sync ( (CamelMimePart *) message, parser, cancellable, error)) { g_prefix_error ( error, _("Cannot get message %s from folder %s: "), uid, lf->folder_path); g_object_unref (message); message = NULL; goto fail; } camel_medium_remove_header ((CamelMedium *) message, "X-Evolution"); fail: /* and unlock now we're finished with it */ camel_local_folder_unlock (lf); if (parser) g_object_unref (parser); /* use the opportunity to notify of changes (particularly if we had a rebuild) */ if (camel_folder_change_info_changed (lf->changes)) { camel_folder_changed (folder, lf->changes); camel_folder_change_info_clear (lf->changes); } return message; }
static gboolean maildir_folder_transfer_messages_to_sync (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, gboolean delete_originals, GPtrArray **transferred_uids, GCancellable *cancellable, GError **error) { gboolean fallback = FALSE; if (delete_originals && CAMEL_IS_MAILDIR_FOLDER (source) && CAMEL_IS_MAILDIR_FOLDER (dest) && camel_folder_get_parent_store (source) == camel_folder_get_parent_store (dest)) { gint i; CamelLocalFolder *lf = (CamelLocalFolder *) source; CamelLocalFolder *df = (CamelLocalFolder *) dest; camel_operation_push_message ( cancellable, _("Moving messages")); camel_folder_freeze (dest); camel_folder_freeze (source); for (i = 0; i < uids->len; i++) { gchar *uid = (gchar *) uids->pdata[i]; gchar *s_filename, *d_filename, *new_filename; CamelMaildirMessageInfo *mdi; CamelMessageInfo *info; if ((info = camel_folder_summary_get (source->summary, uid)) == NULL) { set_cannot_get_message_ex ( error, CAMEL_FOLDER_ERROR_INVALID_UID, uid, lf->folder_path, _("No such message")); return FALSE; } mdi = (CamelMaildirMessageInfo *) info; new_filename = camel_maildir_summary_info_to_name (mdi); d_filename = g_strdup_printf ("%s/cur/%s", df->folder_path, new_filename); s_filename = g_strdup_printf ("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi)); if (g_rename (s_filename, d_filename) != 0) { if (errno == EXDEV) { i = uids->len + 1; fallback = TRUE; } else { g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), _("Cannot transfer message to destination folder: %s"), g_strerror (errno)); camel_message_info_unref (info); g_free (s_filename); g_free (d_filename); g_free (new_filename); break; } } else { CamelMessageInfo *clone; CamelMaildirMessageInfo *mclone; clone = camel_message_info_clone (info); clone->summary = dest->summary; mclone = (CamelMaildirMessageInfo *) clone; /* preserve also UID, as it matches the file name */ mclone->info.info.uid = camel_pstring_strdup (camel_message_info_get_uid (info)); camel_maildir_info_set_filename (clone, g_strdup (new_filename)); /* unset deleted flag when transferring from trash folder */ if ((source->folder_flags & CAMEL_FOLDER_IS_TRASH) != 0) camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED, 0); /* unset junk flag when transferring from junk folder */ if ((source->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0) camel_message_info_set_flags (info, CAMEL_MESSAGE_JUNK, 0); camel_folder_summary_add (dest->summary, clone); camel_folder_change_info_add_uid (df->changes, camel_message_info_get_uid (clone)); camel_folder_set_message_flags ( source, uid, CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN, ~0); camel_folder_change_info_remove_uid (lf->changes, camel_message_info_get_uid (info)); camel_folder_summary_remove (source->summary, info); } camel_message_info_unref (info); g_free (s_filename); g_free (d_filename); g_free (new_filename); } if (lf && camel_folder_change_info_changed (lf->changes)) { camel_folder_changed (source, lf->changes); camel_folder_change_info_clear (lf->changes); } if (df && camel_folder_change_info_changed (df->changes)) { camel_folder_changed (dest, df->changes); camel_folder_change_info_clear (df->changes); } camel_folder_thaw (source); camel_folder_thaw (dest); camel_operation_pop_message (cancellable); } else fallback = TRUE; if (fallback) { CamelFolderClass *folder_class; /* Chain up to parent's transfer_messages_to() method. */ folder_class = CAMEL_FOLDER_CLASS (camel_maildir_folder_parent_class); return folder_class->transfer_messages_to_sync ( source, uids, dest, delete_originals, transferred_uids, cancellable, error); } return TRUE; }
static gboolean mbox_folder_append_message_sync (CamelFolder *folder, CamelMimeMessage *message, CamelMessageInfo *info, gchar **appended_uid, GCancellable *cancellable, GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *) folder; CamelStream *output_stream = NULL, *filter_stream = NULL; CamelMimeFilter *filter_from; CamelMboxSummary *mbs = (CamelMboxSummary *) folder->summary; CamelMessageInfo *mi; gchar *fromline = NULL; struct stat st; gint retval; gboolean has_attachment; #if 0 gchar *xev; #endif /* If we can't lock, dont do anything */ if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) return FALSE; d (printf ("Appending message\n")); /* first, check the summary is correct (updates folder_size too) */ retval = camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, cancellable, error); if (retval == -1) goto fail; /* add it to the summary/assign the uid, etc */ mi = camel_local_summary_add ((CamelLocalSummary *) folder->summary, message, info, lf->changes, error); if (mi == NULL) goto fail; d (printf ("Appending message: uid is %s\n", camel_message_info_get_uid (mi))); has_attachment = camel_mime_message_has_attachment (message); if (((camel_message_info_get_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) && !has_attachment) || ((camel_message_info_get_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) == 0 && has_attachment)) { camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, has_attachment ? CAMEL_MESSAGE_ATTACHMENTS : 0); } output_stream = camel_stream_fs_new_with_name ( lf->folder_path, O_WRONLY | O_APPEND | O_LARGEFILE, 0666, error); if (output_stream == NULL) { g_prefix_error ( error, _("Cannot open mailbox: %s: "), lf->folder_path); goto fail; } /* and we need to set the frompos/XEV explicitly */ ((CamelMboxMessageInfo *) mi)->frompos = mbs->folder_size; #if 0 xev = camel_local_summary_encode_x_evolution ((CamelLocalSummary *) folder->summary, mi); if (xev) { /* the x-ev header should match the 'current' flags, no problem, so store as much */ camel_medium_set_header ((CamelMedium *) message, "X-Evolution", xev); mi->flags &= ~ CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED; g_free (xev); } #endif /* we must write this to the non-filtered stream ... */ fromline = camel_mime_message_build_mbox_from (message); if (camel_stream_write (output_stream, fromline, strlen (fromline), cancellable, error) == -1) goto fail_write; /* and write the content to the filtering stream, that translates '\nFrom' into '\n>From' */ filter_stream = camel_stream_filter_new (output_stream); filter_from = camel_mime_filter_from_new (); camel_stream_filter_add ((CamelStreamFilter *) filter_stream, filter_from); g_object_unref (filter_from); if (camel_data_wrapper_write_to_stream_sync ( (CamelDataWrapper *) message, filter_stream, cancellable, error) == -1 || camel_stream_write (filter_stream, "\n", 1, cancellable, error) == -1 || camel_stream_flush (filter_stream, cancellable, error) == -1) goto fail_write; /* filter stream ref's the output stream itself, so we need to unref it too */ g_object_unref (filter_stream); g_object_unref (output_stream); g_free (fromline); if (!((CamelMessageInfoBase *) mi)->preview && camel_folder_summary_get_need_preview (folder->summary)) { if (camel_mime_message_build_preview ((CamelMimePart *) message, mi) && ((CamelMessageInfoBase *) mi)->preview) camel_folder_summary_add_preview (folder->summary, mi); } /* now we 'fudge' the summary to tell it its uptodate, because its idea of uptodate has just changed */ /* the stat really shouldn't fail, we just wrote to it */ if (g_stat (lf->folder_path, &st) == 0) { ((CamelFolderSummary *) mbs)->time = st.st_mtime; mbs->folder_size = st.st_size; } /* unlock as soon as we can */ camel_local_folder_unlock (lf); if (camel_folder_change_info_changed (lf->changes)) { camel_folder_changed (folder, lf->changes); camel_folder_change_info_clear (lf->changes); } if (appended_uid) *appended_uid = g_strdup(camel_message_info_get_uid(mi)); return TRUE; fail_write: g_prefix_error ( error, _("Cannot append message to mbox file: %s: "), lf->folder_path); if (output_stream) { gint fd; fd = camel_stream_fs_get_fd (CAMEL_STREAM_FS (output_stream)); if (fd != -1) { /* reset the file to original size */ do { retval = ftruncate (fd, mbs->folder_size); } while (retval == -1 && errno == EINTR); } g_object_unref (output_stream); } if (filter_stream) g_object_unref (filter_stream); g_free (fromline); /* remove the summary info so we are not out-of-sync with the mbox */ camel_folder_summary_remove (CAMEL_FOLDER_SUMMARY (mbs), mi); /* and tell the summary it's up-to-date */ if (g_stat (lf->folder_path, &st) == 0) { ((CamelFolderSummary *) mbs)->time = st.st_mtime; mbs->folder_size = st.st_size; } fail: /* make sure we unlock the folder - before we start triggering events into appland */ camel_local_folder_unlock (lf); /* cascade the changes through, anyway, if there are any outstanding */ if (camel_folder_change_info_changed (lf->changes)) { camel_folder_changed (folder, lf->changes); camel_folder_change_info_clear (lf->changes); } return FALSE; }
static gboolean mh_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; gchar *name; gboolean has_attachment; /* FIXME: probably needs additional locking (although mh doesn't appear do do it) */ d(printf("Appending message\n")); /* If we can't lock, don't do anything */ if (!lf || 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 ((CamelLocalSummary *) folder->summary, message, info, lf->changes, error); if (mi == NULL) goto check_changed; has_attachment = camel_mime_message_has_attachment (message); if (((camel_message_info_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) && !has_attachment) || ((camel_message_info_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) == 0 && has_attachment)) { camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, has_attachment ? CAMEL_MESSAGE_ATTACHMENTS : 0); } d(printf("Appending message: uid is %s\n", camel_message_info_uid(mi))); /* write it out, use the uid we got from the summary */ name = g_strdup_printf("%s/%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; /* close this? */ g_object_unref (output_stream); g_free (name); if (appended_uid) *appended_uid = g_strdup(camel_message_info_uid(mi)); 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 mh folder: %s: "), name); if (output_stream) { g_object_unref (output_stream); unlink (name); } g_free (name); check_changed: camel_local_folder_unlock (lf); if (camel_folder_change_info_changed (lf->changes)) { camel_folder_changed (folder, lf->changes); camel_folder_change_info_clear (lf->changes); } return TRUE; }
static CamelMimeMessage * mh_folder_get_message_sync (CamelFolder *folder, const gchar *uid, GCancellable *cancellable, GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *) folder; CamelStream *message_stream = NULL; CamelMimeMessage *message = NULL; CamelMessageInfo *info; gchar *name = NULL; d(printf("getting message: %s\n", uid)); if (!lf || camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) return NULL; /* get the message summary info */ if ((info = camel_folder_summary_get (folder->summary, uid)) == NULL) { set_cannot_get_message_ex ( error, CAMEL_FOLDER_ERROR_INVALID_UID, uid, lf->folder_path, _("No such message")); goto fail; } /* we only need it to check the message exists */ camel_message_info_free (info); name = g_strdup_printf("%s/%s", lf->folder_path, uid); message_stream = camel_stream_fs_new_with_name ( name, O_RDONLY, 0, error); if (message_stream == NULL) { g_prefix_error ( error, _("Cannot get message %s from folder %s: "), name, lf->folder_path); goto fail; } message = camel_mime_message_new (); if (!camel_data_wrapper_construct_from_stream_sync ( (CamelDataWrapper *) message, message_stream, cancellable, error)) { g_prefix_error ( error, _("Cannot get message %s from folder %s: "), name, lf->folder_path); g_object_unref (message); message = NULL; } g_object_unref (message_stream); fail: g_free (name); camel_local_folder_unlock (lf); if (camel_folder_change_info_changed (lf->changes)) { camel_folder_changed (folder, lf->changes); camel_folder_change_info_clear (lf->changes); } return message; }
static CamelMimeMessage * nntp_folder_get_message_sync (CamelFolder *folder, const gchar *uid, GCancellable *cancellable, GError **error) { CamelStore *parent_store; CamelMimeMessage *message = NULL; CamelDataCache *nntp_cache; CamelNNTPStore *nntp_store; CamelFolderChangeInfo *changes; CamelNNTPFolder *nntp_folder; CamelStream *stream = NULL; GIOStream *base_stream; gchar *article, *msgid; gsize article_len; parent_store = camel_folder_get_parent_store (folder); nntp_folder = CAMEL_NNTP_FOLDER (folder); nntp_store = CAMEL_NNTP_STORE (parent_store); article_len = strlen (uid) + 1; article = alloca (article_len); g_strlcpy (article, uid, article_len); msgid = strchr (article, ','); if (msgid == NULL) { g_set_error ( error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Internal error: UID in invalid format: %s"), uid); return NULL; } *msgid++ = 0; /* Lookup in cache, NEWS is global messageid's so use a global cache path */ nntp_cache = camel_nntp_store_ref_cache (nntp_store); base_stream = camel_data_cache_get (nntp_cache, "cache", msgid, NULL); g_clear_object (&nntp_cache); if (base_stream != NULL) { stream = camel_stream_new (base_stream); g_object_unref (base_stream); } else { CamelServiceConnectionStatus connection_status; connection_status = camel_service_get_connection_status ( CAMEL_SERVICE (parent_store)); if (connection_status != CAMEL_SERVICE_CONNECTED) { g_set_error ( error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE, _("This message is not currently available")); goto fail; } stream = nntp_folder_download_message (nntp_folder, article, msgid, cancellable, error); if (stream == NULL) goto fail; } message = camel_mime_message_new (); if (!camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) message, stream, cancellable, error)) { g_prefix_error (error, _("Cannot get message %s: "), uid); g_object_unref (message); message = NULL; } g_object_unref (stream); fail: if (camel_folder_change_info_changed (nntp_folder->changes)) { changes = nntp_folder->changes; nntp_folder->changes = camel_folder_change_info_new (); } else { changes = NULL; } if (changes) { camel_folder_changed (folder, changes); camel_folder_change_info_free (changes); } return message; }
static CamelMimeMessage * nntp_folder_get_message (CamelFolder *folder, const char *uid, CamelException *ex) { CamelMimeMessage *message = NULL; CamelNNTPStore *nntp_store; CamelFolderChangeInfo *changes; CamelNNTPFolder *nntp_folder; CamelStream *stream = NULL; char *article, *msgid; nntp_store = (CamelNNTPStore *) folder->parent_store; nntp_folder = (CamelNNTPFolder *) folder; article = alloca(strlen(uid)+1); strcpy(article, uid); msgid = strchr (article, ','); if (msgid == NULL) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Internal error: UID in invalid format: %s"), uid); return NULL; } *msgid++ = 0; CAMEL_SERVICE_REC_LOCK(nntp_store, connect_lock); /* Lookup in cache, NEWS is global messageid's so use a global cache path */ stream = camel_data_cache_get (nntp_store->cache, "cache", msgid, NULL); if (stream == NULL) { if (camel_disco_store_status ((CamelDiscoStore *) nntp_store) == CAMEL_DISCO_STORE_OFFLINE) { camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, _("This message is not currently available")); goto fail; } stream = nntp_folder_download_message (nntp_folder, article, msgid, ex); if (stream == NULL) goto fail; } message = camel_mime_message_new (); if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream) == -1) { if (errno == EINTR) camel_exception_setv (ex, CAMEL_EXCEPTION_USER_CANCEL, _("User canceled")); else camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot get message %s: %s"), uid, g_strerror (errno)); camel_object_unref(message); message = NULL; } camel_object_unref (stream); fail: if (camel_folder_change_info_changed (nntp_folder->changes)) { changes = nntp_folder->changes; nntp_folder->changes = camel_folder_change_info_new (); } else { changes = NULL; } CAMEL_SERVICE_REC_UNLOCK(nntp_store, connect_lock); if (changes) { camel_object_trigger_event ((CamelObject *) folder, "folder_changed", changes); camel_folder_change_info_free (changes); } return message; }