From f1e6e913a674ce5deb47611a3d1d2ed3047a644c Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Fri, 24 May 2002 20:14:59 +0000 Subject: Use the new readline function. 2002-05-24 Jeffrey Stedfast * providers/imap/camel-imap-command.c (imap_read_untagged): Use the new readline function. * providers/imap/camel-imap-store.c (connect_to_server): Use the new camel_imap_store_readline() function which doesn't suck quite as bad as the original camel_remote_store_recv_line() function. (camel_imap_store_readline): New function to replace camel_remote_store_recv_line(). This function is at least safe with embedded nul chars. Not that any of our callers use it *sigh*. svn path=/trunk/; revision=17012 --- camel/ChangeLog | 13 +++++ camel/camel-stream-fs.c | 9 ++-- camel/camel-stream.c | 81 +++++++++++++++++-------------- camel/providers/imap/camel-imap-command.c | 8 +-- camel/providers/imap/camel-imap-store.c | 42 +++++++++++----- camel/providers/imap/camel-imap-store.h | 2 +- 6 files changed, 96 insertions(+), 59 deletions(-) diff --git a/camel/ChangeLog b/camel/ChangeLog index 148c09e23c..9a7563608d 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,16 @@ +2002-05-24 Jeffrey Stedfast + + * providers/imap/camel-imap-command.c (imap_read_untagged): Use + the new readline function. + + * providers/imap/camel-imap-store.c (connect_to_server): Use the + new camel_imap_store_readline() function which doesn't suck quite + as bad as the original camel_remote_store_recv_line() function. + (camel_imap_store_readline): New function to replace + camel_remote_store_recv_line(). This function is at least safe + with embedded nul chars. Not that any of our callers use it + *sigh*. + 2002-05-24 Jeffrey Stedfast * providers/imap/camel-imap-store.c (connect_to_server): Added diff --git a/camel/camel-stream-fs.c b/camel/camel-stream-fs.c index a1d7cbaca3..917fd1f8e1 100644 --- a/camel/camel-stream-fs.c +++ b/camel/camel-stream-fs.c @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- */ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* camel-stream-fs.c : file system based stream */ /* @@ -109,10 +109,11 @@ camel_stream_fs_get_type (void) * camel_stream_fs_new_with_fd: * @fd: a file descriptor * - * Returns a stream associated with the given file descriptor. - * When the stream is destroyed, the file descriptor will be closed. + * Creates a new fs stream using the given file descriptor @fd as the + * backing store. When the stream is destroyed, the file descriptor + * will be closed. * - * Return value: the stream + * Returns a new fs stream. **/ CamelStream * camel_stream_fs_new_with_fd (int fd) diff --git a/camel/camel-stream.c b/camel/camel-stream.c index 709bfe107c..bcc4640697 100644 --- a/camel/camel-stream.c +++ b/camel/camel-stream.c @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- */ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* camel-stream.c : abstract class for a stream */ /* @@ -22,6 +22,7 @@ * USA */ + #ifdef HAVE_CONFIG_H #include #endif @@ -75,112 +76,116 @@ camel_stream_get_type (void) return camel_stream_type; } + /** * camel_stream_read: * @stream: a CamelStream. - * @buffer: buffer where bytes pulled from the stream are stored. + * @buffer: output buffer * @n: max number of bytes to read. * - * Read at most @n bytes from the @stream object and stores them - * in the buffer pointed at by @buffer. + * Attempts to read up to @len bytes from @stream into @buf. * - * Return value: number of bytes actually read, or -1 on error and - * set errno. + * Returns the number of bytes actually read, or -1 on error and set + * errno. **/ ssize_t camel_stream_read (CamelStream *stream, char *buffer, size_t n) { g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1); g_return_val_if_fail (n == 0 || buffer, -1); - + return CS_CLASS (stream)->read (stream, buffer, n); } + /** * camel_stream_write: * @stream: a CamelStream object. * @buffer: buffer to write. * @n: number of bytes to write * - * Write @n bytes from the buffer pointed at by @buffer into @stream. + * Attempts to write up to @n bytes of @buffer into @stream. * - * Return value: the number of bytes actually written to the stream, - * or -1 on error. + * Returns the number of bytes written to the stream, or -1 on error + * along with setting errno. **/ ssize_t camel_stream_write (CamelStream *stream, const char *buffer, size_t n) { g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1); g_return_val_if_fail (n == 0 || buffer, -1); - + return CS_CLASS (stream)->write (stream, buffer, n); } + /** * camel_stream_flush: - * @stream: a CamelStream object + * @stream: stream * - * Flushes the contents of the stream to its backing store. Only meaningful - * on writable streams. + * Flushes any buffered data to the stream's backing store. Only + * meaningful for writable streams. * - * Return value: -1 on error. + * Returns 0 on success or -1 on fail along with setting errno. **/ int camel_stream_flush (CamelStream *stream) { g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1); - + return CS_CLASS (stream)->flush (stream); } + /** * camel_stream_close: * @stream: * - * Close a stream. + * Closes the stream. * - * Return value: -1 on error. + * Returns 0 on success or -1 on error. **/ int camel_stream_close (CamelStream *stream) { g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1); - + return CS_CLASS (stream)->close (stream); } + /** * camel_stream_eos: * @stream: a CamelStream object * - * Test if there are bytes left to read on the @stream object. + * Tests if there are bytes left to read on the @stream object. * - * Return value: %TRUE if all the contents on the stream has been read, or - * %FALSE if information is still available. + * Returns %TRUE on EOS or %FALSE otherwise. **/ gboolean camel_stream_eos (CamelStream *stream) { g_return_val_if_fail (CAMEL_IS_STREAM (stream), TRUE); - + return CS_CLASS (stream)->eos (stream); } + /** - * camel_stream_reset: reset a stream + * camel_stream_reset: * @stream: the stream object * - * Reset a stream. That is, put it in a state where it can be read + * Resets the stream. That is, put it in a state where it can be read * from the beginning again. Not all streams in Camel are seekable, * but they must all be resettable. * - * Return value: -1 on error. + * Returns 0 on success or -1 on error along with setting errno. **/ int camel_stream_reset (CamelStream *stream) { g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1); - + return CS_CLASS (stream)->reset (stream); } @@ -193,7 +198,7 @@ camel_stream_reset (CamelStream *stream) * * Writes the string to the stream. * - * Return value: the number of characters output, -1 on error. + * Returns the number of characters written or -1 on error. **/ ssize_t camel_stream_write_string (CamelStream *stream, const char *string) @@ -201,14 +206,15 @@ camel_stream_write_string (CamelStream *stream, const char *string) return camel_stream_write (stream, string, strlen (string)); } + /** * camel_stream_printf: * @stream: a stream object * @fmt: a printf-style format string * - * This printfs the given data to @stream. + * Write formatted output to a stream. * - * Return value: the number of characters output, -1 on error. + * Returns the number of characters written or -1 on error. **/ ssize_t camel_stream_printf (CamelStream *stream, const char *fmt, ... ) @@ -216,30 +222,31 @@ camel_stream_printf (CamelStream *stream, const char *fmt, ... ) va_list args; char *string; ssize_t ret; - + g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1); - + va_start (args, fmt); string = g_strdup_vprintf (fmt, args); va_end (args); - + if (!string) return -1; - + ret = camel_stream_write (stream, string, strlen (string)); g_free (string); return ret; } + /** * camel_stream_write_to_stream: * @stream: Source CamelStream. * @output_stream: Destination CamelStream. * - * Write all of a stream (until eos) into another stream, in a blocking - * fashion. + * Write all of a stream (until eos) into another stream, in a + * blocking fashion. * - * Return value: Returns -1 on error, or the number of bytes succesfully + * Returns -1 on error, or the number of bytes succesfully * copied across streams. **/ ssize_t diff --git a/camel/providers/imap/camel-imap-command.c b/camel/providers/imap/camel-imap-command.c index b0df0deefc..4309e18ddd 100644 --- a/camel/providers/imap/camel-imap-command.c +++ b/camel/providers/imap/camel-imap-command.c @@ -290,7 +290,7 @@ camel_imap_command_response (CamelImapStore *store, char **response, CamelImapResponseType type; char *respbuf; - if (camel_imap_store_recv_line (store, &respbuf, ex) < 0) { + if (camel_imap_store_readline (store, &respbuf, ex) < 0) { CAMEL_IMAP_STORE_UNLOCK (store, command_lock); return CAMEL_IMAP_RESPONSE_ERROR; } @@ -457,10 +457,6 @@ imap_read_untagged (CamelImapStore *store, char *line, CamelException *ex) * against any completely correct server. * - WU-imapd 12.264 (at least) will cheerily pass * NULs along if they are embedded in the message - * - The only cause of embedded NULs we've seen is an - * Evolution base64-encoder bug that sometimes - * inserts a NUL into the last line when it - * shouldn't. */ s = d = str->str + 1; @@ -493,7 +489,7 @@ imap_read_untagged (CamelImapStore *store, char *line, CamelException *ex) g_ptr_array_add (data, str); /* Read the next line. */ - if (camel_imap_store_recv_line (store, &line, ex) < 0) + if (camel_imap_store_readline (store, &line, ex) < 0) goto lose; } diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index 312f6c2fb6..b97f8c0f1a 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -556,7 +556,7 @@ connect_to_server (CamelService *service, int ssl_mode, int try_starttls, CamelE store->command = 0; /* Read the greeting, if any. FIXME: deal with PREAUTH */ - if (camel_imap_store_recv_line (store, &buf, ex) < 0) { + if (camel_imap_store_readline (store, &buf, ex) < 0) { if (store->istream) { camel_object_unref (CAMEL_OBJECT (store->istream)); store->istream = NULL; @@ -2223,11 +2223,13 @@ camel_imap_store_connected (CamelImapStore *store, CamelException *ex) /* FIXME: please god, when will the hurting stop? Thus function is so fucking broken it's not even funny. */ -int -camel_imap_store_recv_line (CamelImapStore *store, char **dest, CamelException *ex) +ssize_t +camel_imap_store_readline (CamelImapStore *store, char **dest, CamelException *ex) { CamelStreamBuffer *stream; - char *buf; + char linebuf[1024]; + GByteArray *ba; + ssize_t nread; g_return_val_if_fail (CAMEL_IS_IMAP_STORE (store), -1); g_return_val_if_fail (dest, -1); @@ -2244,11 +2246,17 @@ camel_imap_store_recv_line (CamelImapStore *store, char **dest, CamelException * g_strerror (errno)); return -1; } + stream = CAMEL_STREAM_BUFFER (store->istream); - buf = camel_stream_buffer_read_line (stream); + ba = g_byte_array_new (); + while ((nread = camel_stream_buffer_gets (stream, linebuf, sizeof (linebuf))) > 0) { + g_byte_array_append (ba, linebuf, nread); + if (linebuf[nread - 1] == '\n') + break; + } - if (buf == NULL) { + if (nread <= 0) { if (errno == EINTR) camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, _("Operation cancelled")); else @@ -2260,12 +2268,24 @@ camel_imap_store_recv_line (CamelImapStore *store, char **dest, CamelException * return -1; } - *dest = buf; - #if d(!)0 - if (camel_verbose_debug) - fprintf (stderr, "received: %s\n", *dest); + if (camel_verbose_debug) { + fprintf (stderr, "received: "); + fwrite (*dest, 1, nread, stderr); + } #endif - return strlen (*dest); + /* camel-imap-command.c:imap_read_untagged expects the CRLFs + to be stripped off and be nul-terminated *sigh* */ + nread = ba->len - 1; + ba->data[nread] = '\0'; + if (ba->data[nread - 1] == '\r') { + ba->data[nread - 1] = '\0'; + nread--; + } + + *dest = ba->data; + g_byte_array_free (ba, FALSE); + + return nread; } diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h index 36e6e3c032..9ebbc31ad7 100644 --- a/camel/providers/imap/camel-imap-store.h +++ b/camel/providers/imap/camel-imap-store.h @@ -131,7 +131,7 @@ CamelType camel_imap_store_get_type (void); gboolean camel_imap_store_connected (CamelImapStore *store, CamelException *ex); -int camel_imap_store_recv_line (CamelImapStore *store, char **dest, CamelException *ex); +ssize_t camel_imap_store_readline (CamelImapStore *store, char **dest, CamelException *ex); #ifdef __cplusplus } -- cgit v1.2.3