Fix uip/whom.c for C89 compatibility
[mmh] / uip / rcvstore.c
index 868ed47..33f8f3b 100644 (file)
@@ -7,68 +7,74 @@
 */
 
 #include <h/mh.h>
+#include <h/utils.h>
 #include <fcntl.h>
 #include <h/signals.h>
 #include <errno.h>
 #include <signal.h>
-#include <h/mts.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <locale.h>
+#include <sysexits.h>
 
 static struct swit switches[] = {
 #define CRETSW  0
        { "create",   0 },
 #define NCRETSW  1
-       { "nocreate", 0 },
+       { "nocreate", 2 },
 #define UNSEENSW  2
        { "unseen",   0 },
 #define NUNSEENSW  3
-       { "nounseen", 0 },
+       { "nounseen", 2 },
 #define PUBSW  4
        { "public",   0 },
 #define NPUBSW  5
-       { "nopublic", 0 },
+       { "nopublic", 2 },
 #define ZEROSW  6
        { "zero",     0 },
 #define NZEROSW  7
-       { "nozero",   0 },
+       { "nozero",   2 },
 #define SEQSW  8
        { "sequence name", 0 },
 #define VERSIONSW  9
-       { "version", 0 },
+       { "Version", 0 },
 #define HELPSW  10
        { "help", 0 },
        { NULL, 0 }
 };
 
+char *version=VERSION;
 
 /*
 ** name of temporary file to store incoming message
 */
 static char *tmpfilenam = NULL;
 
-static void unlink_done(int) NORETURN;
+void unlink_done();
+static void fix_mbox(int out, char *ofile);
 
 int
 main(int argc, char **argv)
 {
        int publicsw = -1, zerosw = 0;
        int create = 1, unseensw = 1;
-       int fd, msgnum, seqp = 0;
+       int fd, msgnum;
+       size_t seqp = 0;
        char *cp, *maildir, *folder = NULL, buf[BUFSIZ];
        char **argp, **arguments, *seqs[NUMATTRS+1];
        struct msgs *mp;
        struct stat st;
 
-       done=unlink_done;
+       if (atexit(unlink_done) != 0) {
+               adios(EX_OSERR, NULL, "atexit failed");
+       }
 
-#ifdef LOCALE
        setlocale(LC_ALL, "");
-#endif
-       invo_name = r1bindex(argv[0], '/');
+       invo_name = mhbasename(argv[0]);
 
        /* read user profile/context */
        context_read();
 
-       mts_init(invo_name);
        arguments = getarguments(invo_name, argc, argv, 1);
        argp = arguments;
 
@@ -78,27 +84,27 @@ main(int argc, char **argv)
                        switch (smatch(++cp, switches)) {
                        case AMBIGSW:
                                ambigsw(cp, switches);
-                               done(1);
+                               exit(EX_USAGE);
                        case UNKWNSW:
-                               adios(NULL, "-%s unknown", cp);
+                               adios(EX_USAGE, NULL, "-%s unknown", cp);
 
                        case HELPSW:
                                snprintf(buf, sizeof(buf),
                                                "%s [+folder] [switches]",
                                                invo_name);
                                print_help(buf, switches, 1);
-                               done(1);
+                               exit(argc == 2 ? EX_OK : EX_USAGE);
                        case VERSIONSW:
                                print_version(invo_name);
-                               done(1);
+                               exit(argc == 2 ? EX_OK : EX_USAGE);
 
                        case SEQSW:
                                if (!(cp = *argp++) || *cp == '-')
-                                       adios(NULL, "missing argument name to %s", argp[-2]);
+                                       adios(EX_USAGE, NULL, "missing argument name to %s", argp[-2]);
 
                                /* check if too many sequences specified */
                                if (seqp >= NUMATTRS)
-                                       adios(NULL, "too many sequences (more than %d) specified", NUMATTRS);
+                                       adios(EX_USAGE, NULL, "too many sequences (more than %d) specified", NUMATTRS);
                                seqs[seqp++] = cp;
                                continue;
 
@@ -133,37 +139,34 @@ main(int argc, char **argv)
                }
                if (*cp == '+' || *cp == '@') {
                        if (folder)
-                               adios(NULL, "only one folder at a time!");
+                               adios(EX_USAGE, NULL, "only one folder at a time!");
                        else
-                               folder = pluspath(cp);
+                               folder = mh_xstrdup(expandfol(cp));
                } else {
-                       adios(NULL, "usage: %s [+folder] [switches]",
+                       adios(EX_USAGE, NULL, "usage: %s [+folder] [switches]",
                                        invo_name);
                }
        }
 
        seqs[seqp] = NULL;  /* NULL terminate list of sequences */
 
-       if (!context_find("path"))
-               free(path("./", TFOLDER));
-
        /* if no folder is given, use default folder */
        if (!folder)
-               folder = getfolder(0);
-       maildir = m_maildir(folder);
+               folder = getdeffol();
+       maildir = toabsdir(folder);
 
        /* check if folder exists */
        if (stat(maildir, &st) == NOTOK) {
                if (errno != ENOENT)
-                       adios(maildir, "error on folder");
+                       adios(EX_IOERR, maildir, "error on folder");
                if (!create)
-                       adios(NULL, "folder %s doesn't exist", maildir);
+                       adios(EX_USAGE, NULL, "folder %s doesn't exist", maildir);
                if (!makedir(maildir))
-                       adios(NULL, "unable to create folder %s", maildir);
+                       adios(EX_CANTCREAT, NULL, "unable to create folder %s", maildir);
        }
 
        if (chdir(maildir) == NOTOK)
-               adios(maildir, "unable to change directory to");
+               adios(EX_OSERR, maildir, "unable to change directory to");
 
        /* ignore a few signals */
        SIGNAL(SIGHUP, SIG_IGN);
@@ -174,40 +177,43 @@ main(int argc, char **argv)
        /* create a temporary file */
        tmpfilenam = m_mktemp(invo_name, &fd, NULL);
        if (tmpfilenam == NULL) {
-               adios("rcvstore", "unable to create temporary file");
+               adios(EX_CANTCREAT, "rcvstore", "unable to create temporary file");
        }
        chmod(tmpfilenam, m_gmprot());
 
+       /* check if incoming mail is in mbox-format */
+       fix_mbox(fd, tmpfilenam);
+
        /* copy the message from stdin into temp file */
        cpydata(fileno(stdin), fd, "standard input", tmpfilenam);
 
        if (fstat(fd, &st) == NOTOK) {
                unlink(tmpfilenam);
-               adios(tmpfilenam, "unable to fstat");
+               adios(EX_IOERR, tmpfilenam, "unable to fstat");
        }
        if (close(fd) == NOTOK)
-               adios(tmpfilenam, "error closing");
+               adios(EX_IOERR, tmpfilenam, "error closing");
 
        /* don't add file if it is empty */
        if (st.st_size == 0) {
                unlink(tmpfilenam);
                advise(NULL, "empty file");
-               done(0);
+               exit(EX_OK);
        }
 
        /*
        ** read folder and create message structure
        */
        if (!(mp = folder_read(folder)))
-               adios(NULL, "unable to read folder %s", folder);
+               adios(EX_IOERR, NULL, "unable to read folder %s", folder);
 
        /*
        ** Link message into folder, and possibly add
        ** to the Unseen-Sequence's.
        */
-       if ((msgnum = folder_addmsg(&mp, tmpfilenam, 0, unseensw, 0, 0,
-                       (char *)0)) == -1)
-               done(1);
+       if ((msgnum = folder_addmsg(&mp, tmpfilenam, 0, unseensw, 0, 0, NULL))
+                       == -1)
+               exit(EX_SOFTWARE);
 
        /*
        ** Add the message to any extra sequences
@@ -215,10 +221,10 @@ main(int argc, char **argv)
        */
        for (seqp = 0; seqs[seqp]; seqp++) {
                if (!seq_addmsg(mp, seqs[seqp], msgnum, publicsw, zerosw))
-                       done(1);
+                       exit(EX_SOFTWARE);
        }
 
-       seq_setunseen(mp, 0);  /* synchronize any Unseen-Sequence's */
+       seq_setunseen(mp, 1);  /* add new msgs to unseen sequences */
        seq_save(mp);  /* synchronize and save message sequences */
        folder_free(mp);  /* free folder/message structure */
 
@@ -226,17 +232,45 @@ main(int argc, char **argv)
        unlink(tmpfilenam);  /* remove temporary file */
        tmpfilenam = NULL;
 
-       done(0);
-       return 1;
+       return EX_OK;
+}
+
+static void
+fix_mbox(int out, char *outfile)
+{
+       char mbox[5];
+       int ret;
+
+       if ((ret = read(fileno(stdin), mbox, sizeof(mbox))) != sizeof(mbox)) {
+               if (ret == -1) {
+                       adios(EX_IOERR, "standard input", "error reading");
+               }
+               return;
+       }
+
+       if (strncmp(mbox, "From ", sizeof(mbox))==0) {
+               do {
+                       if ((ret = read(fileno(stdin), mbox, 1)) != 1) {
+                               if (ret == -1) {
+                                       adios(EX_IOERR, "standard input", "error reading");
+                               }
+                               return;
+                       }
+               } while (*mbox != '\n');
+       } else {
+               if (write(out, mbox, sizeof(mbox)) != sizeof(mbox)) {
+                       adios(EX_IOERR, outfile, "error writing");
+               }
+       }
 }
 
 /*
 ** Clean up and exit
 */
-static void
-unlink_done(int status)
+void
+unlink_done()
 {
-       if (tmpfilenam && *tmpfilenam)
+       if (tmpfilenam && *tmpfilenam) {
                unlink(tmpfilenam);
-       exit(status);
+       }
 }