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