Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / uip / mark.c
1 /* mark.c - mark messages */
2 #ifndef lint
3 static char ident[] = "@(#)$Id: mark.c,v 1.5 1995/12/06 23:44:31 jromine Exp $";
4 #endif  /* lint */
5
6 #include "../h/mh.h"
7 #include <stdio.h>
8 #ifdef LOCALE
9 #include        <locale.h>
10 #endif
11
12 /* \f */
13
14 static struct swit switches[] = {
15 #define ADDSW   0
16     "add", 0,
17 #define DELSW   1
18     "delete", 0,
19 #define LSTSW   2
20     "list", 0,
21
22 #define SEQSW   3
23     "sequence name", 0,
24
25 #define PUBLSW  4
26     "public", 0,
27 #define NPUBLSW 5
28     "nopublic", 0,
29
30 #define ZEROSW  6
31     "zero", 0,
32 #define NZEROSW 7
33     "nozero", 0,
34
35 #define HELPSW  8
36     "help", 4,
37
38 #define DEBUGSW 9
39     "debug", -5,
40
41     NULL, 0
42 };
43
44 /* \f */
45
46 /* ARGSUSED */
47
48 main (argc, argv)
49 int     argc;
50 char  **argv;
51 {
52     int     addsw = 0,
53             deletesw = 0,
54             debugsw = 0,
55             listsw = 0,
56             publicsw = -1,
57             zerosw = 0,
58             seqp = 0,
59             msgp = 0,
60             i,
61             msgnum;
62     char   *cp,
63            *maildir,
64            *folder = NULL,
65             buf[100],
66           **ap,
67           **argp,
68            *arguments[MAXARGS],
69            *seqs[NATTRS + 1],
70            *msgs[MAXARGS];
71     struct msgs *mp;
72
73 #ifdef LOCALE
74         setlocale(LC_ALL, "");
75 #endif
76     invo_name = r1bindex (argv[0], '/');
77     if ((cp = m_find (invo_name)) != NULL) {
78         ap = brkstring (cp = getcpy (cp), " ", "\n");
79         ap = copyip (ap, arguments);
80     }
81     else
82         ap = arguments;
83     (void) copyip (argv + 1, ap);
84     argp = arguments;
85
86 /* \f */
87
88     while (cp = *argp++) {
89         if (*cp == '-')
90             switch (smatch (++cp, switches)) {
91                 case AMBIGSW: 
92                     ambigsw (cp, switches);
93                     done (1);
94                 case UNKWNSW: 
95                     adios (NULLCP, "-%s unknown\n", cp);
96                 case HELPSW: 
97                     (void) sprintf (buf, "%s [+folder] [msgs] [switches]",
98                             invo_name);
99                     help (buf, switches);
100                     done (1);
101
102                 case ADDSW: 
103                     addsw++;
104                     deletesw = listsw = 0;
105                     continue;
106                 case DELSW: 
107                     deletesw++;
108                     addsw = listsw = 0;
109                     continue;
110                 case LSTSW: 
111                     listsw++;
112                     addsw = deletesw = 0;
113                     continue;
114
115                 case SEQSW: 
116                     if (!(cp = *argp++) || *cp == '-')
117                         adios (NULLCP, "missing argument to %s", argp[-2]);
118                     if (seqp < NATTRS)
119                         seqs[seqp++] = cp;
120                     else
121                         adios (NULLCP, "only %d sequences allowed!", NATTRS);
122                     continue;
123
124                 case PUBLSW: 
125                     publicsw = 1;
126                     continue;
127                 case NPUBLSW: 
128                     publicsw = 0;
129                     continue;
130
131                 case DEBUGSW: 
132                     debugsw++;
133                     continue;
134
135                 case ZEROSW: 
136                     zerosw++;
137                     continue;
138                 case NZEROSW: 
139                     zerosw = 0;
140                     continue;
141             }
142         if (*cp == '+' || *cp == '@') {
143             if (folder)
144                 adios (NULLCP, "only one folder at a time!");
145             else
146                 folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
147         }
148         else
149             msgs[msgp++] = cp;
150     }
151
152 /* \f */
153
154     if (!addsw && !deletesw && !listsw)
155         if (seqp)
156             addsw++;
157         else
158             listsw++;
159
160     if (!m_find ("path"))
161         free (path ("./", TFOLDER));
162     if (!msgp)
163         msgs[msgp++] = listsw ? "all" :"cur";
164     if (!folder)
165         folder = m_getfolder ();
166     maildir = m_maildir (folder);
167
168     if (chdir (maildir) == NOTOK)
169         adios (maildir, "unable to change directory to");
170     if (!(mp = m_gmsg (folder)))
171         adios (NULLCP, "unable to read folder %s", folder);
172     if (mp -> hghmsg == 0)
173         adios (NULLCP, "no messages in %s", folder);
174
175     for (msgnum = 0; msgnum < msgp; msgnum++)
176         if (!m_convert (mp, msgs[msgnum]))
177             done (1);
178
179     if (publicsw == -1)
180         publicsw = mp -> msgflags & READONLY ? 0 : 1;
181     if (publicsw && (mp -> msgflags & READONLY))
182         adios (NULLCP, "folder %s is read-only, so -public not allowed",
183                 folder);
184
185 /* \f */
186
187     if (debugsw) {
188         printf ("invo_name=%s mypath=%s defpath=%s\n",
189                 invo_name, mypath, defpath);
190         printf ("ctxpath=%s context flags=%s\n",
191                 ctxpath, sprintb (buf, (unsigned) ctxflags, DBITS));
192         printf ("foldpath=%s flags=%s\n",
193                 mp -> foldpath,
194                 sprintb (buf, (unsigned) mp -> msgflags, FBITS));
195         printf ("lowmsg=%d hghmsg=%d nummsg=%d curmsg=%d\n",
196                 mp -> lowmsg, mp -> hghmsg, mp -> nummsg, mp -> curmsg);
197         printf ("lowsel=%d hghsel=%d numsel=%d\n",
198                 mp -> lowsel, mp -> hghsel, mp -> numsel);
199 #ifndef MTR
200         printf ("lowoff=%d hghoff=%d\n",
201                 mp -> lowoff, mp -> hghoff);
202 #else   /* MTR */
203         printf ("lowoff=%d hghoff=%d msgbase=0x%x msgstats=0x%x\n",
204                 mp -> lowoff, mp -> hghoff, mp -> msgbase, mp -> msgstats);
205 #endif  /* MTR */
206     }
207
208     if (seqp == 0 && (addsw || deletesw))
209         adios (NULLCP, "-%s requires at least one -sequence argument",
210                 addsw ? "add" : "delete");
211     seqs[seqp] = NULL;
212
213     if (addsw)
214         for (seqp = 0; seqs[seqp]; seqp++) {
215             if (zerosw && !m_seqnew (mp, seqs[seqp], publicsw))
216                 done (1);
217             for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
218                 if (mp -> msgstats[msgnum] & SELECTED)
219                     if (!m_seqadd (mp, seqs[seqp], msgnum, publicsw))
220                         done (1);
221         }
222
223     if (deletesw)
224         for (seqp = 0; seqs[seqp]; seqp++) {
225             if (zerosw)
226                 for (msgnum = mp -> lowmsg; msgnum <= mp -> hghmsg; msgnum++)
227                     if (mp -> msgstats[msgnum] & EXISTS)
228                         if (!m_seqadd (mp, seqs[seqp], msgnum, publicsw))
229                             done (1);
230             for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
231                 if (mp -> msgstats[msgnum] & SELECTED)
232                     if (!m_seqdel (mp, seqs[seqp], msgnum))
233                         done (1);
234         }
235
236     if (listsw) {
237         int bits = FFATTRSLOT;
238
239 #define empty(s)        ((s) ? (s) : "")
240         if (seqp == 0)
241             for (i = 0; mp -> msgattrs[i]; i++)
242                 printf ("%s%s: %s\n", mp -> msgattrs[i],
243                         mp -> attrstats & (1 << (bits + i))
244                             ? " (private)" : "",
245                         empty(m_seq (mp, mp -> msgattrs[i])));
246         else
247             for (seqp = 0; seqs[seqp]; seqp++)
248                 printf ("%s: %s\n", seqs[seqp], empty(m_seq (mp, seqs[seqp])));
249 #undef  empty
250
251         if (debugsw)
252             for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
253                 if (mp -> msgstats[msgnum] & SELECTED)
254                     printf ("%*d: %s\n", DMAXFOLDER, msgnum,
255                         sprintb (buf, (unsigned) mp -> msgstats[msgnum],
256                             m_seqbits (mp)));
257     }
258
259     m_replace (pfolder, folder);
260     m_sync (mp);
261     m_update ();
262
263     done (0);
264 }