aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers
diff options
context:
space:
mode:
authorChris Toshok <toshok@helixcode.com>2000-09-01 09:58:56 +0800
committerChris Toshok <toshok@src.gnome.org>2000-09-01 09:58:56 +0800
commit71eb39b730cd190c690647d3806d567d55424026 (patch)
treee18c42836d84857e879cefae8263302e018b96a0 /camel/providers
parent3cf4f0d243e0c84b519fe027a3299a925e7075fb (diff)
downloadgsoc2013-evolution-71eb39b730cd190c690647d3806d567d55424026.tar.gz
gsoc2013-evolution-71eb39b730cd190c690647d3806d567d55424026.tar.zst
gsoc2013-evolution-71eb39b730cd190c690647d3806d567d55424026.zip
use camel_remote_store_recv_line.
2000-08-31 Chris Toshok <toshok@helixcode.com> * 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
Diffstat (limited to 'camel/providers')
-rw-r--r--camel/providers/nntp/camel-nntp-folder.c27
-rw-r--r--camel/providers/nntp/camel-nntp-newsrc.c25
-rw-r--r--camel/providers/nntp/camel-nntp-store.c252
-rw-r--r--camel/providers/nntp/camel-nntp-store.h8
-rw-r--r--camel/providers/nntp/camel-nntp-utils.c7
5 files changed, 100 insertions, 219 deletions
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 <config.h>
#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
#include <dirent.h>
#include <sys/stat.h>
#include <errno.h>
@@ -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 <stdlib.h>
@@ -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;