source: trunk/third/nmh/uip/mark.c @ 12455

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