*** /dev/null Sat Nov 23 02:02:36 2024
--- - Sat Nov 23 02:02:40 2024
***************
*** 0 ****
--- 1,173 ----
+ /*
+ * 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.
+ */
+
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include <ctype.h>
+ #include <errno.h>
+
+ #include "nntp.h"
+
+ /* 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 {
+ int rfd;
+ int wfd;
+ nntp_io_t io;
+ nntp_readline_t rl;
+ };
+
+ nntp_t *nntp_create(int rfd, int wfd, nntp_io_t *io)
+ {
+ nntp_t *nntp;
+
+ if ((nntp = (nntp_t *)malloc(sizeof(nntp_t))) == NULL)
+ return NULL;
+
+ if (io == NULL) {
+ nntp->io.read = read;
+ nntp->io.write = write;
+ } else {
+ nntp->io.read = io->read ? io->read : read;
+ nntp->io.write = io->write ? io->write : write;
+ }
+
+ nntp->rfd = rfd;
+ nntp->wfd = wfd;
+ nntp->rl.rl_cnt = 0;
+ nntp->rl.rl_bufptr = NULL;
+ nntp->rl.rl_buf[0] = '\0';
+
+ return nntp;
+ }
+
+ void nntp_destroy(nntp_t *nntp)
+ {
+ if (nntp != NULL)
+ free(nntp);
+ return;
+ }
+
+ 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->rfd, 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] = '\0'; /* 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->wfd, tmp, strlen(tmp)) < 0)
+ return NNTP_ERR_SYSTEM;
+ return NNTP_OK;
+ }
+
+ nntp_rc_t nntp_post(nntp_t *nntp, char *msg)
+ {
+ nntp_rc_t rc = NNTP_OK;
+ char line[NNTP_LINE_MAXLEN];
+
+ if ((rc = nntp_readline(nntp, line, sizeof(line))) != NNTP_OK)
+ return rc;
+ fprintf(stderr, "READ:<%s>\n", line);
+ if ((rc = nntp_writeline(nntp, "mode reader")) != NNTP_OK)
+ return rc;
+ fprintf(stderr, "WRITE:<mode reader>\n");
+ if ((rc = nntp_readline(nntp, line, sizeof(line))) != NNTP_OK)
+ return rc;
+ fprintf(stderr, "READ:<%s>\n", line);
+ if ((rc = nntp_writeline(nntp, "quit")) != NNTP_OK)
+ return rc;
+ fprintf(stderr, "WRITE:<quit>\n");
+ if ((rc = nntp_readline(nntp, line, sizeof(line))) != NNTP_OK)
+ return rc;
+ fprintf(stderr, "READ:<%s>\n", line);
+
+ return rc;
+ }
+
+ char *nntp_error(nntp_t *nntp, 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_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";
+ return str;
+ }
+
|