Main Page   Data Structures   File List   Data Fields   Globals   Examples  

nm-spoolhack.c

This is an example implementing a tool to emulate Unix mail spool stat() behaviour for a flag file to multiplex mail status information of libnewmail plugins.

/* $Id: nm-spoolhack.c 30 2003-10-22 22:46:07Z lennart $ */

/***
  This file is part of libnewmail

  libnewmail 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 of the License, or
  (at your option) any later version.
  
  libnewmail 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 libnewmail; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  USA
***/

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>

#include <newmail.h>

/* The default Unix mail spool emulation file to use */
#define HACKFILE ".newmail.hack"

/* Create a mail spool file with a size > 0, mtime > atime. */
int create_new(const char *fname) {
    int fd = -1, r = 1;
    char c = 'X';
    
    if ((fd = open(fname, O_WRONLY|O_CREAT, 0666)) < 0) {
        fprintf(stderr, "open(\"%s\", ...): %s\n", fname, strerror(errno));
        goto finish;
    }

    if (write(fd, &c, sizeof(c)) != sizeof(c)) {
        fprintf(stderr, "write(): %s\n", strerror(errno));
        goto finish;
    }

    ftruncate(fd, 1);
    
    r = 0;
    
finish:
    if (fd >= 0)
        close(fd);

    return r;

}

/* Create a mail spool file with a size > 0, mtime < atime. */
int create_old(const char *fname) {
    int r = 1, fd = -1;
    char c = 'X';
    ssize_t n;
    
    if ((fd = open(fname, O_RDWR|O_CREAT, 0666)) < 0) {
        fprintf(stderr, "open(\"%s\", ...): %s\n", fname, strerror(errno));
        goto finish;
    }

    do {
        if (lseek(fd, 0, SEEK_SET) != 0) {
            fprintf(stderr, "lseek(): %s\n", strerror(errno));
            goto finish;
        }

        if ((n = read(fd, &c, sizeof(c))) < 0) {
            fprintf(stderr, "read(): %s\n", strerror(errno));
            goto finish;
        }

        if (!n) {
            if (write(fd, &c, sizeof(c)) != sizeof(c)) {
                fprintf(stderr, "write(): %s\n", strerror(errno));
                goto finish;
            }
        }
    } while (!n);

    r = 0;
    
finish:
    if (fd >= 0)
        close(fd);

    return r;        
}

/* Create a mail spool file with size == 0. */
int create_empty(const char *fname) {
    int fd = -1, r = 1;
    if ((fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) {
        fprintf(stderr, "open(\"%s\", ...): %s\n", fname, strerror(errno));
        goto finish;
    }

    r = 0;
    
finish:
    if (fd >= 0)
        close(fd);

    return r;        
    
}

/* Show usage information */
void usage(const char *argv0) {
    const char *r;
    if ((r = strrchr(argv0, '/')))
        r++;
    else
        r = argv0;
    
    printf("%s [-s SPOOLNAME ] [-f HACKFILE]\n\n"
           " SPOOLNAME: The libnewmail spool name to check\n"
           "  HACKFILE: The emulated Unix mail spool file to use, defaults to $HOME/"HACKFILE"\n\n"
           "%s multiplexes the Unix mail spool stat() behaviour for remote mail spools.\n"
           "This may be used to teach simple mail check applets new mail spool techniques without patching.\n", r, r);

    exit(1);
}

int main(int argc, char *argv[]) {
    struct nm_spool *s = NULL;
    struct nm_status st;
    int r = 1;
    char *n = NULL,
        *fname = NULL;
    char t[PATH_MAX];

    /* Iterate through the arguments passed to the process */
    for (;;) {
        int c;
        
        if ((c = getopt(argc, argv, "s:f:h")) == -1)
            break;
        
        switch (c) {
            case 's':
                n = optarg;
                break;
                
            case 'f':
                fname = optarg;
                break;

            default:
                usage(argv[0]);
        }
    }

    if (!fname)
        snprintf(fname = t, sizeof(t), "%s/"HACKFILE, getenv("HOME"));

    /* Open the mail spool */
    if (!(s = nm_open(n))) {
        fprintf(stderr, "nm_open(\"%s\"): %s\n", n, nm_strerror(nm_errno, errno, nm_explanation));
        goto finish;
    }

    /* Issue the query */
    if (nm_query(s, NM_QUERY_CUR|NM_QUERY_NEW, &st) < 0) {
        fprintf(stderr, "nm_check(\"%s\"): %s\n", n, nm_strerror(nm_errno, errno, nm_explanation));
        goto finish;
    }

    /* Create the mail spool file accordingly */
    if (st.cur && st.new)
        r = create_new(fname);
    else if (st.cur)
        r = create_old(fname);
    else
        r = create_empty(fname);
    
finish:

    /* Close the mail spool */
    if (s)
        nm_close(s);

    return r;
    
}

Generated on Thu Oct 23 01:52:10 2003 for libnewmail by doxygen1.2.18