void camel_nntp_grouplist_save (CamelNNTPGroupList *group_list, CamelException *ex) { FILE *fp; gchar *root_dir = camel_nntp_store_get_toplevel_dir(CAMEL_NNTP_STORE(group_list->store)); gchar *grouplist_file = g_strdup_printf ("%s/grouplist", root_dir); g_free (root_dir); fp = g_fopen (grouplist_file, "w"); g_free (grouplist_file); if (fp == NULL) { camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, _("Unable to save grouplist file for %s: %s"), CAMEL_SERVICE(group_list->store)->url->host, strerror(errno)); return; } fprintf (fp, "%lu\n", (long)group_list->time); g_list_foreach (group_list->group_list, (GFunc)save_entry, fp); fclose (fp); }
static gchar * nntp_get_filename (CamelFolder *folder, const gchar *uid, GError **error) { CamelStore *parent_store; CamelDataCache *nntp_cache; CamelNNTPStore *nntp_store; gchar *article, *msgid; gsize article_len; gchar *filename; parent_store = camel_folder_get_parent_store (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; nntp_cache = camel_nntp_store_ref_cache (nntp_store); filename = camel_data_cache_get_filename (nntp_cache, "cache", msgid); g_clear_object (&nntp_cache); return filename; }
static gboolean nntp_folder_refresh_info_sync (CamelFolder *folder, GCancellable *cancellable, GError **error) { CamelStore *parent_store; CamelNNTPStore *nntp_store; CamelFolderChangeInfo *changes = NULL; CamelNNTPFolder *nntp_folder; gchar *line; gboolean success; parent_store = camel_folder_get_parent_store (folder); nntp_folder = CAMEL_NNTP_FOLDER (folder); nntp_store = CAMEL_NNTP_STORE (parent_store); /* When invoked with no fmt, camel_nntp_command() just selects the folder * and should return zero. */ success = !camel_nntp_command ( nntp_store, cancellable, error, nntp_folder, &line, NULL); if (camel_folder_change_info_changed (nntp_folder->changes)) { changes = nntp_folder->changes; nntp_folder->changes = camel_folder_change_info_new (); } if (changes) { camel_folder_changed (folder, changes); camel_folder_change_info_free (changes); } return success; }
gboolean camel_nntp_folder_selected (CamelNNTPFolder *nntp_folder, gchar *line, GCancellable *cancellable, GError **error) { CamelFolder *folder; CamelStore *parent_store; gboolean res; folder = CAMEL_FOLDER (nntp_folder); parent_store = camel_folder_get_parent_store (folder); res = camel_nntp_summary_check ( CAMEL_NNTP_SUMMARY (folder->summary), CAMEL_NNTP_STORE (parent_store), line, nntp_folder->changes, cancellable, error); if (camel_folder_change_info_changed (nntp_folder->changes)) { CamelFolderChangeInfo *changes; changes = nntp_folder->changes; nntp_folder->changes = camel_folder_change_info_new (); camel_folder_changed (CAMEL_FOLDER (nntp_folder), changes); camel_folder_change_info_free (changes); } return res; }
static CamelNNTPGroupList* camel_nntp_get_grouplist_from_file (CamelNNTPStore *store, CamelException *ex) { gchar *root_dir = camel_nntp_store_get_toplevel_dir(CAMEL_NNTP_STORE(store)); gchar *grouplist_file = g_strdup_printf ("%s/grouplist", root_dir); CamelNNTPGroupList *list; FILE *fp; char buf[300]; unsigned long time; g_free (root_dir); fp = g_fopen (grouplist_file, "r"); g_free (grouplist_file); if (fp == NULL) { camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, _("Unable to load grouplist file for %s: %s"), CAMEL_SERVICE(store)->url->host, strerror(errno)); return NULL; } /* read the time */ if (!fgets (buf, sizeof (buf), fp)) { camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, _("Unable to load grouplist file for %s: %s"), CAMEL_SERVICE(store)->url->host, strerror(errno)); fclose (fp); return NULL; } list = g_new0 (CamelNNTPGroupList, 1); list->store = store; sscanf (buf, "%lu", &time); list->time = time; while (fgets (buf, sizeof (buf), fp)) { CamelNNTPGroupListEntry *entry = g_new (CamelNNTPGroupListEntry, 1); char **split_line = g_strsplit (buf, " ", 4); entry->group_name = g_strdup (split_line[0]); entry->high = atoi (split_line[1]); entry->low = atoi (split_line[2]); g_strfreev (split_line); list->group_list = g_list_prepend (list->group_list, entry); } fclose (fp); list->group_list = g_list_reverse(list->group_list); return list; }
static void nntp_folder_dispose (GObject *object) { CamelFolder *folder; CamelStore *store; folder = CAMEL_FOLDER (object); camel_folder_summary_save_to_db (folder->summary, NULL); store = camel_folder_get_parent_store (folder); if (store != NULL) { CamelNNTPStoreSummary *nntp_store_summary; nntp_store_summary = camel_nntp_store_ref_summary ( CAMEL_NNTP_STORE (store)); camel_store_summary_disconnect_folder_summary ( CAMEL_STORE_SUMMARY (nntp_store_summary), folder->summary); g_clear_object (&nntp_store_summary); } /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (camel_nntp_folder_parent_class)->dispose (object); }
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 gboolean nntp_folder_append_message_sync (CamelFolder *folder, CamelMimeMessage *message, CamelMessageInfo *info, gchar **appended_uid, GCancellable *cancellable, GError **error) { CamelStore *parent_store; CamelNNTPStore *nntp_store; CamelNNTPStream *nntp_stream = NULL; CamelStream *filtered_stream; CamelMimeFilter *crlffilter; gint ret; guint u; struct _camel_header_raw *header, *savedhdrs, *n, *tail; const gchar *full_name; gchar *group, *line; gboolean success = TRUE; GError *local_error = NULL; full_name = camel_folder_get_full_name (folder); parent_store = camel_folder_get_parent_store (folder); nntp_store = CAMEL_NNTP_STORE (parent_store); /* send 'POST' command */ ret = camel_nntp_command ( nntp_store, cancellable, error, NULL, &line, "post"); if (ret != 340) { if (ret == 440) { g_set_error ( error, CAMEL_FOLDER_ERROR, CAMEL_FOLDER_ERROR_INSUFFICIENT_PERMISSION, _("Posting failed: %s"), line); success = FALSE; } else if (ret != -1) { g_set_error ( error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Posting failed: %s"), line); success = FALSE; } goto exit; } /* the 'Newsgroups: ' header */ group = g_strdup_printf ("Newsgroups: %s\r\n", full_name); /* remove mail 'To', 'CC', and 'BCC' headers */ savedhdrs = NULL; tail = (struct _camel_header_raw *) &savedhdrs; header = (struct _camel_header_raw *) &CAMEL_MIME_PART (message)->headers; n = header->next; while (n != NULL) { if (!g_ascii_strcasecmp (n->name, "To") || !g_ascii_strcasecmp (n->name, "Cc") || !g_ascii_strcasecmp (n->name, "Bcc")) { header->next = n->next; tail->next = n; n->next = NULL; tail = n; } else { header = n; } n = header->next; } nntp_stream = camel_nntp_store_ref_stream (nntp_store); /* setup stream filtering */ filtered_stream = camel_stream_filter_new (CAMEL_STREAM (nntp_stream)); crlffilter = camel_mime_filter_crlf_new ( CAMEL_MIME_FILTER_CRLF_ENCODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_DOTS); camel_stream_filter_add ( CAMEL_STREAM_FILTER (filtered_stream), crlffilter); g_object_unref (crlffilter); /* write the message */ if (local_error == NULL) camel_stream_write ( CAMEL_STREAM (nntp_stream), group, strlen (group), cancellable, &local_error); if (local_error == NULL) camel_data_wrapper_write_to_stream_sync ( CAMEL_DATA_WRAPPER (message), filtered_stream, cancellable, &local_error); if (local_error == NULL) camel_stream_flush ( filtered_stream, cancellable, &local_error); if (local_error == NULL) camel_stream_write ( CAMEL_STREAM (nntp_stream), "\r\n.\r\n", 5, cancellable, &local_error); if (local_error == NULL) camel_nntp_stream_line ( nntp_stream, (guchar **) &line, &u, cancellable, &local_error); if (local_error == NULL && atoi (line) != 240) local_error = g_error_new_literal ( CAMEL_ERROR, CAMEL_ERROR_GENERIC, line); if (local_error != NULL) { g_propagate_prefixed_error ( error, local_error, _("Posting failed: ")); success = FALSE; } g_object_unref (filtered_stream); g_free (group); header->next = savedhdrs; exit: g_clear_object (&nntp_stream); return success; }
static CamelStream * nntp_folder_download_message (CamelNNTPFolder *nntp_folder, const gchar *id, const gchar *msgid, GCancellable *cancellable, GError **error) { CamelFolder *folder; CamelStore *parent_store; CamelDataCache *nntp_cache; CamelNNTPStore *nntp_store; CamelNNTPStream *nntp_stream = NULL; CamelStream *stream = NULL; gint ret; gchar *line; folder = CAMEL_FOLDER (nntp_folder); parent_store = camel_folder_get_parent_store (folder); nntp_store = CAMEL_NNTP_STORE (parent_store); nntp_cache = camel_nntp_store_ref_cache (nntp_store); ret = camel_nntp_command ( nntp_store, cancellable, error, nntp_folder, &line, "article %s", id); if (ret == 220) { GIOStream *base_stream; nntp_stream = camel_nntp_store_ref_stream (nntp_store); base_stream = camel_data_cache_add ( nntp_cache, "cache", msgid, NULL); if (base_stream != NULL) { gboolean success; stream = camel_stream_new (base_stream); g_object_unref (base_stream); success = (camel_stream_write_to_stream ( CAMEL_STREAM (nntp_stream), stream, cancellable, error) != -1); if (!success) goto fail; success = g_seekable_seek ( G_SEEKABLE (stream), 0, G_SEEK_SET, cancellable, error); if (!success) goto fail; } else { stream = g_object_ref (nntp_stream); } } else if (ret == 423 || ret == 430) { g_set_error ( error, CAMEL_FOLDER_ERROR, CAMEL_FOLDER_ERROR_INVALID_UID, _("Cannot get message %s: %s"), msgid, line); } else if (ret != -1) { g_set_error ( error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Cannot get message %s: %s"), msgid, line); } goto exit; fail: camel_data_cache_remove (nntp_cache, "cache", msgid, NULL); g_prefix_error (error, _("Cannot get message %s: "), msgid); g_clear_object (&stream); exit: g_clear_object (&nntp_cache); g_clear_object (&nntp_stream); return stream; }