1: /* rcvstore.c - incorporate new mail asynchronously 2: originally from Julian Onions */ 3: 4: #include "../h/mh.h" 5: #include <errno.h> 6: #include <signal.h> 7: #include <stdio.h> 8: #include <sys/types.h> 9: #include <sys/stat.h> 10: 11: /* */ 12: 13: static struct swit switches[] = { 14: #define CRETSW 0 15: "create", 0, 16: #define NCRETSW 1 17: "nocreate", 0, 18: 19: #define PUBSW 2 20: "public", 0, 21: #define NPUBSW 3 22: "nopublic", 0, 23: 24: #define SEQSW 4 25: "sequence name", 0, 26: 27: #define ZEROSW 5 28: "zero", 0, 29: #define NZEROSW 6 30: "nozero", 0, 31: 32: #define HELPSW 7 33: "help", 4, 34: 35: NULL, NULL 36: }; 37: 38: /* */ 39: 40: extern int errno; 41: 42: /* */ 43: 44: /* ARGSUSED */ 45: 46: main (argc, argv) 47: int argc; 48: char *argv[]; 49: { 50: int publicsw = -1, 51: zerosw = 0, 52: msgnum, 53: create = 1, 54: fd, 55: seqp = 0; 56: char *cp, 57: *maildir, 58: *folder = NULL, 59: buf[100], 60: **ap, 61: **argp, 62: *arguments[MAXARGS], 63: *seqs[NATTRS]; 64: struct msgs *mp; 65: struct stat st; 66: 67: invo_name = r1bindex (argv[0], '/'); 68: mts_init (invo_name); 69: if ((cp = m_find (invo_name)) != NULL) { 70: ap = brkstring (cp = getcpy (cp), " ", "\n"); 71: ap = copyip (ap, arguments); 72: } 73: else 74: ap = arguments; 75: (void) copyip (argv + 1, ap); 76: argp = arguments; 77: 78: /* */ 79: 80: while (cp = *argp++) { 81: if (*cp == '-') 82: switch (smatch (++cp, switches)) { 83: case AMBIGSW: 84: ambigsw (cp, switches); 85: done (1); 86: case UNKWNSW: 87: adios (NULLCP, "-%s unknown", cp); 88: case HELPSW: 89: (void) sprintf (buf, "%s [+folder] [switches]", invo_name); 90: help (buf, switches); 91: done (1); 92: 93: case SEQSW: 94: if (!(cp = *argp++) || *cp == '-') 95: adios (NULLCP, "missing argument name to %s", 96: argp[-2]); 97: if (seqp < NATTRS) 98: seqs[seqp++] = cp; 99: else 100: adios (NULLCP, "only %d sequences allowed!", NATTRS); 101: continue; 102: case PUBSW: 103: publicsw = 1; 104: continue; 105: case NPUBSW: 106: publicsw = 0; 107: continue; 108: case ZEROSW: 109: zerosw++; 110: continue; 111: case NZEROSW: 112: zerosw = 0; 113: continue; 114: 115: case CRETSW: 116: create++; 117: continue; 118: case NCRETSW: 119: create = 0; 120: continue; 121: } 122: if (*cp == '+' || *cp == '@') { 123: if (folder) 124: adios (NULLCP, "only one folder at a time!"); 125: else 126: folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); 127: } 128: else 129: adios (NULLCP, "usage: %s [+folder] [switches]", invo_name); 130: } 131: 132: /* */ 133: 134: if (!m_find ("path")) 135: free (path ("./", TFOLDER)); 136: if (!folder) 137: folder = defalt; 138: maildir = m_maildir (folder); 139: 140: if (stat (maildir, &st) == NOTOK) { 141: if (errno != ENOENT) 142: adios (maildir, "error on folder"); 143: if (!create) 144: adios (NULLCP, "folder %s doesn't exist", maildir); 145: if (!makedir (maildir)) 146: adios (NULLCP, "unable to create folder %s", maildir); 147: } 148: 149: if (chdir (maildir) == NOTOK) 150: adios (maildir, "unable to change directory to"); 151: if (!(mp = m_gmsg (folder))) 152: adios (NULLCP, "unable to read folder %s", folder); 153: 154: (void) signal (SIGHUP, SIG_IGN); 155: (void) signal (SIGINT, SIG_IGN); 156: (void) signal (SIGQUIT, SIG_IGN); 157: (void) signal (SIGTERM, SIG_IGN); 158: 159: /* */ 160: 161: if ((fd = creat (cp = m_scratch ("", invo_name), m_gmprot ())) == NOTOK) 162: adios (cp, "unable to create"); 163: 164: cpydata (fileno (stdin), fd, "standard input", cp); 165: 166: if (fstat (fd, &st) == NOTOK) { 167: (void) unlink (cp); 168: adios (cp, "unable to fstat"); 169: } 170: (void) close (fd); 171: if (st.st_size == 0) { 172: (void) unlink (cp); 173: advise (NULLCP, "empty file"); 174: done (0); 175: } 176: 177: msgnum = mp -> hghmsg; 178: do { 179: msgnum++, mp -> hghmsg++; 180: if (msgnum > mp -> hghoff) 181: if ((mp = m_remsg (mp, 0, mp -> hghoff + MAXFOLDER)) == NULL) 182: adios (NULLCP, "unable to allocate folder storage"); 183: 184: mp -> msgstats[msgnum] |= EXISTS | UNSEEN; 185: errno = 0; 186: } while (link (cp, m_name (msgnum)) == NOTOK && errno == EEXIST); 187: 188: (void) unlink (cp); 189: if (errno != 0) 190: adios (NULLCP, "can't file message %d", msgnum); 191: 192: if (mp -> lowmsg == 0) 193: mp -> lowmsg = msgnum; 194: mp -> msgflags |= SEQMOD; 195: 196: seqs[seqp] = NULL; 197: for (seqp = 0; seqs[seqp]; seqp++) { 198: if (zerosw && !m_seqnew (mp, seqs[seqp], publicsw)) 199: done (1); 200: if (!m_seqadd (mp, seqs[seqp], msgnum, publicsw)) 201: done (1); 202: } 203: 204: m_setvis (mp, 0); 205: m_sync (mp); 206: m_update (); 207: 208: done (0); 209: }