Statistics
| Revision:

root / src / news.c @ 528

History | View | Annotate | Download (23.9 kB)

1 1 hiro
/*
2 1 hiro
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 293 hiro
 * Copyright (C) 1999-2005 Hiroyuki Yamamoto
4 1 hiro
 *
5 1 hiro
 * This program is free software; you can redistribute it and/or modify
6 1 hiro
 * it under the terms of the GNU General Public License as published by
7 1 hiro
 * the Free Software Foundation; either version 2 of the License, or
8 1 hiro
 * (at your option) any later version.
9 1 hiro
 *
10 1 hiro
 * This program is distributed in the hope that it will be useful,
11 1 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 1 hiro
 * GNU General Public License for more details.
14 1 hiro
 *
15 1 hiro
 * You should have received a copy of the GNU General Public License
16 1 hiro
 * along with this program; if not, write to the Free Software
17 1 hiro
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 1 hiro
 */
19 1 hiro
20 1 hiro
#ifdef HAVE_CONFIG_H
21 1 hiro
#  include "config.h"
22 1 hiro
#endif
23 1 hiro
24 1 hiro
#include "defs.h"
25 1 hiro
26 1 hiro
#include <glib.h>
27 92 hiro
#include <glib/gi18n.h>
28 1 hiro
#include <stdio.h>
29 1 hiro
#include <string.h>
30 1 hiro
#include <stdlib.h>
31 1 hiro
#include <dirent.h>
32 1 hiro
#include <unistd.h>
33 1 hiro
#include <time.h>
34 1 hiro
35 1 hiro
#include "news.h"
36 1 hiro
#include "nntp.h"
37 1 hiro
#include "socket.h"
38 1 hiro
#include "recv.h"
39 1 hiro
#include "procmsg.h"
40 1 hiro
#include "procheader.h"
41 1 hiro
#include "folder.h"
42 1 hiro
#include "session.h"
43 1 hiro
#include "codeconv.h"
44 1 hiro
#include "utils.h"
45 1 hiro
#include "prefs_common.h"
46 1 hiro
#include "prefs_account.h"
47 1 hiro
#include "inputdialog.h"
48 1 hiro
#include "alertpanel.h"
49 1 hiro
#if USE_SSL
50 1 hiro
#  include "ssl.h"
51 1 hiro
#endif
52 1 hiro
53 1 hiro
#define NNTP_PORT        119
54 1 hiro
#if USE_SSL
55 1 hiro
#define NNTPS_PORT        563
56 1 hiro
#endif
57 1 hiro
58 1 hiro
static void news_folder_init                 (Folder        *folder,
59 1 hiro
                                          const gchar        *name,
60 1 hiro
                                          const gchar        *path);
61 1 hiro
62 1 hiro
static Folder        *news_folder_new        (const gchar        *name,
63 1 hiro
                                         const gchar        *folder);
64 1 hiro
static void         news_folder_destroy        (Folder                *folder);
65 1 hiro
66 1 hiro
static GSList *news_get_article_list        (Folder                *folder,
67 1 hiro
                                         FolderItem        *item,
68 1 hiro
                                         gboolean         use_cache);
69 1 hiro
static gchar *news_fetch_msg                (Folder                *folder,
70 1 hiro
                                         FolderItem        *item,
71 1 hiro
                                         gint                 num);
72 1 hiro
static MsgInfo *news_get_msginfo        (Folder                *folder,
73 1 hiro
                                         FolderItem        *item,
74 1 hiro
                                         gint                 num);
75 1 hiro
76 1 hiro
static gint news_close                        (Folder                *folder,
77 1 hiro
                                         FolderItem        *item);
78 1 hiro
79 1 hiro
static gint news_scan_group                (Folder                *folder,
80 1 hiro
                                         FolderItem        *item);
81 1 hiro
82 1 hiro
#if USE_SSL
83 1 hiro
static Session *news_session_new         (const gchar        *server,
84 1 hiro
                                          gushort         port,
85 1 hiro
                                          const gchar        *userid,
86 1 hiro
                                          const gchar        *passwd,
87 1 hiro
                                          SSLType         ssl_type);
88 1 hiro
#else
89 1 hiro
static Session *news_session_new         (const gchar        *server,
90 1 hiro
                                          gushort         port,
91 1 hiro
                                          const gchar        *userid,
92 1 hiro
                                          const gchar        *passwd);
93 1 hiro
#endif
94 1 hiro
95 1 hiro
static gint news_get_article_cmd         (NNTPSession        *session,
96 1 hiro
                                          const gchar        *cmd,
97 1 hiro
                                          gint                 num,
98 1 hiro
                                          gchar                *filename);
99 1 hiro
static gint news_get_article                 (NNTPSession        *session,
100 1 hiro
                                          gint                 num,
101 1 hiro
                                          gchar                *filename);
102 1 hiro
#if 0
103 1 hiro
static gint news_get_header                 (NNTPSession        *session,
104 1 hiro
                                          gint                 num,
105 1 hiro
                                          gchar                *filename);
106 1 hiro
#endif
107 1 hiro
108 1 hiro
static gint news_select_group                 (NNTPSession        *session,
109 1 hiro
                                          const gchar        *group,
110 1 hiro
                                          gint                *num,
111 1 hiro
                                          gint                *first,
112 1 hiro
                                          gint                *last);
113 1 hiro
static GSList *news_get_uncached_articles(NNTPSession        *session,
114 1 hiro
                                          FolderItem        *item,
115 1 hiro
                                          gint                 cache_last,
116 1 hiro
                                          gint                *rfirst,
117 1 hiro
                                          gint                *rlast);
118 1 hiro
static MsgInfo *news_parse_xover         (const gchar        *xover_str);
119 1 hiro
static gchar *news_parse_xhdr                 (const gchar        *xhdr_str,
120 1 hiro
                                          MsgInfo        *msginfo);
121 1 hiro
static GSList *news_delete_old_articles         (GSList        *alist,
122 1 hiro
                                          FolderItem        *item,
123 1 hiro
                                          gint                 first);
124 1 hiro
static void news_delete_all_articles         (FolderItem        *item);
125 1 hiro
static void news_delete_expired_caches         (GSList        *alist,
126 1 hiro
                                          FolderItem        *item);
127 1 hiro
128 1 hiro
static FolderClass news_class =
129 1 hiro
{
130 1 hiro
        F_NEWS,
131 1 hiro
132 1 hiro
        news_folder_new,
133 1 hiro
        news_folder_destroy,
134 1 hiro
135 1 hiro
        NULL,
136 1 hiro
        NULL,
137 1 hiro
138 1 hiro
        news_get_article_list,
139 1 hiro
        news_fetch_msg,
140 1 hiro
        news_get_msginfo,
141 1 hiro
        NULL,
142 1 hiro
        NULL,
143 1 hiro
        NULL,
144 1 hiro
        NULL,
145 1 hiro
        NULL,
146 1 hiro
        NULL,
147 1 hiro
        NULL,
148 1 hiro
        NULL,
149 1 hiro
        NULL,
150 1 hiro
        NULL,
151 1 hiro
        news_close,
152 1 hiro
        news_scan_group,
153 1 hiro
154 1 hiro
        NULL,
155 1 hiro
        NULL,
156 389 hiro
        NULL,
157 1 hiro
        NULL
158 1 hiro
};
159 1 hiro
160 1 hiro
161 1 hiro
FolderClass *news_get_class(void)
162 1 hiro
{
163 1 hiro
        return &news_class;
164 1 hiro
}
165 1 hiro
166 1 hiro
static Folder *news_folder_new(const gchar *name, const gchar *path)
167 1 hiro
{
168 1 hiro
        Folder *folder;
169 1 hiro
170 1 hiro
        folder = (Folder *)g_new0(NewsFolder, 1);
171 1 hiro
        news_folder_init(folder, name, path);
172 1 hiro
173 1 hiro
        return folder;
174 1 hiro
}
175 1 hiro
176 1 hiro
static void news_folder_destroy(Folder *folder)
177 1 hiro
{
178 1 hiro
        gchar *dir;
179 1 hiro
180 1 hiro
        dir = folder_get_path(folder);
181 1 hiro
        if (is_dir_exist(dir))
182 1 hiro
                remove_dir_recursive(dir);
183 1 hiro
        g_free(dir);
184 1 hiro
185 1 hiro
        folder_remote_folder_destroy(REMOTE_FOLDER(folder));
186 1 hiro
}
187 1 hiro
188 1 hiro
static void news_folder_init(Folder *folder, const gchar *name,
189 1 hiro
                             const gchar *path)
190 1 hiro
{
191 1 hiro
        folder->klass = news_get_class();
192 1 hiro
        folder_remote_folder_init(folder, name, path);
193 1 hiro
}
194 1 hiro
195 1 hiro
#if USE_SSL
196 1 hiro
static Session *news_session_new(const gchar *server, gushort port,
197 1 hiro
                                 const gchar *userid, const gchar *passwd,
198 1 hiro
                                 SSLType ssl_type)
199 1 hiro
#else
200 1 hiro
static Session *news_session_new(const gchar *server, gushort port,
201 1 hiro
                                 const gchar *userid, const gchar *passwd)
202 1 hiro
#endif
203 1 hiro
{
204 1 hiro
        gchar buf[NNTPBUFSIZE];
205 1 hiro
        Session *session;
206 1 hiro
207 1 hiro
        g_return_val_if_fail(server != NULL, NULL);
208 1 hiro
209 1 hiro
        log_message(_("creating NNTP connection to %s:%d ...\n"), server, port);
210 1 hiro
211 1 hiro
#if USE_SSL
212 1 hiro
        session = nntp_session_new(server, port, buf, userid, passwd, ssl_type);
213 1 hiro
#else
214 1 hiro
        session = nntp_session_new(server, port, buf, userid, passwd);
215 1 hiro
#endif
216 1 hiro
217 1 hiro
        return session;
218 1 hiro
}
219 1 hiro
220 1 hiro
static Session *news_session_new_for_folder(Folder *folder)
221 1 hiro
{
222 1 hiro
        Session *session;
223 1 hiro
        PrefsAccount *ac;
224 1 hiro
        const gchar *userid = NULL;
225 1 hiro
        gchar *passwd = NULL;
226 1 hiro
        gushort port;
227 1 hiro
228 1 hiro
        g_return_val_if_fail(folder != NULL, NULL);
229 1 hiro
        g_return_val_if_fail(folder->account != NULL, NULL);
230 1 hiro
231 1 hiro
        ac = folder->account;
232 1 hiro
        if (ac->use_nntp_auth && ac->userid && ac->userid[0]) {
233 1 hiro
                userid = ac->userid;
234 1 hiro
                if (ac->passwd && ac->passwd[0])
235 1 hiro
                        passwd = g_strdup(ac->passwd);
236 1 hiro
                else
237 1 hiro
                        passwd = input_dialog_query_password(ac->nntp_server,
238 1 hiro
                                                             userid);
239 1 hiro
        }
240 1 hiro
241 1 hiro
#if USE_SSL
242 1 hiro
        port = ac->set_nntpport ? ac->nntpport
243 1 hiro
                : ac->ssl_nntp ? NNTPS_PORT : NNTP_PORT;
244 1 hiro
        session = news_session_new(ac->nntp_server, port, userid, passwd,
245 1 hiro
                                   ac->ssl_nntp);
246 1 hiro
#else
247 1 hiro
        port = ac->set_nntpport ? ac->nntpport : NNTP_PORT;
248 1 hiro
        session = news_session_new(ac->nntp_server, port, userid, passwd);
249 1 hiro
#endif
250 1 hiro
251 1 hiro
        g_free(passwd);
252 1 hiro
253 1 hiro
        return session;
254 1 hiro
}
255 1 hiro
256 1 hiro
static NNTPSession *news_session_get(Folder *folder)
257 1 hiro
{
258 1 hiro
        RemoteFolder *rfolder = REMOTE_FOLDER(folder);
259 1 hiro
260 1 hiro
        g_return_val_if_fail(folder != NULL, NULL);
261 1 hiro
        g_return_val_if_fail(FOLDER_TYPE(folder) == F_NEWS, NULL);
262 1 hiro
        g_return_val_if_fail(folder->account != NULL, NULL);
263 1 hiro
264 1 hiro
        if (!prefs_common.online_mode)
265 1 hiro
                return NULL;
266 1 hiro
267 1 hiro
        if (!rfolder->session) {
268 1 hiro
                rfolder->session = news_session_new_for_folder(folder);
269 1 hiro
                return NNTP_SESSION(rfolder->session);
270 1 hiro
        }
271 1 hiro
272 1 hiro
        if (time(NULL) - rfolder->session->last_access_time <
273 1 hiro
                SESSION_TIMEOUT_INTERVAL) {
274 1 hiro
                return NNTP_SESSION(rfolder->session);
275 1 hiro
        }
276 1 hiro
277 1 hiro
        if (nntp_mode(NNTP_SESSION(rfolder->session), FALSE)
278 1 hiro
            != NN_SUCCESS) {
279 1 hiro
                log_warning(_("NNTP connection to %s:%d has been"
280 1 hiro
                              " disconnected. Reconnecting...\n"),
281 1 hiro
                            folder->account->nntp_server,
282 1 hiro
                            folder->account->set_nntpport ?
283 1 hiro
                            folder->account->nntpport : NNTP_PORT);
284 1 hiro
                session_destroy(rfolder->session);
285 1 hiro
                rfolder->session = news_session_new_for_folder(folder);
286 1 hiro
        }
287 1 hiro
288 1 hiro
        if (rfolder->session)
289 1 hiro
                session_set_access_time(rfolder->session);
290 1 hiro
291 1 hiro
        return NNTP_SESSION(rfolder->session);
292 1 hiro
}
293 1 hiro
294 1 hiro
static GSList *news_get_article_list(Folder *folder, FolderItem *item,
295 1 hiro
                                     gboolean use_cache)
296 1 hiro
{
297 1 hiro
        GSList *alist;
298 1 hiro
        NNTPSession *session;
299 1 hiro
300 1 hiro
        g_return_val_if_fail(folder != NULL, NULL);
301 1 hiro
        g_return_val_if_fail(item != NULL, NULL);
302 1 hiro
        g_return_val_if_fail(FOLDER_TYPE(folder) == F_NEWS, NULL);
303 1 hiro
304 1 hiro
        session = news_session_get(folder);
305 1 hiro
306 1 hiro
        if (!session) {
307 1 hiro
                alist = procmsg_read_cache(item, FALSE);
308 1 hiro
                item->last_num = procmsg_get_last_num_in_msg_list(alist);
309 1 hiro
        } else if (use_cache) {
310 1 hiro
                GSList *newlist;
311 1 hiro
                gint cache_last;
312 1 hiro
                gint first, last;
313 1 hiro
314 1 hiro
                alist = procmsg_read_cache(item, FALSE);
315 1 hiro
316 1 hiro
                cache_last = procmsg_get_last_num_in_msg_list(alist);
317 1 hiro
                newlist = news_get_uncached_articles
318 1 hiro
                        (session, item, cache_last, &first, &last);
319 285 hiro
                if (newlist)
320 285 hiro
                        item->cache_dirty = TRUE;
321 1 hiro
                if (first == 0 && last == 0) {
322 1 hiro
                        news_delete_all_articles(item);
323 1 hiro
                        procmsg_msg_list_free(alist);
324 1 hiro
                        alist = NULL;
325 285 hiro
                        item->cache_dirty = TRUE;
326 1 hiro
                } else {
327 1 hiro
                        alist = news_delete_old_articles(alist, item, first);
328 1 hiro
                        news_delete_expired_caches(alist, item);
329 1 hiro
                }
330 1 hiro
331 1 hiro
                alist = g_slist_concat(alist, newlist);
332 1 hiro
333 1 hiro
                item->last_num = last;
334 1 hiro
        } else {
335 1 hiro
                gint last;
336 1 hiro
337 1 hiro
                alist = news_get_uncached_articles
338 1 hiro
                        (session, item, 0, NULL, &last);
339 1 hiro
                news_delete_all_articles(item);
340 1 hiro
                item->last_num = last;
341 285 hiro
                item->cache_dirty = TRUE;
342 1 hiro
        }
343 1 hiro
344 1 hiro
        procmsg_set_flags(alist, item);
345 1 hiro
346 1 hiro
        alist = procmsg_sort_msg_list(alist, item->sort_key, item->sort_type);
347 1 hiro
348 293 hiro
        debug_print("cache_dirty: %d, mark_dirty: %d\n",
349 293 hiro
                    item->cache_dirty, item->mark_dirty);
350 285 hiro
351 1 hiro
        return alist;
352 1 hiro
}
353 1 hiro
354 1 hiro
static gchar *news_fetch_msg(Folder *folder, FolderItem *item, gint num)
355 1 hiro
{
356 1 hiro
        gchar *path, *filename;
357 1 hiro
        NNTPSession *session;
358 1 hiro
        gint ok;
359 1 hiro
360 1 hiro
        g_return_val_if_fail(folder != NULL, NULL);
361 1 hiro
        g_return_val_if_fail(item != NULL, NULL);
362 1 hiro
363 1 hiro
        path = folder_item_get_path(item);
364 1 hiro
        if (!is_dir_exist(path))
365 1 hiro
                make_dir_hier(path);
366 1 hiro
        filename = g_strconcat(path, G_DIR_SEPARATOR_S, itos(num), NULL);
367 1 hiro
        g_free(path);
368 1 hiro
369 1 hiro
        if (is_file_exist(filename)) {
370 1 hiro
                debug_print(_("article %d has been already cached.\n"), num);
371 1 hiro
                return filename;
372 1 hiro
        }
373 1 hiro
374 1 hiro
        session = news_session_get(folder);
375 1 hiro
        if (!session) {
376 1 hiro
                g_free(filename);
377 1 hiro
                return NULL;
378 1 hiro
        }
379 1 hiro
380 1 hiro
        ok = news_select_group(session, item->path, NULL, NULL, NULL);
381 1 hiro
        if (ok != NN_SUCCESS) {
382 1 hiro
                if (ok == NN_SOCKET) {
383 1 hiro
                        session_destroy(SESSION(session));
384 1 hiro
                        REMOTE_FOLDER(folder)->session = NULL;
385 1 hiro
                }
386 1 hiro
                g_free(filename);
387 1 hiro
                return NULL;
388 1 hiro
        }
389 1 hiro
390 1 hiro
        debug_print(_("getting article %d...\n"), num);
391 1 hiro
        ok = news_get_article(NNTP_SESSION(REMOTE_FOLDER(folder)->session),
392 1 hiro
                              num, filename);
393 1 hiro
        if (ok != NN_SUCCESS) {
394 1 hiro
                g_warning(_("can't read article %d\n"), num);
395 1 hiro
                if (ok == NN_SOCKET) {
396 1 hiro
                        session_destroy(SESSION(session));
397 1 hiro
                        REMOTE_FOLDER(folder)->session = NULL;
398 1 hiro
                }
399 1 hiro
                g_free(filename);
400 1 hiro
                return NULL;
401 1 hiro
        }
402 1 hiro
403 1 hiro
        return filename;
404 1 hiro
}
405 1 hiro
406 1 hiro
static MsgInfo *news_get_msginfo(Folder *folder, FolderItem *item, gint num)
407 1 hiro
{
408 1 hiro
        MsgInfo *msginfo;
409 1 hiro
        MsgFlags flags = {0, 0};
410 1 hiro
        gchar *file;
411 1 hiro
412 1 hiro
        g_return_val_if_fail(folder != NULL, NULL);
413 1 hiro
        g_return_val_if_fail(item != NULL, NULL);
414 1 hiro
415 1 hiro
        file = news_fetch_msg(folder, item, num);
416 1 hiro
        if (!file) return NULL;
417 1 hiro
418 1 hiro
        msginfo = procheader_parse_file(file, flags, FALSE);
419 1 hiro
420 1 hiro
        g_free(file);
421 1 hiro
422 1 hiro
        return msginfo;
423 1 hiro
}
424 1 hiro
425 1 hiro
static gint news_close(Folder *folder, FolderItem *item)
426 1 hiro
{
427 1 hiro
        return 0;
428 1 hiro
}
429 1 hiro
430 1 hiro
static gint news_scan_group(Folder *folder, FolderItem *item)
431 1 hiro
{
432 1 hiro
        NNTPSession *session;
433 1 hiro
        gint num = 0, first = 0, last = 0;
434 1 hiro
        gint new = 0, unread = 0, total = 0;
435 1 hiro
        gint min = 0, max = 0;
436 1 hiro
        gint ok;
437 1 hiro
438 1 hiro
        g_return_val_if_fail(folder != NULL, -1);
439 1 hiro
        g_return_val_if_fail(item != NULL, -1);
440 1 hiro
441 1 hiro
        session = news_session_get(folder);
442 1 hiro
        if (!session) return -1;
443 1 hiro
444 1 hiro
        ok = news_select_group(session, item->path, &num, &first, &last);
445 1 hiro
        if (ok != NN_SUCCESS) {
446 1 hiro
                if (ok == NN_SOCKET) {
447 1 hiro
                        session_destroy(SESSION(session));
448 1 hiro
                        REMOTE_FOLDER(folder)->session = NULL;
449 1 hiro
                }
450 1 hiro
                return -1;
451 1 hiro
        }
452 1 hiro
453 1 hiro
        if (num == 0) {
454 1 hiro
                item->new = item->unread = item->total = item->last_num = 0;
455 1 hiro
                return 0;
456 1 hiro
        }
457 1 hiro
458 1 hiro
        procmsg_get_mark_sum(item, &new, &unread, &total, &min, &max, first);
459 1 hiro
460 1 hiro
        if (max < first || last < min)
461 1 hiro
                new = unread = total = num;
462 1 hiro
        else {
463 1 hiro
                if (min < first)
464 1 hiro
                        min = first;
465 1 hiro
466 1 hiro
                if (last < max)
467 1 hiro
                        max = last;
468 1 hiro
                else if (max < last) {
469 1 hiro
                        new += last - max;
470 1 hiro
                        unread += last - max;
471 1 hiro
                }
472 1 hiro
473 1 hiro
                if (new > num) new = num;
474 1 hiro
                if (unread > num) unread = num;
475 1 hiro
        }
476 1 hiro
477 1 hiro
        item->new = new;
478 1 hiro
        item->unread = unread;
479 1 hiro
        item->total = num;
480 1 hiro
        item->last_num = last;
481 1 hiro
482 1 hiro
        return 0;
483 1 hiro
}
484 1 hiro
485 1 hiro
static NewsGroupInfo *news_group_info_new(const gchar *name,
486 1 hiro
                                          gint first, gint last, gchar type)
487 1 hiro
{
488 1 hiro
        NewsGroupInfo *ginfo;
489 1 hiro
490 1 hiro
        ginfo = g_new(NewsGroupInfo, 1);
491 1 hiro
        ginfo->name = g_strdup(name);
492 1 hiro
        ginfo->first = first;
493 1 hiro
        ginfo->last = last;
494 1 hiro
        ginfo->type = type;
495 1 hiro
496 1 hiro
        return ginfo;
497 1 hiro
}
498 1 hiro
499 1 hiro
static void news_group_info_free(NewsGroupInfo *ginfo)
500 1 hiro
{
501 1 hiro
        g_free(ginfo->name);
502 1 hiro
        g_free(ginfo);
503 1 hiro
}
504 1 hiro
505 1 hiro
static gint news_group_info_compare(NewsGroupInfo *ginfo1,
506 1 hiro
                                    NewsGroupInfo *ginfo2)
507 1 hiro
{
508 333 hiro
        return g_ascii_strcasecmp(ginfo1->name, ginfo2->name);
509 1 hiro
}
510 1 hiro
511 1 hiro
GSList *news_get_group_list(Folder *folder)
512 1 hiro
{
513 1 hiro
        gchar *path, *filename;
514 1 hiro
        FILE *fp;
515 1 hiro
        GSList *list = NULL;
516 1 hiro
        GSList *last = NULL;
517 1 hiro
        gchar buf[NNTPBUFSIZE];
518 1 hiro
519 1 hiro
        g_return_val_if_fail(folder != NULL, NULL);
520 1 hiro
        g_return_val_if_fail(FOLDER_TYPE(folder) == F_NEWS, NULL);
521 1 hiro
522 1 hiro
        path = folder_item_get_path(FOLDER_ITEM(folder->node->data));
523 1 hiro
        if (!is_dir_exist(path))
524 1 hiro
                make_dir_hier(path);
525 1 hiro
        filename = g_strconcat(path, G_DIR_SEPARATOR_S, NEWSGROUP_LIST, NULL);
526 1 hiro
        g_free(path);
527 1 hiro
528 478 hiro
        if ((fp = g_fopen(filename, "rb")) == NULL) {
529 1 hiro
                NNTPSession *session;
530 1 hiro
                gint ok;
531 1 hiro
532 1 hiro
                session = news_session_get(folder);
533 1 hiro
                if (!session) {
534 1 hiro
                        g_free(filename);
535 1 hiro
                        return NULL;
536 1 hiro
                }
537 1 hiro
538 1 hiro
                ok = nntp_list(session);
539 1 hiro
                if (ok != NN_SUCCESS) {
540 1 hiro
                        if (ok == NN_SOCKET) {
541 1 hiro
                                session_destroy(SESSION(session));
542 1 hiro
                                REMOTE_FOLDER(folder)->session = NULL;
543 1 hiro
                        }
544 1 hiro
                        g_free(filename);
545 1 hiro
                        return NULL;
546 1 hiro
                }
547 1 hiro
                if (recv_write_to_file(SESSION(session)->sock, filename) < 0) {
548 1 hiro
                        log_warning(_("can't retrieve newsgroup list\n"));
549 1 hiro
                        session_destroy(SESSION(session));
550 1 hiro
                        REMOTE_FOLDER(folder)->session = NULL;
551 1 hiro
                        g_free(filename);
552 1 hiro
                        return NULL;
553 1 hiro
                }
554 1 hiro
555 478 hiro
                if ((fp = g_fopen(filename, "rb")) == NULL) {
556 1 hiro
                        FILE_OP_ERROR(filename, "fopen");
557 1 hiro
                        g_free(filename);
558 1 hiro
                        return NULL;
559 1 hiro
                }
560 1 hiro
        }
561 1 hiro
562 1 hiro
        while (fgets(buf, sizeof(buf), fp) != NULL) {
563 1 hiro
                gchar *p = buf;
564 1 hiro
                gchar *name;
565 1 hiro
                gint last_num;
566 1 hiro
                gint first_num;
567 1 hiro
                gchar type;
568 1 hiro
                NewsGroupInfo *ginfo;
569 1 hiro
570 1 hiro
                p = strchr(p, ' ');
571 1 hiro
                if (!p) continue;
572 1 hiro
                *p = '\0';
573 1 hiro
                p++;
574 1 hiro
                name = buf;
575 1 hiro
576 1 hiro
                if (sscanf(p, "%d %d %c", &last_num, &first_num, &type) < 3)
577 1 hiro
                        continue;
578 1 hiro
579 1 hiro
                ginfo = news_group_info_new(name, first_num, last_num, type);
580 1 hiro
581 1 hiro
                if (!last)
582 1 hiro
                        last = list = g_slist_append(NULL, ginfo);
583 1 hiro
                else {
584 1 hiro
                        last = g_slist_append(last, ginfo);
585 1 hiro
                        last = last->next;
586 1 hiro
                }
587 1 hiro
        }
588 1 hiro
589 1 hiro
        fclose(fp);
590 1 hiro
        g_free(filename);
591 1 hiro
592 1 hiro
        list = g_slist_sort(list, (GCompareFunc)news_group_info_compare);
593 1 hiro
594 1 hiro
        return list;
595 1 hiro
}
596 1 hiro
597 1 hiro
void news_group_list_free(GSList *group_list)
598 1 hiro
{
599 1 hiro
        GSList *cur;
600 1 hiro
601 1 hiro
        if (!group_list) return;
602 1 hiro
603 1 hiro
        for (cur = group_list; cur != NULL; cur = cur->next)
604 1 hiro
                news_group_info_free((NewsGroupInfo *)cur->data);
605 1 hiro
        g_slist_free(group_list);
606 1 hiro
}
607 1 hiro
608 1 hiro
void news_remove_group_list_cache(Folder *folder)
609 1 hiro
{
610 1 hiro
        gchar *path, *filename;
611 1 hiro
612 1 hiro
        g_return_if_fail(folder != NULL);
613 1 hiro
        g_return_if_fail(FOLDER_TYPE(folder) == F_NEWS);
614 1 hiro
615 1 hiro
        path = folder_item_get_path(FOLDER_ITEM(folder->node->data));
616 1 hiro
        filename = g_strconcat(path, G_DIR_SEPARATOR_S, NEWSGROUP_LIST, NULL);
617 1 hiro
        g_free(path);
618 1 hiro
619 1 hiro
        if (is_file_exist(filename)) {
620 1 hiro
                if (remove(filename) < 0)
621 1 hiro
                        FILE_OP_ERROR(filename, "remove");
622 1 hiro
        }
623 1 hiro
        g_free(filename);
624 1 hiro
}
625 1 hiro
626 1 hiro
gint news_post(Folder *folder, const gchar *file)
627 1 hiro
{
628 1 hiro
        FILE *fp;
629 1 hiro
        gint ok;
630 1 hiro
631 1 hiro
        g_return_val_if_fail(folder != NULL, -1);
632 1 hiro
        g_return_val_if_fail(FOLDER_TYPE(folder) == F_NEWS, -1);
633 1 hiro
        g_return_val_if_fail(file != NULL, -1);
634 1 hiro
635 478 hiro
        if ((fp = g_fopen(file, "rb")) == NULL) {
636 1 hiro
                FILE_OP_ERROR(file, "fopen");
637 1 hiro
                return -1;
638 1 hiro
        }
639 1 hiro
640 1 hiro
        ok = news_post_stream(folder, fp);
641 1 hiro
642 1 hiro
        fclose(fp);
643 1 hiro
644 1 hiro
        return ok;
645 1 hiro
}
646 1 hiro
647 1 hiro
gint news_post_stream(Folder *folder, FILE *fp)
648 1 hiro
{
649 1 hiro
        NNTPSession *session;
650 1 hiro
        gint ok;
651 1 hiro
652 1 hiro
        g_return_val_if_fail(folder != NULL, -1);
653 1 hiro
        g_return_val_if_fail(FOLDER_TYPE(folder) == F_NEWS, -1);
654 1 hiro
        g_return_val_if_fail(fp != NULL, -1);
655 1 hiro
656 1 hiro
        session = news_session_get(folder);
657 1 hiro
        if (!session) return -1;
658 1 hiro
659 1 hiro
        ok = nntp_post(session, fp);
660 1 hiro
        if (ok != NN_SUCCESS) {
661 1 hiro
                log_warning(_("can't post article.\n"));
662 1 hiro
                if (ok == NN_SOCKET) {
663 1 hiro
                        session_destroy(SESSION(session));
664 1 hiro
                        REMOTE_FOLDER(folder)->session = NULL;
665 1 hiro
                }
666 1 hiro
                return -1;
667 1 hiro
        }
668 1 hiro
669 1 hiro
        return 0;
670 1 hiro
}
671 1 hiro
672 1 hiro
static gint news_get_article_cmd(NNTPSession *session, const gchar *cmd,
673 1 hiro
                                 gint num, gchar *filename)
674 1 hiro
{
675 1 hiro
        gchar *msgid;
676 1 hiro
        gint ok;
677 1 hiro
678 1 hiro
        ok = nntp_get_article(session, cmd, num, &msgid);
679 1 hiro
        if (ok != NN_SUCCESS)
680 1 hiro
                return ok;
681 1 hiro
682 1 hiro
        debug_print("Message-Id = %s, num = %d\n", msgid, num);
683 1 hiro
        g_free(msgid);
684 1 hiro
685 1 hiro
        ok = recv_write_to_file(SESSION(session)->sock, filename);
686 1 hiro
        if (ok < 0) {
687 1 hiro
                log_warning(_("can't retrieve article %d\n"), num);
688 1 hiro
                if (ok == -2)
689 1 hiro
                        return NN_SOCKET;
690 1 hiro
                else
691 1 hiro
                        return NN_IOERR;
692 1 hiro
        }
693 1 hiro
694 1 hiro
        return NN_SUCCESS;
695 1 hiro
}
696 1 hiro
697 1 hiro
static gint news_get_article(NNTPSession *session, gint num, gchar *filename)
698 1 hiro
{
699 1 hiro
        return news_get_article_cmd(session, "ARTICLE", num, filename);
700 1 hiro
}
701 1 hiro
702 1 hiro
#if 0
703 1 hiro
static gint news_get_header(NNTPSession *session, gint num, gchar *filename)
704 1 hiro
{
705 1 hiro
        return news_get_article_cmd(session, "HEAD", num, filename);
706 1 hiro
}
707 1 hiro
#endif
708 1 hiro
709 1 hiro
/**
710 1 hiro
 * news_select_group:
711 1 hiro
 * @session: Active NNTP session.
712 1 hiro
 * @group: Newsgroup name.
713 1 hiro
 * @num: Estimated number of articles.
714 1 hiro
 * @first: First article number.
715 1 hiro
 * @last: Last article number.
716 1 hiro
 *
717 1 hiro
 * Select newsgroup @group with the GROUP command if it is not already
718 1 hiro
 * selected in @session, or article numbers need to be returned.
719 1 hiro
 *
720 1 hiro
 * Return value: NNTP result code.
721 1 hiro
 **/
722 1 hiro
static gint news_select_group(NNTPSession *session, const gchar *group,
723 1 hiro
                              gint *num, gint *first, gint *last)
724 1 hiro
{
725 1 hiro
        gint ok;
726 1 hiro
        gint num_, first_, last_;
727 1 hiro
728 1 hiro
        if (!num || !first || !last) {
729 333 hiro
                if (session->group &&
730 333 hiro
                    g_ascii_strcasecmp(session->group, group) == 0)
731 1 hiro
                        return NN_SUCCESS;
732 1 hiro
                num = &num_;
733 1 hiro
                first = &first_;
734 1 hiro
                last = &last_;
735 1 hiro
        }
736 1 hiro
737 1 hiro
        g_free(session->group);
738 1 hiro
        session->group = NULL;
739 1 hiro
740 1 hiro
        ok = nntp_group(session, group, num, first, last);
741 1 hiro
        if (ok == NN_SUCCESS)
742 1 hiro
                session->group = g_strdup(group);
743 1 hiro
        else
744 1 hiro
                log_warning(_("can't select group: %s\n"), group);
745 1 hiro
746 1 hiro
        return ok;
747 1 hiro
}
748 1 hiro
749 1 hiro
static GSList *news_get_uncached_articles(NNTPSession *session,
750 1 hiro
                                          FolderItem *item, gint cache_last,
751 1 hiro
                                          gint *rfirst, gint *rlast)
752 1 hiro
{
753 1 hiro
        gint ok;
754 1 hiro
        gint num = 0, first = 0, last = 0, begin = 0, end = 0;
755 1 hiro
        gchar buf[NNTPBUFSIZE];
756 1 hiro
        GSList *newlist = NULL;
757 1 hiro
        GSList *llast = NULL;
758 1 hiro
        MsgInfo *msginfo;
759 358 hiro
        gint max_articles;
760 1 hiro
761 1 hiro
        if (rfirst) *rfirst = -1;
762 1 hiro
        if (rlast)  *rlast  = -1;
763 1 hiro
764 1 hiro
        g_return_val_if_fail(session != NULL, NULL);
765 1 hiro
        g_return_val_if_fail(item != NULL, NULL);
766 1 hiro
        g_return_val_if_fail(item->folder != NULL, NULL);
767 358 hiro
        g_return_val_if_fail(item->folder->account != NULL, NULL);
768 1 hiro
        g_return_val_if_fail(FOLDER_TYPE(item->folder) == F_NEWS, NULL);
769 1 hiro
770 1 hiro
        ok = news_select_group(session, item->path, &num, &first, &last);
771 1 hiro
        if (ok != NN_SUCCESS) {
772 1 hiro
                if (ok == NN_SOCKET) {
773 1 hiro
                        session_destroy(SESSION(session));
774 1 hiro
                        REMOTE_FOLDER(item->folder)->session = NULL;
775 1 hiro
                }
776 1 hiro
                return NULL;
777 1 hiro
        }
778 1 hiro
779 1 hiro
        /* calculate getting overview range */
780 1 hiro
        if (first > last) {
781 1 hiro
                log_warning(_("invalid article range: %d - %d\n"),
782 1 hiro
                            first, last);
783 1 hiro
                return NULL;
784 1 hiro
        }
785 1 hiro
786 1 hiro
        if (rfirst) *rfirst = first;
787 1 hiro
        if (rlast)  *rlast  = last;
788 1 hiro
789 1 hiro
        if (cache_last < first)
790 1 hiro
                begin = first;
791 1 hiro
        else if (last < cache_last)
792 1 hiro
                begin = first;
793 1 hiro
        else if (last == cache_last) {
794 1 hiro
                debug_print(_("no new articles.\n"));
795 1 hiro
                return NULL;
796 1 hiro
        } else
797 1 hiro
                begin = cache_last + 1;
798 1 hiro
        end = last;
799 1 hiro
800 358 hiro
        max_articles = item->folder->account->max_nntp_articles;
801 358 hiro
        if (max_articles > 0 && end - begin + 1 > max_articles)
802 358 hiro
                begin = end - max_articles + 1;
803 1 hiro
804 1 hiro
        log_message(_("getting xover %d - %d in %s...\n"),
805 1 hiro
                    begin, end, item->path);
806 1 hiro
        ok = nntp_xover(session, begin, end);
807 1 hiro
        if (ok != NN_SUCCESS) {
808 1 hiro
                log_warning(_("can't get xover\n"));
809 1 hiro
                if (ok == NN_SOCKET) {
810 1 hiro
                        session_destroy(SESSION(session));
811 1 hiro
                        REMOTE_FOLDER(item->folder)->session = NULL;
812 1 hiro
                }
813 1 hiro
                return NULL;
814 1 hiro
        }
815 1 hiro
816 1 hiro
        for (;;) {
817 1 hiro
                if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
818 1 hiro
                        log_warning(_("error occurred while getting xover.\n"));
819 1 hiro
                        session_destroy(SESSION(session));
820 1 hiro
                        REMOTE_FOLDER(item->folder)->session = NULL;
821 1 hiro
                        return newlist;
822 1 hiro
                }
823 1 hiro
824 1 hiro
                if (buf[0] == '.' && buf[1] == '\r') break;
825 1 hiro
826 1 hiro
                msginfo = news_parse_xover(buf);
827 1 hiro
                if (!msginfo) {
828 1 hiro
                        log_warning(_("invalid xover line: %s\n"), buf);
829 1 hiro
                        continue;
830 1 hiro
                }
831 1 hiro
832 1 hiro
                msginfo->folder = item;
833 1 hiro
                msginfo->flags.perm_flags = MSG_NEW|MSG_UNREAD;
834 1 hiro
                msginfo->flags.tmp_flags = MSG_NEWS;
835 1 hiro
                msginfo->newsgroups = g_strdup(item->path);
836 1 hiro
837 1 hiro
                if (!newlist)
838 1 hiro
                        llast = newlist = g_slist_append(newlist, msginfo);
839 1 hiro
                else {
840 1 hiro
                        llast = g_slist_append(llast, msginfo);
841 1 hiro
                        llast = llast->next;
842 1 hiro
                }
843 1 hiro
        }
844 1 hiro
845 1 hiro
        ok = nntp_xhdr(session, "to", begin, end);
846 1 hiro
        if (ok != NN_SUCCESS) {
847 1 hiro
                log_warning(_("can't get xhdr\n"));
848 1 hiro
                if (ok == NN_SOCKET) {
849 1 hiro
                        session_destroy(SESSION(session));
850 1 hiro
                        REMOTE_FOLDER(item->folder)->session = NULL;
851 1 hiro
                }
852 1 hiro
                return newlist;
853 1 hiro
        }
854 1 hiro
855 1 hiro
        llast = newlist;
856 1 hiro
857 1 hiro
        for (;;) {
858 1 hiro
                if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
859 1 hiro
                        log_warning(_("error occurred while getting xhdr.\n"));
860 1 hiro
                        session_destroy(SESSION(session));
861 1 hiro
                        REMOTE_FOLDER(item->folder)->session = NULL;
862 1 hiro
                        return newlist;
863 1 hiro
                }
864 1 hiro
865 1 hiro
                if (buf[0] == '.' && buf[1] == '\r') break;
866 1 hiro
                if (!llast) {
867 1 hiro
                        g_warning("llast == NULL\n");
868 1 hiro
                        continue;
869 1 hiro
                }
870 1 hiro
871 1 hiro
                msginfo = (MsgInfo *)llast->data;
872 1 hiro
                msginfo->to = news_parse_xhdr(buf, msginfo);
873 1 hiro
874 1 hiro
                llast = llast->next;
875 1 hiro
        }
876 1 hiro
877 1 hiro
        ok = nntp_xhdr(session, "cc", begin, end);
878 1 hiro
        if (ok != NN_SUCCESS) {
879 1 hiro
                log_warning(_("can't get xhdr\n"));
880 1 hiro
                if (ok == NN_SOCKET) {
881 1 hiro
                        session_destroy(SESSION(session));
882 1 hiro
                        REMOTE_FOLDER(item->folder)->session = NULL;
883 1 hiro
                }
884 1 hiro
                return newlist;
885 1 hiro
        }
886 1 hiro
887 1 hiro
        llast = newlist;
888 1 hiro
889 1 hiro
        for (;;) {
890 1 hiro
                if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
891 1 hiro
                        log_warning(_("error occurred while getting xhdr.\n"));
892 1 hiro
                        session_destroy(SESSION(session));
893 1 hiro
                        REMOTE_FOLDER(item->folder)->session = NULL;
894 1 hiro
                        return newlist;
895 1 hiro
                }
896 1 hiro
897 1 hiro
                if (buf[0] == '.' && buf[1] == '\r') break;
898 1 hiro
                if (!llast) {
899 1 hiro
                        g_warning("llast == NULL\n");
900 1 hiro
                        continue;
901 1 hiro
                }
902 1 hiro
903 1 hiro
                msginfo = (MsgInfo *)llast->data;
904 1 hiro
                msginfo->cc = news_parse_xhdr(buf, msginfo);
905 1 hiro
906 1 hiro
                llast = llast->next;
907 1 hiro
        }
908 1 hiro
909 1 hiro
        session_set_access_time(SESSION(session));
910 1 hiro
911 1 hiro
        return newlist;
912 1 hiro
}
913 1 hiro
914 1 hiro
#define PARSE_ONE_PARAM(p, srcp) \
915 1 hiro
{ \
916 1 hiro
        p = strchr(srcp, '\t'); \
917 1 hiro
        if (!p) return NULL; \
918 1 hiro
        else \
919 1 hiro
                *p++ = '\0'; \
920 1 hiro
}
921 1 hiro
922 1 hiro
static MsgInfo *news_parse_xover(const gchar *xover_str)
923 1 hiro
{
924 1 hiro
        MsgInfo *msginfo;
925 1 hiro
        gchar *subject, *sender, *size, *line, *date, *msgid, *ref, *tmp;
926 1 hiro
        gchar *p;
927 1 hiro
        gint num, size_int, line_int;
928 1 hiro
        gchar *xover_buf;
929 1 hiro
930 1 hiro
        Xstrdup_a(xover_buf, xover_str, return NULL);
931 1 hiro
932 1 hiro
        PARSE_ONE_PARAM(subject, xover_buf);
933 1 hiro
        PARSE_ONE_PARAM(sender, subject);
934 1 hiro
        PARSE_ONE_PARAM(date, sender);
935 1 hiro
        PARSE_ONE_PARAM(msgid, date);
936 1 hiro
        PARSE_ONE_PARAM(ref, msgid);
937 1 hiro
        PARSE_ONE_PARAM(size, ref);
938 1 hiro
        PARSE_ONE_PARAM(line, size);
939 1 hiro
940 1 hiro
        tmp = strchr(line, '\t');
941 1 hiro
        if (!tmp) tmp = strchr(line, '\r');
942 1 hiro
        if (!tmp) tmp = strchr(line, '\n');
943 1 hiro
        if (tmp) *tmp = '\0';
944 1 hiro
945 1 hiro
        num = atoi(xover_str);
946 1 hiro
        size_int = atoi(size);
947 1 hiro
        line_int = atoi(line);
948 1 hiro
949 1 hiro
        /* set MsgInfo */
950 1 hiro
        msginfo = g_new0(MsgInfo, 1);
951 1 hiro
        msginfo->msgnum = num;
952 1 hiro
        msginfo->size = size_int;
953 1 hiro
954 1 hiro
        msginfo->date = g_strdup(date);
955 1 hiro
        msginfo->date_t = procheader_date_parse(NULL, date, 0);
956 1 hiro
957 145 hiro
        msginfo->from = conv_unmime_header(sender, NULL);
958 145 hiro
        msginfo->fromname = procheader_get_fromname(msginfo->from);
959 1 hiro
960 145 hiro
        msginfo->subject = conv_unmime_header(subject, NULL);
961 1 hiro
962 1 hiro
        extract_parenthesis(msgid, '<', '>');
963 1 hiro
        remove_space(msgid);
964 1 hiro
        if (*msgid != '\0')
965 1 hiro
                msginfo->msgid = g_strdup(msgid);
966 1 hiro
967 1 hiro
        eliminate_parenthesis(ref, '(', ')');
968 1 hiro
        if ((p = strrchr(ref, '<')) != NULL) {
969 1 hiro
                extract_parenthesis(p, '<', '>');
970 1 hiro
                remove_space(p);
971 1 hiro
                if (*p != '\0')
972 1 hiro
                        msginfo->inreplyto = g_strdup(p);
973 1 hiro
        }
974 1 hiro
975 1 hiro
        return msginfo;
976 1 hiro
}
977 1 hiro
978 1 hiro
static gchar *news_parse_xhdr(const gchar *xhdr_str, MsgInfo *msginfo)
979 1 hiro
{
980 1 hiro
        gchar *p;
981 1 hiro
        gchar *tmp;
982 1 hiro
        gint num;
983 1 hiro
984 1 hiro
        p = strchr(xhdr_str, ' ');
985 1 hiro
        if (!p)
986 1 hiro
                return NULL;
987 1 hiro
        else
988 1 hiro
                p++;
989 1 hiro
990 1 hiro
        num = atoi(xhdr_str);
991 1 hiro
        if (msginfo->msgnum != num) return NULL;
992 1 hiro
993 1 hiro
        tmp = strchr(p, '\r');
994 1 hiro
        if (!tmp) tmp = strchr(p, '\n');
995 1 hiro
996 1 hiro
        if (tmp)
997 1 hiro
                return g_strndup(p, tmp - p);
998 1 hiro
        else
999 1 hiro
                return g_strdup(p);
1000 1 hiro
}
1001 1 hiro
1002 1 hiro
static GSList *news_delete_old_articles(GSList *alist, FolderItem *item,
1003 1 hiro
                                        gint first)
1004 1 hiro
{
1005 1 hiro
        GSList *cur, *next;
1006 1 hiro
        MsgInfo *msginfo;
1007 1 hiro
        gchar *dir;
1008 1 hiro
1009 1 hiro
        g_return_val_if_fail(item != NULL, alist);
1010 1 hiro
        g_return_val_if_fail(item->folder != NULL, alist);
1011 1 hiro
        g_return_val_if_fail(FOLDER_TYPE(item->folder) == F_NEWS, alist);
1012 1 hiro
1013 1 hiro
        if (first < 2) return alist;
1014 1 hiro
1015 1 hiro
        debug_print("Deleting cached articles 1 - %d ...\n", first - 1);
1016 1 hiro
1017 1 hiro
        dir = folder_item_get_path(item);
1018 1 hiro
        remove_numbered_files(dir, 1, first - 1);
1019 1 hiro
        g_free(dir);
1020 1 hiro
1021 1 hiro
        for (cur = alist; cur != NULL; ) {
1022 1 hiro
                next = cur->next;
1023 1 hiro
1024 1 hiro
                msginfo = (MsgInfo *)cur->data;
1025 1 hiro
                if (msginfo && msginfo->msgnum < first) {
1026 1 hiro
                        procmsg_msginfo_free(msginfo);
1027 1 hiro
                        alist = g_slist_remove(alist, msginfo);
1028 285 hiro
                        item->cache_dirty = TRUE;
1029 1 hiro
                }
1030 1 hiro
1031 1 hiro
                cur = next;
1032 1 hiro
        }
1033 1 hiro
1034 1 hiro
        return alist;
1035 1 hiro
}
1036 1 hiro
1037 1 hiro
static void news_delete_all_articles(FolderItem *item)
1038 1 hiro
{
1039 1 hiro
        gchar *dir;
1040 1 hiro
1041 1 hiro
        g_return_if_fail(item != NULL);
1042 1 hiro
        g_return_if_fail(item->folder != NULL);
1043 1 hiro
        g_return_if_fail(FOLDER_TYPE(item->folder) == F_NEWS);
1044 1 hiro
1045 1 hiro
        debug_print("Deleting all cached articles...\n");
1046 1 hiro
1047 1 hiro
        dir = folder_item_get_path(item);
1048 1 hiro
        remove_all_numbered_files(dir);
1049 1 hiro
        g_free(dir);
1050 1 hiro
}
1051 1 hiro
1052 1 hiro
static void news_delete_expired_caches(GSList *alist, FolderItem *item)
1053 1 hiro
{
1054 1 hiro
        gchar *dir;
1055 1 hiro
1056 1 hiro
        g_return_if_fail(item != NULL);
1057 1 hiro
        g_return_if_fail(item->folder != NULL);
1058 1 hiro
        g_return_if_fail(FOLDER_TYPE(item->folder) == F_NEWS);
1059 1 hiro
1060 1 hiro
        debug_print("Deleting expired cached articles...\n");
1061 1 hiro
1062 1 hiro
        dir = folder_item_get_path(item);
1063 1 hiro
        remove_expired_files(dir, 24 * 7);
1064 1 hiro
        g_free(dir);
1065 1 hiro
}