Annotation of 43BSDReno/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: 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: }

unix.superglobalmegacorp.com

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