head 1.28;
access;
symbols
SOURCE_RESTRUCTURING_BEFORE:1.27
LMTP2NNTP_1_2a1:1.27
LMTP2NNTP_1_1_1:1.27
LMTP2NNTP_1_1_0:1.27
LMTP2NNTP_1_1b4:1.27
LMTP2NNTP_1_1b3:1.27
LMTP2NNTP_1_1b2:1.27
LMTP2NNTP_1_1b1:1.26
LMTP2NNTP_1_0_0:1.25
LMTP2NNTP_0_9_7:1.25
LMTP2NNTP_0_9_6:1.25
LMTP2NNTP_0_9_5:1.25
LMTP2NNTP_0_9_4:1.19
LMTP2NNTP_0_9_3:1.19
LMTP2NNTP_0_9_2:1.15
LMTP2NNTP_0_9_1:1.8
LMTP2NNTP_0_9_0:1.8;
locks; strict;
comment @ * @;
1.28
date 2001.12.31.11.09.53; author thl; state dead;
branches;
next 1.27;
1.27
date 2001.10.15.12.48.57; author thl; state Exp;
branches;
next 1.26;
1.26
date 2001.10.09.12.08.59; author rse; state Exp;
branches;
next 1.25;
1.25
date 2001.09.11.13.38.07; author thl; state Exp;
branches;
next 1.24;
1.24
date 2001.09.10.14.11.33; author thl; state Exp;
branches;
next 1.23;
1.23
date 2001.09.10.12.48.14; author thl; state Exp;
branches;
next 1.22;
1.22
date 2001.09.10.10.15.26; author thl; state Exp;
branches;
next 1.21;
1.21
date 2001.09.07.15.02.08; author thl; state Exp;
branches;
next 1.20;
1.20
date 2001.09.04.09.46.06; author rse; state Exp;
branches;
next 1.19;
1.19
date 2001.08.28.12.49.33; author thl; state Exp;
branches;
next 1.18;
1.18
date 2001.08.27.14.49.32; author thl; state Exp;
branches;
next 1.17;
1.17
date 2001.08.27.14.29.11; author thl; state Exp;
branches;
next 1.16;
1.16
date 2001.08.27.14.25.33; author thl; state Exp;
branches;
next 1.15;
1.15
date 2001.08.23.09.12.30; author rse; state Exp;
branches;
next 1.14;
1.14
date 2001.08.23.09.00.22; author rse; state Exp;
branches;
next 1.13;
1.13
date 2001.08.23.08.36.16; author rse; state Exp;
branches;
next 1.12;
1.12
date 2001.08.23.08.10.12; author rse; state Exp;
branches;
next 1.11;
1.11
date 2001.08.23.07.52.25; author thl; state Exp;
branches;
next 1.10;
1.10
date 2001.08.23.07.50.42; author thl; state Exp;
branches;
next 1.9;
1.9
date 2001.08.21.07.40.41; author thl; state Exp;
branches;
next 1.8;
1.8
date 2001.08.16.15.00.50; author thl; state Exp;
branches;
next 1.7;
1.7
date 2001.08.14.14.42.41; author thl; state Exp;
branches;
next 1.6;
1.6
date 2001.08.14.08.15.25; author thl; state Exp;
branches;
next 1.5;
1.5
date 2001.08.13.15.16.32; author thl; state Exp;
branches;
next 1.4;
1.4
date 2001.08.13.06.41.42; author thl; state Exp;
branches;
next 1.3;
1.3
date 2001.08.07.09.05.55; author thl; state Exp;
branches;
next 1.2;
1.2
date 2001.08.02.14.58.39; author thl; state Exp;
branches;
next 1.1;
1.1
date 2001.08.01.07.04.13; author thl; state Exp;
branches;
next ;
desc
@@
1.28
log
@Mega-Commit: Finally restructure the lmtp2nntp source tree in order to clean
it up. We especially use a consistent prefix for all inlined sources.
@
text
@/*
** Copyright (c) 2001 The OSSP Project
** Copyright (c) 2001 Cable & Wireless Deutschland
**
** This file is part of OSSP lmtp2nntp, an LMTP speaking local
** mailer which forwards mails as Usenet news articles via NNTP.
** It can be found at http://www.ossp.org/pkg/lmtp2nntp/.
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version
** 2.0 of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this file; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA, or contact the OSSP project .
**
** nntp.c: Network News Transfer Protocol (NNTP) client library
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "nntp.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if defined(HAVE_DMALLOC_H) && defined(DMALLOC)
#include "dmalloc.h"
#endif
#ifndef FALSE
#define FALSE (1 != 1)
#endif
#ifndef TRUE
#define TRUE (!FALSE)
#endif
#ifndef NUL
#define NUL '\0'
#endif
/* maximum NNTP protocol line length */
#define NNTP_LINE_MAXLEN 1024
typedef struct {
int rl_cnt;
char *rl_bufptr;
char rl_buf[NNTP_LINE_MAXLEN];
} nntp_readline_t;
struct nntp_st {
nntp_io_t io;
nntp_readline_t rl;
struct timeval tv;
int kludgeinn441dup;
char *lastresp;
};
ssize_t nntp_fd_read(void *_ctx, void *buf, size_t buflen)
{
nntp_fd_t *ctx = (nntp_fd_t *)_ctx;
return read(ctx->fd, buf, buflen);
}
ssize_t nntp_fd_write(void *_ctx, const void *buf, size_t buflen)
{
nntp_fd_t *ctx = (nntp_fd_t *)_ctx;
return write(ctx->fd, buf, buflen);
}
nntp_t *nntp_create(nntp_io_t *io)
{
nntp_t *nntp;
if ((nntp = (nntp_t *)malloc(sizeof(nntp_t))) == NULL)
return NULL;
if (io == NULL)
return NULL;
nntp->io.ctx = io->ctx;
nntp->io.read = io->read;
nntp->io.write = io->write;
nntp->rl.rl_cnt = 0;
nntp->rl.rl_bufptr = NULL;
nntp->rl.rl_buf[0] = NUL;
nntp->kludgeinn441dup = FALSE;
nntp->lastresp = NULL;
return nntp;
}
nntp_rc_t nntp_init(nntp_t *nntp)
{
nntp_rc_t rc;
char line[NNTP_LINE_MAXLEN];
/* RFC0977 2.4.3. General Responses
* In general, 1xx codes may be ignored or displayed as desired; code 200
* or 201 is sent upon initial connection to the NNTP server depending
* upon posting permission; code 400 will be sent when the NNTP server
* discontinues service (by operator request, for example); and 5xx codes
* indicate that the command could not be performed for some unusual
* reason.
*
* 1xx text
* 200 server ready - posting allowed
* 201 server ready - no posting allowed
* 400 service discontinued
* 500 command not recognized
* 501 command syntax error
* 502 access restriction or permission denied
* 503 program fault - command not performed
*/
do {
if ((rc = nntp_readline(nntp, line, sizeof(line))) != NNTP_OK) {
return rc;
}
} while (line[0] == '1');
/* 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 (strncmp(line, "200", 3) == 0 && strstr(line, " INN ") != NULL) {
nntp->kludgeinn441dup = TRUE;
}
else {
nntp->kludgeinn441dup = FALSE;
}
if (strncmp(line, "200", 3) == 0)
return NNTP_OK;
return NNTP_ERR_INIT;
}
void nntp_destroy(nntp_t *nntp)
{
if (nntp != NULL) {
if (nntp->lastresp != NULL)
free(nntp->lastresp);
free(nntp);
}
return;
}
char *nntp_lastresp(nntp_t *nntp)
{
if (nntp == NULL)
return "";
if(nntp->lastresp == NULL)
return "";
return nntp->lastresp;
}
nntp_rc_t nntp_readline(nntp_t *nntp, char *buf, size_t buflen)
{
/* read a line (characters until NL) from input stream */
size_t n;
char c;
nntp_readline_t *rl = &nntp->rl;
if (nntp == NULL)
return NNTP_ERR_ARG;
for (n = 0; n < buflen-1;) {
/* fetch one character (but read more) */
if (rl->rl_cnt <= 0) {
do {
rl->rl_cnt = nntp->io.read(nntp->io.ctx, rl->rl_buf, NNTP_LINE_MAXLEN);
} while (rl->rl_cnt == -1 && errno == EINTR);
if (rl->rl_cnt == -1)
return NNTP_ERR_SYSTEM;
if (rl->rl_cnt == 0)
return NNTP_EOF;
rl->rl_bufptr = rl->rl_buf;
}
/* act on fetched character */
rl->rl_cnt--;
c = *rl->rl_bufptr++;
if (c == '\r')
continue; /* skip copying CR */
if (c == '\n')
break; /* end of line */
buf[n++] = c; /* output char into given buffer */
}
buf[n] = NUL; /* string termination */
if (n == (buflen-1))
return NNTP_ERR_OVERFLOW;
return NNTP_OK;
}
nntp_rc_t nntp_writeline(nntp_t *nntp, char *buf)
{
char tmp[NNTP_LINE_MAXLEN];
if (nntp == NULL)
return NNTP_ERR_ARG;
strncpy(tmp, buf, NNTP_LINE_MAXLEN-3);
strcat(tmp, "\r\n");
if (nntp->io.write(nntp->io.ctx, tmp, strlen(tmp)) < 0)
return NNTP_ERR_SYSTEM;
return NNTP_OK;
}
nntp_rc_t nntp_post(nntp_t *nntp, msg_t *msg)
{
nntp_rc_t rc = NNTP_OK;
char line[NNTP_LINE_MAXLEN];
/* RFC2980
*
* 2.3 MODE READER
* MODE READER is used by the client to indicate to the server that it is
* a news reading client. Some implementations make use of this
* information to reconfigure themselves for better performance in
* responding to news reader commands. This command can be contrasted
* with the SLAVE command in RFC0977, which was not widely implemented.
* MODE READER was first available in INN.
*
* 2.3.1 Responses
* 200 Hello, you can post
* 201 Hello, you can't post
*
* Research:
*
* < 200 dev16 InterNetNews server INN 2.3.2 ready
* > POST
* < 500 "post" not implemented; try "help".
* > MODE READER
* < 200 dev16 InterNetNews NNRP server INN 2.3.2 ready (posting ok).
* > POST
* < 340 Ok, recommended ID <...>
*
* In other words, INN *requires* the use of "MODE READER". This has been
* verified when INN is configured for expecting both news readers and
* feeders from a given source address. When INN is configured to expect
* readers only for a given source address the use of "MODE READER" is
* optional.
*/
*line = NUL;
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;
/* 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
* about the RFC2980 "MODE READER" command. But any other response is not
* expected and we treat this as an error.
*/
if (strncmp(line, "201", 3) == 0)
CU(NNTP_ERR_DELIVERY);
if ( strncmp(line, "200", 3) != 0
&& strncmp(line, "5" , 1) != 0
)
CU(NNTP_ERR_DELIVERY);
/* check if this server already knows that artice
* > STAT
* < 223 yes, article already known
* < 430 no, i don't know the article, yet
*/
*line = NUL;
strcat(line, "STAT ");
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, "223", 3) == 0)
return NNTP_OK;
if (strncmp(line, "430", 3) != 0)
CU(NNTP_ERR_DELIVERY);
/* post the article
* > POST
* < 340 gimme that thing
* > From: ...
* > Subject: ...
* > Newsgroups: ...
* > Message-ID: <...>
* > [additional headers]
* >
* > [body with dots escaped]
* > .
* < 240 ok, thank you
* < 441 duplicate (ok for us)
*
* Research:
*
* < 200 dev16 InterNetNews server INN 2.3.2 ready
* > POST
* [...]
* 240 Article posted <...>
* 441 435 Duplicate
* 441 437 Too old
* 441 Duplicate "Newsgroups" header
* 441 Required "Subject" header is missing
* 441 Obsolete "Received" header
* 441 Line # too long
*
* In other words, INN uses 441 for other status messages as well.
*/
*line = NUL;
strcat(line, "POST");
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, "340", 3) != 0)
CU(NNTP_ERR_DELIVERY);
do {
rc = nntp->io.write(nntp->io.ctx, msg->cpMsg, strlen(msg->cpMsg));
} while (rc == -1 && errno == EINTR);
if (rc == -1)
return NNTP_ERR_SYSTEM;
if ((rc = nntp_readline(nntp, line, sizeof(line))) != NNTP_OK)
return rc;
if (strncmp(line, "240", 3) == 0)
return NNTP_OK;
if (nntp->kludgeinn441dup) {
if (strncmp(line, "441 435", 7) == 0)
return NNTP_OK;
}
else {
if (strncmp(line, "441", 3) == 0)
return NNTP_OK;
}
CU(NNTP_ERR_DELIVERY);
CUS:
nntp->lastresp = strdup(line);
return rc;
}
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 .
* < 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
* < 335 [no text; this number means positive response]
* < 435 Duplicate
* < 437 Missing "Path" header
* < 437 Unwanted newsgroup "quux"
* < 480 Transfer permission denied
*/
*line = NUL;
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)
|| (strncmp(line, "480", 3) == 0))
CU(NNTP_ERR_DELIVERY);
if (strncmp(line, "335", 3) != 0)
CU(NNTP_ERR_DELIVERY);
do {
rc = nntp->io.write(nntp->io.ctx, msg->cpMsg, strlen(msg->cpMsg));
} while (rc == -1 && errno == EINTR);
if (rc == -1)
return NNTP_ERR_SYSTEM;
if ((rc = nntp_readline(nntp, line, sizeof(line))) != NNTP_OK)
return rc;
if (strncmp(line, "235", 3) == 0)
return NNTP_OK;
if (strncmp(line, "436", 3) == 0)
return NNTP_DEFER;
CU(NNTP_ERR_DELIVERY);
CUS:
nntp->lastresp = strdup(line);
return rc;
}
char *nntp_error(nntp_rc_t rc)
{
char *str;
str = "NNTP: errorcode has no description";
if (rc == NNTP_OK ) str = "NNTP: no error";
else if (rc == NNTP_EOF ) str = "NNTP: end of file";
else if (rc == NNTP_DEFER ) str = "NNTP: transmission deferred";
else if (rc == NNTP_FAKE ) str = "NNTP: fake status not real";
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_DELIVERY) str = "NNTP: cannot deliver message";
else if (rc == NNTP_ERR_INIT ) str = "NNTP: initialization failed";
else if (rc == NNTP_ERR_UNKNOWN ) str = "NNTP: unknown error";
return str;
}
@
1.27
log
@Remember text from last NNTP error message and pass it back to LMTP
@
text
@@
1.26
log
@- Change NNTP library to fully use OSSP SA.
- Removed timeout handling from NNTP library and use SA timeouts instead.
@
text
@d70 1
d101 1
d154 3
a156 1
if (nntp != NULL)
d158 1
d162 9
d271 1
a271 1
return NNTP_ERR_DELIVERY;
d275 1
a275 1
return NNTP_ERR_DELIVERY;
d292 1
a292 1
return NNTP_ERR_DELIVERY;
d330 1
a330 1
return NNTP_ERR_DELIVERY;
d353 5
a357 1
return NNTP_ERR_DELIVERY;
d398 1
a398 1
return NNTP_ERR_DELIVERY;
d401 1
a401 1
return NNTP_ERR_DELIVERY;
d418 5
a422 1
return NNTP_ERR_DELIVERY;
@
1.25
log
@we do no longer care about checking groups
@
text
@a65 2
int rfd;
int wfd;
d72 1
a72 1
static int nntp_select(void *ctx, int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
d74 2
a75 1
return select(nfds, rfds, wfds, efds, tv);
d78 1
a78 1
static ssize_t nntp_read(void *ctx, int fd, void *buf, size_t buflen)
d80 2
a81 1
return read(fd, buf, buflen);
d84 1
a84 6
static ssize_t nntp_write(void *ctx, int fd, const void *buf, size_t buflen)
{
return write(fd, buf, buflen);
}
nntp_t *nntp_create(int rfd, int wfd, nntp_io_t *io)
d91 5
a95 14
if (io == NULL) {
nntp->io.ctx = NULL;
nntp->io.select = nntp_select;
nntp->io.read = nntp_read;
nntp->io.write = nntp_write;
} else {
nntp->io.ctx = io->ctx;
nntp->io.select = io->select ? io->select : nntp_select;
nntp->io.read = io->read ? io->read : nntp_read;
nntp->io.write = io->write ? io->write : nntp_write;
}
nntp->rfd = rfd;
nntp->wfd = wfd;
a98 1
nntp_timeout(nntp, 3);
a103 7
nntp_rc_t nntp_timeout(nntp_t *nntp, long timeout)
{
nntp->tv.tv_sec = timeout;
nntp->tv.tv_usec = 0;
return NNTP_OK;
}
a162 3
struct timeval tv;
fd_set fds;
int rc;
a169 9
FD_ZERO(&fds);
FD_SET(nntp->rfd, &fds);
tv.tv_sec = nntp->tv.tv_sec;
tv.tv_usec = nntp->tv.tv_usec;
rc = nntp->io.select(nntp->io.ctx, nntp->rfd + 1, &fds, NULL, NULL, &tv);
if (rc == 0)
return NNTP_TIMEOUT;
else if (rc == -1)
return NNTP_ERR_SYSTEM;
d171 1
a171 1
rl->rl_cnt = nntp->io.read(nntp->io.ctx, nntp->rfd, rl->rl_buf, NNTP_LINE_MAXLEN);
d204 1
a204 1
if (nntp->io.write(nntp->io.ctx, nntp->wfd, tmp, strlen(tmp)) < 0)
d319 1
a319 1
rc = nntp->io.write(nntp->io.ctx, nntp->wfd, msg->cpMsg, strlen(msg->cpMsg));
d386 1
a386 1
rc = nntp->io.write(nntp->io.ctx, nntp->wfd, msg->cpMsg, strlen(msg->cpMsg));
a408 1
else if (rc == NNTP_TIMEOUT ) str = "NNTP: timeout";
@
1.24
log
@fake mode now supports NTTP-less setups
@
text
@a373 9
#if 0
/* check if this server accepts at least one of the newsgroups
> GROUP
< 211 yes, group exists
< 411 no, group doesn't exist
*/
#endif
@
1.23
log
@POST really should be called DELIVERY as we support posting and feeding
@
text
@d454 1
@
1.22
log
@Str is not used here
@
text
@d291 1
a291 1
return NNTP_ERR_POST;
d295 1
a295 1
return NNTP_ERR_POST;
d312 1
a312 1
return NNTP_ERR_POST;
d350 1
a350 1
return NNTP_ERR_POST;
d373 1
a373 1
return NNTP_ERR_POST;
d423 1
a423 1
return NNTP_ERR_POST;
d426 1
a426 1
return NNTP_ERR_POST;
d443 1
a443 1
return NNTP_ERR_POST;
d457 1
a457 1
else if (rc == NNTP_ERR_POST ) str = "NNTP: cannot post message";
@
1.21
log
@Replace ad-hoc tracing with L2_LEVEL_TRACE based approach.
@
text
@a36 1
#include "str.h"
@
1.20
log
@Finally apply GNU General Public License (GPL) to OSSP lmtp2nntp.
@
text
@d75 15
d98 4
a101 3
nntp->io.select = select;
nntp->io.read = read;
nntp->io.write = write;
d103 4
a106 3
nntp->io.select = io->select ? io->select : select;
nntp->io.read = io->read ? io->read : read;
nntp->io.write = io->write ? io->write : write;
d200 1
a200 1
rc = nntp->io.select(nntp->rfd + 1, &fds, NULL, NULL, &tv);
d206 1
a206 1
rl->rl_cnt = nntp->io.read(nntp->rfd, rl->rl_buf, NNTP_LINE_MAXLEN);
d239 1
a239 1
if (nntp->io.write(nntp->wfd, tmp, strlen(tmp)) < 0)
d354 1
a354 1
rc = nntp->io.write(nntp->wfd, msg->cpMsg, strlen(msg->cpMsg));
d430 1
a430 1
rc = nntp->io.write(nntp->wfd, msg->cpMsg, strlen(msg->cpMsg));
@
1.19
log
@news regarding INNs MODE READER behavior and 441 returns
@
text
@d2 24
a25 27
* nntp.c: NNTP library (implementation)
*
* Copyright (c) 2001 The OSSP Project (http://www.ossp.org/)
* Copyright (c) 2001 Cable & Wireless Deutschland (http://www.cw.com/de/)
*
* This file is part of OSSP lmtp2nntp, an NNTP speaking local
* mailer which forwards mails as Usenet news articles via NNTP.
* It can be found at http://www.ossp.com/pkg/lmtp2nntp/.
*
* Permission to use, copy, modify, and distribute this software for
* any purpose with or without fee is hereby granted, provided that
* the above copyright notice and this permission notice appear in all
* copies.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
@
1.18
log
@now using NUL instead of '\0'
@
text
@d144 1
a144 1
* server INN 2.3.2 ready (posting * ok)."
d259 5
a263 1
* In other words, INN *requires* the use of "MODE READER".
d326 1
@
1.17
log
@removed DEBUGs; updated 00TODO;
@
text
@d56 4
d99 1
a99 1
nntp->rl.rl_buf[0] = '\0';
d211 1
a211 1
buf[n] = '\0'; /* string termination */
d261 1
a261 1
*line = '\0';
d285 1
a285 1
*line = '\0';
d325 1
a325 1
*line = '\0';
d388 1
a388 1
*line = '\0';
@
1.16
log
@removed ==TRUE and !=TRUE comparisons in favor of ==FALSE, !=FALSE and boolean expressions
@
text
@a133 1
/*fprintf(stderr, "DEBUG: nntp_readline returned ***%d***\n", rc); */
a137 2
/*fprintf(stderr, "DEBUG: nntp_readline got ***%s***\n", line); */
a143 1
/*fprintf(stderr, "DEBUG: INN kludge activated!\n"); */
a146 1
/*fprintf(stderr, "DEBUG: no INN kludge!\n"); */
a209 1
/*fprintf(stderr, "DEBUG: nntp_readline <<<%s\n", buf); */
a220 1
/*fprintf(stderr, "DEBUG: nntp_writeline >>>%s", tmp); */
a337 1
/*fprintf(stderr, "DEBUG: answer to post = ***%s***, rc = %s\n", line, nntp_error(rc)); */
a413 1
/*fprintf(stderr, "DEBUG: answer to post = ***%s***, rc = %s\n", line, nntp_error(rc)); */
@
1.15
log
@Add DMalloc support
@
text
@d350 1
a350 1
if (nntp->kludgeinn441dup == TRUE) {
@
1.14
log
@Ops, no assignment! A comparison, of course.
@
text
@d42 7
@
1.13
log
@remove dependency to Str library
@
text
@d332 1
a332 1
} while (rc == -1 && errno = EINTR);
d409 1
a409 1
} while (rc == -1 && errno = EINTR);
@
1.12
log
@remove fixmes
@
text
@d138 1
a138 1
if (str_parse(line, "m/^200.*\\sINN\\s/")) {
@
1.11
log
@added NNTP_ERR_UNKNOWN which is useful for injecting artifical errors when debugging
@
text
@d330 4
a333 1
if ((rc = nntp->io.write(nntp->wfd, msg->cpMsg, strlen(msg->cpMsg))) < 0) /*FIXME while() wrapper around write required */
d407 4
a410 1
if ((rc = nntp->io.write(nntp->wfd, msg->cpMsg, strlen(msg->cpMsg))) < 0) /*FIXME while() wrapper around write required */
@
1.10
log
@fixed style vs. optimization
@
text
@d433 1
@
1.9
log
@replaced c++ style // comments with c style /* */ comments
@
text
@d231 1
a231 1
/* RFC 2980
d238 1
a238 1
* with the SLAVE command in RFC 977, which was not widely implemented.
d397 5
a401 4
if ( (strncmp(line, "437", 3) == 0) /*FIXME style vs. optimization - redundant lines */
|| (strncmp(line, "480", 3) == 0)
|| (strncmp(line, "335", 3) != 0)
)
@
1.8
log
@INN kludge, IHAVE feeding, -d deliverymode command line option, DEFER handing
@
text
@d127 1
a127 1
//fprintf(stderr, "DEBUG: nntp_readline returned ***%d***\n", rc);
d132 1
a132 1
//fprintf(stderr, "DEBUG: nntp_readline got ***%s***\n", line);
d140 1
a140 1
//fprintf(stderr, "DEBUG: INN kludge activated!\n");
d144 1
a144 1
//fprintf(stderr, "DEBUG: no INN kludge!\n");
d208 1
a208 1
//fprintf(stderr, "DEBUG: nntp_readline <<<%s\n", buf);
d220 1
a220 1
//fprintf(stderr, "DEBUG: nntp_writeline >>>%s", tmp);
d330 1
a330 1
if ((rc = nntp->io.write(nntp->wfd, msg->cpMsg, strlen(msg->cpMsg))) < 0) //FIXME while() wrapper around write required
d335 1
a335 1
//fprintf(stderr, "DEBUG: answer to post = ***%s***, rc = %s\n", line, nntp_error(rc));
d397 1
a397 1
if ( (strncmp(line, "437", 3) == 0) //FIXME style vs. optimization - redundant lines
d403 1
a403 1
if ((rc = nntp->io.write(nntp->wfd, msg->cpMsg, strlen(msg->cpMsg))) < 0) //FIXME while() wrapper around write required
d408 1
a408 1
//fprintf(stderr, "DEBUG: answer to post = ***%s***, rc = %s\n", line, nntp_error(rc));
@
1.7
log
@connected LMTP and NNTP side, now featuring all three -g groupmodes, added post1000 articles burn-in
@
text
@d40 8
d64 1
d90 1
d134 13
a256 1
//fprintf(stderr, "DEBUG: before MODE READER\n");
a262 1
//fprintf(stderr, "DEBUG: after MODE READER\n");
a326 2
if (strncmp(line, "xxx", 3) == 0)
return NNTP_OK;
d336 2
a337 3
if ( (strncmp(line, "240", 3) == 0)
|| (strncmp(line, "441", 3) == 0)
)
d339 10
d361 58
d426 1
d431 1
@
1.6
log
@cleanup msg.[ch], moved tracing to trace.[ch], added target to Makefile, added -t switch in lmtp2nntp.[c|pod], incorporated tracing into lmtp.[ch] and nntp.[ch], run.sh now using new tracing option
@
text
@d234 1
d241 1
a259 1
#if 0
a270 1
#endif
d296 1
d316 1
a316 1
//fprintf(stderr, "DEBUG: answer to post = ***%s***, rc = %s\n", line, nntp_error(nntp, rc));
d333 1
a333 1
char *nntp_error(nntp_t *nntp, nntp_rc_t rc)
@
1.5
log
@first successful posting
@
text
@d117 1
a117 1
fprintf(stderr, "DEBUG: nntp_readline returned ***%d***\n", rc);
d122 1
a122 1
// fprintf(stderr, "DEBUG: nntp_readline got ***%s***\n", line);
d185 1
a185 1
fprintf(stderr, "DEBUG: nntp_readline <<<%s\n", buf);
d197 1
a197 1
fprintf(stderr, "DEBUG: nntp_writeline >>>%s", tmp);
d315 1
a315 1
fprintf(stderr, "DEBUG: answer to post = ***%s***, rc = %s\n", line, nntp_error(nntp, rc));
@
1.4
log
@moved message issues from lmtp2nntp.[ch] and nntp.[ch] into separate new file msg.[ch]
@
text
@d185 1
a185 1
fprintf(stderr, "DEBUG: nntp_readline >>>%s\n", buf);
d208 45
d258 1
d269 2
a270 1
return NNTP_ERR_POSTPERM; //FIXME
d285 13
d300 1
a300 2
strcat(line, "POST ");
strcat(line, msg->cpMsgid);
d308 1
a308 1
return NNTP_ERR_POSTPERM; //FIXME
d310 1
a310 2
fprintf(stderr, "DEBUG: before write ***%s***(%d)\n", msg->cpMsg, strlen(msg->cpMsg));
if ((rc = nntp->io.write(nntp->wfd, msg->cpMsg, strlen(msg->cpMsg))) < 0)
a311 1
fprintf(stderr, "DEBUG: after write, written = %i\n", rc);
a312 14
{//DEBUG paragraph
int i;
char buf[NNTP_LINE_MAXLEN];
fprintf(stderr, "DEBUG: before writeline\n");
if ((rc = nntp_writeline(nntp, "\r\n.\r\nHELP\r\n")) != NNTP_OK);
fprintf(stderr, "DEBUG: writeline returned %d\n", rc);
fprintf(stderr, "DEBUG: before io.read(%d, ..., %d)\n", nntp->rfd, NNTP_LINE_MAXLEN);
i = nntp->io.read(nntp->rfd, &buf, NNTP_LINE_MAXLEN);
fprintf(stderr, "DEBUG: io.read = ***%s***, rc = %d\n", buf, i);
for (i=0; i<10; i++) {
d314 1
a314 1
; //return rc;
d316 5
a320 3
};
}
return NNTP_OK;
d342 1
@
1.3
log
@lmtp/nntp joined at command args and lhlo
@
text
@d185 1
d197 1
d203 1
a203 1
nntp_rc_t nntp_post(nntp_t *nntp, char *msg)
d208 10
d220 23
a242 2
fprintf(stderr, "READ:<%s>\n", line);
if ((rc = nntp_writeline(nntp, "mode reader")) != NNTP_OK)
a243 1
fprintf(stderr, "WRITE:\n");
d246 24
a269 4
fprintf(stderr, "READ:<%s>\n", line);
if ((rc = nntp_writeline(nntp, "quit")) != NNTP_OK)
return rc;
fprintf(stderr, "WRITE:\n");
d271 5
a275 2
return rc;
fprintf(stderr, "READ:<%s>\n", line);
d277 1
a277 5
#if 0 //FIXME
allservers = x; /* total number of servers specified */
deliveries = 0; /* counts successful deliveries */
for (i=0; i < allservers; i++) {
if (post() == NNTP_OK) {
a283 28
/* check if this server already knows that artice
> STAT
< 223 yes, article already known
< 430 no, i don't know the article, yet
*/
/* post the article
> POST
< 340 gimme that thing
> From: ...
> Subject: ...
> Newsgroups: ...
> Message-ID: <...>
> [additional headers]
>
> [body with dots escaped]
> .
< 240 ok, thank you
< 441 duplicate (ok for us)
*/
}
}
if (((mode == DELIVERYMODE_MANY) || (mode == DELIVERYMODE_ONCE)) && (deliveries >= 1))
rc = NNTP_OK;
else if ((mode == DELIVERYMODE_ALL) && (deliveries == allservers))
rc = NNTP_OK
else
rc = NNTP_ERR_POST;
a284 1
return rc;
@
1.2
log
@no more dummy-OKs on the lmtp side, some first steps on the nntp side
@
text
@d36 2
d55 1
a60 1
char line[NNTP_LINE_MAXLEN];
d66 3
a68 2
nntp->io.read = read;
nntp->io.write = write;
d70 3
a72 2
nntp->io.read = io->read ? io->read : read;
nntp->io.write = io->write ? io->write : write;
d80 1
d85 7
a91 1
#if 0 //FIXME
d95 1
d116 2
a117 1
if ((rc = nntp_readline(nntp, line, sizeof(line))) != NNTP_OK)
d119 5
a123 1
while (line[0] == '1');
a128 1
#endif
d143 3
d153 9
d271 1
@
1.1
log
@first client using sock.[ch]. Just connects, reads, writes and quits
@
text
@d58 1
d80 34
d194 40
@