Reverted previous changes for NNTP authentication support (needs to be
[claws.git] / src / news.c
index 279b8f960622a8408007f7b2aeb32959867d0fa6..db631d285f3ce3799af5c48dfb8203d911b2092a 100644 (file)
@@ -28,6 +28,7 @@
 #include <dirent.h>
 #include <unistd.h>
 
+#include "defs.h"
 #include "intl.h"
 #include "news.h"
 #include "nntp.h"
@@ -41,6 +42,9 @@
 #include "codeconv.h"
 #include "utils.h"
 #include "prefs_common.h"
+#include "prefs_account.h"
+#include "inputdialog.h"
+#include "alertpanel.h"
 
 static gint news_get_article_cmd        (NNTPSession   *session,
                                          const gchar   *cmd,
@@ -68,7 +72,7 @@ Session *news_session_new(const gchar *server, gushort port)
 {
        gchar buf[NNTPBUFSIZE];
        NNTPSession *session;
-       gint nntp_sock;
+       SockInfo *nntp_sock;
 
        g_return_val_if_fail(server != NULL, NULL);
 
@@ -91,7 +95,8 @@ Session *news_session_new(const gchar *server, gushort port)
 
 void news_session_destroy(NNTPSession *session)
 {
-       close(SESSION(session)->sock);
+       sock_close(SESSION(session)->sock);
+       SESSION(session)->sock = NULL;
 
        g_free(session->group);
 }
@@ -266,6 +271,58 @@ static gint news_get_header(NNTPSession *session, gint num, gchar *filename)
        return news_get_article_cmd(session, "HEAD", num, filename);
 }
 
+static gchar *news_query_password(NNTPSession *session,
+                                 const gchar *user)
+{
+       gchar *message;
+       gchar *pass;
+
+       message = g_strdup_printf
+               (_("Input password for %s on %s:"),
+                user,
+                SESSION(session)->server);
+
+       pass = input_dialog_with_invisible(_("Input password"),
+                                          message, NULL);
+       g_free(message);
+/*     manage_window_focus_in(inc_dialog->mainwin->window, */
+/*                            NULL, NULL); */
+       return pass;
+}
+
+static gint news_authenticate(NNTPSession *session,
+                             FolderItem *item)
+{
+       gint ok;
+       const gchar *user;
+       gchar *pass;
+       gboolean need_free_pass = FALSE;
+
+       debug_print(_("news server requested authentication\n"));
+       if (!item || !item->folder || !item->folder->account)
+               return NN_ERROR;
+       user = item->folder->account->userid;
+       if (!user)
+               return NN_ERROR;
+       ok = nntp_authinfo_user(SESSION(session)->sock, user);
+       if (ok == NN_AUTHCONT) {
+               pass = item->folder->account->passwd;
+               if (!pass || !pass[0]) {
+                       pass = news_query_password(session, user);
+                       need_free_pass = TRUE;
+               }
+               ok = nntp_authinfo_pass(SESSION(session)->sock, pass);
+               if (need_free_pass)
+                       g_free(pass);
+       }
+       if (ok != NN_SUCCESS) {
+               log_warning(_("NNTP authentication failed\n"));
+               alertpanel_error(_("Authentication for %s on %s failed."),
+                                user, SESSION(session)->server);
+       }
+       return ok;
+}
+
 static GSList *news_get_uncached_articles(NNTPSession *session,
                                          FolderItem *item, gint cache_last,
                                          gint *rfirst, gint *rlast)
@@ -287,6 +344,13 @@ static GSList *news_get_uncached_articles(NNTPSession *session,
 
        ok = nntp_group(SESSION(session)->sock, item->path,
                        &num, &first, &last);
+       if (ok == NN_AUTHREQ) {
+               ok = news_authenticate(session, item);
+               if (ok != NN_SUCCESS)
+                       return NULL;
+               ok = nntp_group(SESSION(session)->sock, item->path,
+                               &num, &first, &last);
+       }
        if (ok != NN_SUCCESS) {
                log_warning(_("can't set group: %s\n"), item->path);
                return NULL;
@@ -482,3 +546,89 @@ static void news_delete_all_article(FolderItem *item)
 
        debug_print(_("done.\n"));
 }
+
+/*
+  news_get_group_list returns a strings list.
+  These strings are the names of the newsgroups of a server.
+  item is the FolderItem of the news server.
+  The names of the newsgroups are cached into a file so that
+  when the function is called again, there is no need to make
+  a request to the server.
+ */
+
+GSList * news_get_group_list(FolderItem *item)
+{
+       gchar *path, *filename;
+       gint ok;
+       NNTPSession *session;
+       GSList * group_list = NULL;
+       FILE * f;
+       gchar buf[NNTPBUFSIZE];
+       int len;
+
+       if (item == NULL)
+         return NULL;
+
+       path = folder_item_get_path(item);
+
+       if (!is_dir_exist(path))
+               make_dir_hier(path);
+
+       filename = g_strconcat(path, G_DIR_SEPARATOR_S, GROUPLIST_FILE, NULL);
+       g_free(path);
+
+       session = news_session_get(item->folder);
+
+       if (session == NULL)
+         return NULL;
+
+       if (is_file_exist(filename)) {
+               debug_print(_("group list has been already cached.\n"));
+       }
+       else {
+           ok = nntp_list(SESSION(session)->sock);
+           if (ok != NN_SUCCESS)
+             return NULL;
+           
+           if (recv_write_to_file(SESSION(session)->sock, filename) < 0) {
+             log_warning(_("can't retrieve group list\n"));
+             return NULL;
+           }
+       }
+
+       f = fopen(filename, "r");
+       while (fgets(buf, NNTPBUFSIZE, f)) {
+           char * s;
+
+           len = 0;
+           while ((buf[len] != 0) && (buf[len] != ' '))
+             len++;
+           buf[len] = 0;
+           s = g_strdup(buf);
+
+           group_list = g_slist_append(group_list, s);
+       }
+       fclose(f);
+       g_free(filename);
+
+       group_list = g_slist_sort(group_list, (GCompareFunc) g_strcasecmp);
+
+       return group_list;
+}
+
+/*
+  remove the cache file of the names of the newsgroups.
+ */
+
+void news_reset_group_list(FolderItem *item)
+{
+       gchar *path, *filename;
+
+       debug_print(_("\tDeleting cached group list... "));
+       path = folder_item_get_path(item);
+       filename = g_strconcat(path, G_DIR_SEPARATOR_S, GROUPLIST_FILE, NULL);
+       g_free(path);
+       if (remove(filename) != 0)
+         log_warning(_("can't delete cached group list %s\n"), filename);
+       g_free(filename);
+}