|
|
1.1 root 1: /* pick.c - select messages by content */
2:
3: #include "../h/mh.h"
4: #include "../zotnet/tws.h"
5: #include <stdio.h>
6:
7: /* */
8:
9: static struct swit switches[] = {
10: #define ANDSW 0
11: "and", 0,
12: #define ORSW 1
13: "or", 0,
14: #define NOTSW 2
15: "not", 0,
16: #define LBRSW 3
17: "lbrace", 0,
18: #define RBRSW 4
19: "rbrace", 0,
20:
21: #define CCSW 5
22: "cc pattern", 0,
23: #define DATESW 6
24: "date pattern", 0,
25: #define FROMSW 7
26: "from pattern", 0,
27: #define SRCHSW 8
28: "search pattern", 0,
29: #define SUBJSW 9
30: "subject pattern", 0,
31: #define TOSW 10
32: "to pattern", 0,
33: #define OTHRSW 11
34: "-othercomponent pattern", 0,
35: #define AFTRSW 12
36: "after date", 0,
37: #define BEFRSW 13
38: "before date", 0,
39: #define DATFDSW 14
40: "datefield field", 5,
41:
42: #define SEQSW 15
43: "sequence name", 0,
44: #define PUBLSW 16
45: "public", 0,
46: #define NPUBLSW 17
47: "nopublic", 0,
48: #define ZEROSW 18
49: "zero", 0,
50: #define NZEROSW 19
51: "nozero", 0,
52:
53: #define LISTSW 20
54: "list", 0,
55: #define NLISTSW 21
56: "nolist", 0,
57:
58: #define HELPSW 22
59: "help", 4,
60:
61: NULL, NULL
62: };
63:
64: /* */
65:
66: static int listsw = 0;
67:
68: /* */
69:
70: /* ARGSUSED */
71:
72: main(argc, argv)
73: int argc;
74: char *argv[];
75: {
76: int publicsw = -1,
77: zerosw = 1,
78: msgp = 0,
79: seqp = 0,
80: vecp = 0,
81: lo,
82: hi,
83: msgnum;
84: char *maildir,
85: *folder = NULL,
86: buf[100],
87: *cp,
88: **ap,
89: **argp,
90: *arguments[MAXARGS],
91: *msgs[MAXARGS],
92: *seqs[NATTRS + 1],
93: *vec[MAXARGS];
94: struct msgs *mp;
95: register FILE *fp;
96:
97: invo_name = r1bindex (argv[0], '/');
98: if ((cp = m_find (invo_name)) != NULL) {
99: ap = brkstring (cp = getcpy (cp), " ", "\n");
100: ap = copyip (ap, arguments);
101: }
102: else
103: ap = arguments;
104: (void) copyip (argv + 1, ap);
105: argp = arguments;
106:
107: /* */
108:
109: while (cp = *argp++) {
110: if (*cp == '-') {
111: if (*++cp == '-') {
112: vec[vecp++] = --cp;
113: goto pattern;
114: }
115: switch (smatch (cp, switches)) {
116: case AMBIGSW:
117: ambigsw (cp, switches);
118: done (1);
119: case UNKWNSW:
120: adios (NULLCP, "-%s unknown", cp);
121: case HELPSW:
122: (void) sprintf (buf, "%s [+folder] [msgs] [switches]",
123: invo_name);
124: help (buf, switches);
125: listsw = 0; /* HACK */
126: done (1);
127:
128: case CCSW:
129: case DATESW:
130: case FROMSW:
131: case SUBJSW:
132: case TOSW:
133: case DATFDSW:
134: case AFTRSW:
135: case BEFRSW:
136: case SRCHSW:
137: vec[vecp++] = --cp;
138: pattern: ;
139: if (!(cp = *argp++))/* allow -xyz arguments */
140: adios (NULLCP, "missing argument to %s", argp[-2]);
141: vec[vecp++] = cp;
142: continue;
143: case OTHRSW:
144: adios (NULLCP, "internal error!");
145:
146: case ANDSW:
147: case ORSW:
148: case NOTSW:
149: case LBRSW:
150: case RBRSW:
151: vec[vecp++] = --cp;
152: continue;
153:
154: case SEQSW:
155: if (!(cp = *argp++) || *cp == '-')
156: adios (NULLCP, "missing argument to %s", argp[-2]);
157: if (seqp < NATTRS)
158: seqs[seqp++] = cp;
159: else
160: adios (NULLCP, "only %d sequences allowed!", NATTRS);
161: listsw = 0;
162: continue;
163: case PUBLSW:
164: publicsw = 1;
165: continue;
166: case NPUBLSW:
167: publicsw = 0;
168: continue;
169: case ZEROSW:
170: zerosw++;
171: continue;
172: case NZEROSW:
173: zerosw = 0;
174: continue;
175:
176: case LISTSW:
177: listsw++;
178: continue;
179: case NLISTSW:
180: listsw = 0;
181: continue;
182: }
183: }
184: if (*cp == '+' || *cp == '@')
185: if (folder)
186: adios (NULLCP, "only one folder at a time!");
187: else
188: folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
189: else
190: msgs[msgp++] = cp;
191: }
192: vec[vecp] = NULL;
193:
194: /* */
195:
196: if (!m_find ("path"))
197: free (path ("./", TFOLDER));
198: if (!msgp)
199: msgs[msgp++] = "all";
200: if (!folder)
201: folder = m_getfolder ();
202: maildir = m_maildir (folder);
203:
204: if (chdir (maildir) == NOTOK)
205: adios (maildir, "unable to change directory to");
206: if (!(mp = m_gmsg (folder)))
207: adios (NULLCP, "unable to read folder %s", folder);
208: if (mp -> hghmsg == 0)
209: adios (NULLCP, "no messages in %s", folder);
210:
211: for (msgnum = 0; msgnum < msgp; msgnum++)
212: if (!m_convert (mp, msgs[msgnum]))
213: done (1);
214: m_setseq (mp);
215:
216: if (seqp == 0)
217: listsw++;
218: if (publicsw == -1)
219: publicsw = mp -> msgflags & READONLY ? 0 : 1;
220: if (publicsw && (mp -> msgflags & READONLY))
221: adios (NULLCP, "folder %s is read-only, so -public not allowed",
222: folder);
223:
224: /* */
225:
226: if (!pcompile (vec, NULLCP))
227: done (1);
228:
229: lo = mp -> lowsel;
230: hi = mp -> hghsel;
231:
232: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
233: if (mp -> msgstats[msgnum] & SELECTED) {
234: if ((fp = fopen (cp = m_name (msgnum), "r")) == NULL)
235: admonish (cp, "unable to read message");
236: if (fp && pmatches (fp, msgnum, 0L, 0L)) {
237: if (msgnum < lo)
238: lo = msgnum;
239: if (msgnum > hi)
240: hi = msgnum;
241: }
242: else {
243: mp -> msgstats[msgnum] &= ~SELECTED;
244: mp -> numsel--;
245: }
246: if (fp)
247: (void) fclose (fp);
248: }
249:
250: mp -> lowsel = lo;
251: mp -> hghsel = hi;
252:
253: if (mp -> numsel <= 0)
254: adios (NULLCP, "no messages match specification");
255:
256: /* */
257:
258: seqs[seqp] = NULL;
259: for (seqp = 0; seqs[seqp]; seqp++) {
260: if (zerosw && !m_seqnew (mp, seqs[seqp], publicsw))
261: done (1);
262: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
263: if (mp -> msgstats[msgnum] & SELECTED)
264: if (!m_seqadd (mp, seqs[seqp], msgnum, publicsw))
265: done (1);
266: }
267:
268: if (listsw) {
269: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
270: if (mp -> msgstats[msgnum] & SELECTED)
271: printf ("%s\n", m_name (msgnum));
272: }
273: else
274: printf ("%d hit%s\n", mp -> numsel,
275: mp -> numsel == 1 ? "" : "s");
276:
277: m_replace (pfolder, folder);
278: m_sync (mp);
279: m_update ();
280:
281: done (0);
282: }
283:
284: /* */
285:
286: void
287: done(status)
288: int status;
289: {
290: if (listsw && status && !isatty (fileno (stdout)))
291: printf ("0\n");
292: exit (status);
293: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.