]> diplodocus.org Git - nmh/blob - uip/mark.c
We're not using the .Bu macro anymore.
[nmh] / uip / mark.c
1
2 /*
3 * mark.c -- add message(s) to sequences in given folder
4 * -- delete messages (s) from sequences in given folder
5 * -- list sequences in given folder
6 *
7 * $Id$
8 *
9 * This code is Copyright (c) 2002, by the authors of nmh. See the
10 * COPYRIGHT file in the root directory of the nmh distribution for
11 * complete copyright information.
12 */
13
14 #include <h/mh.h>
15 #include <h/utils.h>
16
17 static struct swit switches[] = {
18 #define ADDSW 0
19 { "add", 0 },
20 #define DELSW 1
21 { "delete", 0 },
22 #define LSTSW 2
23 { "list", 0 },
24 #define SEQSW 3
25 { "sequence name", 0 },
26 #define PUBLSW 4
27 { "public", 0 },
28 #define NPUBLSW 5
29 { "nopublic", 0 },
30 #define ZEROSW 6
31 { "zero", 0 },
32 #define NZEROSW 7
33 { "nozero", 0 },
34 #define VERSIONSW 8
35 { "version", 0 },
36 #define HELPSW 9
37 { "help", 0 },
38 #define DEBUGSW 10
39 { "debug", -5 },
40 { NULL, 0 }
41 };
42
43 /*
44 * static prototypes
45 */
46 static void print_debug (struct msgs *);
47 static void seq_printdebug (struct msgs *);
48
49
50 int
51 main (int argc, char **argv)
52 {
53 int addsw = 0, deletesw = 0, debugsw = 0;
54 int listsw = 0, publicsw = -1, zerosw = 0;
55 int seqp = 0, msgnum;
56 char *cp, *maildir, *folder = NULL, buf[BUFSIZ];
57 char **argp, **arguments;
58 char *seqs[NUMATTRS + 1];
59 struct msgs_array msgs = { 0, 0, NULL };
60 struct msgs *mp;
61
62 #ifdef LOCALE
63 setlocale(LC_ALL, "");
64 #endif
65 invo_name = r1bindex (argv[0], '/');
66
67 /* read user profile/context */
68 context_read();
69
70 arguments = getarguments (invo_name, argc, argv, 1);
71 argp = arguments;
72
73 /*
74 * Parse arguments
75 */
76 while ((cp = *argp++)) {
77 if (*cp == '-') {
78 switch (smatch (++cp, switches)) {
79 case AMBIGSW:
80 ambigsw (cp, switches);
81 done (1);
82 case UNKWNSW:
83 adios (NULL, "-%s unknown\n", cp);
84
85 case HELPSW:
86 snprintf (buf, sizeof(buf), "%s [+folder] [msgs] [switches]",
87 invo_name);
88 print_help (buf, switches, 1);
89 done (1);
90 case VERSIONSW:
91 print_version(invo_name);
92 done (1);
93
94 case ADDSW:
95 addsw++;
96 deletesw = listsw = 0;
97 continue;
98 case DELSW:
99 deletesw++;
100 addsw = listsw = 0;
101 continue;
102 case LSTSW:
103 listsw++;
104 addsw = deletesw = 0;
105 continue;
106
107 case SEQSW:
108 if (!(cp = *argp++) || *cp == '-')
109 adios (NULL, "missing argument to %s", argp[-2]);
110
111 /* check if too many sequences specified */
112 if (seqp >= NUMATTRS)
113 adios (NULL, "too many sequences (more than %d) specified", NUMATTRS);
114 seqs[seqp++] = cp;
115 continue;
116
117 case PUBLSW:
118 publicsw = 1;
119 continue;
120 case NPUBLSW:
121 publicsw = 0;
122 continue;
123
124 case DEBUGSW:
125 debugsw++;
126 continue;
127
128 case ZEROSW:
129 zerosw++;
130 continue;
131 case NZEROSW:
132 zerosw = 0;
133 continue;
134 }
135 }
136 if (*cp == '+' || *cp == '@') {
137 if (folder)
138 adios (NULL, "only one folder at a time!");
139 else
140 folder = pluspath (cp);
141 } else
142 app_msgarg(&msgs, cp);
143 }
144
145 /*
146 * If we haven't specified -add, -delete, or -list,
147 * then use -add if a sequence was specified, else
148 * use -list.
149 */
150 if (!addsw && !deletesw && !listsw) {
151 if (seqp)
152 addsw++;
153 else
154 listsw++;
155 }
156
157 if (!context_find ("path"))
158 free (path ("./", TFOLDER));
159 if (!msgs.size)
160 app_msgarg(&msgs, listsw ? "all" :"cur");
161 if (!folder)
162 folder = getfolder (1);
163 maildir = m_maildir (folder);
164
165 if (chdir (maildir) == NOTOK)
166 adios (maildir, "unable to change directory to");
167
168 /* read folder and create message structure */
169 if (!(mp = folder_read (folder)))
170 adios (NULL, "unable to read folder %s", folder);
171
172 /* print some general debugging info */
173 if (debugsw)
174 print_debug(mp);
175
176 /* check for empty folder */
177 if (mp->nummsg == 0)
178 adios (NULL, "no messages in %s", folder);
179
180 /* parse all the message ranges/sequences and set SELECTED */
181 for (msgnum = 0; msgnum < msgs.size; msgnum++)
182 if (!m_convert (mp, msgs.msgs[msgnum]))
183 done (1);
184
185 if (publicsw == 1 && is_readonly(mp))
186 adios (NULL, "folder %s is read-only, so -public not allowed", folder);
187
188 /*
189 * Make sure at least one sequence has been
190 * specified if we are adding or deleting.
191 */
192 if (seqp == 0 && (addsw || deletesw))
193 adios (NULL, "-%s requires at least one -sequence argument",
194 addsw ? "add" : "delete");
195 seqs[seqp] = NULL;
196
197 /* Adding messages to sequences */
198 if (addsw) {
199 for (seqp = 0; seqs[seqp]; seqp++)
200 if (!seq_addsel (mp, seqs[seqp], publicsw, zerosw))
201 done (1);
202 }
203
204 /* Deleting messages from sequences */
205 if (deletesw) {
206 for (seqp = 0; seqs[seqp]; seqp++)
207 if (!seq_delsel (mp, seqs[seqp], publicsw, zerosw))
208 done (1);
209 }
210
211 /* Listing messages in sequences */
212 if (listsw) {
213 if (seqp) {
214 /* print the sequences given */
215 for (seqp = 0; seqs[seqp]; seqp++)
216 seq_print (mp, seqs[seqp]);
217 } else {
218 /* else print them all */
219 seq_printall (mp);
220 }
221
222 /* print debugging info about SELECTED messages */
223 if (debugsw)
224 seq_printdebug (mp);
225 }
226
227 seq_save (mp); /* synchronize message sequences */
228 context_replace (pfolder, folder); /* update current folder */
229 context_save (); /* save the context file */
230 folder_free (mp); /* free folder/message structure */
231 return done (0);
232 }
233
234
235 /*
236 * Print general debugging info
237 */
238 static void
239 print_debug (struct msgs *mp)
240 {
241 char buf[100];
242
243 printf ("invo_name = %s\n", invo_name);
244 printf ("mypath = %s\n", mypath);
245 printf ("defpath = %s\n", defpath);
246 printf ("ctxpath = %s\n", ctxpath);
247 printf ("context flags = %s\n", snprintb (buf, sizeof(buf),
248 (unsigned) ctxflags, DBITS));
249 printf ("foldpath = %s\n", mp->foldpath);
250 printf ("folder flags = %s\n\n", snprintb(buf, sizeof(buf),
251 (unsigned) mp->msgflags, FBITS));
252 printf ("lowmsg=%d hghmsg=%d nummsg=%d curmsg=%d\n",
253 mp->lowmsg, mp->hghmsg, mp->nummsg, mp->curmsg);
254 printf ("lowsel=%d hghsel=%d numsel=%d\n",
255 mp->lowsel, mp->hghsel, mp->numsel);
256 printf ("lowoff=%d hghoff=%d\n\n", mp->lowoff, mp->hghoff);
257 }
258
259
260 /*
261 * Print debugging info about all the SELECTED
262 * messages and the sequences they are in.
263 */
264 static void
265 seq_printdebug (struct msgs *mp)
266 {
267 int msgnum;
268 char buf[100];
269
270 printf ("\n");
271 for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
272 if (is_selected (mp, msgnum))
273 printf ("%*d: %s\n", DMAXFOLDER, msgnum,
274 snprintb (buf, sizeof(buf),
275 (unsigned) mp->msgstats[msgnum - mp->lowoff], seq_bits (mp)));
276 }
277 }