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