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: }

Defined functions

file_dates defined in line 274; used 1 times
getws defined in line 193; used 2 times
main defined in line 45; never used
msgsort defined in line 265; used 2 times
read_dates defined in line 152; used 1 times

Defined variables

smsgs defined in line 31; used 12 times
switches defined in line 9; used 3 times

Defined struct's

smsg defined in line 26; used 8 times

Defined macros

DATESW defined in line 10; never used
HELPSW defined in line 18; never used
NVERBSW defined in line 15; never used
VERBSW defined in line 13; never used
Last modified: 1985-11-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1414
Valid CSS Valid XHTML 1.0 Strict