|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.