1 /* refile.c - file messages away */
3 static char ident[] = "@(#)$Id: refile.c,v 1.10 1992/12/15 00:20:22 jromine Exp $";
17 static struct swit switches[] = {
53 static char maildir[BUFSIZ];
61 static opnfolds(), clsfolds(), removeit();
84 *filevec[NFOLDERS + 2],
85 **files = &filevec[1], /* leave room for removeit:vec[0] */
87 struct st_fold folders[NFOLDERS + 1];
91 setlocale(LC_ALL, "");
93 invo_name = r1bindex (argv[0], '/');
94 if ((cp = m_find (invo_name)) != NULL) {
95 ap = brkstring (cp = getcpy (cp), " ", "\n");
96 ap = copyip (ap, arguments);
100 (void) copyip (argv + 1, ap);
105 while (cp = *argp++) {
107 switch (smatch (++cp, switches)) {
109 ambigsw (cp, switches);
112 adios (NULLCP, "-%s unknown\n", cp);
114 (void) sprintf (buf, "%s [msgs] [switches] +folder ...",
116 help (buf, switches);
135 adios (NULLCP, "only one source folder at a time!");
136 if (!(cp = *argp++) || *cp == '-')
137 adios (NULLCP, "missing argument to %s", argp[-2]);
138 folder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp,
139 *cp != '@' ? TFOLDER : TSUBCWF);
142 if (filep > NFOLDERS)
143 adios (NULLCP, "only %d files allowed!", NFOLDERS);
145 files[filep++] = getcpy (m_draft (NULLCP, NULLCP, 1, &isdf));
148 if (filep > NFOLDERS)
149 adios (NULLCP, "only %d files allowed!", NFOLDERS);
150 if (!(cp = *argp++) || *cp == '-')
151 adios (NULLCP, "missing argument to %s", argp[-2]);
152 files[filep++] = path (cp, TFILE);
156 if (!(rmmproc = *argp++) || *rmmproc == '-')
157 adios (NULLCP, "missing argument to %s", argp[-2]);
163 if (*cp == '+' || *cp == '@') {
164 if (foldp > NFOLDERS)
165 adios (NULLCP, "only %d folders allowed!", NFOLDERS);
166 folders[foldp++].f_name =
167 path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
175 if (!m_find ("path"))
176 free (path ("./", TFOLDER));
178 adios (NULLCP, "no folder specified");
181 if (!msgp && !foldp && !filep && (cp = getenv ("mhdraft")) && *cp)
187 adios (NULLCP, "use -file or some messages, not both");
188 opnfolds (folders, foldp);
189 for (i = 0; i < filep; i++)
190 if (m_file (files[i], folders, foldp, prsrvf))
193 removeit (NULLMP, filep, filevec);
198 msgs[msgp++] = "cur";
200 folder = m_getfolder ();
201 (void) strcpy (maildir, m_maildir (folder));
203 if (chdir (maildir) == NOTOK)
204 adios (maildir, "unable to change directory to");
205 if (!(mp = m_gmsg (folder)))
206 adios (NULLCP, "unable to read folder %s", folder);
207 if (mp -> hghmsg == 0)
208 adios (NULLCP, "no messages in %s", folder);
210 for (msgnum = 0; msgnum < msgp; msgnum++)
211 if (!m_convert (mp, msgs[msgnum]))
215 opnfolds (folders, foldp);
216 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
217 if (mp -> msgstats[msgnum] & SELECTED) {
218 cp = getcpy (m_name (msgnum));
219 if (m_file (cp, folders, foldp, prsrvf))
224 mp -> msgstats[msgnum] |= DELETED;
226 mp -> msgstats[msgnum] &= ~EXISTS;
230 mp -> msgflags |= SEQMOD;
231 clsfolds (folders, foldp);
233 m_replace (pfolder, folder);
234 if (mp -> hghsel != mp -> curmsg
235 && (mp -> numsel != mp -> nummsg || linkf))
236 m_setcur (mp, mp -> hghsel);
241 removeit (mp, filep, filevec);
248 static opnfolds (folders, nfolders)
249 register struct st_fold *folders;
253 char nmaildir[BUFSIZ];
254 register struct st_fold *fp,
256 register struct msgs *mp;
259 for (ep = (fp = folders) + nfolders; fp < ep; fp++) {
260 (void) chdir (m_maildir (""));
261 (void) strcpy (nmaildir, m_maildir (fp -> f_name));
263 if (stat (nmaildir, &st) == NOTOK) {
265 adios (nmaildir, "error on folder");
266 cp = concat ("Create folder \"", nmaildir, "\"? ", NULLCP);
270 if (!makedir (nmaildir))
271 adios (NULLCP, "unable to create folder %s", nmaildir);
274 if (chdir (nmaildir) == NOTOK)
275 adios (nmaildir, "unable to change directory to");
276 if (!(mp = m_gmsg (fp -> f_name)))
277 adios (NULLCP, "unable to read folder %s", fp -> f_name);
282 (void) chdir (maildir);
288 static clsfolds (folders, nfolders)
289 register struct st_fold *folders;
292 register struct st_fold *fp,
294 register struct msgs *mp;
296 for (ep = (fp = folders) + nfolders; fp < ep; fp++) {
305 static removeit (mp, filep, files)
306 register struct msgs *mp;
308 register char **files;
317 vec = files++; /* filevec[1] */
321 if (mp -> numsel > MAXARGS - 2)
322 adios (NULLCP, "more than %d messages for %s exec",
323 MAXARGS - 2, rmmproc);
324 vec = (char **) calloc ((unsigned) (mp -> numsel + 2), sizeof *vec);
326 adios (NULLCP, "unable to allocate exec vector");
328 for (i = mp -> lowsel; i <= mp -> hghsel; i++)
329 if (mp -> msgstats[i] & SELECTED)
330 vec[vecp++] = getcpy (m_name (i));
334 (void) fflush (stdout);
335 vec[0] = r1bindex (rmmproc, '/');
336 execvp (rmmproc, vec);
337 adios (rmmproc, "unable to exec");
341 files++; /* filevec[1] */
342 for (i = 0; i < filep; i++)
343 if (unlink (files[i]) == NOTOK)
344 admonish (files[i], "unable to unlink");
347 for (i = mp -> lowsel; i <= mp -> hghsel; i++)
348 if (mp -> msgstats[i] & SELECTED)
349 if (unlink (cp = m_name (i)) == NOTOK)
350 admonish (cp, "unable to unlink");
355 m_file (msg, folders, nfolders, prsrvf)
357 struct st_fold *folders;
367 register struct st_fold *fp,
369 register struct msgs *mp;
373 for (ep = (fp = folders) + nfolders; fp < ep; fp++) {
375 if (prsrvf && (msgnum = m_atoi (nmsg = msg)) > 0) {
376 if (msgnum >= mp -> hghoff)
377 if (mp = m_remsg (mp, 0, msgnum + MAXFOLDER))
380 adios (NULLCP, "unable to allocate folder storage");
381 if (!(mp -> msgstats[msgnum] & EXISTS)) {
382 mp -> msgstats[msgnum] |= EXISTS;
384 mp -> msgstats[msgnum] &= ~DELETED;
388 mp -> msgstats[msgnum] |= SELECTED;
389 if (msgnum > mp -> hghmsg)
390 mp -> hghmsg = msgnum;
393 if (mp -> hghmsg >= mp -> hghoff)
394 if (mp = m_remsg (mp, 0, mp -> hghoff + MAXFOLDER))
397 adios (NULLCP, "unable to allocate folder storage");
399 nmsg = m_name (msgnum = ++mp -> hghmsg);
401 mp -> msgstats[msgnum] |= EXISTS | SELECTED;
403 if (mp -> lowmsg == 0)
404 mp -> lowmsg = msgnum;
405 if (mp -> lowsel == 0 || msgnum < mp -> lowsel)
406 mp -> lowsel = msgnum;
407 if (msgnum > mp -> hghsel)
408 mp -> hghsel = msgnum;
412 (void) sprintf (newmsg, "%s/%s", mp -> foldpath, nmsg);
413 if (link (msg, newmsg) == NOTOK) {
416 #else /* EISREMOTE */
417 if ((linkerr = errno) == EISREMOTE)
419 #endif /* EISREMOTE */
420 if (linkerr == EEXIST
421 || (linkerr == EXDEV && stat (newmsg, &st) != NOTOK)) {
422 if (linkerr != EEXIST
423 || stat (msg, &s1) == NOTOK
424 || stat (newmsg, &st) == NOTOK
425 || s1.st_ino != st.st_ino) {
426 advise (NULLCP, "message %s:%s already exists",
427 fp -> f_name, newmsg);
432 if (linkerr == EXDEV) {
433 if ((in = open (msg, 0)) == NOTOK) {
434 advise (msg, "unable to open message %s");
437 (void) fstat (in, &st);
438 if ((out = creat (newmsg, (int) st.st_mode & 0777))
440 advise (newmsg, "unable to create");
444 cpydata (in, out, msg, newmsg);
449 advise (newmsg, "error linking %s to", msg);