[PATCH] RFC 3977 and reconnect on mode switching server
Urs Janßen <[email protected]> Fri, 30 Apr 2010 00:47:29 +0200
| Newsgroups | gmane.network.tin.devel |
|---|---|
| Organization | tin.org |
| Message-ID | <[email protected]> |
tin remembered the capabilites on reconnect and thus failed to
reissue mode reader on mode switching servers after a reconnect. the
patch belowfixes the problem.
we also need to catch 401 (and 483, but TLS is missing so this could
be "ignored") in get_respcode and parse its argument to propper
handle it. as many nntp_commands() do not capture the response string we
currently can't do this. (i.e. when not sending "MODE READER" inn >=
2.5.2 responses to any READER cmd. with "401 MODE-READER"). any
volunteers?
=== modified file 'src/nntplib.c'
--- src/nntplib.c 2010-04-02 13:33:44 +0000
+++ src/nntplib.c 2010-04-29 09:45:20 +0000
@@ -1010,7 +1010,46 @@
i = new_nntp_command("CAPABILITIES", INF_CAPABILITIES, buf, sizeof(buf));
switch (i) {
case INF_CAPABILITIES:
+ /* clear capabilities */
nntp_caps.type = CAPABILITIES;
+ nntp_caps.version = 0;
+ nntp_caps.mode_reader = FALSE;
+ nntp_caps.reader = FALSE;
+ nntp_caps.post = FALSE;
+ nntp_caps.list_active = FALSE;
+ nntp_caps.list_active_times = FALSE;
+ nntp_caps.list_distrib_pats = FALSE;
+ nntp_caps.list_headers = FALSE;
+ nntp_caps.list_newsgroups = FALSE;
+ nntp_caps.list_overview_fmt = FALSE;
+ nntp_caps.list_motd = FALSE;
+ nntp_caps.list_subscriptions = FALSE;
+ nntp_caps.list_distributions = FALSE;
+ nntp_caps.list_moderators = FALSE;
+ nntp_caps.list_counts = FALSE;
+ nntp_caps.xpat = FALSE;
+ nntp_caps.hdr = FALSE;
+ nntp_caps.hdr_cmd = NULL;
+ nntp_caps.over = FALSE;
+ nntp_caps.over_msgid = FALSE;
+ nntp_caps.over_cmd = NULL;
+ nntp_caps.newnews = FALSE;
+ nntp_caps.implementation = NULL;
+ nntp_caps.starttls = FALSE;
+ nntp_caps.authinfo_user = FALSE;
+ nntp_caps.authinfo_sasl = FALSE;
+ nntp_caps.authinfo_state = FALSE;
+ nntp_caps.sasl = SASL_NONE;
+#if 0
+ nntp_caps.streaming = FALSE;
+ nntp_caps.ihave = FALSE;
+#endif /* 0 */
+#ifndef BROKEN_LISTGROUP
+ nntp_caps.broken_listgroup = FALSE;
+#else
+ nntp_caps.broken_listgroup = TRUE;
+#endif /*! BROKEN_LISTGROUP */
+
while ((ptr = tin_fgets(FAKE_NNTP_FP, FALSE)) != NULL) {
# ifdef DEBUG
if (debug & DEBUG_NNTP)
@@ -1023,7 +1062,7 @@
d = strpbrk(d, " \t");
while (d != NULL && (d + 1 < (ptr + strlen(ptr)))) {
d++;
- nntp_caps.version = MAX(nntp_caps.version, (unsigned int) atoi(d));
+ nntp_caps.version = /* MAX(nntp_caps.version, */ (unsigned int) atoi(d)/*)*/;
d = strpbrk(d, " \t");
}
}
@@ -1740,7 +1779,7 @@
* Performs authentication if required and repeats the last command if
* necessary after a timeout.
*
- * TODO: make this handle 483 (RFC 3977) return codes
+ * TODO: make this handle 401 and 483 (RFC 3977) return codes
*/
int
get_respcode(
@@ -1762,47 +1801,45 @@
# endif /* DEBUG */
strncpy(savebuf, last_put, sizeof(savebuf) - 1); /* Take copy, as authenticate() will clobber this */
- if (authenticate(nntp_server, userid, FALSE)) {
- if (nntp_caps.type == CAPABILITIES) {
- check_extensions();
- can_post = nntp_caps.post && !force_no_post;
- }
- if (curr_group != NULL) {
- DEBUG_IO((stderr, _("Rejoin current group\n")));
- snprintf(last_put, sizeof(last_put), "GROUP %s", curr_group->name);
- put_server(last_put);
- s_gets(last_put, NNTP_STRLEN, nntp_rd_fp);
-# ifdef DEBUG
- if (debug & DEBUG_NNTP)
- debug_print_file("NNTP", "<<< %s", last_put);
-# endif /* DEBUG */
- DEBUG_IO((stderr, _("Read (%s)\n"), last_put));
- }
- strcpy(last_put, savebuf);
-
- put_server(last_put);
- ptr = tin_fgets(FAKE_NNTP_FP, FALSE);
-
- if (tin_errno) {
-# ifdef DEBUG
- if (debug & DEBUG_NNTP)
- debug_print_file("NNTP", "<<< Error: tin_errno <> 0");
-# endif /* DEBUG */
- return -1;
- }
-
-# ifdef DEBUG
- if (debug & DEBUG_NNTP)
- debug_print_file("NNTP", "<<< %s", ptr);
-# endif /* DEBUG */
- respcode = (int) strtol(ptr, &end, 10);
- if (message != NULL && mlen > 1) /* Pass out the rest of the text */
- strncpy(message, end, mlen - 1);
-
- } else {
+ if (!authenticate(nntp_server, userid, FALSE)) {
error_message(2, _(txt_auth_failed), nntp_caps.type == CAPABILITIES ? ERR_AUTHFAIL : ERR_ACCESS);
tin_done(EXIT_FAILURE);
}
+ if (nntp_caps.type == CAPABILITIES) {
+ check_extensions();
+ can_post = nntp_caps.post && !force_no_post;
+ }
+ if (curr_group != NULL) {
+ DEBUG_IO((stderr, _("Rejoin current group\n")));
+ snprintf(last_put, sizeof(last_put), "GROUP %s", curr_group->name);
+ put_server(last_put);
+ s_gets(last_put, NNTP_STRLEN, nntp_rd_fp);
+# ifdef DEBUG
+ if (debug & DEBUG_NNTP)
+ debug_print_file("NNTP", "<<< %s", last_put);
+# endif /* DEBUG */
+ DEBUG_IO((stderr, _("Read (%s)\n"), last_put));
+ }
+ strcpy(last_put, savebuf);
+
+ put_server(last_put);
+ ptr = tin_fgets(FAKE_NNTP_FP, FALSE);
+
+ if (tin_errno) {
+# ifdef DEBUG
+ if (debug & DEBUG_NNTP)
+ debug_print_file("NNTP", "<<< Error: tin_errno <> 0");
+# endif /* DEBUG */
+ return -1;
+ }
+
+# ifdef DEBUG
+ if (debug & DEBUG_NNTP)
+ debug_print_file("NNTP", "<<< %s", ptr);
+# endif /* DEBUG */
+ respcode = (int) strtol(ptr, &end, 10);
+ if (message != NULL && mlen > 1) /* Pass out the rest of the text */
+ strncpy(message, end, mlen - 1);
}
return respcode;
}