diff options
Diffstat (limited to 'src/nm-spoolhack.c')
-rw-r--r-- | src/nm-spoolhack.c | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/src/nm-spoolhack.c b/src/nm-spoolhack.c new file mode 100644 index 0000000..59630ab --- /dev/null +++ b/src/nm-spoolhack.c @@ -0,0 +1,196 @@ +/* $Id: nmail-async.c 23 2003-06-04 22:04:34Z 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; + +} |