Commit c08b926f c08b926f664b27953483a0dffcbe381ddaa154e5 by Sergey Poznyakoff

Re-implement MH sequences via mailbox properties.

* libmailutils/mailbox/header.c (mu_header_clear): New function.
(mu_header_sget_value_n): Tolerate pval == NULL.
* libmailutils/property/assocprop.c (_assoc_prop_setval): Bugfix.
(_assoc_prop_clear): New method.
(mu_assoc_property_init): Reference the stream.
(mu_assoc_property_init): Initialize _prop_clear.
* libmailutils/property/create.c (_mu_property_init): Now extern.
* libmailutils/property/propset.c (mu_property_set_value): Null value
means unset.
* libmailutils/tests/prop.at: Test property clear and invalidate.
* libmailutils/tests/prop.c: New commands: 0 for property clear and ! for
invalidate.

* libmailutils/property/mhprop.c: New file.
* libmailutils/property/propclr.c: New file.
* libmailutils/property/propinv.c: New file.
* libmailutils/property/Makefile.am (noinst_LTLIBRARIES): Add new files.

* include/mailutils/header.h (mu_header_clear): New proto.
* include/mailutils/property.h (mu_property_clear)
(mu_property_invalidate): New protos.
(mu_mh_prop): New struct.
(mu_mh_property_init): New proto.
* include/mailutils/sys/property.h (_mu_property) <_prop_clear>: New member.
(_mu_property_init): New proto.
* include/mailutils/mh.h: New file.
* include/mailutils/Makefile.am (pkginclude_HEADERS): Add mh.h

* libproto/mh/profile.c: New file.
* libproto/mh/Makefile.am (libmu_mh_la_SOURCES): Add new files.

* libproto/mh/mbox.c (mh_get_property): New static function.
(_mailbox_mh_init): Set _get_property.

* mh/mh_global.c (current_message, sequences): Remove.  Use mbox
properties instead.
(mh_global_sequences_get)
(mh_global_sequences_set)
(mh_global_sequences_iterate)
(mh_global_sequences_drop): Take mbox as first argument. All callers
updated.
* mh/mh_init.c (mh_init2): Remove call to mh_global_sequences_get.
* mh/mh_msgset.c (msgset_cur): Use mh_mailbox_get_cur.
* mh/mh_sequence.c (mh_seq_read, write_sequence)
(delete_sequence, mh_seq_add, mh_seq_delete): Take mbox as first argument.
All callers updated.

* mh/mh.h: Include mailutils/property.h.
(current_message): Remove.
(mh_mailbox_cur_default): New extern.
(mh_global_sequences_get)
(mh_global_sequences_set)
(mh_global_sequences_iterate)
(mh_global_sequences_drop): Take mbox as first argument. All callers
updated.

* mh/mh_format.c (builtin_cur): Rewrite using mh_message_number.

* mh/mboxprop.c: New file.
* mh/Makefile.am (libmh_a_SOURCES): Add new file.

* mh/folder.c: Update calls to sequence management functions.
* mh/mark.c: Likewise.
* mh/pick.c: Likewise.

* mh/inc.c (main): Set mh_mailbox_cur_default to 1.
Invalidate properties if changecur is not set.
* mh/prompter.c (main): Destroy the iterator.
* mh/rmf.c: Rewrite using mu_mailbox_remove.
* mh/scan.c: Always close the mailbox.

* mh/tests/folder.at: Update.
* mh/tests/inc.at: Update.  Inc now sets cur to 1 if it was not
originally set.  This is what others MHs do.
1 parent 77d2867d
...@@ -67,6 +67,7 @@ pkginclude_HEADERS = \ ...@@ -67,6 +67,7 @@ pkginclude_HEADERS = \
67 mailutils.h\ 67 mailutils.h\
68 md5.h\ 68 md5.h\
69 message.h\ 69 message.h\
70 mh.h\
70 mime.h\ 71 mime.h\
71 monitor.h\ 72 monitor.h\
72 mu_auth.h\ 73 mu_auth.h\
......
...@@ -78,6 +78,7 @@ extern "C" { ...@@ -78,6 +78,7 @@ extern "C" {
78 extern int mu_header_create (mu_header_t *, const char *, size_t); 78 extern int mu_header_create (mu_header_t *, const char *, size_t);
79 extern void mu_header_destroy (mu_header_t *); 79 extern void mu_header_destroy (mu_header_t *);
80 extern int mu_header_invalidate (mu_header_t); 80 extern int mu_header_invalidate (mu_header_t);
81 extern int mu_header_clear (mu_header_t header);
81 82
82 extern int mu_header_is_modified (mu_header_t); 83 extern int mu_header_is_modified (mu_header_t);
83 extern int mu_header_clear_modified (mu_header_t); 84 extern int mu_header_clear_modified (mu_header_t);
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2007, 2010 Free Software Foundation,
3 Inc.
4
5 GNU Mailutils is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 GNU Mailutils is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
17
18 #ifndef _MAILUTILS_MH_H
19 #define _MAILUTILS_MH_H
20
21 extern mu_property_t mu_mh_profile;
22 extern mu_property_t mu_mh_context;
23
24 #define MU_MH_SEQUENCES_FILE ".mh_sequences"
25 #define MU_MH_USER_PROFILE ".mh_profile"
26 #define MU_MH_GLOBAL_PROFILE "mh-profile"
27 #define MU_MH_CONTEXT_FILE "context"
28
29 typedef int (*mu_mhprop_iterator_t) (const char *field, const char *value,
30 void *data);
31
32 const char *mu_mhprop_get_value (mu_property_t prop, const char *name,
33 const char *defval);
34 int mu_mhprop_iterate (mu_property_t prop, mu_mhprop_iterator_t fp,
35 void *data);
36
37 #endif
38
...@@ -46,6 +46,8 @@ int mu_property_sget_value (mu_property_t prop, const char *key, ...@@ -46,6 +46,8 @@ int mu_property_sget_value (mu_property_t prop, const char *key,
46 const char **buffer); 46 const char **buffer);
47 int mu_property_aget_value (mu_property_t prop, const char *key, 47 int mu_property_aget_value (mu_property_t prop, const char *key,
48 char **buffer); 48 char **buffer);
49 int mu_property_clear (mu_property_t prop);
50 int mu_property_invalidate (mu_property_t prop);
49 51
50 /* Helper functions. */ 52 /* Helper functions. */
51 int mu_property_set (mu_property_t, const char *); 53 int mu_property_set (mu_property_t, const char *);
...@@ -57,6 +59,14 @@ int mu_property_get_iterator (mu_property_t, mu_iterator_t *itr); ...@@ -57,6 +59,14 @@ int mu_property_get_iterator (mu_property_t, mu_iterator_t *itr);
57 /* Implementation init functions */ 59 /* Implementation init functions */
58 int mu_assoc_property_init (mu_property_t); 60 int mu_assoc_property_init (mu_property_t);
59 61
62 struct mu_mh_prop
63 {
64 char *filename;
65 int ro;
66 };
67
68 int mu_mh_property_init (mu_property_t);
69
60 #ifdef __cplusplus 70 #ifdef __cplusplus
61 } 71 }
62 #endif 72 #endif
......
...@@ -62,8 +62,11 @@ struct _mu_property ...@@ -62,8 +62,11 @@ struct _mu_property
62 int (*_prop_unset) (struct _mu_property *, const char *); 62 int (*_prop_unset) (struct _mu_property *, const char *);
63 /* Return iterator for this property object */ 63 /* Return iterator for this property object */
64 int (*_prop_getitr) (struct _mu_property *, mu_iterator_t *); 64 int (*_prop_getitr) (struct _mu_property *, mu_iterator_t *);
65 /* Clear all properties. */
66 int (*_prop_clear) (struct _mu_property *);
65 }; 67 };
66 68
69 int _mu_property_init (mu_property_t prop);
67 int _mu_property_check (mu_property_t prop); 70 int _mu_property_check (mu_property_t prop);
68 71
69 # ifdef __cplusplus 72 # ifdef __cplusplus
......
...@@ -612,6 +612,22 @@ mu_header_insert (mu_header_t header, ...@@ -612,6 +612,22 @@ mu_header_insert (mu_header_t header,
612 return 0; 612 return 0;
613 } 613 }
614 614
615 int
616 mu_header_clear (mu_header_t header)
617 {
618 int status;
619
620 if (header == NULL)
621 return EINVAL;
622
623 status = mu_header_fill (header);
624 if (status)
625 return status;
626 mu_header_invalidate (header);
627 HEADER_SET_MODIFIED (header);
628 return 0;
629 }
630
615 631
616 int 632 int
617 mu_header_sget_value_n (mu_header_t header, 633 mu_header_sget_value_n (mu_header_t header,
...@@ -630,7 +646,7 @@ mu_header_sget_value_n (mu_header_t header, ...@@ -630,7 +646,7 @@ mu_header_sget_value_n (mu_header_t header,
630 ent = mu_hdrent_find (header, name, n); 646 ent = mu_hdrent_find (header, name, n);
631 if (!ent) 647 if (!ent)
632 return MU_ERR_NOENT; 648 return MU_ERR_NOENT;
633 649 if (pval)
634 *pval = MU_HDRENT_VALUE (header, ent); 650 *pval = MU_HDRENT_VALUE (header, ent);
635 return 0; 651 return 0;
636 } 652 }
......
...@@ -20,8 +20,11 @@ noinst_LTLIBRARIES = libproperty.la ...@@ -20,8 +20,11 @@ noinst_LTLIBRARIES = libproperty.la
20 libproperty_la_SOURCES = \ 20 libproperty_la_SOURCES = \
21 assocprop.c\ 21 assocprop.c\
22 create.c\ 22 create.c\
23 mhprop.c\
24 propclr.c\
23 propget.c\ 25 propget.c\
24 propitr.c\ 26 propitr.c\
27 propinv.c\
25 propset.c 28 propset.c
26 29
27 INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils 30 INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
......
...@@ -66,7 +66,7 @@ _assoc_prop_setval (struct _mu_property *prop, const char *key, ...@@ -66,7 +66,7 @@ _assoc_prop_setval (struct _mu_property *prop, const char *key,
66 int rc; 66 int rc;
67 67
68 rc = mu_assoc_ref_install (assoc, key, (void **)&item); 68 rc = mu_assoc_ref_install (assoc, key, (void **)&item);
69 if (rc == MU_ERR_NOENT) 69 if (rc == 0)
70 { 70 {
71 item->value = strdup (val); 71 item->value = strdup (val);
72 if (!item->value) 72 if (!item->value)
...@@ -75,7 +75,7 @@ _assoc_prop_setval (struct _mu_property *prop, const char *key, ...@@ -75,7 +75,7 @@ _assoc_prop_setval (struct _mu_property *prop, const char *key,
75 return ENOMEM; 75 return ENOMEM;
76 } 76 }
77 } 77 }
78 else if (overwrite) 78 else if (rc == MU_ERR_EXISTS && overwrite)
79 { 79 {
80 char *newval = strdup (val); 80 char *newval = strdup (val);
81 if (!newval) 81 if (!newval)
...@@ -84,7 +84,7 @@ _assoc_prop_setval (struct _mu_property *prop, const char *key, ...@@ -84,7 +84,7 @@ _assoc_prop_setval (struct _mu_property *prop, const char *key,
84 item->value = newval; 84 item->value = newval;
85 } 85 }
86 else 86 else
87 return MU_ERR_EXISTS; 87 return rc;
88 return 0; 88 return 0;
89 } 89 }
90 90
...@@ -96,6 +96,14 @@ _assoc_prop_unset (struct _mu_property *prop, const char *key) ...@@ -96,6 +96,14 @@ _assoc_prop_unset (struct _mu_property *prop, const char *key)
96 return mu_assoc_remove (assoc, key); 96 return mu_assoc_remove (assoc, key);
97 } 97 }
98 98
99 static int
100 _assoc_prop_clear (struct _mu_property *prop)
101 {
102 mu_assoc_t assoc = prop->_prop_data;
103 mu_assoc_clear (assoc);
104 return 0;
105 }
106
99 107
100 static void * 108 static void *
101 _assoc_prop_dataptr (void *in) 109 _assoc_prop_dataptr (void *in)
...@@ -187,7 +195,6 @@ _assoc_prop_save (struct _mu_property *prop) ...@@ -187,7 +195,6 @@ _assoc_prop_save (struct _mu_property *prop)
187 return rc; 195 return rc;
188 } 196 }
189 197
190
191 int 198 int
192 mu_assoc_property_init (struct _mu_property *prop) 199 mu_assoc_property_init (struct _mu_property *prop)
193 { 200 {
...@@ -203,8 +210,6 @@ mu_assoc_property_init (struct _mu_property *prop) ...@@ -203,8 +210,6 @@ mu_assoc_property_init (struct _mu_property *prop)
203 prop->_prop_done = _assoc_prop_done; 210 prop->_prop_done = _assoc_prop_done;
204 if (prop->_prop_init_data) 211 if (prop->_prop_init_data)
205 { 212 {
206 mu_stream_t str = prop->_prop_init_data;
207 mu_stream_ref (str);
208 prop->_prop_fill = _assoc_prop_fill; 213 prop->_prop_fill = _assoc_prop_fill;
209 prop->_prop_save = _assoc_prop_save; 214 prop->_prop_save = _assoc_prop_save;
210 } 215 }
...@@ -217,6 +222,7 @@ mu_assoc_property_init (struct _mu_property *prop) ...@@ -217,6 +222,7 @@ mu_assoc_property_init (struct _mu_property *prop)
217 prop->_prop_setval = _assoc_prop_setval; 222 prop->_prop_setval = _assoc_prop_setval;
218 prop->_prop_unset = _assoc_prop_unset; 223 prop->_prop_unset = _assoc_prop_unset;
219 prop->_prop_getitr = _assoc_prop_getitr; 224 prop->_prop_getitr = _assoc_prop_getitr;
225 prop->_prop_clear = _assoc_prop_clear;
220 return 0; 226 return 0;
221 } 227 }
222 228
......
...@@ -122,7 +122,7 @@ mu_property_save (mu_property_t prop) ...@@ -122,7 +122,7 @@ mu_property_save (mu_property_t prop)
122 return rc; 122 return rc;
123 } 123 }
124 124
125 static int 125 int
126 _mu_property_init (mu_property_t prop) 126 _mu_property_init (mu_property_t prop)
127 { 127 {
128 int rc = 0; 128 int rc = 0;
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library. If not, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #include <mailutils/errno.h>
23 #include <mailutils/error.h>
24 #include <mailutils/stream.h>
25 #include <mailutils/iterator.h>
26 #include <mailutils/header.h>
27 #include <mailutils/nls.h>
28 #include <mailutils/filter.h>
29 #include <mailutils/property.h>
30 #include <mailutils/sys/property.h>
31 #include <stdlib.h>
32
33 static void
34 _mh_prop_done (struct _mu_property *prop)
35 {
36 struct mu_mh_prop *mhprop = prop->_prop_init_data;
37 mu_header_t header = prop->_prop_data;
38 mu_header_destroy (&header);
39 free (mhprop->filename);
40 free (mhprop);
41 }
42
43 static int
44 _mh_prop_getval (struct _mu_property *prop,
45 const char *key, const char **pval)
46 {
47 mu_header_t header = prop->_prop_data;
48
49 if (!header)
50 return MU_ERR_NOENT;
51 return mu_header_sget_value (header, key, pval);
52 }
53
54 static int
55 _mh_prop_setval (struct _mu_property *prop, const char *key,
56 const char *val, int overwrite)
57 {
58 struct mu_mh_prop *mhprop = prop->_prop_init_data;
59 mu_header_t header = prop->_prop_data;
60 if (!header)
61 {
62 int rc;
63 if ((rc = mu_header_create (&header, NULL, 0)) != 0)
64 {
65 mu_error (_("cannot create context %s: %s"),
66 mhprop->filename, mu_strerror (rc));
67 return 1;
68 }
69 prop->_prop_data = header;
70 }
71 return mu_header_set_value (header, key, val, overwrite);
72 }
73
74 static int
75 _mh_prop_unset (struct _mu_property *prop, const char *key)
76 {
77 mu_header_t header = prop->_prop_data;
78 if (!header)
79 return 0;
80 return mu_header_remove (header, key, 1);
81 }
82
83 static int
84 _mh_prop_getitr (struct _mu_property *prop, mu_iterator_t *pitr)
85 {
86 mu_header_t header = prop->_prop_data;
87 return mu_header_get_iterator (header, pitr);
88 }
89
90 static int
91 _mh_prop_clear (struct _mu_property *prop)
92 {
93 mu_header_t header = prop->_prop_data;
94 return mu_header_clear (header);
95 }
96
97
98 static int
99 _mh_prop_read_stream (mu_header_t *phdr, mu_stream_t stream)
100 {
101 int rc;
102 mu_stream_t flt;
103 const char *argv[3];
104 mu_off_t size;
105 size_t total;
106 char *blurb;
107
108 rc = mu_stream_size (stream, &size);
109 if (rc)
110 return rc;
111
112 argv[0] = "INLINE-COMMENT";
113 argv[1] = "#";
114 argv[2] = NULL;
115 rc = mu_filter_create_args (&flt, stream, argv[0], 2, argv,
116 MU_FILTER_DECODE, MU_STREAM_READ);
117 if (rc)
118 {
119 mu_error (_("cannot open filter stream: %s"), mu_strerror (rc));
120 return rc;
121 }
122
123 blurb = malloc (size + 1);
124 if (!blurb)
125 {
126 mu_stream_destroy (&flt);
127 return ENOMEM;
128 }
129
130 total = 0;
131 while (1)
132 {
133 size_t n;
134
135 rc = mu_stream_read (flt, blurb + total, size - total, &n);
136 if (rc)
137 break;
138 if (n == 0)
139 break;
140 total += n;
141 }
142
143 mu_stream_destroy (&flt);
144 if (rc)
145 {
146 free (blurb);
147 return rc;
148 }
149
150 rc = mu_header_create (phdr, blurb, total);
151 free (blurb);
152 return rc;
153 }
154
155 static int
156 _mh_prop_write_stream (mu_header_t header, struct mu_mh_prop *mhprop,
157 mu_stream_t stream)
158 {
159 int rc;
160 mu_stream_t instream;
161 mu_off_t size;
162
163 mu_header_get_streamref (header, &instream);
164 rc = mu_stream_copy (stream, instream, 0, &size);
165 if (rc)
166 {
167 mu_error (_("error writing to context file %s: %s"),
168 mhprop->filename, mu_strerror (rc));
169 return rc;
170 }
171 else
172 rc = mu_stream_truncate (stream, size);
173 mu_stream_destroy (&instream);
174 return rc;
175 }
176
177 static int
178 _mh_prop_fill (struct _mu_property *prop)
179 {
180 struct mu_mh_prop *mhprop = prop->_prop_init_data;
181 int rc;
182 mu_stream_t stream;
183 mu_header_t header;
184
185 rc = mu_file_stream_create (&stream, mhprop->filename, MU_STREAM_READ);
186 if (rc)
187 {
188 if ((rc = mu_header_create (&header, NULL, 0)) != 0)
189 mu_error (_("cannot create context %s: %s"),
190 mhprop->filename, mu_strerror (rc));
191 }
192 else
193 {
194 rc = _mh_prop_read_stream (&header, stream);
195 mu_stream_unref (stream);
196 }
197 if (rc == 0)
198 prop->_prop_data = header;
199 return rc;
200 }
201
202 static int
203 _mh_prop_save (struct _mu_property *prop)
204 {
205 struct mu_mh_prop *mhprop = prop->_prop_init_data;
206 mu_header_t header = prop->_prop_data;
207 mu_stream_t stream;
208 int rc;
209
210 if (mhprop->ro)
211 return 0;
212
213 rc = mu_file_stream_create (&stream, mhprop->filename,
214 MU_STREAM_WRITE|MU_STREAM_CREAT);
215 if (rc)
216 return rc;
217 rc = _mh_prop_write_stream (header, mhprop, stream);
218 mu_stream_unref (stream);
219 return rc;
220 }
221
222 int
223 mu_mh_property_init (struct _mu_property *prop)
224 {
225 struct mu_mh_prop *mhprop = prop->_prop_init_data;
226
227 if (!mhprop)
228 return EINVAL;
229
230 prop->_prop_data = NULL;
231
232 prop->_prop_done = _mh_prop_done;
233 prop->_prop_fill = _mh_prop_fill;
234 prop->_prop_save = _mh_prop_save;
235 prop->_prop_getval = _mh_prop_getval;
236 prop->_prop_setval = _mh_prop_setval;
237 prop->_prop_unset = _mh_prop_unset;
238 prop->_prop_getitr = _mh_prop_getitr;
239 prop->_prop_clear = _mh_prop_clear;
240 return 0;
241 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library. If not, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #include <mailutils/types.h>
23 #include <mailutils/errno.h>
24 #include <mailutils/sys/property.h>
25
26 int
27 mu_property_clear (mu_property_t prop)
28 {
29 int rc = _mu_property_check (prop);
30 if (rc)
31 return rc;
32 if (!prop->_prop_clear)
33 return MU_ERR_EMPTY_VFN;
34 rc = prop->_prop_clear (prop);
35 if (rc == 0)
36 prop->_prop_flags |= MU_PROP_MODIFIED;
37 return rc;
38 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library. If not, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #include <mailutils/types.h>
23 #include <mailutils/errno.h>
24 #include <mailutils/sys/property.h>
25
26 int
27 mu_property_invalidate (mu_property_t prop)
28 {
29 int rc;
30
31 if (!prop)
32 return EINVAL;
33 rc = _mu_property_init (prop);
34 if (rc)
35 return rc;
36 if (prop->_prop_flags & MU_PROP_FILL)
37 {
38 if (!prop->_prop_clear)
39 return MU_ERR_EMPTY_VFN;
40 rc = prop->_prop_clear (prop);
41 if (rc)
42 return rc;
43 prop->_prop_flags &= ~(MU_PROP_FILL | MU_PROP_MODIFIED);
44 }
45 return 0;
46 }
...@@ -28,7 +28,13 @@ int ...@@ -28,7 +28,13 @@ int
28 mu_property_set_value (mu_property_t prop, const char *key, 28 mu_property_set_value (mu_property_t prop, const char *key,
29 const char *value, int overwrite) 29 const char *value, int overwrite)
30 { 30 {
31 int rc = _mu_property_check (prop); 31 int rc;
32
33 if (!value)
34 rc = mu_property_unset (prop, key);
35 else
36 {
37 rc = _mu_property_check (prop);
32 if (rc) 38 if (rc)
33 return rc; 39 return rc;
34 if (!prop->_prop_setval) 40 if (!prop->_prop_setval)
...@@ -36,6 +42,7 @@ mu_property_set_value (mu_property_t prop, const char *key, ...@@ -36,6 +42,7 @@ mu_property_set_value (mu_property_t prop, const char *key,
36 rc = prop->_prop_setval (prop, key, value, overwrite); 42 rc = prop->_prop_setval (prop, key, value, overwrite);
37 if (rc == 0) 43 if (rc == 0)
38 prop->_prop_flags |= MU_PROP_MODIFIED; 44 prop->_prop_flags |= MU_PROP_MODIFIED;
45 }
39 return rc; 46 return rc;
40 } 47 }
41 48
......
...@@ -97,5 +97,28 @@ test=6.b ...@@ -97,5 +97,28 @@ test=6.b
97 user=gray 97 user=gray
98 ]) 98 ])
99 99
100 TESTPROP([clear],[prop07],[
101 prop --dump user=gray package=mailutils org=GNU 0 ?org
102 ],
103 [0: user=gray: Success
104 1: package=mailutils: Success
105 2: org=GNU: Success
106 3: clear: Success
107 4: org is not set
108 Property dump:
109 ])
110
111 TESTPROP([invalidate],[prop08],[
112 prop --file=db user=foo
113 prop --file=db ?user user=bar +user '!' +user
114 ],
115 [0: user=foo: Success
116 0: user is set
117 1: user=bar: Success
118 2: user=bar
119 3: invalidate: Success
120 4: user=foo
121 ])
122
100 m4_popdef([TESTPROP]) 123 m4_popdef([TESTPROP])
101 124
......
...@@ -29,6 +29,8 @@ help (char *progname) ...@@ -29,6 +29,8 @@ help (char *progname)
29 printf (" ?X query whether X is set\n"); 29 printf (" ?X query whether X is set\n");
30 printf (" +X query the value of the property X\n"); 30 printf (" +X query the value of the property X\n");
31 printf (" -X unset property X\n"); 31 printf (" -X unset property X\n");
32 printf (" 0 clear all properties\n");
33 printf (" ! invalidate properties\n");
32 exit (0); 34 exit (0);
33 } 35 }
34 36
...@@ -66,7 +68,6 @@ main (int argc, char **argv) ...@@ -66,7 +68,6 @@ main (int argc, char **argv)
66 { 68 {
67 MU_ASSERT (mu_file_stream_create (&str, filename, 69 MU_ASSERT (mu_file_stream_create (&str, filename,
68 MU_STREAM_RDWR|MU_STREAM_CREAT)); 70 MU_STREAM_RDWR|MU_STREAM_CREAT));
69 mu_stream_unref (str);
70 if (i == argc) 71 if (i == argc)
71 dumpit = 1; 72 dumpit = 1;
72 } 73 }
...@@ -119,6 +120,16 @@ main (int argc, char **argv) ...@@ -119,6 +120,16 @@ main (int argc, char **argv)
119 else 120 else
120 printf ("%d: %s=%s\n", j, key, val); 121 printf ("%d: %s=%s\n", j, key, val);
121 } 122 }
123 else if (key[0] == '0' && key[1] == 0)
124 {
125 rc = mu_property_clear (prop);
126 printf ("%d: clear: %s\n", j, mu_strerror (rc));
127 }
128 else if (key[0] == '!' && key[1] == 0)
129 {
130 rc = mu_property_invalidate (prop);
131 printf ("%d: invalidate: %s\n", j, mu_strerror (rc));
132 }
122 else 133 else
123 { 134 {
124 mu_error ("%d: unrecognized command", i); 135 mu_error ("%d: unrecognized command", i);
......
...@@ -22,6 +22,7 @@ libmu_mh_la_LDFLAGS=-version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@ ...@@ -22,6 +22,7 @@ libmu_mh_la_LDFLAGS=-version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@
22 libmu_mh_la_LIBADD = ${MU_LIB_MAILUTILS} 22 libmu_mh_la_LIBADD = ${MU_LIB_MAILUTILS}
23 libmu_mh_la_SOURCES = \ 23 libmu_mh_la_SOURCES = \
24 folder.c\ 24 folder.c\
25 mbox.c 25 mbox.c\
26 profile.c
26 27
27 28
......
...@@ -22,8 +22,6 @@ ...@@ -22,8 +22,6 @@
22 # include <config.h> 22 # include <config.h>
23 #endif 23 #endif
24 24
25 #ifdef ENABLE_MH
26
27 #include <sys/types.h> 25 #include <sys/types.h>
28 #include <stdlib.h> 26 #include <stdlib.h>
29 #include <stdio.h> 27 #include <stdio.h>
...@@ -63,6 +61,7 @@ ...@@ -63,6 +61,7 @@
63 #include <mailutils/observer.h> 61 #include <mailutils/observer.h>
64 #include <mailutils/io.h> 62 #include <mailutils/io.h>
65 #include <mailutils/cctype.h> 63 #include <mailutils/cctype.h>
64 #include <mailutils/mh.h>
66 #include <mailutils/sys/mailbox.h> 65 #include <mailutils/sys/mailbox.h>
67 #include <mailutils/sys/registrar.h> 66 #include <mailutils/sys/registrar.h>
68 #include <mailutils/sys/amd.h> 67 #include <mailutils/sys/amd.h>
...@@ -359,6 +358,30 @@ mh_remove (struct _amd_data *amd) ...@@ -359,6 +358,30 @@ mh_remove (struct _amd_data *amd)
359 } 358 }
360 359
361 360
361 static int
362 mh_get_property (mu_mailbox_t mailbox, mu_property_t *pprop)
363 {
364 struct _amd_data *amd = mailbox->data;
365 mu_property_t property = NULL;
366 struct mu_mh_prop *mhprop;
367 const char *p;
368
369 mhprop = calloc (1, sizeof (mhprop[0]));
370 if (!mhprop)
371 return ENOMEM;
372 p = mu_mhprop_get_value (mu_mh_profile, "mh-sequences",
373 MU_MH_SEQUENCES_FILE);
374 mhprop->filename = mu_make_file_name (amd->name, p);
375 mu_property_create_init (&property, mu_mh_property_init, mhprop);
376 mu_mailbox_set_property (mailbox, property);
377
378 /*FIXME mu_property_set_value (property, "TYPE", "MH", 1);*/
379 *pprop = property;
380 return 0;
381 }
382
383
384
362 385
363 int 386 int
364 _mailbox_mh_init (mu_mailbox_t mailbox) 387 _mailbox_mh_init (mu_mailbox_t mailbox)
...@@ -383,14 +406,9 @@ _mailbox_mh_init (mu_mailbox_t mailbox) ...@@ -383,14 +406,9 @@ _mailbox_mh_init (mu_mailbox_t mailbox)
383 amd->next_uid = _mh_next_seq; 406 amd->next_uid = _mh_next_seq;
384 amd->remove = mh_remove; 407 amd->remove = mh_remove;
385 408
386 /* Set our properties. */ 409 mailbox->_get_property = mh_get_property;
387 {
388 mu_property_t property = NULL;
389 mu_mailbox_get_property (mailbox, &property);
390 mu_property_set_value (property, "TYPE", "MH", 1);
391 }
392 410
393 return 0; 411 return 0;
394 } 412 }
395 413
396 #endif 414
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 #include <mailutils/property.h>
21 #include <mailutils/iterator.h>
22 #include <mailutils/errno.h>
23 #include <mailutils/mh.h>
24
25 mu_property_t mu_mh_profile;
26 mu_property_t mu_mh_context;
27
28 const char *
29 mu_mhprop_get_value (mu_property_t prop, const char *name, const char *defval)
30 {
31 const char *p;
32
33 if (!prop || mu_property_sget_value (prop, name, &p))
34 p = defval;
35 return p;
36 }
37
38 int
39 mu_mhprop_iterate (mu_property_t prop, mu_mhprop_iterator_t fp, void *data)
40 {
41 mu_iterator_t itr;
42 int rc;
43
44 if (!prop)
45 return EINVAL;
46 rc = mu_property_get_iterator (prop, &itr);
47 if (rc)
48 return rc;
49 for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
50 mu_iterator_next (itr))
51 {
52 const char *name, *val;
53 mu_iterator_current_kv (itr, (const void **)&name, (void**)&val);
54 rc = fp (name, val, data);
55 if (rc)
56 break;
57 }
58 mu_iterator_destroy (&itr);
59 return rc;
60 }
...@@ -28,6 +28,7 @@ mhpath ...@@ -28,6 +28,7 @@ mhpath
28 pick 28 pick
29 pick-gram.c 29 pick-gram.c
30 pick-gram.h 30 pick-gram.h
31 prompter
31 refile 32 refile
32 repl 33 repl
33 rmf 34 rmf
......
...@@ -64,6 +64,7 @@ noinst_LIBRARIES = libmh.a ...@@ -64,6 +64,7 @@ noinst_LIBRARIES = libmh.a
64 64
65 libmh_a_SOURCES= \ 65 libmh_a_SOURCES= \
66 compcommon.c\ 66 compcommon.c\
67 mboxprop.c\
67 mh_alias_gram.c\ 68 mh_alias_gram.c\
68 mh_alias_lex.c\ 69 mh_alias_lex.c\
69 mh_argp.c\ 70 mh_argp.c\
......
...@@ -740,6 +740,7 @@ roll_back (const char *folder_name, struct pack_tab *pack_tab, size_t i) ...@@ -740,6 +740,7 @@ roll_back (const char *folder_name, struct pack_tab *pack_tab, size_t i)
740 740
741 struct fixup_data 741 struct fixup_data
742 { 742 {
743 mu_mailbox_t mbox;
743 const char *folder_dir; 744 const char *folder_dir;
744 struct pack_tab *pack_tab; 745 struct pack_tab *pack_tab;
745 size_t count; 746 size_t count;
...@@ -797,12 +798,12 @@ _fixup (const char *name, const char *value, struct fixup_data *fd, int flags) ...@@ -797,12 +798,12 @@ _fixup (const char *name, const char *value, struct fixup_data *fd, int flags)
797 798
798 mu_wordsplit_free (&ws); 799 mu_wordsplit_free (&ws);
799 800
800 mh_seq_add (name, &msgset, flags | SEQ_ZERO); 801 mh_seq_add (fd->mbox, name, &msgset, flags | SEQ_ZERO);
801 free (msgset.list); 802 free (msgset.list);
802 803
803 if (verbose) 804 if (verbose)
804 { 805 {
805 const char *p = mh_seq_read (name, flags); 806 const char *p = mh_seq_read (fd->mbox, name, flags);
806 fprintf (stderr, "Sequence %s: %s\n", name, p); 807 fprintf (stderr, "Sequence %s: %s\n", name, p);
807 } 808 }
808 809
...@@ -917,18 +918,23 @@ action_pack () ...@@ -917,18 +918,23 @@ action_pack ()
917 fprintf (stderr, _("Finished packing messages.\n")); 918 fprintf (stderr, _("Finished packing messages.\n"));
918 919
919 /* Fix-up sequences */ 920 /* Fix-up sequences */
921 if (!dry_run)
922 {
923 mbox = mh_open_folder (mh_current_folder (), 0);
924 fd.mbox = mbox;
920 fd.folder_dir = folder_dir; 925 fd.folder_dir = folder_dir;
921 fd.pack_tab = pack_tab; 926 fd.pack_tab = pack_tab;
922 fd.count = count; 927 fd.count = count;
923 if (verbose) 928 if (verbose)
924 fprintf (stderr, _("Fixing global sequences\n")); 929 fprintf (stderr, _("Fixing global sequences\n"));
925 mh_global_sequences_iterate (fixup_global, &fd); 930 mh_global_sequences_iterate (mbox, fixup_global, &fd);
926 if (verbose) 931 if (verbose)
927 fprintf (stderr, _("Fixing private sequences\n")); 932 fprintf (stderr, _("Fixing private sequences\n"));
928 mh_global_context_iterate (fixup_private, &fd); 933 mh_global_context_iterate (fixup_private, &fd);
929 934 mu_mailbox_close (mbox);
930 if (!dry_run) 935 mu_mailbox_destroy (&mbox);
931 mh_global_save_state (); 936 mh_global_save_state ();
937 }
932 938
933 return 0; 939 return 0;
934 } 940 }
......
...@@ -175,6 +175,8 @@ main (int argc, char **argv) ...@@ -175,6 +175,8 @@ main (int argc, char **argv)
175 mh_argp_init (); 175 mh_argp_init ();
176 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, 176 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
177 opt_handler, NULL, NULL); 177 opt_handler, NULL, NULL);
178 /* Inc sets missing cur to 1 */
179 mh_mailbox_cur_default = 1;
178 180
179 if (!quiet && mh_format_parse (format_str, &format)) 181 if (!quiet && mh_format_parse (format_str, &format))
180 { 182 {
...@@ -256,9 +258,11 @@ main (int argc, char **argv) ...@@ -256,9 +258,11 @@ main (int argc, char **argv)
256 if (n == 1 && changecur) 258 if (n == 1 && changecur)
257 { 259 {
258 mu_message_t msg = NULL; 260 mu_message_t msg = NULL;
261 size_t cur;
259 262
260 mu_mailbox_get_message (output, lastmsg+1, &msg); 263 mu_mailbox_get_message (output, lastmsg + 1, &msg);
261 mh_message_number (msg, &current_message); 264 mh_message_number (msg, &cur);
265 mh_mailbox_set_cur (output, cur);
262 } 266 }
263 267
264 if (!quiet) 268 if (!quiet)
...@@ -272,7 +276,11 @@ main (int argc, char **argv) ...@@ -272,7 +276,11 @@ main (int argc, char **argv)
272 } 276 }
273 } 277 }
274 278
275 if (changecur) 279 if (!changecur)
280 {
281 mu_property_t prop = mh_mailbox_get_property (output);
282 mu_property_invalidate (prop);
283 }
276 mh_global_save_state (); 284 mh_global_save_state ();
277 285
278 mu_mailbox_close (output); 286 mu_mailbox_close (output);
......
...@@ -117,30 +117,40 @@ opt_handler (int key, char *arg, struct argp_state *state) ...@@ -117,30 +117,40 @@ opt_handler (int key, char *arg, struct argp_state *state)
117 return 0; 117 return 0;
118 } 118 }
119 119
120
121 struct mark_closure
122 {
123 mu_mailbox_t mbox;
124 mh_msgset_t *msgset;
125 };
126
120 static int 127 static int
121 action_add (void *item, void *data) 128 action_add (void *item, void *data)
122 { 129 {
123 mh_seq_add ((char *)item, (mh_msgset_t *)data, seq_flags); 130 struct mark_closure *clos = data;
131 mh_seq_add (clos->mbox, (char *)item, clos->msgset, seq_flags);
124 return 0; 132 return 0;
125 } 133 }
126 134
127 static int 135 static int
128 action_delete (void *item, void *data) 136 action_delete (void *item, void *data)
129 { 137 {
130 mh_seq_delete ((char *)item, (mh_msgset_t *)data, seq_flags); 138 struct mark_closure *clos = data;
139 mh_seq_delete (clos->mbox, (char *)item, clos->msgset, seq_flags);
131 return 0; 140 return 0;
132 } 141 }
133 142
134 static int 143 static int
135 action_list (void *item, void *data) 144 action_list (void *item, void *data)
136 { 145 {
146 struct mark_closure *clos = data;
137 char *name = item; 147 char *name = item;
138 const char *val; 148 const char *val;
139 149
140 val = mh_seq_read (name, 0); 150 val = mh_seq_read (clos->mbox, name, 0);
141 if (val) 151 if (val)
142 printf ("%s: %s\n", name, val); 152 printf ("%s: %s\n", name, val);
143 else if ((val = mh_seq_read (name, SEQ_PRIVATE))) 153 else if ((val = mh_seq_read (clos->mbox, name, SEQ_PRIVATE)))
144 printf ("%s (%s): %s\n", name, _("private"), val); 154 printf ("%s (%s): %s\n", name, _("private"), val);
145 return 0; 155 return 0;
146 } 156 }
...@@ -171,9 +181,9 @@ list_public (const char *name, const char *value, void *data) ...@@ -171,9 +181,9 @@ list_public (const char *name, const char *value, void *data)
171 } 181 }
172 182
173 static void 183 static void
174 list_all () 184 list_all (mu_mailbox_t mbox)
175 { 185 {
176 mh_global_sequences_iterate (list_public, NULL); 186 mh_global_sequences_iterate (mbox, list_public, NULL);
177 mh_global_context_iterate (list_private, NULL); 187 mh_global_context_iterate (list_private, NULL);
178 } 188 }
179 189
...@@ -184,6 +194,7 @@ main (int argc, char **argv) ...@@ -184,6 +194,7 @@ main (int argc, char **argv)
184 mh_msgset_t msgset; 194 mh_msgset_t msgset;
185 mu_mailbox_t mbox; 195 mu_mailbox_t mbox;
186 mu_url_t url; 196 mu_url_t url;
197 struct mark_closure clos;
187 198
188 MU_APP_INIT_NLS (); 199 MU_APP_INIT_NLS ();
189 mh_argp_init (); 200 mh_argp_init ();
...@@ -201,6 +212,8 @@ main (int argc, char **argv) ...@@ -201,6 +212,8 @@ main (int argc, char **argv)
201 mh_msgset_parse (mbox, &msgset, argc, argv, "cur"); 212 mh_msgset_parse (mbox, &msgset, argc, argv, "cur");
202 mh_msgset_uids (mbox, &msgset); 213 mh_msgset_uids (mbox, &msgset);
203 214
215 clos.mbox = mbox;
216 clos.msgset = &msgset;
204 switch (action) 217 switch (action)
205 { 218 {
206 case ARG_ADD: 219 case ARG_ADD:
...@@ -209,7 +222,7 @@ main (int argc, char **argv) ...@@ -209,7 +222,7 @@ main (int argc, char **argv)
209 mu_error (_("--add requires at least one --sequence argument")); 222 mu_error (_("--add requires at least one --sequence argument"));
210 return 1; 223 return 1;
211 } 224 }
212 mu_list_do (seq_list, action_add, (void *) &msgset); 225 mu_list_do (seq_list, action_add, (void *) &clos);
213 mh_global_save_state (); 226 mh_global_save_state ();
214 break; 227 break;
215 228
...@@ -219,17 +232,18 @@ main (int argc, char **argv) ...@@ -219,17 +232,18 @@ main (int argc, char **argv)
219 mu_error (_("--delete requires at least one --sequence argument")); 232 mu_error (_("--delete requires at least one --sequence argument"));
220 return 1; 233 return 1;
221 } 234 }
222 mu_list_do (seq_list, action_delete, (void *) &msgset); 235 mu_list_do (seq_list, action_delete, (void *) &clos);
223 mh_global_save_state (); 236 mh_global_save_state ();
224 break; 237 break;
225 238
226 case ARG_LIST: 239 case ARG_LIST:
227 if (!seq_list) 240 if (!seq_list)
228 list_all (); 241 list_all (mbox);
229 else 242 else
230 mu_list_do (seq_list, action_list, NULL); 243 mu_list_do (seq_list, action_list, &clos);
231 break; 244 break;
232 } 245 }
233 246 mu_mailbox_close (mbox);
247 mu_mailbox_destroy (&mbox);
234 return 0; 248 return 0;
235 } 249 }
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2005, 2006, 2007, 2009, 2010 Free
3 Software Foundation, Inc.
4
5 GNU Mailutils is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 GNU Mailutils is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
17
18 /* MH message sets. */
19
20 #include <mh.h>
21
22 /* Default value for missing "cur". Valid values are 0 and 1. */
23 int mh_mailbox_cur_default = 0;
24
25 void
26 mh_mailbox_get_cur (mu_mailbox_t mbox, size_t *pcur)
27 {
28 mu_property_t prop = NULL;
29 const char *s;
30 int rc = mu_mailbox_get_property (mbox, &prop);
31 if (rc)
32 {
33 mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_get_property", NULL, rc);
34 exit (1);
35 }
36 rc = mu_property_sget_value (prop, "cur", &s);
37 if (rc == MU_ERR_NOENT)
38 *pcur = mh_mailbox_cur_default;
39 else if (rc == 0)
40 {
41 char *p;
42 *pcur = strtoul (s, &p, 10);
43 if (*p)
44 {
45 mu_error (_("invalid \"cur\" value (%s)"), s);
46 *pcur = 1;
47 }
48 }
49 else
50 {
51 mu_diag_funcall (MU_DIAG_ERROR, "mu_property_sget_value", NULL, rc);
52 exit (1);
53 }
54 }
55
56 void
57 mh_mailbox_set_cur (mu_mailbox_t mbox, size_t cur)
58 {
59 mu_property_t prop = NULL;
60 int rc = mu_mailbox_get_property (mbox, &prop);
61 if (rc)
62 {
63 mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_get_property", NULL, rc);
64 exit (1);
65 }
66 rc = mu_property_set_value (prop, "cur", mu_umaxtostr (0, cur), 1);
67 if (rc)
68 {
69 mu_diag_funcall (MU_DIAG_ERROR, "mu_property_set_value", NULL, rc);
70 exit (1);
71 }
72 }
73
74
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
55 #include <mailutils/envelope.h> 55 #include <mailutils/envelope.h>
56 #include <mailutils/mime.h> 56 #include <mailutils/mime.h>
57 #include <mailutils/io.h> 57 #include <mailutils/io.h>
58 #include <mailutils/property.h>
58 59
59 #include <mu_umaxtostr.h> 60 #include <mu_umaxtostr.h>
60 61
...@@ -233,9 +234,9 @@ typedef int (*mh_context_iterator) (const char *field, const char *value, ...@@ -233,9 +234,9 @@ typedef int (*mh_context_iterator) (const char *field, const char *value,
233 #define SEQ_PRIVATE 1 234 #define SEQ_PRIVATE 1
234 #define SEQ_ZERO 2 235 #define SEQ_ZERO 2
235 236
236 extern size_t current_message;
237 extern char mh_list_format[]; 237 extern char mh_list_format[];
238 extern int rcpt_mask; 238 extern int rcpt_mask;
239 extern int mh_mailbox_cur_default;
239 240
240 void mh_init (void); 241 void mh_init (void);
241 void mh_init2 (void); 242 void mh_init2 (void);
...@@ -251,13 +252,19 @@ const char *mh_global_context_get (const char *name, const char *defval); ...@@ -251,13 +252,19 @@ const char *mh_global_context_get (const char *name, const char *defval);
251 int mh_global_context_set (const char *name, const char *value); 252 int mh_global_context_set (const char *name, const char *value);
252 const char *mh_set_current_folder (const char *val); 253 const char *mh_set_current_folder (const char *val);
253 const char *mh_current_folder (void); 254 const char *mh_current_folder (void);
254 const char *mh_global_sequences_get (const char *name, const char *defval); 255
255 int mh_global_sequences_set (const char *name, const char *value); 256 mu_property_t mh_mailbox_get_property (mu_mailbox_t mbox);
257 const char *mh_global_sequences_get (mu_mailbox_t mbox,
258 const char *name, const char *defval);
259 void mh_global_sequences_set (mu_mailbox_t mbox,
260 const char *name, const char *value);
261 void mh_global_sequences_iterate (mu_mailbox_t mbox,
262 mh_context_iterator fp, void *data);
263 void mh_global_sequences_drop (mu_mailbox_t mbox);
264
256 void mh_global_save_state (void); 265 void mh_global_save_state (void);
257 int mh_global_profile_iterate (mh_context_iterator fp, void *data); 266 int mh_global_profile_iterate (mh_context_iterator fp, void *data);
258 int mh_global_context_iterate (mh_context_iterator fp, void *data); 267 int mh_global_context_iterate (mh_context_iterator fp, void *data);
259 int mh_global_sequences_iterate (mh_context_iterator fp, void *data);
260 void mh_global_sequences_drop (void);
261 268
262 int mh_interactive_mode_p (void); 269 int mh_interactive_mode_p (void);
263 int mh_getyn (const char *fmt, ...) MU_PRINTFLIKE(1,2); 270 int mh_getyn (const char *fmt, ...) MU_PRINTFLIKE(1,2);
...@@ -300,7 +307,7 @@ int mh_msgset_parse (mu_mailbox_t mbox, mh_msgset_t *msgset, ...@@ -300,7 +307,7 @@ int mh_msgset_parse (mu_mailbox_t mbox, mh_msgset_t *msgset,
300 int mh_msgset_member (mh_msgset_t *msgset, size_t num); 307 int mh_msgset_member (mh_msgset_t *msgset, size_t num);
301 void mh_msgset_reverse (mh_msgset_t *msgset); 308 void mh_msgset_reverse (mh_msgset_t *msgset);
302 void mh_msgset_negate (mu_mailbox_t mbox, mh_msgset_t *msgset); 309 void mh_msgset_negate (mu_mailbox_t mbox, mh_msgset_t *msgset);
303 int mh_msgset_current (mu_mailbox_t mbox, mh_msgset_t *msgset, int index); 310 void mh_msgset_current (mu_mailbox_t mbox, mh_msgset_t *msgset, int index);
304 void mh_msgset_free (mh_msgset_t *msgset); 311 void mh_msgset_free (mh_msgset_t *msgset);
305 void mh_msgset_uids (mu_mailbox_t mbox, mh_msgset_t *msgset); 312 void mh_msgset_uids (mu_mailbox_t mbox, mh_msgset_t *msgset);
306 313
...@@ -358,9 +365,11 @@ int mhl_format_run (mu_list_t fmt, int width, int length, int flags, ...@@ -358,9 +365,11 @@ int mhl_format_run (mu_list_t fmt, int width, int length, int flags,
358 mu_message_t msg, mu_stream_t output); 365 mu_message_t msg, mu_stream_t output);
359 void mhl_format_destroy (mu_list_t *fmt); 366 void mhl_format_destroy (mu_list_t *fmt);
360 367
361 void mh_seq_add (const char *name, mh_msgset_t *mset, int flags); 368 void mh_seq_add (mu_mailbox_t mbox, const char *name, mh_msgset_t *mset,
362 int mh_seq_delete (const char *name, mh_msgset_t *mset, int flags); 369 int flags);
363 const char *mh_seq_read (const char *name, int flags); 370 int mh_seq_delete (mu_mailbox_t mbox, const char *name, mh_msgset_t *mset,
371 int flags);
372 const char *mh_seq_read (mu_mailbox_t mbox, const char *name, int flags);
364 373
365 void mh_comp_draft (const char *formfile, const char *defformfile, 374 void mh_comp_draft (const char *formfile, const char *defformfile,
366 const char *draftfile); 375 const char *draftfile);
...@@ -371,3 +380,6 @@ void ali_verbatim (int enable); ...@@ -371,3 +380,6 @@ void ali_verbatim (int enable);
371 380
372 char *mh_safe_make_file_name (const char *dir, const char *file); 381 char *mh_safe_make_file_name (const char *dir, const char *file);
373 382
383 void mh_mailbox_get_cur (mu_mailbox_t mbox, size_t *pcur);
384 void mh_mailbox_set_cur (mu_mailbox_t mbox, size_t cur);
385
......
...@@ -913,8 +913,19 @@ static void ...@@ -913,8 +913,19 @@ static void
913 builtin_cur (struct mh_machine *mach) 913 builtin_cur (struct mh_machine *mach)
914 { 914 {
915 size_t msgno = mach->msgno; 915 size_t msgno = mach->msgno;
916 size_t cur;
917 int rc;
918 mu_mailbox_t mbox;
919
920 rc = mu_message_get_mailbox (mach->message, &mbox);
921 if (rc)
922 {
923 mu_diag_funcall (MU_DIAG_ERROR, "mu_message_get_mailbox", NULL, rc);
924 exit (1);
925 }
916 mh_message_number (mach->message, &msgno); 926 mh_message_number (mach->message, &msgno);
917 mach->arg_num = msgno == current_message; 927 mh_mailbox_get_cur (mbox, &cur); /* FIXME: Cache this */
928 mach->arg_num = msgno == cur;
918 } 929 }
919 930
920 static void 931 static void
......
...@@ -20,10 +20,8 @@ ...@@ -20,10 +20,8 @@
20 #include <mh.h> 20 #include <mh.h>
21 21
22 static const char *current_folder = NULL; 22 static const char *current_folder = NULL;
23 size_t current_message = 0;
24 mh_context_t *context; 23 mh_context_t *context;
25 mh_context_t *profile; 24 mh_context_t *profile;
26 mh_context_t *sequences;
27 int rcpt_mask = RCPT_DEFAULT; 25 int rcpt_mask = RCPT_DEFAULT;
28 int mh_auto_install = 1; 26 int mh_auto_install = 1;
29 27
...@@ -139,52 +137,86 @@ mh_set_current_folder (const char *val) ...@@ -139,52 +137,86 @@ mh_set_current_folder (const char *val)
139 } 137 }
140 138
141 /* Global sequences */ 139 /* Global sequences */
142 140 mu_property_t
143 void 141 mh_mailbox_get_property (mu_mailbox_t mbox)
144 _mh_init_global_sequences ()
145 { 142 {
146 const char *name; 143 mu_property_t prop;
147 char *p, *seq_name; 144 int rc = mu_mailbox_get_property (mbox, &prop);
148 145 if (rc)
149 if (sequences) 146 {
150 return; 147 mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_get_property", NULL, rc);
151 148 exit (1);
152 _mh_init_global_context (); 149 }
153 name = mh_global_profile_get ("mh-sequences", MH_SEQUENCES_FILE); 150 return prop;
154 p = mh_expand_name (NULL, current_folder, 0);
155 seq_name = mh_safe_make_file_name (p, name);
156 free (p);
157 sequences = mh_context_create (seq_name, 1);
158 if (mh_context_read (sequences) == 0)
159 current_message = strtoul (mh_context_get_value (sequences, "cur", "0"),
160 NULL, 10);
161 } 151 }
162 152
163 void 153 void
164 mh_global_sequences_drop () 154 mh_global_sequences_drop (mu_mailbox_t mbox)
165 { 155 {
166 mh_context_destroy (&sequences); 156 mu_property_t prop = mh_mailbox_get_property (mbox);
157 int rc = mu_property_clear (prop);
158 if (rc)
159 {
160 mu_diag_funcall (MU_DIAG_ERROR, "mu_property_clear", NULL, rc);
161 exit (1);
162 }
167 } 163 }
168 164
169 const char * 165 const char *
170 mh_global_sequences_get (const char *name, const char *defval) 166 mh_global_sequences_get (mu_mailbox_t mbox, const char *name,
171 { 167 const char *defval)
172 _mh_init_global_sequences (); 168 {
173 return mh_context_get_value (sequences, name, defval); 169 mu_property_t prop = mh_mailbox_get_property (mbox);
170 const char *s;
171 int rc = mu_property_sget_value (prop, name, &s);
172 if (rc == MU_ERR_NOENT)
173 s = defval;
174 else if (rc)
175 {
176 mu_diag_funcall (MU_DIAG_ERROR, "mu_property_sget_value", name, rc);
177 exit (1);
178 }
179 return s;
174 } 180 }
175 181
176 int 182 void
177 mh_global_sequences_set (const char *name, const char *value) 183 mh_global_sequences_set (mu_mailbox_t mbox, const char *name,
184 const char *value)
178 { 185 {
179 _mh_init_global_sequences (); 186 mu_property_t prop = mh_mailbox_get_property (mbox);
180 return mh_context_set_value (sequences, name, value); 187 int rc = mu_property_set_value (prop, name, value, 1);
188 if (rc && !(!value && rc == MU_ERR_NOENT))
189 {
190 mu_diag_funcall (MU_DIAG_ERROR, "mu_property_set_value", name, rc);
191 exit (1);
192 }
181 } 193 }
182 194
183 int 195 /* FIXME: Rewrite using mu_mhprop_iterate */
184 mh_global_sequences_iterate (mh_context_iterator fp, void *data) 196 void
197 mh_global_sequences_iterate (mu_mailbox_t mbox,
198 mh_context_iterator fp, void *data)
185 { 199 {
186 _mh_init_global_context (); 200 int rc;
187 return mh_context_iterate (sequences, fp, data); 201 mu_iterator_t itr;
202 mu_property_t prop = mh_mailbox_get_property (mbox);
203
204 rc = mu_property_get_iterator (prop, &itr);
205 if (rc)
206 {
207 mu_diag_funcall (MU_DIAG_ERROR, "mu_property_get_iterator", NULL, rc);
208 exit (1);
209 }
210 for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
211 mu_iterator_next (itr))
212 {
213 const char *name, *val;
214
215 mu_iterator_current_kv (itr, (const void **)&name, (void**)&val);
216 if (fp (name, val, data))
217 break;
218 }
219 mu_iterator_destroy (&itr);
188 } 220 }
189 221
190 /* Global state */ 222 /* Global state */
...@@ -192,9 +224,6 @@ mh_global_sequences_iterate (mh_context_iterator fp, void *data) ...@@ -192,9 +224,6 @@ mh_global_sequences_iterate (mh_context_iterator fp, void *data)
192 void 224 void
193 mh_global_save_state () 225 mh_global_save_state ()
194 { 226 {
195 mh_context_set_value (sequences, "cur", mu_umaxtostr (0, current_message));
196 mh_context_write (sequences);
197
198 mh_context_set_value (context, "Current-Folder", current_folder); 227 mh_context_set_value (context, "Current-Folder", current_folder);
199 mh_context_write (context); 228 mh_context_write (context);
200 } 229 }
......
...@@ -67,7 +67,6 @@ void ...@@ -67,7 +67,6 @@ void
67 mh_init2 () 67 mh_init2 ()
68 { 68 {
69 mh_current_folder (); 69 mh_current_folder ();
70 mh_global_sequences_get ("cur", NULL);
71 } 70 }
72 71
73 int 72 int
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
18 /* MH message sets. */ 18 /* MH message sets. */
19 19
20 #include <mh.h> 20 #include <mh.h>
21 #include <mailutils/argcv.h>
22 21
23 /* Expand a message set (msgcnt;msglist) to accomodate `inc' more 22 /* Expand a message set (msgcnt;msglist) to accomodate `inc' more
24 elements */ 23 elements */
...@@ -72,6 +71,9 @@ msgset_cur (mu_mailbox_t mbox, size_t *pnum) ...@@ -72,6 +71,9 @@ msgset_cur (mu_mailbox_t mbox, size_t *pnum)
72 { 71 {
73 size_t i, count = 0; 72 size_t i, count = 0;
74 static int cached_n = 0; 73 static int cached_n = 0;
74 size_t cur;
75
76 mh_mailbox_get_cur (mbox, &cur);
75 77
76 if (cached_n) 78 if (cached_n)
77 { 79 {
...@@ -87,7 +89,7 @@ msgset_cur (mu_mailbox_t mbox, size_t *pnum) ...@@ -87,7 +89,7 @@ msgset_cur (mu_mailbox_t mbox, size_t *pnum)
87 89
88 mu_mailbox_get_message (mbox, i, &msg); 90 mu_mailbox_get_message (mbox, i, &msg);
89 mh_message_number (msg, &uid); 91 mh_message_number (msg, &uid);
90 if (uid == current_message) 92 if (uid == cur)
91 { 93 {
92 *pnum = cached_n = i; 94 *pnum = cached_n = i;
93 return 0; 95 return 0;
...@@ -244,7 +246,7 @@ expand_user_seq (mu_mailbox_t mbox, mh_msgset_t *msgset, char *arg) ...@@ -244,7 +246,7 @@ expand_user_seq (mu_mailbox_t mbox, mh_msgset_t *msgset, char *arg)
244 p = strchr (arg, ':'); 246 p = strchr (arg, ':');
245 if (p) 247 if (p)
246 *p++ = 0; 248 *p++ = 0;
247 listp = mh_global_sequences_get (arg, NULL); 249 listp = mh_global_sequences_get (mbox, arg, NULL);
248 if (!listp) 250 if (!listp)
249 { 251 {
250 int len; 252 int len;
...@@ -255,7 +257,7 @@ expand_user_seq (mu_mailbox_t mbox, mh_msgset_t *msgset, char *arg) ...@@ -255,7 +257,7 @@ expand_user_seq (mu_mailbox_t mbox, mh_msgset_t *msgset, char *arg)
255 if (strncmp (arg, neg, len)) 257 if (strncmp (arg, neg, len))
256 return 1; 258 return 1;
257 negate = 1; 259 negate = 1;
258 listp = mh_global_sequences_get (arg + len, NULL); 260 listp = mh_global_sequences_get (mbox, arg + len, NULL);
259 if (!listp) 261 if (!listp)
260 return 1; 262 return 1;
261 } 263 }
...@@ -569,13 +571,21 @@ mh_msgset_reverse (mh_msgset_t *msgset) ...@@ -569,13 +571,21 @@ mh_msgset_reverse (mh_msgset_t *msgset)
569 571
570 /* Set the current message to that contained at position `index' 572 /* Set the current message to that contained at position `index'
571 in the given message set */ 573 in the given message set */
572 int 574 void
573 mh_msgset_current (mu_mailbox_t mbox, mh_msgset_t *msgset, int index) 575 mh_msgset_current (mu_mailbox_t mbox, mh_msgset_t *msgset, int index)
574 { 576 {
575 mu_message_t msg = NULL; 577 mu_message_t msg = NULL;
576 if (mu_mailbox_get_message (mbox, msgset->list[index], &msg)) 578 int rc;
577 return 1; 579 size_t cur;
578 return mh_message_number (msg, &current_message); 580
581 rc = mu_mailbox_get_message (mbox, msgset->list[index], &msg);
582 if (rc)
583 {
584 mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_get_message", NULL, rc);
585 exit (1);
586 }
587 mh_message_number (msg, &cur);
588 mh_mailbox_set_cur (mbox, cur);
579 } 589 }
580 590
581 /* Free memory allocated for the message set. Note, that the msgset 591 /* Free memory allocated for the message set. Note, that the msgset
......
...@@ -28,7 +28,7 @@ private_sequence_name (const char *name) ...@@ -28,7 +28,7 @@ private_sequence_name (const char *name)
28 } 28 }
29 29
30 const char * 30 const char *
31 mh_seq_read (const char *name, int flags) 31 mh_seq_read (mu_mailbox_t mbox, const char *name, int flags)
32 { 32 {
33 const char *value; 33 const char *value;
34 34
...@@ -39,12 +39,12 @@ mh_seq_read (const char *name, int flags) ...@@ -39,12 +39,12 @@ mh_seq_read (const char *name, int flags)
39 free (p); 39 free (p);
40 } 40 }
41 else 41 else
42 value = mh_global_sequences_get (name, NULL); 42 value = mh_global_sequences_get (mbox, name, NULL);
43 return value; 43 return value;
44 } 44 }
45 45
46 static void 46 static void
47 write_sequence (const char *name, char *value, int private) 47 write_sequence (mu_mailbox_t mbox, const char *name, char *value, int private)
48 { 48 {
49 if (private) 49 if (private)
50 { 50 {
...@@ -53,24 +53,24 @@ write_sequence (const char *name, char *value, int private) ...@@ -53,24 +53,24 @@ write_sequence (const char *name, char *value, int private)
53 free (p); 53 free (p);
54 } 54 }
55 else 55 else
56 mh_global_sequences_set (name, value); 56 mh_global_sequences_set (mbox, name, value);
57 } 57 }
58 58
59 static void 59 static void
60 delete_sequence (const char *name, int private) 60 delete_sequence (mu_mailbox_t mbox, const char *name, int private)
61 { 61 {
62 write_sequence (name, NULL, private); 62 write_sequence (mbox, name, NULL, private);
63 } 63 }
64 64
65 void 65 void
66 mh_seq_add (const char *name, mh_msgset_t *mset, int flags) 66 mh_seq_add (mu_mailbox_t mbox, const char *name, mh_msgset_t *mset, int flags)
67 { 67 {
68 const char *value = mh_seq_read (name, flags); 68 const char *value = mh_seq_read (mbox, name, flags);
69 char *new_value, *p; 69 char *new_value, *p;
70 const char *buf; 70 const char *buf;
71 size_t i, len; 71 size_t i, len;
72 72
73 delete_sequence (name, !(flags & SEQ_PRIVATE)); 73 delete_sequence (mbox, name, !(flags & SEQ_PRIVATE));
74 74
75 if (flags & SEQ_ZERO) 75 if (flags & SEQ_ZERO)
76 value = NULL; 76 value = NULL;
...@@ -99,9 +99,11 @@ mh_seq_add (const char *name, mh_msgset_t *mset, int flags) ...@@ -99,9 +99,11 @@ mh_seq_add (const char *name, mh_msgset_t *mset, int flags)
99 *p++ = ' '; 99 *p++ = ' ';
100 } 100 }
101 *p = 0; 101 *p = 0;
102 write_sequence (name, new_value, flags & SEQ_PRIVATE); 102 write_sequence (mbox, name, new_value, flags & SEQ_PRIVATE);
103 /* FIXME
103 if (mu_c_strcasecmp (name, "cur") == 0) 104 if (mu_c_strcasecmp (name, "cur") == 0)
104 current_message = strtoul (new_value, NULL, 0); 105 current_message = strtoul (new_value, NULL, 0);
106 */
105 free (new_value); 107 free (new_value);
106 } 108 }
107 109
...@@ -119,9 +121,10 @@ cmp_msgnum (const void *a, const void *b) ...@@ -119,9 +121,10 @@ cmp_msgnum (const void *a, const void *b)
119 } 121 }
120 122
121 int 123 int
122 mh_seq_delete (const char *name, mh_msgset_t *mset, int flags) 124 mh_seq_delete (mu_mailbox_t mbox, const char *name,
125 mh_msgset_t *mset, int flags)
123 { 126 {
124 const char *value = mh_seq_read (name, flags); 127 const char *value = mh_seq_read (mbox, name, flags);
125 char *new_val; 128 char *new_val;
126 char *p; 129 char *p;
127 size_t i, count; 130 size_t i, count;
...@@ -167,7 +170,7 @@ mh_seq_delete (const char *name, mh_msgset_t *mset, int flags) ...@@ -167,7 +170,7 @@ mh_seq_delete (const char *name, mh_msgset_t *mset, int flags)
167 } 170 }
168 } 171 }
169 *p = 0; 172 *p = 0;
170 write_sequence (name, count > 0 ? new_val : NULL, flags & SEQ_PRIVATE); 173 write_sequence (mbox, name, count > 0 ? new_val : NULL, flags & SEQ_PRIVATE);
171 mu_wordsplit_free (&ws); 174 mu_wordsplit_free (&ws);
172 free (new_val); 175 free (new_val);
173 176
......
...@@ -298,10 +298,18 @@ pick_message (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) ...@@ -298,10 +298,18 @@ pick_message (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
298 } 298 }
299 } 299 }
300 300
301
302 struct pick_closure
303 {
304 mu_mailbox_t mbox;
305 mh_msgset_t *msgset;
306 };
307
301 static int 308 static int
302 action_add (void *item, void *data) 309 action_add (void *item, void *data)
303 { 310 {
304 mh_seq_add ((char *)item, (mh_msgset_t *)data, seq_flags); 311 struct pick_closure *clos = data;
312 mh_seq_add (clos->mbox, (char *)item, clos->msgset, seq_flags);
305 return 0; 313 return 0;
306 } 314 }
307 315
...@@ -395,13 +403,18 @@ main (int argc, char **argv) ...@@ -395,13 +403,18 @@ main (int argc, char **argv)
395 403
396 if (seq_list) 404 if (seq_list)
397 { 405 {
406 struct pick_closure clos;
398 mh_msgset_t msgset; 407 mh_msgset_t msgset;
399 msgset.count = msgno_count; 408 msgset.count = msgno_count;
400 msgset.list = obstack_finish (&msgno_stk); 409 msgset.list = obstack_finish (&msgno_stk);
401 mu_list_do (seq_list, action_add, (void*) &msgset); 410 clos.mbox = mbox;
411 clos.msgset = &msgset;
412 mu_list_do (seq_list, action_add, &clos);
402 } 413 }
403 414
404 mh_global_save_state (); 415 mh_global_save_state ();
416 mu_mailbox_close (mbox);
417 mu_mailbox_destroy (&mbox);
405 return status; 418 return status;
406 } 419 }
407 420
......
...@@ -255,6 +255,7 @@ main (int argc, char **argv) ...@@ -255,6 +255,7 @@ main (int argc, char **argv)
255 mu_opool_destroy (&opool); 255 mu_opool_destroy (&opool);
256 } 256 }
257 } 257 }
258 mu_iterator_destroy (&itr);
258 mu_stream_printf (strout, "--------\n"); 259 mu_stream_printf (strout, "--------\n");
259 mu_stream_write (tmp, "\n", 1, NULL); 260 mu_stream_write (tmp, "\n", 1, NULL);
260 261
......
...@@ -53,7 +53,7 @@ struct mh_option mh_option[] = { ...@@ -53,7 +53,7 @@ struct mh_option mh_option[] = {
53 53
54 int explicit_folder; /* Was the folder explicitly given */ 54 int explicit_folder; /* Was the folder explicitly given */
55 int interactive; /* Ask for confirmation before deleting */ 55 int interactive; /* Ask for confirmation before deleting */
56 int recurse; /* Recursively process all the sub-directories */ 56 int recursive; /* Recursively process all the sub-directories */
57 57
58 static char *cur_folder_path; /* Full pathname of the current folder */ 58 static char *cur_folder_path; /* Full pathname of the current folder */
59 static char *folder_name; /* Name of the (topmost) folder to be 59 static char *folder_name; /* Name of the (topmost) folder to be
...@@ -78,11 +78,11 @@ opt_handler (int key, char *arg, struct argp_state *state) ...@@ -78,11 +78,11 @@ opt_handler (int key, char *arg, struct argp_state *state)
78 break; 78 break;
79 79
80 case ARG_RECURSIVE: 80 case ARG_RECURSIVE:
81 recurse = is_true (arg); 81 recursive = is_true (arg);
82 break; 82 break;
83 83
84 case ARG_NORECURSIVE: 84 case ARG_NORECURSIVE:
85 recurse = 0; 85 recursive = 0;
86 break; 86 break;
87 87
88 default: 88 default:
...@@ -107,6 +107,31 @@ current_folder_path () ...@@ -107,6 +107,31 @@ current_folder_path ()
107 static int 107 static int
108 rmf (const char *name) 108 rmf (const char *name)
109 { 109 {
110 mu_mailbox_t mbox = NULL;
111 int rc;
112
113 rc = mu_mailbox_create_default (&mbox, name);
114 if (rc)
115 {
116 mu_error (_("cannot create mailbox %s: %s"),
117 name, strerror (rc));
118 return 1;
119 }
120
121 rc = mu_mailbox_remove (mbox);
122 mu_mailbox_destroy (&mbox);
123 if (rc)
124 {
125 mu_error (_("cannot remove %s: %s"), name, mu_strerror (rc));
126 return 1;
127 }
128 return 0;
129 }
130
131 /* Recursive rmf */
132 static int
133 recrmf (const char *name)
134 {
110 DIR *dir; 135 DIR *dir;
111 struct dirent *entry; 136 struct dirent *entry;
112 int failures = 0; 137 int failures = 0;
...@@ -137,50 +162,24 @@ rmf (const char *name) ...@@ -137,50 +162,24 @@ rmf (const char *name)
137 mu_diag_funcall (MU_DIAG_ERROR, "stat", p, errno); 162 mu_diag_funcall (MU_DIAG_ERROR, "stat", p, errno);
138 } 163 }
139 else if (S_ISDIR (st.st_mode)) 164 else if (S_ISDIR (st.st_mode))
140 { 165 failures += recrmf (p);
141 if (recurse)
142 failures += rmf (p);
143 else
144 {
145 printf ("%s: file `%s' not deleted, continuing...\n",
146 mu_program_name, p);
147 failures++;
148 }
149 }
150 else
151 {
152 if (unlink (p))
153 {
154 mu_diag_funcall (MU_DIAG_ERROR, "unlink", p, errno);
155 failures++;
156 }
157 }
158 free (p); 166 free (p);
159 } 167 }
160 closedir (dir); 168 closedir (dir);
161 169
162 if (failures == 0) 170 if (failures == 0)
163 failures += rmdir (name); 171 failures += rmf (name);
164 else 172 else
165 printf ("%s: folder `%s' not removed\n", 173 printf ("%s: folder `%s' not removed\n",
166 mu_program_name, name); 174 mu_program_name, name);
167 175
168 if (failures == 0)
169 {
170 if (cur_folder_path && strcmp (name, cur_folder_path) == 0)
171 {
172 mh_set_current_folder ("inbox");
173 mh_global_sequences_drop ();
174 mh_global_save_state ();
175 printf ("[+inbox now current]\n");
176 }
177 }
178 return failures; 176 return failures;
179 } 177 }
180 178
181 int 179 int
182 main (int argc, char **argv) 180 main (int argc, char **argv)
183 { 181 {
182 int status;
184 char *name; 183 char *name;
185 184
186 /* Native Language Support */ 185 /* Native Language Support */
...@@ -199,6 +198,23 @@ main (int argc, char **argv) ...@@ -199,6 +198,23 @@ main (int argc, char **argv)
199 } 198 }
200 else 199 else
201 name = mh_expand_name (NULL, folder_name, 0); 200 name = mh_expand_name (NULL, folder_name, 0);
202 rmf (name); 201 if (recursive)
202 status = recrmf (name);
203 else
204 {
205 if (interactive && !mh_getyn (_("Remove folder %s"), name))
206 exit (0);
207 status = rmf (name);
208 }
209 if (status == 0)
210 {
211 if (cur_folder_path && strcmp (name, cur_folder_path) == 0)
212 {
213 mh_set_current_folder ("inbox");
214 mh_global_save_state ();
215 printf ("[+inbox now current]\n");
216 }
203 return 0; 217 return 0;
218 }
219 return 1;
204 } 220 }
......
...@@ -219,7 +219,8 @@ main (int argc, char **argv) ...@@ -219,7 +219,8 @@ main (int argc, char **argv)
219 219
220 clear_screen (); 220 clear_screen ();
221 mh_global_save_state (); 221 mh_global_save_state ();
222 222 mu_mailbox_close (mbox);
223 mu_mailbox_destroy (&mbox);
223 return status; 224 return status;
224 } 225 }
225 226
......
...@@ -96,7 +96,6 @@ Mail/inbox/2 ...@@ -96,7 +96,6 @@ Mail/inbox/2
96 Mail/inbox/3 96 Mail/inbox/3
97 Mail/inbox/4 97 Mail/inbox/4
98 Mail/inbox/5 98 Mail/inbox/5
99 Mail/inbox/.mh_sequences
100 ]) 99 ])
101 100
102 MH_CHECK([folder --pack=N],[folder06 folder--pack=N],[ 101 MH_CHECK([folder --pack=N],[folder06 folder--pack=N],[
...@@ -115,7 +114,6 @@ Mail/inbox/2 ...@@ -115,7 +114,6 @@ Mail/inbox/2
115 Mail/inbox/3 114 Mail/inbox/3
116 Mail/inbox/4 115 Mail/inbox/4
117 Mail/inbox/5 116 Mail/inbox/5
118 Mail/inbox/.mh_sequences
119 ]) 117 ])
120 118
121 MH_CHECK([folder -push/-pop],[folder07 folder-push folder-pop folder-push-pop], 119 MH_CHECK([folder -push/-pop],[folder07 folder-push folder-pop folder-push-pop],
......
...@@ -22,7 +22,7 @@ inc -notruncate -file ./mbox1 | sed 's/ *$//' ...@@ -22,7 +22,7 @@ inc -notruncate -file ./mbox1 | sed 's/ *$//'
22 cmp $abs_top_srcdir/testsuite/spool/mbox1 mbox1 22 cmp $abs_top_srcdir/testsuite/spool/mbox1 mbox1
23 ], 23 ],
24 [0], 24 [0],
25 [ 1 12/28 Foo Bar <foobar@n Jabberwocky<<`Twas brillig, and the slithy toves 25 [ 1+ 12/28 Foo Bar <foobar@n Jabberwocky<<`Twas brillig, and the slithy toves
26 2 12/28 Bar <bar@dontmail Re: Jabberwocky<<It seems very pretty, but it's 26 2 12/28 Bar <bar@dontmail Re: Jabberwocky<<It seems very pretty, but it's
27 3 07/13 Sergey Poznyakoff Simple MIME<<------- =_aaaaaaaaaa0 Content-Type: 27 3 07/13 Sergey Poznyakoff Simple MIME<<------- =_aaaaaaaaaa0 Content-Type:
28 4 07/13 Sergey Poznyakoff Nested MIME<<------- =_aaaaaaaaaa0 Content-Type: 28 4 07/13 Sergey Poznyakoff Nested MIME<<------- =_aaaaaaaaaa0 Content-Type:
...@@ -36,7 +36,7 @@ echo "Next" ...@@ -36,7 +36,7 @@ echo "Next"
36 inc -truncate -file ./mbox1 | sed 's/ *$//' 36 inc -truncate -file ./mbox1 | sed 's/ *$//'
37 ], 37 ],
38 [0], 38 [0],
39 [ 1 12/28 Foo Bar <foobar@n Jabberwocky<<`Twas brillig, and the slithy toves 39 [ 1+ 12/28 Foo Bar <foobar@n Jabberwocky<<`Twas brillig, and the slithy toves
40 2 12/28 Bar <bar@dontmail Re: Jabberwocky<<It seems very pretty, but it's 40 2 12/28 Bar <bar@dontmail Re: Jabberwocky<<It seems very pretty, but it's
41 3 07/13 Sergey Poznyakoff Simple MIME<<------- =_aaaaaaaaaa0 Content-Type: 41 3 07/13 Sergey Poznyakoff Simple MIME<<------- =_aaaaaaaaaa0 Content-Type:
42 4 07/13 Sergey Poznyakoff Nested MIME<<------- =_aaaaaaaaaa0 Content-Type: 42 4 07/13 Sergey Poznyakoff Nested MIME<<------- =_aaaaaaaaaa0 Content-Type:
...@@ -50,12 +50,42 @@ mkdir Mail/new ...@@ -50,12 +50,42 @@ mkdir Mail/new
50 inc +new -file ./mbox1 | sed 's/ *$//' 50 inc +new -file ./mbox1 | sed 's/ *$//'
51 ], 51 ],
52 [0], 52 [0],
53 [ 1 12/28 Foo Bar <foobar@n Jabberwocky<<`Twas brillig, and the slithy toves 53 [ 1+ 12/28 Foo Bar <foobar@n Jabberwocky<<`Twas brillig, and the slithy toves
54 2 12/28 Bar <bar@dontmail Re: Jabberwocky<<It seems very pretty, but it's 54 2 12/28 Bar <bar@dontmail Re: Jabberwocky<<It seems very pretty, but it's
55 3 07/13 Sergey Poznyakoff Simple MIME<<------- =_aaaaaaaaaa0 Content-Type: 55 3 07/13 Sergey Poznyakoff Simple MIME<<------- =_aaaaaaaaaa0 Content-Type:
56 4 07/13 Sergey Poznyakoff Nested MIME<<------- =_aaaaaaaaaa0 Content-Type: 56 4 07/13 Sergey Poznyakoff Nested MIME<<------- =_aaaaaaaaaa0 Content-Type:
57 5 07/13 Sergey Poznyakoff Empty MIME Parts<<------- =_aaaaaaaaaa0 Content- 57 5 07/13 Sergey Poznyakoff Empty MIME Parts<<------- =_aaaaaaaaaa0 Content-
58 ]) 58 ])
59 59
60 MH_CHECK([inc -changecur],[inc03 inc-changecur],[
61 MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
62 MUT_MBCOPY([$abs_top_srcdir/testsuite/spool/mbox1])
63 inc -changecur -file ./mbox1 | sed 's/ *$//'
64 ],
65 [0],
66 [ 6+ 12/28 Foo Bar <foobar@n Jabberwocky<<`Twas brillig, and the slithy toves
67 7 12/28 Bar <bar@dontmail Re: Jabberwocky<<It seems very pretty, but it's
68 8 07/13 Sergey Poznyakoff Simple MIME<<------- =_aaaaaaaaaa0 Content-Type:
69 9 07/13 Sergey Poznyakoff Nested MIME<<------- =_aaaaaaaaaa0 Content-Type:
70 10 07/13 Sergey Poznyakoff Empty MIME Parts<<------- =_aaaaaaaaaa0 Content-
71 ])
72
73 MH_CHECK([inc -nochangecur],[inc04 inc-nochangecur],[
74 MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
75 echo "cur: 1" > Mail/inbox/.mh_sequences
76 MUT_MBCOPY([$abs_top_srcdir/testsuite/spool/mbox1])
77 inc -nochangecur -file ./mbox1 | sed 's/ *$//'
78 grep ^cur: Mail/inbox/.mh_sequences
79 ],
80 [0],
81 [ 6 12/28 Foo Bar <foobar@n Jabberwocky<<`Twas brillig, and the slithy toves
82 7 12/28 Bar <bar@dontmail Re: Jabberwocky<<It seems very pretty, but it's
83 8 07/13 Sergey Poznyakoff Simple MIME<<------- =_aaaaaaaaaa0 Content-Type:
84 9 07/13 Sergey Poznyakoff Nested MIME<<------- =_aaaaaaaaaa0 Content-Type:
85 10 07/13 Sergey Poznyakoff Empty MIME Parts<<------- =_aaaaaaaaaa0 Content-
86 cur: 1
87 ])
88
89
60 m4_popdef[MH_KEYWORDS]) 90 m4_popdef[MH_KEYWORDS])
61 # End of inc.at 91 # End of inc.at
......