From 71eb39b730cd190c690647d3806d567d55424026 Mon Sep 17 00:00:00 2001 From: Chris Toshok Date: Fri, 1 Sep 2000 01:58:56 +0000 Subject: use camel_remote_store_recv_line. 2000-08-31 Chris Toshok * providers/nntp/camel-nntp-utils.c (get_OVER_headers): use camel_remote_store_recv_line. * providers/nntp/camel-nntp-folder.c (nntp_folder_get_message): use camel_remote_store_recv_line to build message. also, free our buffer so we don't leak like mad. * providers/nntp/camel-nntp-store.c: (camel_nntp_store_get_additional_data) remove. (camel_nntp_store_get_extensions): use camel_remote_store_recv_line. (camel_nntp_store_get_overview_fmt): same. also, don't rely on _get_additional_data anymore since it's easier to parse without. (camel_nntp_command): use camel_remote_store_send_string and camel_remote_store_recv_line. * providers/nntp/camel-nntp-store.h: CamelRemoteStore is the parent class now. remove istream/ostream since CamelRemoteStore takes care of that for us. also remove the prototype for camel_nntp_store_get_additional_data. * providers/nntp/camel-nntp-newsrc.c (camel_nntp_newsrc_write): make sure to clear dirty bit. (camel_nntp_newsrc_read_for_server): don't worry about continually trying to open the file - if it fails we just return an unpopulated .newsrc file. svn path=/trunk/; revision=5153 --- camel/providers/nntp/camel-nntp-folder.c | 27 ++-- camel/providers/nntp/camel-nntp-newsrc.c | 25 +-- camel/providers/nntp/camel-nntp-store.c | 252 ++++++++++--------------------- camel/providers/nntp/camel-nntp-store.h | 8 +- camel/providers/nntp/camel-nntp-utils.c | 7 +- 5 files changed, 100 insertions(+), 219 deletions(-) (limited to 'camel/providers') diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c index 371c4698e2..43209758a7 100644 --- a/camel/providers/nntp/camel-nntp-folder.c +++ b/camel/providers/nntp/camel-nntp-folder.c @@ -42,7 +42,6 @@ #include "string-utils.h" #include "camel-stream-mem.h" -#include "camel-stream-buffer.h" #include "camel-data-wrapper.h" #include "camel-mime-message.h" #include "camel-folder-summary.h" @@ -196,8 +195,7 @@ nntp_folder_set_message_flags (CamelFolder *folder, const char *uid, static CamelMimeMessage * nntp_folder_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex) { - CamelStream *nntp_istream; - CamelStream *message_stream; + CamelStream *message_stream = NULL; CamelMimeMessage *message = NULL; CamelStore *parent_store; char *buf; @@ -213,8 +211,6 @@ nntp_folder_get_message (CamelFolder *folder, const gchar *uid, CamelException * message_id = strchr (uid, ',') + 1; status = camel_nntp_command (CAMEL_NNTP_STORE( parent_store ), NULL, "ARTICLE %s", message_id); - nntp_istream = CAMEL_NNTP_STORE (parent_store)->istream; - /* if the message_id was not found, raise an exception and return */ if (status != CAMEL_NNTP_OK) { camel_exception_setv (ex, @@ -234,8 +230,13 @@ nntp_folder_get_message (CamelFolder *folder, const gchar *uid, CamelException * buf[0] = 0; while (!done) { - char *line = camel_stream_buffer_read_line ( CAMEL_STREAM_BUFFER ( nntp_istream )); int line_length; + char *line; + + if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (parent_store), &line, ex) < 0) { + g_error ("recv_line failed while building message\n"); + break; + } /* XXX check exception */ @@ -261,24 +262,16 @@ nntp_folder_get_message (CamelFolder *folder, const gchar *uid, CamelException * message_stream = camel_stream_mem_new_with_buffer(buf, buf_len); message = camel_mime_message_new (); - if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, message_stream) == -1) { - camel_object_unref (CAMEL_OBJECT (message)); - camel_object_unref (CAMEL_OBJECT (message_stream)); - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INVALID_UID, /* XXX */ - "Could not create message for message_id %s.", message_id); + camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER(message), message_stream); - return NULL; - } camel_object_unref (CAMEL_OBJECT (message_stream)); - /* init other fields? */ - camel_object_ref (CAMEL_OBJECT (folder)); - #if 0 gtk_signal_connect (CAMEL_OBJECT (message), "message_changed", message_changed, folder); #endif + g_free (buf); + return message; } diff --git a/camel/providers/nntp/camel-nntp-newsrc.c b/camel/providers/nntp/camel-nntp-newsrc.c index 9510fe5bfa..af40308219 100644 --- a/camel/providers/nntp/camel-nntp-newsrc.c +++ b/camel/providers/nntp/camel-nntp-newsrc.c @@ -371,6 +371,8 @@ camel_nntp_newsrc_write(CamelNNTPNewsrc *newsrc) camel_nntp_newsrc_write_to_file(newsrc, fp); + newsrc->dirty = FALSE; + fclose(fp); } @@ -445,30 +447,15 @@ camel_nntp_newsrc_read_for_server (const char *server) char *filename = g_strdup_printf ("%s/.newsrc-%s", g_get_home_dir(), server); CamelNNTPNewsrc *newsrc; - if ((fp = fopen(filename, "r")) == NULL) { - int fd; - - g_warning ("~/.newsrc-%s not present. creating empty file\n", server); - - if ((fd = open (filename, O_CREAT, O_TRUNC, O_WRONLY, 0777)) < 0) { - g_warning ("unable to create ~/.newsrc-%s file\n", server); - g_free (filename); - return NULL; - } - close (fd); - - if ((fp = fopen(filename, "r")) == NULL) { - g_warning ("unable to open ~/.newsrc-%s file on second try.\n", server); - g_free (filename); - return NULL; - } - } - newsrc = g_new0(CamelNNTPNewsrc, 1); newsrc->filename = filename; newsrc->groups = g_hash_table_new (g_str_hash, g_str_equal); newsrc->subscribed_groups = g_hash_table_new (g_str_hash, g_str_equal); + if ((fp = fopen(filename, "r")) == NULL) { + g_warning ("~/.newsrc-%s not present.\n", server); + return newsrc; + } while (fgets(buf, MAX_LINE_LENGTH, fp) != NULL) { /* we silently ignore (and lose!) lines longer than 20 * 1500 chars. diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c index 37cb184f28..1330f93091 100644 --- a/camel/providers/nntp/camel-nntp-store.c +++ b/camel/providers/nntp/camel-nntp-store.c @@ -25,8 +25,6 @@ #include #include -#include -#include #include #include #include @@ -40,8 +38,6 @@ #include "camel-folder-summary.h" #include "camel-nntp-store.h" #include "camel-nntp-folder.h" -#include "camel-stream-buffer.h" -#include "camel-stream-fs.h" #include "camel-exception.h" #include "camel-url.h" #include "string-utils.h" @@ -50,6 +46,8 @@ #define DUMP_EXTENSIONS +static CamelRemoteStoreClass *remote_store_class = NULL; + static CamelServiceClass *service_class = NULL; /* Returns the class for a CamelNNTPStore */ @@ -66,11 +64,13 @@ camel_nntp_store_get_extensions (CamelNNTPStore *store) if (CAMEL_NNTP_OK == camel_nntp_command (store, NULL, "LIST EXTENSIONS")) { gboolean done = FALSE; + CamelException ex; while (!done) { char *line; - line = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER(store->istream)); + if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &line, &ex) < 0) + break; /* XXX */ if (*line == '.') { done = TRUE; @@ -114,9 +114,9 @@ static void camel_nntp_store_get_overview_fmt (CamelNNTPStore *store) { int status; - char *result; - char *field; int i; + gboolean done = FALSE; + CamelException ex; status = camel_nntp_command (store, NULL, "LIST OVERVIEW.FMT"); @@ -129,63 +129,66 @@ camel_nntp_store_get_overview_fmt (CamelNNTPStore *store) store->extensions &= ~CAMEL_NNTP_EXT_OVER; return; } - - result = camel_nntp_command_get_additional_data (store); - /* count the number of fields the server returns in the - overview. start at 1 because the article number is always - first */ + /* start at 1 because the article number is always first */ store->num_overview_fields = 1; - + for (i = 0; i < CAMEL_NNTP_OVER_LAST; i ++) { store->overview_field [i].index = -1; } - while ((field = strsep (&result, "\n"))) { - CamelNNTPOverField *over_field = NULL; - char *colon = NULL;; + while (!done) { + char *line; - if (field[0] == '\0') - break; + if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &line, &ex) < 0) + break; /* XXX */ - if (!strncasecmp (field, "From:", 5)) { - over_field = &store->overview_field [ CAMEL_NNTP_OVER_FROM ]; - over_field->index = store->num_overview_fields; - colon = field + 5; - } - else if (!strncasecmp (field, "Subject:", 7)) { - over_field = &store->overview_field [ CAMEL_NNTP_OVER_SUBJECT ]; - over_field->index = store->num_overview_fields; - colon = field + 7; - } - else if (!strncasecmp (field, "Date:", 5)) { - over_field = &store->overview_field [ CAMEL_NNTP_OVER_DATE ]; - over_field->index = store->num_overview_fields; - colon = field + 5; - } - else if (!strncasecmp (field, "Message-ID:", 11)) { - over_field = &store->overview_field [ CAMEL_NNTP_OVER_MESSAGE_ID ]; - over_field->index = store->num_overview_fields; - colon = field + 11; - } - else if (!strncasecmp (field, "References:", 11)) { - over_field = &store->overview_field [ CAMEL_NNTP_OVER_REFERENCES ]; - over_field->index = store->num_overview_fields; - colon = field + 11; - } - else if (!strncasecmp (field, "Bytes:", 6)) { - over_field = &store->overview_field [ CAMEL_NNTP_OVER_BYTES ]; - over_field->index = store->num_overview_fields; - colon = field + 11; + if (*line == '.') { + done = TRUE; } + else { + CamelNNTPOverField *over_field = NULL; + char *colon = NULL;; + + if (!strncasecmp (line, "From:", 5)) { + over_field = &store->overview_field [ CAMEL_NNTP_OVER_FROM ]; + over_field->index = store->num_overview_fields; + colon = line + 5; + } + else if (!strncasecmp (line, "Subject:", 7)) { + over_field = &store->overview_field [ CAMEL_NNTP_OVER_SUBJECT ]; + over_field->index = store->num_overview_fields; + colon = line + 7; + } + else if (!strncasecmp (line, "Date:", 5)) { + over_field = &store->overview_field [ CAMEL_NNTP_OVER_DATE ]; + over_field->index = store->num_overview_fields; + colon = line + 5; + } + else if (!strncasecmp (line, "Message-ID:", 11)) { + over_field = &store->overview_field [ CAMEL_NNTP_OVER_MESSAGE_ID ]; + over_field->index = store->num_overview_fields; + colon = line + 11; + } + else if (!strncasecmp (line, "References:", 11)) { + over_field = &store->overview_field [ CAMEL_NNTP_OVER_REFERENCES ]; + over_field->index = store->num_overview_fields; + colon = line + 11; + } + else if (!strncasecmp (line, "Bytes:", 6)) { + over_field = &store->overview_field [ CAMEL_NNTP_OVER_BYTES ]; + over_field->index = store->num_overview_fields; + colon = line + 11; + } - if (colon && !strcmp (colon + 1, "full")) - over_field->full = TRUE; + if (colon && !strncmp (colon + 1, "full", 4)) + over_field->full = TRUE; - store->num_overview_fields ++; - } + store->num_overview_fields ++; + } - g_free (result); + g_free (line); + } for (i = 0; i < CAMEL_NNTP_OVER_LAST; i ++) { if (store->overview_field [i].index == -1) { @@ -199,9 +202,6 @@ camel_nntp_store_get_overview_fmt (CamelNNTPStore *store) static gboolean nntp_store_connect (CamelService *service, CamelException *ex) { - struct hostent *h; - struct sockaddr_in sin; - int fd; char *buf; int resp_code; CamelNNTPStore *store = CAMEL_NNTP_STORE (service); @@ -213,37 +213,12 @@ nntp_store_connect (CamelService *service, CamelException *ex) return FALSE; } - if (!service_class->connect (service, ex)) - return FALSE; - - h = camel_service_gethost (service, ex); - if (!h) + if (CAMEL_SERVICE_CLASS (remote_store_class)->connect (service, ex) == FALSE) return FALSE; - sin.sin_family = h->h_addrtype; - sin.sin_port = htons (service->url->port ? service->url->port : NNTP_PORT); - memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr)); - - fd = socket (h->h_addrtype, SOCK_STREAM, 0); - if (fd == -1 || - connect (fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not connect to %s (port %s): %s", - service->url->host, service->url->port, - strerror(errno)); - if (fd > -1) - close (fd); - return FALSE; - } - - store->ostream = camel_stream_fs_new_with_fd (fd); - store->istream = camel_stream_buffer_new (store->ostream, - CAMEL_STREAM_BUFFER_READ); - /* Read the greeting */ - buf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream)); - if (!buf) { - return -1; + if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (service), &buf, ex) < 0) { + return FALSE; } /* check if posting is allowed. */ @@ -290,10 +265,6 @@ nntp_store_disconnect (CamelService *service, CamelException *ex) if (!service_class->disconnect (service, ex)) return FALSE; - camel_object_unref (CAMEL_OBJECT (store->ostream)); - camel_object_unref (CAMEL_OBJECT (store->istream)); - store->ostream = NULL; - store->istream = NULL; return TRUE; } @@ -312,6 +283,8 @@ nntp_store_get_folder (CamelStore *store, const gchar *folder_name, CamelFolder *new_folder; CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store); + printf ("get_folder called on folder_name=%s\n", folder_name); + /* if we haven't already read our .newsrc, read it now */ if (!nntp_store->newsrc) nntp_store->newsrc = @@ -369,6 +342,9 @@ camel_nntp_store_class_init (CamelNNTPStoreClass *camel_nntp_store_class) CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_nntp_store_class); CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS (camel_nntp_store_class); + remote_store_class = CAMEL_REMOTE_STORE_CLASS(camel_type_get_global_classfuncs + (camel_remote_store_get_type ())); + service_class = CAMEL_SERVICE_CLASS (camel_type_get_global_classfuncs (camel_service_get_type ())); /* virtual method overload */ @@ -396,7 +372,7 @@ camel_nntp_store_get_type (void) static CamelType camel_nntp_store_type = CAMEL_INVALID_TYPE; if (camel_nntp_store_type == CAMEL_INVALID_TYPE) { - camel_nntp_store_type = camel_type_register (CAMEL_STORE_TYPE, "CamelNNTPStore", + camel_nntp_store_type = camel_type_register (CAMEL_REMOTE_STORE_TYPE, "CamelNNTPStore", sizeof (CamelNNTPStore), sizeof (CamelNNTPStoreClass), (CamelObjectClassInitFunc) camel_nntp_store_class_init, @@ -436,38 +412,32 @@ camel_nntp_command (CamelNNTPStore *store, char **ret, char *fmt, ...) va_list ap; int status; int resp_code; + char *real_fmt; + CamelException ex; + + real_fmt = g_strdup_printf ("%s\r\n", fmt); va_start (ap, fmt); - cmdbuf = g_strdup_vprintf (fmt, ap); + cmdbuf = g_strdup_vprintf (real_fmt, ap); va_end (ap); - /* make sure we're connected */ - if (store->ostream == NULL) { - CamelException ex; - - camel_exception_init (&ex); - nntp_store_connect (CAMEL_SERVICE (store), &ex); - if (camel_exception_get_id (&ex)) { - camel_exception_clear (&ex); - return CAMEL_NNTP_FAIL; - } - camel_exception_clear (&ex); - } + g_free (real_fmt); /* Send the command */ - camel_stream_write (store->ostream, cmdbuf, strlen (cmdbuf)); + if (camel_remote_store_send_string (CAMEL_REMOTE_STORE (store), &ex, cmdbuf) < 0) { + g_free (cmdbuf); + return CAMEL_NNTP_FAIL; + } + g_free (cmdbuf); - camel_stream_write (store->ostream, "\r\n", 2); /* Read the response */ - respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream)); - - if (!respbuf) { + if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &respbuf, &ex) < 0) { if (ret) *ret = g_strdup (g_strerror (errno)); return CAMEL_NNTP_FAIL; } - + resp_code = atoi (respbuf); if (resp_code < 400) @@ -487,74 +457,6 @@ camel_nntp_command (CamelNNTPStore *store, char **ret, char *fmt, ...) return status; } -/** - * camel_nntp_command_get_additional_data: get "additional data" from - * a NNTP command. - * @store: the NNTP store - * - * This command gets the additional data returned by This command gets - * the additional data returned by "multi-line" NNTP commands, such as - * LIST. This command must only be called after a successful - * (CAMEL_NNTP_OK) call to camel_nntp_command for a command that has a - * multi-line response. The returned data is un-byte-stuffed, and has - * lines termined by newlines rather than CR/LF pairs. - * - * Return value: the data, which the caller must free. - **/ -char * -camel_nntp_command_get_additional_data (CamelNNTPStore *store) -{ - CamelStreamBuffer *stream = CAMEL_STREAM_BUFFER (store->istream); - GPtrArray *data; - char *buf; - int i, status = CAMEL_NNTP_OK; - - /* make sure we're connected */ - if (store->ostream == NULL) { - CamelException ex; - - camel_exception_init (&ex); - nntp_store_connect (CAMEL_SERVICE (store), &ex); - if (camel_exception_get_id (&ex)) { - camel_exception_clear (&ex); - return NULL; - } - camel_exception_clear (&ex); - } - - data = g_ptr_array_new (); - while (1) { - buf = camel_stream_buffer_read_line (stream); - if (!buf) { - status = CAMEL_NNTP_FAIL; - break; - } - - if (!strcmp (buf, ".")) - break; - if (*buf == '.') - memmove (buf, buf + 1, strlen (buf)); - g_ptr_array_add (data, buf); - } - - if (status == CAMEL_NNTP_OK) { - /* Append an empty string to the end of the array - * so when we g_strjoinv it, we get a "\n" after - * the last real line. - */ - g_ptr_array_add (data, ""); - g_ptr_array_add (data, NULL); - buf = g_strjoinv ("\n", (char **)data->pdata); - } else - buf = NULL; - - for (i = 0; i < data->len - 2; i++) - g_free (data->pdata[i]); - g_ptr_array_free (data, TRUE); - - return buf; -} - void camel_nntp_store_subscribe_group (CamelStore *store, const gchar *group_name) diff --git a/camel/providers/nntp/camel-nntp-store.h b/camel/providers/nntp/camel-nntp-store.h index a74ea84f5e..77f04d87ee 100644 --- a/camel/providers/nntp/camel-nntp-store.h +++ b/camel/providers/nntp/camel-nntp-store.h @@ -31,7 +31,7 @@ extern "C" { #pragma } #endif /* __cplusplus }*/ -#include "camel-store.h" +#include "camel-remote-store.h" #include "camel-nntp-newsrc.h" #define CAMEL_NNTP_STORE_TYPE (camel_nntp_store_get_type ()) @@ -58,7 +58,7 @@ typedef struct { } CamelNNTPOverField; typedef struct { - CamelStore parent_object; + CamelRemoteStore parent_object; #define CAMEL_NNTP_EXT_SEARCH (1<<0) #define CAMEL_NNTP_EXT_SETGET (1<<1) @@ -77,13 +77,12 @@ typedef struct { CamelNNTPNewsrc *newsrc; - CamelStream *istream, *ostream; } CamelNNTPStore; typedef struct { - CamelStoreClass parent_class; + CamelRemoteStoreClass parent_class; } CamelNNTPStoreClass; @@ -102,7 +101,6 @@ gchar *camel_nntp_store_get_toplevel_dir (CamelNNTPStore *store); /* support functions */ enum { CAMEL_NNTP_OK, CAMEL_NNTP_ERR, CAMEL_NNTP_FAIL }; int camel_nntp_command (CamelNNTPStore *store, char **ret, char *fmt, ...); -char *camel_nntp_command_get_additional_data (CamelNNTPStore *store); /* Standard Camel function */ CamelType camel_nntp_store_get_type (void); diff --git a/camel/providers/nntp/camel-nntp-utils.c b/camel/providers/nntp/camel-nntp-utils.c index 01b7876134..509fe452cc 100644 --- a/camel/providers/nntp/camel-nntp-utils.c +++ b/camel/providers/nntp/camel-nntp-utils.c @@ -26,7 +26,6 @@ #include "camel-nntp-folder.h" #include "camel-nntp-store.h" #include "camel-nntp-utils.h" -#include "camel-stream-buffer.h" #include "camel-stream-mem.h" #include @@ -45,13 +44,15 @@ get_OVER_headers(CamelNNTPStore *nntp_store, CamelFolder *folder, last_message); if (status == CAMEL_NNTP_OK) { - CamelStream *nntp_istream = nntp_store->istream; gboolean done = FALSE; while (!done) { char *line; - line = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER ( nntp_istream )); + if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (nntp_store), &line, ex) < 0) { + g_warning ("failed to recv_line while building OVER header list\n"); + break; + } if (*line == '.') { done = TRUE; -- cgit v1.2.3