#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <newmail.h>
#define HACKFILE ".newmail.hack"
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;
}
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;
}
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;
}
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];
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"));
if (!(s = nm_open(n))) {
fprintf(stderr, "nm_open(\"%s\"): %s\n", n, nm_strerror(nm_errno, errno, nm_explanation));
goto finish;
}
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;
}
if (st.cur && st.new)
r = create_new(fname);
else if (st.cur)
r = create_old(fname);
else
r = create_empty(fname);
finish:
if (s)
nm_close(s);
return r;
}