Fix out-of-bounds error when incorporating email from stdin
[mmh] / sbr / seq_del.c
1 /*
2 ** seq_del.c -- delete message(s) from a sequence
3 **
4 ** This code is Copyright (c) 2002, by the authors of nmh.  See the
5 ** COPYRIGHT file in the root directory of the nmh distribution for
6 ** complete copyright information.
7 */
8
9 #include <h/mh.h>
10
11
12 /*
13 ** Delete all SELECTED messages from sequence
14 **
15 ** If public ==  1, make sequence public.
16 ** If public ==  0, make sequence private.
17 ** If public == -1, leave the public/private bit alone for existing
18 **                  sequences.  For new sequences, set this bit based
19 **                  on its readonly status.
20 **
21 ** If error, return 0, else return 1.
22 */
23
24 int
25 seq_delsel(struct msgs *mp, char *cp, int public, int zero)
26 {
27         unsigned int i;
28         int msgnum, new_seq = 1;
29
30         if (!seq_nameok(cp))
31                 return 0;
32
33         /*
34         ** Get the number for this sequence
35         */
36         for (i = 0; mp->msgattrs[i]; i++) {
37                 if (strcmp(mp->msgattrs[i], cp)==0) {
38                         new_seq = 0;
39                         break;
40                 }
41         }
42
43         /*
44         ** If the zero flag is set, first add all existing
45         ** messages in this folder to the sequence.
46         */
47         if (zero) {
48                 /*
49                 ** create the sequence, if necessary
50                 */
51                 if (new_seq) {
52                         if (i >= NUMATTRS) {
53                                 advise(NULL, "only %d sequences allowed (no room for %s)!", NUMATTRS, cp);
54                                 return 0;
55                         }
56                         if (!(mp->msgattrs[i] = strdup(cp))) {
57                                 advise(NULL, "strdup failed");
58                                 return 0;
59                         }
60                         mp->msgattrs[i + 1] = NULL;
61                 }
62                 /*
63                 ** now add sequence bit to all existing messages
64                 */
65                 for (msgnum = mp->lowmsg; msgnum <= mp->hghmsg; msgnum++) {
66                         if (does_exist(mp, msgnum))
67                                 add_sequence(mp, i, msgnum);
68                         else
69                                 clear_sequence(mp, i, msgnum);
70                 }
71         } else {
72                 if (new_seq) {
73                         advise(NULL, "no such sequence as %s", cp);
74                         return 0;
75                 }
76         }
77
78         /*
79         ** Now clear the bit on all selected messages
80         */
81         for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++)
82                 if (is_selected(mp, msgnum))
83                         clear_sequence(mp, i, msgnum);
84
85         /*
86         ** Set the public/private bit for this sequence.
87         */
88         if (public == 1)
89                 make_seq_public(mp, i);
90         else if (public == 0)
91                 make_seq_private(mp, i);
92         else if (new_seq) {
93                 /*
94                 ** If public == -1, then only set the
95                 ** public/private bit for new sequences.
96                 */
97                 if (is_readonly(mp))
98                         make_seq_private(mp, i);
99                 else
100                         make_seq_public(mp, i);
101         }
102
103         mp->msgflags |= SEQMOD;
104         return 1;
105 }
106
107
108 /*
109 ** Delete message from sequence.
110 **
111 ** If error, return 0, else return 1.
112 */
113
114 int
115 seq_delmsg(struct msgs *mp, char *cp, int msgnum)
116 {
117         int i;
118
119         if (!seq_nameok(cp))
120                 return 0;
121
122         for (i = 0; mp->msgattrs[i]; i++) {
123                 if (strcmp(mp->msgattrs[i], cp)==0) {
124                         clear_sequence(mp, i, msgnum);
125                         mp->msgflags |= SEQMOD;
126                         return 1;
127                 }
128         }
129
130         advise(NULL, "no such sequence as %s", cp);
131         return 0;
132 }