fix missing MODE_READER bug
[claws.git] / src / nntp.c
index 0fa9332a1fa6324c99968aabc652424049c059df..e771ecb7e81292e1258524987938db5677107de3 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999,2000 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2001 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include "intl.h"
 #include "nntp.h"
 #include "socket.h"
+#include "ssl.h"
 #include "utils.h"
 
 static gint verbose = 1;
 
-static void nntp_gen_send(NNTPSockInfo *sock, const gchar *format, ...);
-static gint nntp_gen_recv(NNTPSockInfo *sock, gchar *buf, gint size);
-static gint nntp_gen_command(NNTPSockInfo *sock, gchar *argbuf,
-                            const gchar *format, ...);
-
+static void nntp_gen_send      (NNTPSockInfo   *sock,
+                                const gchar    *format,
+                                ...);
+static gint nntp_gen_recv      (NNTPSockInfo   *sock,
+                                gchar          *buf,
+                                gint            size);
+static gint nntp_gen_command   (NNTPSockInfo   *sock,
+                                gchar          *argbuf,
+                                const gchar    *format,
+                                ...);
+
+#if USE_SSL
+NNTPSockInfo *nntp_open(const gchar *server, gushort port, gchar *buf, gboolean use_ssl)
+#else
 NNTPSockInfo *nntp_open(const gchar *server, gushort port, gchar *buf)
+#endif
 {
        SockInfo *sock;
        NNTPSockInfo *nntp_sock;
 
-       nntp_sock = g_new0(NNTPSockInfo, 1);
        if ((sock = sock_connect(server, port)) == NULL) {
                log_warning(_("Can't connect to NNTP server: %s:%d\n"),
                            server, port);
-               g_free(nntp_sock);
                return NULL;
        }
+
+#if USE_SSL
+       if (use_ssl && !ssl_init_socket(sock)) {
+                sock_close(sock);
+                return NULL;
+       }
+#endif
+       
+       nntp_sock = g_new0(NNTPSockInfo, 1);
        nntp_sock->sock = sock;
 
        if (nntp_ok(nntp_sock, buf) == NN_SUCCESS)
@@ -60,28 +78,37 @@ NNTPSockInfo *nntp_open(const gchar *server, gushort port, gchar *buf)
        }
 }
 
+#if USE_SSL
+NNTPSockInfo *nntp_open_auth(const gchar *server, gushort port, gchar *buf,
+                            const gchar *userid, const gchar *passwd, gboolean use_ssl)
+#else
 NNTPSockInfo *nntp_open_auth(const gchar *server, gushort port, gchar *buf,
                             const gchar *userid, const gchar *passwd)
+#endif
 {
        NNTPSockInfo *sock;
 
+#if USE_SSL
+       sock = nntp_open(server, port, buf, use_ssl);
+#else
        sock = nntp_open(server, port, buf);
-       if (!sock)
-               return NULL;
+#endif
+
+       if (!sock) return NULL;
+
        sock->userid = g_strdup(userid);
        sock->passwd = g_strdup(passwd);
+
        return sock;
 }
 
-
 void nntp_close(NNTPSockInfo *sock)
 {
-       if (!sock)
-               return;
+       if (!sock) return;
 
        sock_close(sock->sock);
-       g_free(sock->passwd);
        g_free(sock->userid);
+       g_free(sock->passwd);
        g_free(sock);
 }
 
@@ -94,6 +121,11 @@ gint nntp_group(NNTPSockInfo *sock, const gchar *group,
 
        ok = nntp_gen_command(sock, buf, "GROUP %s", group);
 
+       if (ok != NN_SUCCESS) {
+               ok = nntp_gen_command(sock, buf, "MODE READER");
+               if (ok == NN_SUCCESS)
+                       ok = nntp_gen_command(sock, buf, "GROUP %s", group);
+       }       
        if (ok != NN_SUCCESS)
                return ok;
 
@@ -106,7 +138,8 @@ gint nntp_group(NNTPSockInfo *sock, const gchar *group,
        return NN_SUCCESS;
 }
 
-gint nntp_get_article(NNTPSockInfo *sock, const gchar *cmd, gint num, gchar **msgid)
+gint nntp_get_article(NNTPSockInfo *sock, const gchar *cmd, gint num,
+                     gchar **msgid)
 {
        gint ok;
        gchar buf[NNTPBUFSIZE];
@@ -187,6 +220,23 @@ gint nntp_xover(NNTPSockInfo *sock, gint first, gint last)
        return NN_SUCCESS;
 }
 
+gint nntp_xhdr(NNTPSockInfo *sock, const gchar *header, gint first, gint last)
+{
+       gint ok;
+       gchar buf[NNTPBUFSIZE];
+
+       ok = nntp_gen_command(sock, buf, "XHDR %s %d-%d", header, first, last);
+       if (ok != NN_SUCCESS)
+               return ok;
+
+       return NN_SUCCESS;
+}
+
+gint nntp_list(NNTPSockInfo *sock)
+{
+       return nntp_gen_command(sock, NULL, "LIST");
+}
+
 gint nntp_post(NNTPSockInfo *sock, FILE *fp)
 {
        gint ok;
@@ -233,7 +283,7 @@ gint nntp_mode(NNTPSockInfo *sock, gboolean stream)
        gint ok;
 
        if (sock->auth_failed)
-               return NN_AUTHREQ; /* force reconnection */
+               return NN_AUTHREQ;
 
        ok = nntp_gen_command(sock, NULL, "MODE %s",
                              stream ? "STREAM" : "READER");
@@ -247,18 +297,19 @@ gint nntp_ok(NNTPSockInfo *sock, gchar *argbuf)
        gchar buf[NNTPBUFSIZE];
 
        if ((ok = nntp_gen_recv(sock, buf, sizeof(buf))) == NN_SUCCESS) {
-               if (strlen(buf) < 4)
+               if (strlen(buf) < 3)
                        return NN_ERROR;
 
                if ((buf[0] == '1' || buf[0] == '2' || buf[0] == '3') &&
-                   buf[3] == ' ') {
+                   (buf[3] == ' ' || buf[3] == '\0')) {
                        if (argbuf)
                                strcpy(argbuf, buf);
 
-                       if (!strncmp(buf, "381 ", 4))
+                       if (!strncmp(buf, "381", 3))
                                return NN_AUTHCONT;
+
                        return NN_SUCCESS;
-               } else if (!strncmp(buf, "480 ", 4))
+               } else if (!strncmp(buf, "480", 3))
                        return NN_AUTHREQ;
                else
                        return NN_ERROR;
@@ -278,7 +329,7 @@ static void nntp_gen_send(NNTPSockInfo *sock, const gchar *format, ...)
 
        if (verbose) {
                if (!g_strncasecmp(buf, "AUTHINFO PASS", 13))
-                       log_print("NNTP> AUTHINFO PASS ***\n");
+                       log_print("NNTP> AUTHINFO PASS ********\n");
                else
                        log_print("NNTP> %s\n", buf);
        }
@@ -308,7 +359,7 @@ static gint nntp_gen_command(NNTPSockInfo *sock, gchar *argbuf,
        gint ok;
 
        va_start(args, format);
-       g_vsnprintf(buf, sizeof(buf) - 2, format, args);
+       g_vsnprintf(buf, sizeof(buf), format, args);
        va_end(args);
 
        nntp_gen_send(sock, "%s", buf);
@@ -318,6 +369,7 @@ static gint nntp_gen_command(NNTPSockInfo *sock, gchar *argbuf,
                        sock->auth_failed = TRUE;
                        return ok;
                }
+
                nntp_gen_send(sock, "AUTHINFO USER %s", sock->userid);
                ok = nntp_ok(sock, NULL);
                if (ok == NN_AUTHCONT) {
@@ -328,18 +380,10 @@ static gint nntp_gen_command(NNTPSockInfo *sock, gchar *argbuf,
                        sock->auth_failed = TRUE;
                        return ok;
                }
+
                nntp_gen_send(sock, "%s", buf);
                ok = nntp_ok(sock, argbuf);
        }
-       return ok;
-}
 
-/*
-  nntp_list sends the command "LIST" to the news server,
-  a function is needed to read the newsgroups list.
- */
-
-gint nntp_list(NNTPSockInfo *sock)
-{
-       return nntp_gen_command(sock, NULL, "LIST");
+       return ok;
 }