2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2001 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 (NNTPSockInfo
*sock
,
38 static gint
nntp_gen_recv (NNTPSockInfo
*sock
,
41 static gint
nntp_gen_command (NNTPSockInfo
*sock
,
46 NNTPSockInfo
*nntp_open(const gchar
*server
, gushort port
, gchar
*buf
)
49 NNTPSockInfo
*nntp_sock
;
51 if ((sock
= sock_connect(server
, port
)) == NULL
) {
52 log_warning(_("Can't connect to NNTP server: %s:%d\n"),
56 nntp_sock
= g_new0(NNTPSockInfo
, 1);
57 nntp_sock
->sock
= sock
;
59 if (nntp_ok(nntp_sock
, buf
) == NN_SUCCESS
)
68 NNTPSockInfo
*nntp_open_auth(const gchar
*server
, gushort port
, gchar
*buf
,
69 const gchar
*userid
, const gchar
*passwd
)
73 sock
= nntp_open(server
, port
, buf
);
74 if (!sock
) return NULL
;
76 sock
->userid
= g_strdup(userid
);
77 sock
->passwd
= g_strdup(passwd
);
82 void nntp_close(NNTPSockInfo
*sock
)
86 sock_close(sock
->sock
);
92 gint
nntp_group(NNTPSockInfo
*sock
, const gchar
*group
,
93 gint
*num
, gint
*first
, gint
*last
)
97 gchar buf
[NNTPBUFSIZE
];
99 ok
= nntp_gen_command(sock
, buf
, "GROUP %s", group
);
101 if (ok
!= NN_SUCCESS
)
104 if (sscanf(buf
, "%d %d %d %d", &resp
, num
, first
, last
)
106 log_warning(_("protocol error: %s\n"), buf
);
113 gint
nntp_get_article(NNTPSockInfo
*sock
, const gchar
*cmd
, gint num
,
117 gchar buf
[NNTPBUFSIZE
];
120 ok
= nntp_gen_command(sock
, buf
, "%s %d", cmd
, num
);
122 ok
= nntp_gen_command(sock
, buf
, cmd
);
124 if (ok
!= NN_SUCCESS
)
127 extract_parenthesis(buf
, '<', '>');
128 if (buf
[0] == '\0') {
129 log_warning(_("protocol error\n"));
132 *msgid
= g_strdup(buf
);
137 gint
nntp_article(NNTPSockInfo
*sock
, gint num
, gchar
**msgid
)
139 return nntp_get_article(sock
, "ARTICLE", num
, msgid
);
142 gint
nntp_body(NNTPSockInfo
*sock
, gint num
, gchar
**msgid
)
144 return nntp_get_article(sock
, "BODY", num
, msgid
);
147 gint
nntp_head(NNTPSockInfo
*sock
, gint num
, gchar
**msgid
)
149 return nntp_get_article(sock
, "HEAD", num
, msgid
);
152 gint
nntp_stat(NNTPSockInfo
*sock
, gint num
, gchar
**msgid
)
154 return nntp_get_article(sock
, "STAT", num
, msgid
);
157 gint
nntp_next(NNTPSockInfo
*sock
, gint
*num
, gchar
**msgid
)
161 gchar buf
[NNTPBUFSIZE
];
163 ok
= nntp_gen_command(sock
, buf
, "NEXT");
165 if (ok
!= NN_SUCCESS
)
168 if (sscanf(buf
, "%d %d", &resp
, num
) != 2) {
169 log_warning(_("protocol error: %s\n"), buf
);
173 extract_parenthesis(buf
, '<', '>');
174 if (buf
[0] == '\0') {
175 log_warning(_("protocol error\n"));
178 *msgid
= g_strdup(buf
);
183 gint
nntp_xover(NNTPSockInfo
*sock
, gint first
, gint last
)
186 gchar buf
[NNTPBUFSIZE
];
188 ok
= nntp_gen_command(sock
, buf
, "XOVER %d-%d", first
, last
);
189 if (ok
!= NN_SUCCESS
)
195 gint
nntp_xhdr(NNTPSockInfo
*sock
, const gchar
*header
, gint first
, gint last
)
198 gchar buf
[NNTPBUFSIZE
];
200 ok
= nntp_gen_command(sock
, buf
, "XHDR %s %d-%d", header
, first
, last
);
201 if (ok
!= NN_SUCCESS
)
207 gint
nntp_list(NNTPSockInfo
*sock
)
209 return nntp_gen_command(sock
, NULL
, "LIST");
212 gint
nntp_post(NNTPSockInfo
*sock
, FILE *fp
)
215 gchar buf
[NNTPBUFSIZE
];
217 ok
= nntp_gen_command(sock
, buf
, "POST");
218 if (ok
!= NN_SUCCESS
)
221 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
224 if (sock_write(sock
->sock
, ".", 1) < 0) {
225 log_warning(_("Error occurred while posting\n"));
230 if (sock_puts(sock
->sock
, buf
) < 0) {
231 log_warning(_("Error occurred while posting\n"));
236 sock_write(sock
->sock
, ".\r\n", 3);
237 if ((ok
= nntp_ok(sock
, buf
)) != NN_SUCCESS
)
243 gint
nntp_newgroups(NNTPSockInfo
*sock
)
248 gint
nntp_newnews(NNTPSockInfo
*sock
)
253 gint
nntp_mode(NNTPSockInfo
*sock
, gboolean stream
)
257 if (sock
->auth_failed
)
260 ok
= nntp_gen_command(sock
, NULL
, "MODE %s",
261 stream
? "STREAM" : "READER");
266 gint
nntp_ok(NNTPSockInfo
*sock
, gchar
*argbuf
)
269 gchar buf
[NNTPBUFSIZE
];
271 if ((ok
= nntp_gen_recv(sock
, buf
, sizeof(buf
))) == NN_SUCCESS
) {
275 if ((buf
[0] == '1' || buf
[0] == '2' || buf
[0] == '3') &&
276 (buf
[3] == ' ' || buf
[3] == '\0')) {
280 if (!strncmp(buf
, "381", 3))
284 } else if (!strncmp(buf
, "480", 3))
293 static void nntp_gen_send(NNTPSockInfo
*sock
, const gchar
*format
, ...)
295 gchar buf
[NNTPBUFSIZE
];
298 va_start(args
, format
);
299 g_vsnprintf(buf
, sizeof(buf
), format
, args
);
303 if (!g_strncasecmp(buf
, "AUTHINFO PASS", 13))
304 log_print("NNTP> AUTHINFO PASS ********\n");
306 log_print("NNTP> %s\n", buf
);
310 sock_write(sock
->sock
, buf
, strlen(buf
));
313 static gint
nntp_gen_recv(NNTPSockInfo
*sock
, gchar
*buf
, gint size
)
315 if (sock_gets(sock
->sock
, buf
, size
) == -1)
321 log_print("NNTP< %s\n", buf
);
326 static gint
nntp_gen_command(NNTPSockInfo
*sock
, gchar
*argbuf
,
327 const gchar
*format
, ...)
329 gchar buf
[NNTPBUFSIZE
];
333 va_start(args
, format
);
334 g_vsnprintf(buf
, sizeof(buf
), format
, args
);
337 nntp_gen_send(sock
, "%s", buf
);
338 ok
= nntp_ok(sock
, argbuf
);
339 if (ok
== NN_AUTHREQ
) {
340 if (!sock
->userid
|| !sock
->passwd
) {
341 sock
->auth_failed
= TRUE
;
345 nntp_gen_send(sock
, "AUTHINFO USER %s", sock
->userid
);
346 ok
= nntp_ok(sock
, NULL
);
347 if (ok
== NN_AUTHCONT
) {
348 nntp_gen_send(sock
, "AUTHINFO PASS %s", sock
->passwd
);
349 ok
= nntp_ok(sock
, NULL
);
351 if (ok
!= NN_SUCCESS
) {
352 sock
->auth_failed
= TRUE
;
356 nntp_gen_send(sock
, "%s", buf
);
357 ok
= nntp_ok(sock
, argbuf
);