aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/nntp/camel-nntp-store.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers/nntp/camel-nntp-store.c')
-rw-r--r--camel/providers/nntp/camel-nntp-store.c149
1 files changed, 69 insertions, 80 deletions
diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c
index 75b8ef9409..bedcd3f13c 100644
--- a/camel/providers/nntp/camel-nntp-store.c
+++ b/camel/providers/nntp/camel-nntp-store.c
@@ -35,17 +35,17 @@
#include "libgnome/libgnome.h"
+#include "camel-nntp-resp-codes.h"
#include "camel-folder-summary.h"
#include "camel-nntp-store.h"
#include "camel-nntp-folder.h"
+#include "camel-nntp-auth.h"
#include "camel-exception.h"
#include "camel-url.h"
#include "string-utils.h"
#define NNTP_PORT 119
-#define DUMP_EXTENSIONS
-
static CamelRemoteStoreClass *remote_store_class = NULL;
static CamelServiceClass *service_class = NULL;
@@ -58,11 +58,11 @@ static CamelServiceClass *service_class = NULL;
static gboolean ensure_news_dir_exists (CamelNNTPStore *store);
static void
-camel_nntp_store_get_extensions (CamelNNTPStore *store)
+camel_nntp_store_get_extensions (CamelNNTPStore *store, CamelException *ex)
{
store->extensions = 0;
- if (CAMEL_NNTP_OK == camel_nntp_command (store, NULL, "LIST EXTENSIONS")) {
+ if (camel_nntp_command (store, ex, NULL, "LIST EXTENSIONS") == NNTP_LIST_FOLLOWS) {
gboolean done = FALSE;
CamelException ex;
@@ -113,19 +113,16 @@ camel_nntp_store_get_extensions (CamelNNTPStore *store)
}
static void
-camel_nntp_store_get_overview_fmt (CamelNNTPStore *store)
+camel_nntp_store_get_overview_fmt (CamelNNTPStore *store, CamelException *ex)
{
int status;
int i;
gboolean done = FALSE;
- CamelException ex;
-
- camel_exception_init (&ex);
- status = camel_nntp_command (store, NULL,
+ status = camel_nntp_command (store, ex, NULL,
"LIST OVERVIEW.FMT");
- if (status != CAMEL_NNTP_OK) {
+ if (status != NNTP_LIST_FOLLOWS) {
/* if we can't get the overview format, we should
disable OVER support */
g_warning ("server reported support of OVER but LIST OVERVIEW.FMT failed."
@@ -144,7 +141,7 @@ camel_nntp_store_get_overview_fmt (CamelNNTPStore *store)
while (!done) {
char *line;
- if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &line, &ex) < 0)
+ if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &line, ex) < 0)
break; /* XXX */
if (*line == '.') {
@@ -227,11 +224,11 @@ nntp_store_connect (CamelService *service, CamelException *ex)
/* check if posting is allowed. */
resp_code = atoi (buf);
- if (resp_code == 200) {
+ if (resp_code == NNTP_GREETING_POSTING_OK) {
g_print ("posting allowed\n");
store->posting_allowed = TRUE;
}
- else if (resp_code == 201) {
+ else if (resp_code == NNTP_GREETING_NO_POSTING) {
g_print ("no posting allowed\n");
store->posting_allowed = FALSE;
}
@@ -243,11 +240,11 @@ nntp_store_connect (CamelService *service, CamelException *ex)
g_free (buf);
/* get a list of extensions that the server supports */
- camel_nntp_store_get_extensions (store);
+ camel_nntp_store_get_extensions (store, ex);
/* if the server supports the OVER extension, get the overview.fmt */
if (store->extensions & CAMEL_NNTP_EXT_OVER)
- camel_nntp_store_get_overview_fmt (store);
+ camel_nntp_store_get_overview_fmt (store, ex);
return TRUE;
}
@@ -257,11 +254,7 @@ nntp_store_disconnect (CamelService *service, CamelException *ex)
{
CamelNNTPStore *store = CAMEL_NNTP_STORE (service);
- /*if (!service->connected)
- * return TRUE;
- */
-
- camel_nntp_command (store, NULL, "QUIT");
+ camel_nntp_command (store, ex, NULL, "QUIT");
if (store->newsrc)
camel_nntp_newsrc_write (store->newsrc);
@@ -283,8 +276,6 @@ static CamelFolder *
nntp_store_get_folder (CamelStore *store, const gchar *folder_name,
gboolean get_folder, CamelException *ex)
{
- CamelNNTPFolder *new_nntp_folder;
- CamelFolder *new_folder;
CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
printf ("get_folder called on folder_name=%s\n", folder_name);
@@ -302,23 +293,7 @@ nntp_store_get_folder (CamelStore *store, const gchar *folder_name,
return NULL;
}
- /* check if folder has already been created */
- /* call the standard routine for that when */
- /* it is done ... */
-
- new_nntp_folder = CAMEL_NNTP_FOLDER (camel_object_new (CAMEL_NNTP_FOLDER_TYPE));
- new_folder = CAMEL_FOLDER (new_nntp_folder);
-
- /* XXX We shouldn't be passing NULL here, but it's equivalent to
- * what was there before, and there's no
- * CamelNNTPFolder::get_subfolder yet anyway...
- */
- CF_CLASS (new_folder)->init (new_folder, store, NULL,
- folder_name, ".", FALSE, ex);
-
- CF_CLASS (new_folder)->refresh_info (new_folder, ex);
-
- return new_folder;
+ return camel_nntp_folder_new (store, folder_name, ex);
}
static void
@@ -396,22 +371,63 @@ camel_nntp_store_get_type (void)
* no extended response, @ret will be set to NULL.) The caller must
* free this buffer when it is done with it.
*
- * Return value: one of CAMEL_NNTP_OK (command executed successfully),
- * CAMEL_NNTP_ERR (command encounted an error), or CAMEL_NNTP_FAIL
- * (a protocol-level error occurred, and Camel is uncertain of the
- * result of the command.)
+ * Return value: the response code of the nntp command.
**/
+static int
+camel_nntp_command_send_recv (CamelNNTPStore *store, CamelException *ex, char **ret, char *cmd)
+{
+ char *respbuf;
+ int resp_code;
+ gboolean again;
+
+ do {
+ again = FALSE;
+
+ /* Send the command */
+ if (camel_remote_store_send_string (CAMEL_REMOTE_STORE (store), ex, cmd) < 0) {
+ return NNTP_PROTOCOL_ERROR;
+ }
+
+ /* Read the response */
+ if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &respbuf, ex) < 0) {
+ if (ret)
+ *ret = g_strdup (g_strerror (errno));
+ return NNTP_PROTOCOL_ERROR;
+ }
+
+ resp_code = atoi (respbuf);
+
+ /* this is kind of a gross hack, but since an auth challenge
+ can pop up at any time, and we want to shield this from our
+ callers, we handle authentication here. */
+ if (resp_code == NNTP_AUTH_REQUIRED) {
+ resp_code = camel_nntp_auth_authenticate (store, ex);
+ if (resp_code != NNTP_AUTH_ACCEPTED) {
+ return resp_code;
+ }
+
+ /* need to resend our command here */
+ again = TRUE;
+ }
+ } while (again);
+
+ if (ret) {
+ *ret = strchr (respbuf, ' ');
+ if (*ret)
+ *ret = g_strdup (*ret + 1);
+ }
+ g_free (respbuf);
+
+ return resp_code;
+}
+
int
-camel_nntp_command (CamelNNTPStore *store, char **ret, char *fmt, ...)
+camel_nntp_command (CamelNNTPStore *store, CamelException *ex, char **ret, char *fmt, ...)
{
- char *cmdbuf, *respbuf;
+ char *cmdbuf;
va_list ap;
- int status;
int resp_code;
char *real_fmt;
- CamelException ex;
-
- camel_exception_init (&ex);
real_fmt = g_strdup_printf ("%s\r\n", fmt);
@@ -421,38 +437,11 @@ camel_nntp_command (CamelNNTPStore *store, char **ret, char *fmt, ...)
g_free (real_fmt);
- /* Send the command */
- if (camel_remote_store_send_string (CAMEL_REMOTE_STORE (store), &ex, cmdbuf) < 0) {
- g_free (cmdbuf);
- return CAMEL_NNTP_FAIL;
- }
+ resp_code = camel_nntp_command_send_recv (store, ex, ret, cmdbuf);
g_free (cmdbuf);
- /* Read the response */
- 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)
- status = CAMEL_NNTP_OK;
- else if (resp_code < 500)
- status = CAMEL_NNTP_ERR;
- else
- status = CAMEL_NNTP_FAIL;
-
- if (ret) {
- *ret = strchr (respbuf, ' ');
- if (*ret)
- *ret = g_strdup (*ret + 1);
- }
- g_free (respbuf);
-
- return status;
+ return resp_code;
}
void
@@ -469,8 +458,8 @@ camel_nntp_store_subscribe_group (CamelStore *store,
return;
}
- if (CAMEL_NNTP_OK == camel_nntp_command ( CAMEL_NNTP_STORE (store),
- &ret, "GROUP %s", group_name)) {
+ if (camel_nntp_command ( CAMEL_NNTP_STORE (store),
+ ex, &ret, "GROUP %s", group_name) == NNTP_GROUP_SELECTED) {
/* we create an empty summary file here, so that when
the group is opened we'll know we need to build it. */
gchar *summary_file;