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

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

unix.superglobalmegacorp.com

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