|
|
1.1 ! root 1: /* refile.c - file messages away */ ! 2: ! 3: #include "../h/mh.h" ! 4: #include <errno.h> ! 5: #include <stdio.h> ! 6: #include <sys/types.h> ! 7: #include <sys/stat.h> ! 8: ! 9: /* */ ! 10: ! 11: static struct swit switches[] = { ! 12: #define DRAFTSW 0 ! 13: "draft", 0, ! 14: ! 15: #define LINKSW 1 ! 16: "link", 0, ! 17: #define NLINKSW 2 ! 18: "nolink", 0, ! 19: ! 20: #define PRESSW 3 ! 21: "preserve", 0, ! 22: #define NPRESSW 4 ! 23: "nopreserve", 0, ! 24: ! 25: #define SRCSW 5 ! 26: "src +folder", 0, ! 27: ! 28: #define FILESW 6 ! 29: "file file", 0, ! 30: ! 31: #define HELPSW 7 ! 32: "help", 4, ! 33: ! 34: NULL, NULL ! 35: }; ! 36: ! 37: /* */ ! 38: ! 39: extern int errno; ! 40: ! 41: ! 42: static char maildir[BUFSIZ]; ! 43: ! 44: ! 45: struct st_fold { ! 46: char *f_name; ! 47: struct msgs *f_mp; ! 48: }; ! 49: ! 50: /* */ ! 51: ! 52: /* ARGSUSED */ ! 53: ! 54: main (argc, argv) ! 55: int argc; ! 56: char **argv; ! 57: { ! 58: int linkf = 0, ! 59: prsrvf = 0, ! 60: filep = 0, ! 61: foldp = 0, ! 62: msgp = 0, ! 63: isdf = 0, ! 64: i, ! 65: msgnum; ! 66: char *cp, ! 67: *folder = NULL, ! 68: buf[100], ! 69: **ap, ! 70: **argp, ! 71: *arguments[MAXARGS], ! 72: *files[NFOLDERS + 1], ! 73: *msgs[MAXARGS]; ! 74: struct st_fold folders[NFOLDERS + 1]; ! 75: struct msgs *mp; ! 76: ! 77: invo_name = r1bindex (argv[0], '/'); ! 78: if ((cp = m_find (invo_name)) != NULL) { ! 79: ap = brkstring (cp = getcpy (cp), " ", "\n"); ! 80: ap = copyip (ap, arguments); ! 81: } ! 82: else ! 83: ap = arguments; ! 84: (void) copyip (argv + 1, ap); ! 85: argp = arguments; ! 86: ! 87: /* */ ! 88: ! 89: while (cp = *argp++) { ! 90: if (*cp == '-') ! 91: switch (smatch (++cp, switches)) { ! 92: case AMBIGSW: ! 93: ambigsw (cp, switches); ! 94: done (1); ! 95: case UNKWNSW: ! 96: adios (NULLCP, "-%s unknown\n", cp); ! 97: case HELPSW: ! 98: (void) sprintf (buf, "%s [msgs] [switches] +folder ...", ! 99: invo_name); ! 100: help (buf, switches); ! 101: done (1); ! 102: ! 103: case LINKSW: ! 104: linkf++; ! 105: continue; ! 106: case NLINKSW: ! 107: linkf = 0; ! 108: continue; ! 109: ! 110: case PRESSW: ! 111: prsrvf++; ! 112: continue; ! 113: case NPRESSW: ! 114: prsrvf = 0; ! 115: continue; ! 116: ! 117: case SRCSW: ! 118: if (folder) ! 119: adios (NULLCP, "only one source folder at a time!"); ! 120: if (!(cp = *argp++) || *cp == '-') ! 121: adios (NULLCP, "missing argument to %s", argp[-2]); ! 122: folder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp, ! 123: *cp != '@' ? TFOLDER : TSUBCWF); ! 124: continue; ! 125: case DRAFTSW: ! 126: if (filep > NFOLDERS) ! 127: adios (NULLCP, "only %d files allowed!", NFOLDERS); ! 128: isdf = 0; ! 129: files[filep++] = getcpy (m_draft (NULLCP, NULLCP, 1, &isdf)); ! 130: continue; ! 131: case FILESW: ! 132: if (filep > NFOLDERS) ! 133: adios (NULLCP, "only %d files allowed!", NFOLDERS); ! 134: if (!(cp = *argp++) || *cp == '-') ! 135: adios (NULLCP, "missing argument to %s", argp[-2]); ! 136: files[filep++] = path (cp, TFILE); ! 137: continue; ! 138: } ! 139: if (*cp == '+' || *cp == '@') { ! 140: if (foldp > NFOLDERS) ! 141: adios (NULLCP, "only %d folders allowed!", NFOLDERS); ! 142: folders[foldp++].f_name = ! 143: path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); ! 144: } ! 145: else ! 146: msgs[msgp++] = cp; ! 147: } ! 148: ! 149: /* */ ! 150: ! 151: if (!m_find ("path")) ! 152: free (path ("./", TFOLDER)); ! 153: if (foldp == 0) ! 154: adios (NULLCP, "no folder specified"); ! 155: ! 156: #ifdef WHATNOW ! 157: if (!msgp && !filep && (cp = getenv ("mhdraft")) && *cp) ! 158: files[filep++] = cp; ! 159: #endif WHATNOW ! 160: ! 161: if (filep > 0) { ! 162: if (folder || msgp) ! 163: adios (NULLCP, "use -file or some messages, not both"); ! 164: opnfolds (folders, foldp); ! 165: for (i = 0; i < filep; i++) ! 166: if (m_file (files[i], folders, foldp, prsrvf)) ! 167: done (1); ! 168: if (!linkf) ! 169: remove (NULLMP, filep, files); ! 170: done (0); ! 171: } ! 172: ! 173: if (!msgp) ! 174: msgs[msgp++] = "cur"; ! 175: if (!folder) ! 176: folder = m_getfolder (); ! 177: (void) strcpy (maildir, m_maildir (folder)); ! 178: ! 179: if (chdir (maildir) == NOTOK) ! 180: adios (maildir, "unable to change directory to"); ! 181: if (!(mp = m_gmsg (folder))) ! 182: adios (NULLCP, "unable to read folder %s", folder); ! 183: if (mp -> hghmsg == 0) ! 184: adios (NULLCP, "no messages in %s", folder); ! 185: ! 186: for (msgnum = 0; msgnum < msgp; msgnum++) ! 187: if (!m_convert (mp, msgs[msgnum])) ! 188: done (1); ! 189: m_setseq (mp); ! 190: ! 191: opnfolds (folders, foldp); ! 192: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 193: if (mp -> msgstats[msgnum] & SELECTED) { ! 194: cp = getcpy (m_name (msgnum)); ! 195: if (m_file (cp, folders, foldp, prsrvf)) ! 196: done (1); ! 197: free (cp); ! 198: if (!linkf) { ! 199: #ifdef notdef ! 200: mp -> msgstats[msgnum] |= DELETED; ! 201: #endif notdef ! 202: mp -> msgstats[msgnum] &= ~EXISTS; ! 203: } ! 204: } ! 205: if (!linkf) ! 206: mp -> msgflags |= SEQMOD; ! 207: clsfolds (folders, foldp); ! 208: ! 209: m_replace (pfolder, folder); ! 210: if (mp -> hghsel != mp -> curmsg ! 211: && (mp -> numsel != mp -> nummsg || linkf)) ! 212: m_setcur (mp, mp -> hghsel); ! 213: m_sync (mp); ! 214: m_update (); ! 215: ! 216: if (!linkf) ! 217: remove (mp, filep, files); ! 218: ! 219: done (0); ! 220: } ! 221: ! 222: /* */ ! 223: ! 224: static opnfolds (folders, nfolders) ! 225: register struct st_fold *folders; ! 226: int nfolders; ! 227: { ! 228: register char *cp; ! 229: char nmaildir[BUFSIZ]; ! 230: register struct st_fold *fp, ! 231: *ep; ! 232: register struct msgs *mp; ! 233: struct stat st; ! 234: ! 235: for (ep = (fp = folders) + nfolders; fp < ep; fp++) { ! 236: (void) chdir (m_maildir ("")); ! 237: (void) strcpy (nmaildir, m_maildir (fp -> f_name)); ! 238: ! 239: if (stat (nmaildir, &st) == NOTOK) { ! 240: if (errno != ENOENT) ! 241: adios (nmaildir, "error on folder"); ! 242: cp = concat ("Create folder \"", nmaildir, "\"? ", NULLCP); ! 243: if (!getanswer (cp)) ! 244: done (1); ! 245: free (cp); ! 246: if (!makedir (nmaildir)) ! 247: adios (NULLCP, "unable to create folder %s", nmaildir); ! 248: } ! 249: ! 250: if (chdir (nmaildir) == NOTOK) ! 251: adios (nmaildir, "unable to change directory to"); ! 252: if (!(mp = m_gmsg (fp -> f_name))) ! 253: adios (NULLCP, "unable to read folder %s", fp -> f_name); ! 254: mp -> curmsg = 0; ! 255: ! 256: fp -> f_mp = mp; ! 257: ! 258: (void) chdir (maildir); ! 259: } ! 260: } ! 261: ! 262: /* */ ! 263: ! 264: static clsfolds (folders, nfolders) ! 265: register struct st_fold *folders; ! 266: int nfolders; ! 267: { ! 268: register struct st_fold *fp, ! 269: *ep; ! 270: register struct msgs *mp; ! 271: ! 272: for (ep = (fp = folders) + nfolders; fp < ep; fp++) { ! 273: mp = fp -> f_mp; ! 274: m_setseq (mp); ! 275: m_sync (mp); ! 276: } ! 277: } ! 278: ! 279: /* */ ! 280: ! 281: static remove (mp, filep, files) ! 282: register struct msgs *mp; ! 283: register int filep; ! 284: register char **files; ! 285: { ! 286: register int i, ! 287: vecp; ! 288: register char *cp, ! 289: **vec; ! 290: ! 291: if (rmmproc) { ! 292: if (filep > 0) ! 293: vec = files; ! 294: else { ! 295: if (mp -> numsel > MAXARGS - 2) ! 296: adios (NULLCP, "more than %d messages for %s exec", ! 297: MAXARGS - 2, rmmproc); ! 298: vec = (char **) calloc ((unsigned) (mp -> numsel + 2), sizeof *vec); ! 299: if (vec == NULL) ! 300: adios (NULLCP, "unable to allocate exec vector"); ! 301: vecp = 1; ! 302: for (i = mp -> lowsel; i <= mp -> hghsel; i++) ! 303: if (mp -> msgstats[i] & SELECTED) ! 304: vec[vecp++] = getcpy (m_name (i)); ! 305: vec[vecp] = NULL; ! 306: } ! 307: ! 308: (void) fflush (stdout); ! 309: vec[0] = r1bindex (rmmproc, '/'); ! 310: execvp (rmmproc, vec); ! 311: adios (rmmproc, "unable to exec"); ! 312: } ! 313: ! 314: if (filep > 0) { ! 315: for (i = 0; i < filep; i++) ! 316: if (unlink (files[i]) == NOTOK) ! 317: admonish (files[i], "unable to unlink"); ! 318: } ! 319: else ! 320: for (i = mp -> lowsel; i <= mp -> hghsel; i++) ! 321: if (mp -> msgstats[i] & SELECTED) ! 322: if (unlink (cp = m_name (i)) == NOTOK) ! 323: admonish (cp, "unable to unlink"); ! 324: } ! 325: ! 326: /* */ ! 327: ! 328: m_file (msg, folders, nfolders, prsrvf) ! 329: register char *msg; ! 330: struct st_fold *folders; ! 331: int nfolders, ! 332: prsrvf; ! 333: { ! 334: int in, ! 335: out, ! 336: linkerr, ! 337: msgnum; ! 338: register char *nmsg; ! 339: char newmsg[BUFSIZ]; ! 340: register struct st_fold *fp, ! 341: *ep; ! 342: register struct msgs *mp; ! 343: struct stat st, ! 344: s1; ! 345: ! 346: for (ep = (fp = folders) + nfolders; fp < ep; fp++) { ! 347: mp = fp -> f_mp; ! 348: if (prsrvf && (msgnum = m_atoi (nmsg = msg)) > 0) { ! 349: if (msgnum >= mp -> hghoff) ! 350: if (mp = m_remsg (mp, 0, msgnum + MAXFOLDER)) ! 351: fp -> f_mp = mp; ! 352: else ! 353: adios (NULLCP, "unable to allocate folder storage"); ! 354: if (!(mp -> msgstats[msgnum] & EXISTS)) { ! 355: mp -> msgstats[msgnum] |= EXISTS; ! 356: #ifdef notdef ! 357: mp -> msgstats[msgnum] &= ~DELETED; ! 358: #endif notdef ! 359: mp -> nummsg++; ! 360: } ! 361: mp -> msgstats[msgnum] |= SELECTED; ! 362: if (msgnum > mp -> hghmsg) ! 363: mp -> hghmsg = msgnum; ! 364: } ! 365: else { ! 366: if (mp -> hghmsg >= mp -> hghoff) ! 367: if (mp = m_remsg (mp, 0, mp -> hghoff + MAXFOLDER)) ! 368: fp -> f_mp = mp; ! 369: else ! 370: adios (NULLCP, "unable to allocate folder storage"); ! 371: ! 372: nmsg = m_name (msgnum = ++mp -> hghmsg); ! 373: mp -> nummsg++; ! 374: mp -> msgstats[msgnum] |= EXISTS | SELECTED; ! 375: } ! 376: if (mp -> lowmsg == 0) ! 377: mp -> lowmsg = msgnum; ! 378: if (mp -> lowsel == 0 || msgnum < mp -> lowsel) ! 379: mp -> lowsel = msgnum; ! 380: if (msgnum > mp -> hghsel) ! 381: mp -> hghsel = msgnum; ! 382: ! 383: /* */ ! 384: ! 385: (void) sprintf (newmsg, "%s/%s", mp -> foldpath, nmsg); ! 386: if (link (msg, newmsg) == NOTOK) { ! 387: linkerr = errno; ! 388: if (linkerr == EEXIST ! 389: || (linkerr == EXDEV && stat (newmsg, &st) != NOTOK)) { ! 390: if (linkerr != EEXIST ! 391: || stat (msg, &s1) == NOTOK ! 392: || stat (newmsg, &st) == NOTOK ! 393: || s1.st_ino != st.st_ino) { ! 394: advise (NULLCP, "message %s:%s already exists", ! 395: fp -> f_name, newmsg); ! 396: return 1; ! 397: } ! 398: continue; ! 399: } ! 400: if (linkerr == EXDEV) { ! 401: if ((in = open (msg, 0)) == NOTOK) { ! 402: advise (msg, "unable to open message %s"); ! 403: return 1; ! 404: } ! 405: (void) fstat (in, &st); ! 406: if ((out = creat (newmsg, (int) st.st_mode & 0777)) ! 407: == NOTOK) { ! 408: advise (newmsg, "unable to create"); ! 409: (void) close (in); ! 410: return 1; ! 411: } ! 412: cpydata (in, out, msg, newmsg); ! 413: (void) close (in); ! 414: (void) close (out); ! 415: } ! 416: else { ! 417: advise (newmsg, "error linking %s to", msg); ! 418: return 1; ! 419: } ! 420: } ! 421: } ! 422: ! 423: return 0; ! 424: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.