OSSP CVS Repository

ossp - Check-in [542]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 542
Date: 2001-Jul-17 14:40:06 (local)
2001-Jul-17 12:40:06 (UTC)
User:thl
Branch:
Comment: ralf s. engelschall first api draft
Tickets:
Inspections:
Files:
ossp-pkg/lmtp2nntp/.cvsignore      1.1 -> 1.2     1 inserted, 1 deleted
ossp-pkg/lmtp2nntp/00TODO      1.1 -> 1.2     31 inserted, 2 deleted
ossp-pkg/lmtp2nntp/lmtp.c      added-> 1.1
ossp-pkg/lmtp2nntp/lmtp.h      added-> 1.1
ossp-pkg/lmtp2nntp/lmtp2nntp.c      added-> 1.1
ossp-pkg/lmtp2nntp/lmtp2nntp.pod      added-> 1.1

ossp-pkg/lmtp2nntp/.cvsignore 1.1 -> 1.2

--- .cvsignore   2001/07/16 12:18:09     1.1
+++ .cvsignore   2001/07/17 12:40:06     1.2
@@ -1,2 +1,2 @@
-mail2nntp
+lmtp2nntp
 research


ossp-pkg/lmtp2nntp/00TODO 1.1 -> 1.2

--- 00TODO       2001/07/16 12:12:21     1.1
+++ 00TODO       2001/07/17 12:40:06     1.2
@@ -3,13 +3,42 @@
 
 RESULT:
 - robust checking and handling of NNTP protocol errors
-- logging into a single file -> write(2) !fwrite(3)
+        - logging into a single file -> write(2) !fwrite(3)
 - invoked as mailer using LMTP, providing useful return status
 - invoked as command line (lowpri)
 - queuing is not supported for command line and a client issue for LMTP
 - remove To: and Cc: headers
 - allow crosspostings only through command line
 - new manpage
-- (optional) syslog
+        - (optional) syslog
 - command line choice for sending "exactly once" or "at least once" (default)
 
+   **** SMTP ENGINE ****
+
+[RFC821, 4.5.1. MINIMUM IMPLEMENTATION]
+In order to make SMTP workable, the following minimum implementation is required for all receivers:
+[RFC821, 4.1.2. COMMAND SYNTAX]
+
+Verb Parameter                         Buffer
+----+---------------------------------+-------------------
+HELO <SP> <domain> <CRLF>
+MAIL <SP> FROM:<reverse-path> <CRLF>   (char *)sender
+RCPT <SP> TO:<forward-path> <CRLF>     (char **)recipients
+DATA <CRLF>                            (char *)message
+RSET <CRLF>
+NOOP <CRLF>
+QUIT <CRLF>
+
+
+State Function Continue
+-----+--------+-----------------
+  0    wait()   LHLO > 1, MAIL > 2
+  1    wait()   MAIL > 2
+  2    wait()   RCPT > 3
+  3    wait()   RCPT > 3, DATA > 4
+  4    data()   >1
+
+  x    wait()   RSET > 1
+  x    wait()   NOOP > x
+  x    wait()   QUIT > exit
+


ossp-pkg/lmtp2nntp/lmtp.c -> 1.1

*** /dev/null    Mon Oct  3 22:15:36 2022
--- -    Mon Oct  3 22:15:40 2022
***************
*** 0 ****
--- 1,128 ----
+ 
+ #include <stdlib.h>
+ 
+ #include "lmtp.h"
+ #include "lmtp_p.h"
+ 
+ static int readline(lmtp_readline_t *rl, int fd, char *buf, size_t buflen)
+ {
+     size_t n;
+     ssize_t rc;
+     char c = '\0', *cp;
+ 
+     cp = (char *)buf;
+     for (n = 1; n < buflen; n++) {
+ 
+         /* fetch one character (but read more) */
+         rc = 1;
+         if (rl->rl_cnt <= 0) {
+             if ((rl->rl_cnt = rl->rl_read(fd, rl->rl_buf, LMTP_READLINE_MAXLEN)) < 0)
+                 rc = -1;
+             else if (rl->rl_cnt == 0)
+                 rc = 0;
+             else
+                 rl->rl_bufptr = rl->rl_buf;
+         }
+         if (rc == 1) {
+             rl->rl_cnt--;
+             c = *rl->rl_bufptr++;
+         }
+ 
+         /* act on fetched character */
+         if (rc == 1) {
+             if (c == '\r') {
+                 n--;
+                 continue;
+             }
+             *cp++ = c;
+             if (c == '\n')
+                 break;
+         }
+         else if (rc == 0) {
+             if (n == 1)
+                 return 0;
+             else
+                 break;
+         }
+         else
+             return -1;
+     }
+     *cp = '\0';
+     return n;
+ }
+ 
+ lmtp_t *lmtp_create(int rfd, int wfd, lmtp_io_t *io)
+ {
+     lmtp_t *lmtp = NULL;
+ 
+     if ((lmtp = (lmtp_t *)malloc(sizeof(lmtp_t))) == NULL) 
+         return NULL;
+     lmtp->io.select = select;
+     lmtp->io.read = read;
+     lmtp->io.write = write;
+     lmtp->rl.rl_cnt = 0;
+     lmtp->rl.rl_bufptr = NULL;
+     lmtp->rl.rl_read = lmtp->io.read;
+     /* lmtp->dispatch = ... */
+     return lmtp;
+ }
+ 
+ void lmtp_destroy(lmtp_t *lmtp)
+ {
+     return;
+ }
+ 
+ lmtp_rc_t lmtp_request(lmtp_t *lmtp, lmtp_req_t *req)
+ {
+     lmtp_rc_t rc = LMTP_OK;
+     return rc;
+ }
+ 
+ lmtp_rc_t lmtp_result(lmtp_t *lmtp, lmtp_res_t *res)
+ {
+     lmtp_rc_t rc = LMTP_OK;
+     return rc;
+ }
+ 
+ char **lmtp_message(lmtp_t *lmtp, char *verb)
+ {
+     char **cpp = NULL;
+     return cpp;
+ }
+ 
+ void lmtp_reset(lmtp_t *lmtp)
+ {
+     return;
+ }
+ 
+ char *lmtp_error(lmtp_t *lmtp, lmtp_rc_t rc)
+ {
+     char *str = NULL;
+     return str;
+ }
+ 
+ lmtp_cb_t lmtp_register(lmtp_t *lmtp, char *verb, lmtp_type_t type, lmtp_cb_t *cb, void *ctx)
+ {
+     lmtp_cb_t old = NULL;
+     return old;
+ }
+ 
+ lmtp_rc_t lmtp_loop(lmtp_t *lmtp)
+ {
+     lmtp_req_t req;
+     lmtp_res_t res;
+     lmtp_rc_t rc;
+     int i;
+ 
+     while ((rc = lmtp_request(lmtp, &req)) == LMTP_OK) {
+         for (i = 0; lmtp->dispatch[i]->verb != NULL; i++) {
+             if (strcmp(req.verb, lmtp->dispatch[i]->verb) == 0) {
+                 lmtp->dispatch[i]->cb(&lmtp->io, &req, &res, lmtp->dispatch[i]->cbctx);
+                 if ((rc = lmtp_result(lmtp, &res)) != LMTP_OK)
+                     return rc;
+             }
+         }
+     }
+     return rc;
+ }
+ 


ossp-pkg/lmtp2nntp/lmtp.h -> 1.1

*** /dev/null    Mon Oct  3 22:15:36 2022
--- -    Mon Oct  3 22:15:40 2022
***************
*** 0 ****
--- 1,52 ----
+ #ifndef __LMTP_H__
+ #define __LMTP_H__
+ 
+ #include <sys/types.h>
+ #include <sys/uio.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ 
+ struct lmtp_st;
+ typedef struct lmtp_st lmtp_t;
+ 
+ typedef struct {
+     int     (*select)(int nfds, fd_set *rfds, fd_set *wrfds, fd_set *efds, struct timeval *t);
+     ssize_t (*read)  (int fd, void *buf, size_t nbytes);
+     ssize_t (*write) (int fd, const void *buf, size_t nbytes);
+ } lmtp_io_t;
+ 
+ typedef struct {
+     char *verb;
+     char *msg;
+ } lmtp_req_t;
+ 
+ typedef struct {
+     int rc;
+     char *dsn;
+     char *msg;
+ } lmtp_res_t;
+ 
+ typedef enum {
+     LMTP_OK,
+     LMTP_ERR_SYSTEM, /* see errno */
+     LMTP_ERR_INVALID_VERB
+ } lmtp_rc_t;
+ 
+ typedef enum {
+     LMTP_TYPE_SINGLELINE,
+     LMTP_TYPE_MULTILINE 
+ } lmtp_type_t;
+ 
+ typedef lmtp_rc_t (*lmtp_cb_t)(lmtp_io_t *io, lmtp_req_t *req, lmtp_res_t *res, void *ctx);
+ 
+ lmtp_t     *lmtp_create  (int rfd, int wfd, lmtp_io_t *io);
+ void        lmtp_destroy (lmtp_t *lmtp);
+ lmtp_rc_t   lmtp_request (lmtp_t *lmtp, lmtp_req_t *req);
+ lmtp_rc_t   lmtp_result  (lmtp_t *lmtp, lmtp_res_t *res);
+ char      **lmtp_message (lmtp_t *lmtp, char *verb);
+ void        lmtp_reset   (lmtp_t *lmtp);
+ char       *lmtp_error   (lmtp_t *lmtp, lmtp_rc_t rc);
+ lmtp_cb_t   lmtp_register(lmtp_t *lmtp, char *verb, lmtp_type_t type, lmtp_cb_t *cb, void *ctx);
+ lmtp_rc_t   lmtp_loop    (lmtp_t *lmtp);
+ 
+ #endif /* __LMTP_H__ */


ossp-pkg/lmtp2nntp/lmtp2nntp.c -> 1.1

*** /dev/null    Mon Oct  3 22:15:36 2022
--- -    Mon Oct  3 22:15:40 2022
***************
*** 0 ****
--- 1,66 ----
+ 
+ /*
+  * mail2nntp.c
+  *
+  * The mail2nntp program reads mail from stdin and posts it
+  * to one or more newsgroups using NNTP. It delivers the mes-
+  * sage immediately or fails.  If queuing is desired it can
+  * operate as a LMTP server.
+  *
+  * The OSSP Project, Cable & Wireless Deutschland GmbH
+  * Thomas Lotterer, <thomas.lotterer@cw.com>
+  *
+  */
+ 
+ #include <stdio.h>
+ #include <unistd.h>
+ 
+ #define ERR_EXECUTION -1
+ #define ERR_DELIVERY -2
+ 
+ void usage(char *command);
+ 
+ int main(int argc, char **argv)
+ {
+     int i; // general purpose scratch int, index ...
+ 
+     // read in the arguments
+ 
+     while ((i = getopt(argc, argv, "p:l:h:m:tv")) != -1)
+         switch (i) {
+             case 'p': // -p protocol
+                 break;
+             case 'l': // -l logtarget
+                 break;
+             case 'h': // -h host[:port]
+                 break;
+             case 'm': // -m mode
+                 break;
+             case 'd': // -t (tracing)
+                 break;
+             case 'v': // -v (verbose)
+                 break;
+             case '?':
+             default:
+                 usage(argv[0]);
+                 exit(ERR_EXECUTION);
+         }
+     argc -= optind; argv += optind; // remaining args is/are newsgroup/s
+ 
+     printf("Hello, World!\n");
+     return 0;
+ }
+ 
+ /*
+  * print usage information
+  *
+  */
+ 
+ void usage(char *command)
+ {
+     fprintf(stderr, "USAGE: %s [-p protocol] [-l logtarget] "\
+      "[-h host[:port]] [-m mode] [-t] [-v] newsgroup [newsgroup ...]\n",
+      command);
+     return;
+ }
+ 


ossp-pkg/lmtp2nntp/lmtp2nntp.pod -> 1.1

*** /dev/null    Mon Oct  3 22:15:36 2022
--- -    Mon Oct  3 22:15:40 2022
***************
*** 0 ****
--- 1,129 ----
+ 
+ =pod
+ 
+ =head1 NAME
+ 
+ B<lmtp2nntp> - mail to nntp gateway
+ 
+ =head1 SYNOPSIS
+ 
+ B<lmtp2nntp> 
+ [B<-p> I<protocol>]
+ [B<-l> I<logtarget>]
+ [B<-h> I<host>[I<:port>]]
+ [B<-m> I<mode>]
+ [B<-t>]
+ [B<-v>]
+ I<newsgroup> 
+ [I<newsgroup> ...]
+ 
+ =head1 DESCRIPTION
+ 
+ The B<lmtp2nntp> program reads mail from stdin and posts it to one or more
+ newsgroups using NNTP. It delivers the message immediately or fails.
+ If queuing is desired it can operate as a LMTP server.
+ 
+ The following options are available:
+ 
+ =over 4
+ 
+ =item B<-p> I<protocol>
+ 
+ Incoming protocol. Default is C<stdin> which means B<lmtp2nntp>
+ reads the incoming mail from F<stdin> in RFC822 message format and reports errors to F<stderr>.
+ Alternatively if I<protocol> is C<LMTP>, B<lmtp2nntp> speaks Local Mail
+ Transport Protocol (LMTP) according to RFC 2033 on F<stdin>/F<stdout>.
+ 
+ =item B<-l> C<stderr>
+ 
+ =item B<-l> C<syslog>[C<:>I<facility>]
+ 
+ =item B<-l> C<file:>I<localfile>
+ 
+ Logging target. This option can be specified more than once. Default is no
+ logging. Default I<facility> for C<syslog:> is C<lmtp2nntp>.
+ 
+ =item B<-h> I<host>[:<port>]
+ 
+ Hostname or address and optional TCP port of a NNTP service. Unless a port
+ is specified, getserbyname(nntp) is queried with fallback to 119/tcp. If C<-h>
+ option is ommited, the environment
+ variable C<NNTPSERVER> is read, if this is undefined or empty C<news> is
+ used and if this doesn't resolve, C<localhost> is assumed. This
+ option can be specified more than once. The program connects to the
+ services in given order.
+ 
+ =item B<-m> I<mode>
+ 
+ Mode of delivery. Possible values for I<mode> are C<many> (default) and
+ C<once>. If multiple NNTP servers are given and running in C<many> mode, it
+ posts to as many servers as it can. Sucessfully posting the message one or
+ more times returns success. In I<once> mode it stops processing immediately
+ after the first successful delivery and returns success.
+ 
+ =item B<-t>
+ 
+ Enable LMTP protocol tracing in logfile. When using C<syslog:> these messages
+ are logged with C<debug> level.
+ 
+ =item B<-v>
+ 
+ Enable verbose processing messages in logfile.  When using C<syslog:> these
+ messages are logged with C<info> level.
+ 
+ =item I<newsgroup> 
+ 
+ Newsgroup to post the message to. Multiple groups can be specified.
+ Crosspostings only succeed if delivery to I<all> groups succeed.
+ 
+ =back
+ 
+ =head1 SENDMAIL INTEGRATION
+ 
+   Mlmtp2nntp, P=/... /*FIXME*/
+ 
+ =head1 EXAMPLE
+ 
+  $ cat rfc822.message | lmtp2nntp -l /tmp/log -v -h mynews foo.bar
+ 
+ reads rfc822.message and posts it into group "foo.bar" using NNTP service on
+ host "mynews". Activity is logged to /tmp/log. If posting is
+ successful, the exit status is 0.
+ 
+  $ cat rfc822.message | lmtp2nntp -h news1 -h news2 -h news3 foo.bar
+ 
+ reads rfc822.message and posts it into group "foo.bar" using NNTP service on
+ all hosts "news1", "news2" and "news3". Activtiy is not logged.
+ If at least one posting is successful, the exit status is 0.
+ 
+  $ cat rfc822.message | lmtp2nntp -l stderr foo.bar quux.bar test.bar
+ 
+ reads rfc822.message and posts it into groups "foo.bar", "quux.bar" and
+ "test.bar" using NNTP service on host C<${NNTPSERVER:-news}>. Activity
+ is logged to stderr. Only if all three crosspostings succeed, the exit
+ status is 0.
+ 
+ =head1 DIAGNOSTICS
+ 
+ when invoked from command line
+ 
+  0 = successful execution and delivery
+  1 = execution failed
+  2 = cannot deliver to any nntpserver
+ 
+ when invoked as LMTP server
+ 
+  0 = successful execution
+  1 = execution failed
+ 
+ delivery status is part of the LMTP protocol
+ 
+ =head1 AUTHOR
+ 
+  The OSSP Project
+  Cable & Wireless Deutschland GmbH
+  Thomas Lotterer
+  <thomas.lotterer@cw.com>
+ 
+ =cut
+ 

CVSTrac 2.0.1