Annotation of 43BSD/contrib/mh/uip/sortm.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.