2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999,2000 Hiroyuki Yamamoto
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 static gint verbose = 1;
35 static void nntp_gen_send(SockInfo *sock, const gchar *format, ...);
36 static gint nntp_gen_recv(SockInfo *sock, gchar *buf, gint size);
38 SockInfo *nntp_open(const gchar *server, gushort port, gchar *buf)
42 if ((sock = sock_connect(server, port)) == NULL) {
43 log_warning(_("Can't connect to NNTP server: %s:%d\n"),
48 if (nntp_ok(sock, buf) == NN_SUCCESS)
56 gint nntp_group(SockInfo *sock, const gchar *group,
57 gint *num, gint *first, gint *last)
61 gchar buf[NNTPBUFSIZE];
63 nntp_gen_send(sock, "GROUP %s", group);
65 if ((ok = nntp_ok(sock, buf)) != NN_SUCCESS)
68 if (sscanf(buf, "%d %d %d %d", &resp, num, first, last)
70 log_warning(_("protocol error: %s\n"), buf);
77 gint nntp_get_article(SockInfo *sock, const gchar *cmd, gint num, gchar **msgid)
80 gchar buf[NNTPBUFSIZE];
83 nntp_gen_send(sock, "%s %d", cmd, num);
85 nntp_gen_send(sock, cmd);
87 if ((ok = nntp_ok(sock, buf)) != NN_SUCCESS)
90 extract_parenthesis(buf, '<', '>');
92 log_warning(_("protocol error\n"));
95 *msgid = g_strdup(buf);
100 gint nntp_article(SockInfo *sock, gint num, gchar **msgid)
102 return nntp_get_article(sock, "ARTICLE", num, msgid);
105 gint nntp_body(SockInfo *sock, gint num, gchar **msgid)
107 return nntp_get_article(sock, "BODY", num, msgid);
110 gint nntp_head(SockInfo *sock, gint num, gchar **msgid)
112 return nntp_get_article(sock, "HEAD", num, msgid);
115 gint nntp_stat(SockInfo *sock, gint num, gchar **msgid)
117 return nntp_get_article(sock, "STAT", num, msgid);
120 gint nntp_next(SockInfo *sock, gint *num, gchar **msgid)
124 gchar buf[NNTPBUFSIZE];
126 nntp_gen_send(sock, "NEXT");
128 if ((ok = nntp_ok(sock, buf)) != NN_SUCCESS)
131 if (sscanf(buf, "%d %d", &resp, num) != 2) {
132 log_warning(_("protocol error: %s\n"), buf);
136 extract_parenthesis(buf, '<', '>');
137 if (buf[0] == '\0') {
138 log_warning(_("protocol error\n"));
141 *msgid = g_strdup(buf);
146 gint nntp_xover(SockInfo *sock, gint first, gint last)
149 gchar buf[NNTPBUFSIZE];
151 nntp_gen_send(sock, "XOVER %d-%d", first, last);
152 if ((ok = nntp_ok(sock, buf)) != NN_SUCCESS)
158 gint nntp_post(SockInfo *sock, FILE *fp)
161 gchar buf[NNTPBUFSIZE];
163 nntp_gen_send(sock, "POST");
164 if ((ok = nntp_ok(sock, buf)) != NN_SUCCESS)
167 while (fgets(buf, sizeof(buf), fp) != NULL) {
170 if (sock_write(sock, ".", 1) < 0) {
171 log_warning(_("Error occurred while posting\n"));
176 if (sock_puts(sock, buf) < 0) {
177 log_warning(_("Error occurred while posting\n"));
182 sock_write(sock, ".\r\n", 3);
183 if ((ok = nntp_ok(sock, buf)) != NN_SUCCESS)
189 gint nntp_newgroups(SockInfo *sock)
194 gint nntp_newnews(SockInfo *sock)
199 gint nntp_mode(SockInfo *sock, gboolean stream)
203 nntp_gen_send(sock, "MODE %s", stream ? "STREAM" : "READER");
204 ok = nntp_ok(sock, NULL);
209 gint nntp_authinfo_user(SockInfo *sock, const gchar *user)
212 gchar buf[NNTPBUFSIZE];
214 nntp_gen_send(sock, "AUTHINFO USER %s", user);
215 ok = nntp_ok(sock, buf);
220 gint nntp_authinfo_pass(SockInfo *sock, const gchar *pass)
223 gchar buf[NNTPBUFSIZE];
225 nntp_gen_send(sock, "AUTHINFO PASS %s", pass);
226 ok = nntp_ok(sock, buf);
231 gint nntp_ok(SockInfo *sock, gchar *argbuf)
234 gchar buf[NNTPBUFSIZE];
236 if ((ok = nntp_gen_recv(sock, buf, sizeof(buf))) == NN_SUCCESS) {
240 if ((buf[0] == '1' || buf[0] == '2' || buf[0] == '3') &&
245 if (!strncmp(buf, "381 ", 4))
248 } else if (!strncmp(buf, "480 ", 4))
257 static void nntp_gen_send(SockInfo *sock, const gchar *format, ...)
259 gchar buf[NNTPBUFSIZE];
262 va_start(args, format);
263 g_vsnprintf(buf, sizeof(buf), format, args);
267 if (!g_strncasecmp(buf, "AUTHINFO PASS", 13))
268 log_print("NNTP> AUTHINFO PASS ***\n");
270 log_print("NNTP> %s\n", buf);
274 sock_write(sock, buf, strlen(buf));
277 static gint nntp_gen_recv(SockInfo *sock, gchar *buf, gint size)
279 if (sock_read(sock, buf, size) == -1)
285 log_print("NNTP< %s\n", buf);
291 nntp_list sends the command "LIST" to the news server,
292 a function is needed to read the newsgroups list.
295 gint nntp_list(SockInfo *sock)
297 GList * result = NULL;
301 gchar buf[NNTPBUFSIZE];
303 nntp_gen_send(sock, "LIST");
305 if ((ok = nntp_ok(sock, buf)) != NN_SUCCESS)
309 log_print("NNTP< %s\n", buf);