OSSP CVS Repository

ossp - ossp-pkg/lmtp2nntp/lmtp2nntp.c 1.4
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/lmtp2nntp/lmtp2nntp.c 1.4

/*
 * 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>
#include <errno.h>
#include <string.h>
#include <fcntl.h>

/* third party */
#include "str.h"

/* own headers */
#include "lmtp.h"

#define ERR_EXECUTION -1
#define ERR_DELIVERY -2

#define MESSAGE_MAXLEN 8*1024*1024

static ssize_t trace_read(int d, void *buf, size_t nbytes);
static ssize_t trace_write(int d, const void *buf, size_t nbytes);

static lmtp_rc_t lmtp_cb_lhlo   (lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx);
static lmtp_rc_t lmtp_cb_mail   (lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx);
static lmtp_rc_t lmtp_cb_rcpt   (lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx);
static lmtp_rc_t lmtp_cb_data   (lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx);
static lmtp_rc_t lmtp_cb_noop   (lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx);
static lmtp_rc_t lmtp_cb_rset   (lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx);
static lmtp_rc_t lmtp_cb_quit   (lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx);

static void usage(char *command);
static void test(void);

int main(int argc, char **argv)
{
    int i; /* general purpose scratch int, index ... */

    {
        char buf[1000];
        int bufused = 0;
        int tracefile;

// printf("DEBUG: start of argdump\n", buf);
        for (i=0; i<argc; i++) {
// printf("DEBUG: [%d]=***%s***\n", i, argv[i]);
            bufused+=sprintf(buf+bufused, "[%d]=\"%s\"\n", i, argv[i]);
        }
// printf("DEBUG: buffer ***%s***\n", buf);
        if ((tracefile = open("/tmp/t", O_CREAT|O_WRONLY|O_APPEND, 0664)) != -1) {
            write(tracefile, buf, bufused);
// printf("DEBUG: writing\n", buf);
            close(tracefile);
        }
// printf("DEBUG: end of argdump\n", buf);
    }

    /* read in the arguments */

#if 0

    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:
                //FIXME usage(argv[0]);
                //FIXME exit(ERR_EXECUTION);
        }
    argc -= optind; argv += optind; // remaining args is/are newsgroup/s
#endif
    
    //FIXME printf("Hello, World!\n");
    test();
    //FIXME printf("Hello, Again!\n");
    return 0;
}

/*
 * print usage information
 *
 */

static void usage(char *command)
{
    fprintf(stderr, "USAGE: %s [-p protocol] [-l logtarget] "\
     "[-h host[:port]] [-m mode] [-t] [-v] newsgroup [newsgroup ...]\n",
     command);
    return;
}

/*
 * tracing
 *
 */
ssize_t trace_read(int d, void *buf, size_t nbytes)
{
    ssize_t rc;
    int tracefile;

    rc = read(d, buf, nbytes);
    if ((tracefile = open("/tmp/t", O_CREAT|O_WRONLY|O_APPEND, 0664)) != -1) {
        write(tracefile, buf, rc);
        close(tracefile);
    }
    return rc;
}

ssize_t trace_write(int d, const void *buf, size_t nbytes)
{
    ssize_t rc;
    int tracefile;

    rc = write(d, buf, nbytes);
    if ((tracefile = open("/tmp/t", O_CREAT|O_WRONLY|O_APPEND, 0664)) != -1) {
        write(tracefile, buf, rc);
        close(tracefile);
    }
    return rc;
}

/*
 * test a function
 *
 */

extern void lmtp_debug_dumplmtp(lmtp_t *lmtp);
static void test(void)
{
    lmtp_t *lmtp;
    lmtp_rc_t rc;
    lmtp_req_t req;
    lmtp_res_t res;
    lmtp_io_t io;
#define BUFLEN 100
    char buf[BUFLEN];
    lmtp_cb_t oldcb = NULL;
    

    io.read=trace_read;
    io.write=trace_write;
    io.select=select;
    lmtp = lmtp_create(STDIN_FILENO, STDOUT_FILENO, &io);
    // lmtp_debug_dumplmtp(lmtp);
    lmtp_register(lmtp, "LHLO",         NULL, NULL,&oldcb,NULL); // printf("DEBUG: 1 oldcb=%d\n", (int)oldcb);
    lmtp_register(lmtp, "LHLO", lmtp_cb_lhlo, NULL,&oldcb,NULL); // printf("DEBUG: 2 oldcb=%d\n", (int)oldcb);
    lmtp_register(lmtp, "LHLO",         NULL, NULL,&oldcb,NULL); // printf("DEBUG: 3 oldcb=%d\n", (int)oldcb);
    lmtp_register(lmtp, "MAIL", lmtp_cb_mail, NULL, NULL, NULL);
    lmtp_register(lmtp, "RCPT", lmtp_cb_rcpt, NULL, NULL, NULL);
    lmtp_register(lmtp, "DATA", lmtp_cb_data, NULL, NULL, NULL);
    lmtp_register(lmtp, "NOOP", lmtp_cb_noop, NULL, NULL, NULL);
    lmtp_register(lmtp, "RSET", lmtp_cb_rset, NULL, NULL, NULL);
    lmtp_register(lmtp, "QUIT", lmtp_cb_quit, NULL, NULL, NULL);
    // lmtp_debug_dumplmtp(lmtp);

    /*
    printf("DEBUG: 05 lmtp_response\n");    res.statuscode="123";
                                            res.dsncode="1.2.3";
                                            res.statusmsg="Hello,\nthis is a\nmultiline\nmessage";
                                            lmtp_response(lmtp, &res);
    */

    /*
    do { 
        rc = lmtp_readline(lmtp, buf, BUFLEN);
        printf("DEBUG: 06 lmtp_readline=%d ***%s***\n", rc, buf);
    } while(rc == LMTP_OK);
    */

    /*
    do {
        rc = lmtp_request(lmtp, &req);
        printf("DEBUG: 07 lmtp_request=%d ***%s***%s***\n", rc, req.verb, req.msg);
    } while(rc == LMTP_OK || rc == LMTP_ERR_VERB);
    */

    /* printf("DEBUG: 08 lmtp_loop=%d\n", */ lmtp_loop(lmtp) /*)*/;

    /* printf("DEBUG: 99.\n"); */
    return;
}
static lmtp_rc_t lmtp_cb_lhlo(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx)
{
    lmtp_res_t res;
    lmtp_rc_t rc = LMTP_OK;
    res.statuscode = "250";
    res.dsncode    = NULL; /* DSN not used for greeting */
    res.statusmsg  = "ENHANCEDSTATUSCODES\nDSN\nPIPELINING\n8BITMIME";
        /*
         *  RFC2034 = EHANCEDSTATUSCODES
         *  RFC1894 = DSN
         *  RFC1854 = PIPELINING
         *  RFC1652 = 8BITMIME
         */
    lmtp_response(lmtp, &res);
    return rc;
}

static lmtp_rc_t lmtp_cb_mail(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx)
{
    lmtp_res_t res;
    lmtp_rc_t rc = LMTP_OK;
    res.statuscode = "553";
    res.dsncode    = "5.1.8";
    res.statusmsg  = "Bad sender FIXME";
    res.statuscode = "250";
    res.dsncode    = "2.1.0";
    res.statusmsg  = "Sender ok FIXME";
    lmtp_response(lmtp, &res);
    return rc;
}

static lmtp_rc_t lmtp_cb_rcpt(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx)
{
    lmtp_rc_t rc = LMTP_OK;
    lmtp_res_t res;
    char **cp;

    res.statuscode = "250";
    res.dsncode    = "2.1.5";
    res.statusmsg  = "Recipient ok FIXME";
    lmtp_response(lmtp, &res);

    cp = lmtp_message(lmtp, "RCPT");
    if (cp == NULL) {
        printf("DEBUG: cp=NULL\n");
    } else {
        printf("DEBUG: cp=%d\n", cp);
    }

    return rc;
}


static lmtp_rc_t lmtp_cb_data(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx)
{
    lmtp_res_t res;
    lmtp_rc_t rc = LMTP_OK;
    char *buf;
    char errorstring[128];

    res.statuscode = "354";
    res.dsncode    = NULL; /* DSN not used for data */
    res.statusmsg  = "Enter mail, end with \".\" on a line by itself";
    lmtp_response(lmtp, &res);
    rc = lmtp_readmsg(lmtp, &buf, MESSAGE_MAXLEN);
    if(rc == LMTP_OK) {
// printf("DEBUG: message=***%s***\n", buf);
        res.statuscode = "250";
        res.dsncode    = "2.0.0";
        res.statusmsg  = "Message accepted for delivery";
    } else if (rc == LMTP_ERR_OVERFLOW) {
        res.statuscode = "500";
        res.dsncode    = "5.0.0";
        res.statusmsg  = "Message accepted for delivery";
    } else if (rc == LMTP_ERR_SYSTEM) {
        res.statuscode = "500";
        res.dsncode    = "5.0.0";
        str_format(errorstring, sizeof(errorstring),
                   "Message accepted for delivery %s", strerror(errno));
        res.statusmsg  = errorstring;
    }
    lmtp_response(lmtp, &res);
    return rc;
}

static lmtp_rc_t lmtp_cb_noop(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx)
{
    lmtp_res_t res;
    lmtp_rc_t rc = LMTP_OK;
    res.statuscode = "250";
    res.dsncode    = "2.0.0";
    res.statusmsg  = "OK";
    lmtp_response(lmtp, &res);
    return rc;
}
static lmtp_rc_t lmtp_cb_rset(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx)
{
    lmtp_res_t res;
    lmtp_rc_t rc = LMTP_OK;
    res.statuscode = "250";
    res.dsncode    = "2.0.0";
    res.statusmsg  = "Reset state.";
    lmtp_response(lmtp, &res);
    return rc;
}
static lmtp_rc_t lmtp_cb_quit(lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx)
{
    lmtp_res_t res;
    lmtp_rc_t rc = LMTP_EOF;
    res.statuscode = "221";
    res.dsncode    = "2.0.0";
    res.statusmsg  = "Closing connection.";
    lmtp_response(lmtp, &res);
    return rc;
}


CVSTrac 2.0.1