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

Defined functions

clsfolds defined in line 264; used 1 times
m_file defined in line 328; used 2 times
main defined in line 54; never used
opnfolds defined in line 224; used 2 times
remove defined in line 281; used 2 times

Defined variables

maildir defined in line 42; used 4 times
switches defined in line 11; used 3 times

Defined struct's

st_fold defined in line 45; used 14 times

Defined macros

DRAFTSW defined in line 12; never used
FILESW defined in line 28; never used
HELPSW defined in line 31; never used
LINKSW defined in line 15; never used
NLINKSW defined in line 17; never used
NPRESSW defined in line 22; never used
PRESSW defined in line 20; never used
SRCSW defined in line 25; never used
Last modified: 1986-04-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1880
Valid CSS Valid XHTML 1.0 Strict