|
|
1.1 ! root 1: /* sortm.c - sort messages in a folder by date/time */ ! 2: ! 3: #include "../h/mh.h" ! 4: #include "../zotnet/tws.h" ! 5: #include <stdio.h> ! 6: ! 7: /* */ ! 8: ! 9: static struct swit switches[] = { ! 10: #define DATESW 0 ! 11: "datefield field", 0, ! 12: ! 13: #define VERBSW 1 ! 14: "verbose", 0, ! 15: #define NVERBSW 2 ! 16: "noverbose", 0, ! 17: ! 18: #define HELPSW 3 ! 19: "help", 4, ! 20: ! 21: NULL, NULL ! 22: }; ! 23: ! 24: /* */ ! 25: ! 26: struct smsg { ! 27: int s_msg; ! 28: struct tws s_tws; ! 29: }; ! 30: ! 31: static struct smsg *smsgs; ! 32: ! 33: ! 34: int msgsort (); ! 35: ! 36: struct tws *getws (); ! 37: ! 38: ! 39: long time (); ! 40: ! 41: /* */ ! 42: ! 43: /* ARGSUSED */ ! 44: ! 45: main (argc, argv) ! 46: int argc; ! 47: char **argv; ! 48: { ! 49: int verbosw = 0, ! 50: msgp = 0, ! 51: i, ! 52: msgnum; ! 53: char *cp, ! 54: *maildir, ! 55: *datesw = NULL, ! 56: *folder = NULL, ! 57: buf[100], ! 58: **ap, ! 59: **argp, ! 60: *arguments[MAXARGS], ! 61: *msgs[MAXARGS]; ! 62: struct msgs *mp; ! 63: ! 64: invo_name = r1bindex (argv[0], '/'); ! 65: if ((cp = m_find (invo_name)) != NULL) { ! 66: ap = brkstring (cp = getcpy (cp), " ", "\n"); ! 67: ap = copyip (ap, arguments); ! 68: } ! 69: else ! 70: ap = arguments; ! 71: (void) copyip (argv + 1, ap); ! 72: argp = arguments; ! 73: ! 74: /* */ ! 75: ! 76: while (cp = *argp++) { ! 77: if (*cp == '-') ! 78: switch (smatch (++cp, switches)) { ! 79: case AMBIGSW: ! 80: ambigsw (cp, switches); ! 81: done (1); ! 82: case UNKWNSW: ! 83: adios (NULLCP, "-%s unknown", cp); ! 84: case HELPSW: ! 85: (void) sprintf (buf, "%s [+folder] [msgs] [switches]", ! 86: invo_name); ! 87: help (buf, switches); ! 88: done (1); ! 89: ! 90: case DATESW: ! 91: if (datesw) ! 92: adios (NULLCP, "only one date field at a time!"); ! 93: if (!(datesw = *argp++) || *datesw == '-') ! 94: adios (NULLCP, "missing argument to %s", argp[-2]); ! 95: continue; ! 96: ! 97: case VERBSW: ! 98: verbosw++; ! 99: continue; ! 100: case NVERBSW: ! 101: verbosw = 0; ! 102: continue; ! 103: } ! 104: if (*cp == '+' || *cp == '@') { ! 105: if (folder) ! 106: adios (NULLCP, "only one folder at a time!"); ! 107: else ! 108: folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); ! 109: } ! 110: else ! 111: msgs[msgp++] = cp; ! 112: } ! 113: ! 114: /* */ ! 115: ! 116: if (!m_find ("path")) ! 117: free (path ("./", TFOLDER)); ! 118: if (!msgp) ! 119: msgs[msgp++] = "all"; ! 120: if (!datesw) ! 121: datesw = "Date"; ! 122: if (!folder) ! 123: folder = m_getfolder (); ! 124: maildir = m_maildir (folder); ! 125: ! 126: if (chdir (maildir) == NOTOK) ! 127: adios (maildir, "unable to change directory to"); ! 128: if (!(mp = m_gmsg (folder))) ! 129: adios (NULLCP, "unable to read folder %s", folder); ! 130: if (mp -> hghmsg == 0) ! 131: adios (NULLCP, "no messages in %s", folder); ! 132: ! 133: for (msgnum = 0; msgnum < msgp; msgnum++) ! 134: if (!m_convert (mp, msgs[msgnum])) ! 135: done (1); ! 136: m_setseq (mp); ! 137: ! 138: if ((i = read_dates (mp, datesw)) <= 0) ! 139: adios (NULLCP, "no messages to sort"); ! 140: qsort ((char *) smsgs, i, sizeof *smsgs, msgsort); ! 141: file_dates (mp, verbosw); ! 142: ! 143: m_replace (pfolder, folder); ! 144: m_sync (mp); ! 145: m_update (); ! 146: ! 147: done (0); ! 148: } ! 149: ! 150: /* */ ! 151: ! 152: static int read_dates (mp, datesw) ! 153: register struct msgs *mp; ! 154: register char *datesw; ! 155: { ! 156: int msgnum; ! 157: struct tws tb; ! 158: register struct smsg *s; ! 159: register struct tws *tw; ! 160: ! 161: twscopy (&tb, dtwstime ()); ! 162: ! 163: smsgs = (struct smsg *) ! 164: calloc ((unsigned) (mp -> hghsel - mp -> lowsel + 2), ! 165: sizeof *smsgs); ! 166: if (smsgs == NULL) ! 167: adios (NULLCP, "unable to allocate sort storage"); ! 168: ! 169: s = smsgs; ! 170: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) { ! 171: tw = NULL; ! 172: if (mp -> msgstats[msgnum] & SELECTED) { ! 173: if ((tw = getws (datesw, msgnum)) == NULL) ! 174: tw = msgnum != mp -> lowsel ? &((s - 1) -> s_tws) : &tb; ! 175: } ! 176: else ! 177: if (mp -> msgstats[msgnum] & EXISTS) ! 178: tw = &tb; ! 179: ! 180: if (tw) { ! 181: s -> s_msg = msgnum; ! 182: twscopy (&s -> s_tws, tw); ! 183: s++; ! 184: } ! 185: } ! 186: ! 187: s -> s_msg = 0; ! 188: return (s - smsgs); ! 189: } ! 190: ! 191: /* */ ! 192: ! 193: static struct tws *getws (datesw, msg) ! 194: register char *datesw; ! 195: int msg; ! 196: { ! 197: int compnum, ! 198: state; ! 199: register char *hp, ! 200: *msgnam; ! 201: char buf[BUFSIZ], ! 202: nam[NAMESZ]; ! 203: register struct tws *tw; ! 204: register FILE *in; ! 205: ! 206: if ((in = fopen (msgnam = m_name (msg), "r")) == NULL) { ! 207: admonish (msgnam, "unable to read message"); ! 208: return NULL; ! 209: } ! 210: ! 211: /* */ ! 212: ! 213: for (compnum = 1, state = FLD, hp = NULL;;) { ! 214: switch (state = m_getfld (state, nam, buf, sizeof buf, in)) { ! 215: case FLD: ! 216: case FLDEOF: ! 217: case FLDPLUS: ! 218: compnum++; ! 219: if (hp != NULL) ! 220: free (hp), hp = NULL; ! 221: hp = add (buf, NULLCP); ! 222: while (state == FLDPLUS) { ! 223: state = m_getfld (state, nam, buf, sizeof buf, in); ! 224: hp = add (buf, hp); ! 225: } ! 226: if (uleq (nam, datesw)) ! 227: break; ! 228: if (state != FLDEOF) ! 229: continue; ! 230: ! 231: case BODY: ! 232: case BODYEOF: ! 233: case FILEEOF: ! 234: admonish (NULLCP, "no %s field in message %d", datesw, msg); ! 235: ! 236: case LENERR: ! 237: case FMTERR: ! 238: if (state == LENERR || state == FMTERR) ! 239: admonish (NULLCP, ! 240: "format error in message %d(header #%d)", ! 241: msg, compnum); ! 242: if (hp != NULL) ! 243: free (hp); ! 244: (void) fclose (in); ! 245: return NULL; ! 246: ! 247: default: ! 248: adios (NULLCP, "internal error -- you lose"); ! 249: } ! 250: break; ! 251: } ! 252: ! 253: if ((tw = dparsetime (hp)) == NULL) ! 254: admonish (NULLCP, "unable to parse %s field in message %d", ! 255: datesw, msg); ! 256: ! 257: if (hp != NULL) ! 258: free (hp); ! 259: (void) fclose (in); ! 260: return tw; ! 261: } ! 262: ! 263: /* */ ! 264: ! 265: static int msgsort (a, b) ! 266: register struct smsg *a, ! 267: *b; ! 268: { ! 269: return twsort (&a -> s_tws, &b -> s_tws); ! 270: } ! 271: ! 272: /* */ ! 273: ! 274: static file_dates (mp, verbosw) ! 275: register struct msgs *mp; ! 276: int verbosw; ! 277: { ! 278: register int i, ! 279: j, ! 280: k; ! 281: short stats; ! 282: char f1[BUFSIZ], ! 283: f2[BUFSIZ], ! 284: tmpfil[BUFSIZ]; ! 285: ! 286: (void) strcpy (tmpfil, m_scratch ("", invo_name)); ! 287: ! 288: for (i = 0; j = smsgs[i++].s_msg;) ! 289: if (i != j) { ! 290: (void) strcpy (f1, m_name (i)); ! 291: (void) strcpy (f2, m_name (j)); ! 292: if (mp -> msgstats[i] & EXISTS) { ! 293: if (verbosw) ! 294: printf ("swap messages %s and %s\n", f2, f1); ! 295: ! 296: if (rename (f1, tmpfil) == NOTOK) { ! 297: admonish (tmpfil, "unable to rename %s to ", f1); ! 298: continue; ! 299: } ! 300: ! 301: if (rename (f2, f1) == NOTOK) { ! 302: admonish (f1, "unable to rename %s to", f2); ! 303: continue; ! 304: } ! 305: ! 306: if (rename (tmpfil, f2) == NOTOK) { ! 307: admonish (f2, "unable to rename %s to", tmpfil); ! 308: continue; ! 309: } ! 310: ! 311: for (k = i; smsgs[k].s_msg; k++) ! 312: if (smsgs[k].s_msg == i) { ! 313: smsgs[k].s_msg = j; ! 314: break; ! 315: } ! 316: } ! 317: else { ! 318: if (verbosw) ! 319: printf ("message %s becomes message %s\n", f2, f1); ! 320: ! 321: if (rename (f2, f1) == NOTOK) { ! 322: admonish (f1, "unable to rename %s to ", f2); ! 323: continue; ! 324: } ! 325: } ! 326: ! 327: smsgs[i - 1].s_msg = i; ! 328: stats = mp -> msgstats[i]; ! 329: mp -> msgstats[i] = mp -> msgstats[j]; ! 330: mp -> msgstats[j] = stats; ! 331: if (mp -> curmsg == j) ! 332: m_setcur (mp, i); ! 333: mp -> msgflags |= SEQMOD; ! 334: } ! 335: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.