--- nntp.c 2001/08/14 14:42:41 1.7
+++ nntp.c 2001/08/16 15:00:50 1.8
@@ -37,6 +37,14 @@
#include <sys/time.h>
#include "nntp.h"
+#include "str.h"
+
+#ifndef FALSE
+#define FALSE (1 != 1)
+#endif
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
/* maximum NNTP protocol line length */
#define NNTP_LINE_MAXLEN 1024
@@ -53,6 +61,7 @@
nntp_io_t io;
nntp_readline_t rl;
struct timeval tv;
+ int kludgeinn441dup;
};
nntp_t *nntp_create(int rfd, int wfd, nntp_io_t *io)
@@ -78,6 +87,7 @@
nntp->rl.rl_bufptr = NULL;
nntp->rl.rl_buf[0] = '\0';
nntp_timeout(nntp, 3);
+ nntp->kludgeinn441dup = FALSE;
return nntp;
}
@@ -121,6 +131,19 @@
//fprintf(stderr, "DEBUG: nntp_readline got ***%s***\n", line);
+ /* prepare for the INN kludge using 441 returns for other things but
+ * "Duplicate". Typical welcome string is "200 host InterNetNews NNRP
+ * server INN 2.3.2 ready (posting * ok)."
+ */
+ if (str_parse(line, "m/^200.*\\sINN\\s/")) {
+ nntp->kludgeinn441dup = TRUE;
+ //fprintf(stderr, "DEBUG: INN kludge activated!\n");
+ }
+ else {
+ nntp->kludgeinn441dup = FALSE;
+ //fprintf(stderr, "DEBUG: no INN kludge!\n");
+ }
+
if (strncmp(line, "200", 3) == 0)
return NNTP_OK;
@@ -231,14 +254,12 @@
*
* In other words, INN *requires* the use of "MODE READER".
*/
- //fprintf(stderr, "DEBUG: before MODE READER\n");
*line = '\0';
strcat(line, "MODE READER");
if ((rc = nntp_writeline(nntp, line)) != NNTP_OK)
return rc;
if ((rc = nntp_readline(nntp, line, sizeof(line))) != NNTP_OK)
return rc;
- //fprintf(stderr, "DEBUG: after MODE READER\n");
/* A 200 response means posting ok, 201 means posting not allowed. We
* don't care about 5xx errors, they simply mean the server doesn't know
@@ -303,8 +324,6 @@
return rc;
if ((rc = nntp_readline(nntp, line, sizeof(line))) != NNTP_OK)
return rc;
- if (strncmp(line, "xxx", 3) == 0)
- return NNTP_OK;
if (strncmp(line, "340", 3) != 0)
return NNTP_ERR_POST;
@@ -314,10 +333,19 @@
if ((rc = nntp_readline(nntp, line, sizeof(line))) != NNTP_OK)
return rc;
//fprintf(stderr, "DEBUG: answer to post = ***%s***, rc = %s\n", line, nntp_error(rc));
- if ( (strncmp(line, "240", 3) == 0)
- || (strncmp(line, "441", 3) == 0)
- )
+
+ if (strncmp(line, "240", 3) == 0)
return NNTP_OK;
+
+ if (nntp->kludgeinn441dup == TRUE) {
+ if (strncmp(line, "441 435", 7) == 0)
+ return NNTP_OK;
+ }
+ else {
+ if (strncmp(line, "441", 3) == 0)
+ return NNTP_OK;
+ }
+
return NNTP_ERR_POST;
#if 0
@@ -330,6 +358,64 @@
#endif
}
+nntp_rc_t nntp_feed(nntp_t *nntp, msg_t *msg)
+{
+ nntp_rc_t rc = NNTP_OK;
+ char line[NNTP_LINE_MAXLEN];
+
+ /* RFC0977 3.4. The IHAVE command, 3.4.2. Responses
+ * < 235 article transferred ok
+ * < 335 send article to be transferred. End with <CR-LF>.<CR-LF>
+ * < 435 article not wanted - do not send it
+ * < 436 transfer failed - try again later
+ * < 437 article rejected - do not try again
+ *
+ * Research:
+ * < 200 dev16 InterNetNews server INN 2.3.2 ready
+ * > IHAVE <messageid>
+ * < 335 [no text; this number means positive response]
+ * < 435 Duplicate
+ * < 437 Missing "Path" header
+ * < 437 Unwanted newsgroup "quux"
+ * < 480 Transfer permission denied
+ */
+ *line = '\0';
+ strcat(line, "IHAVE ");
+ strcat(line, msg->cpMsgid);
+ if ((rc = nntp_writeline(nntp, line)) != NNTP_OK)
+ return rc;
+
+ if ((rc = nntp_readline(nntp, line, sizeof(line))) != NNTP_OK)
+ return rc;
+
+ if (strncmp(line, "435", 3) == 0)
+ return NNTP_OK;
+
+ if (strncmp(line, "436", 3) == 0)
+ return NNTP_DEFER;
+
+ if ( (strncmp(line, "437", 3) == 0) //FIXME style vs. optimization - redundant lines
+ || (strncmp(line, "480", 3) == 0)
+ || (strncmp(line, "335", 3) != 0)
+ )
+ return NNTP_ERR_POST;
+
+ if ((rc = nntp->io.write(nntp->wfd, msg->cpMsg, strlen(msg->cpMsg))) < 0) //FIXME while() wrapper around write required
+ return NNTP_ERR_SYSTEM;
+
+ if ((rc = nntp_readline(nntp, line, sizeof(line))) != NNTP_OK)
+ return rc;
+ //fprintf(stderr, "DEBUG: answer to post = ***%s***, rc = %s\n", line, nntp_error(rc));
+
+ if (strncmp(line, "235", 3) == 0)
+ return NNTP_OK;
+
+ if (strncmp(line, "436", 3) == 0)
+ return NNTP_DEFER;
+
+ return NNTP_ERR_POST;
+}
+
char *nntp_error(nntp_rc_t rc)
{
char *str;
@@ -337,10 +423,12 @@
if (rc == NNTP_OK ) str = "NNTP: no error";
else if (rc == NNTP_EOF ) str = "NNTP: end of file";
else if (rc == NNTP_TIMEOUT ) str = "NNTP: timeout";
+ else if (rc == NNTP_DEFER ) str = "NNTP: transmission deferred";
else if (rc == NNTP_ERR_SYSTEM ) str = "NNTP: see errno";
else if (rc == NNTP_ERR_ARG ) str = "NNTP: invalid argument";
else if (rc == NNTP_ERR_OVERFLOW) str = "NNTP: buffer overflow";
else if (rc == NNTP_ERR_POST ) str = "NNTP: cannot post message";
+ else if (rc == NNTP_ERR_INIT ) str = "NNTP: initialization failed";
return str;
}
|