Commit e072a273 e072a2734eaf1bffdacfc20fcb598d79a50d11e7 by Sergey Poznyakoff

Add functions for operations on message sets.

* configure.ac: Build libmailutils/msgset/Makefile
* include/mailutils/msgset.h: New file.
* include/mailutils/Makefile.am (pkginclude_HEADERS): Add msgset.h
* include/mailutils/mailutils.h: Include mailutils/msgset.h
* include/mailutils/sys/msgset.h: New file.
* include/mailutils/sys/Makefile.am (sysinclude_HEADERS): Add msgset.h
* include/mailutils/types.hin (mu_msgset_t): New type.
* libmailutils/Makefile.am (SUBDIRS): Add msgset.
(libmailutils_la_LIBADD): Add libmsgset.la
* libmailutils/msgset/Makefile.am: New file.
* libmailutils/msgset/add.c: New file.
* libmailutils/msgset/aggr.c: New file.
* libmailutils/msgset/clear.c: New file.
* libmailutils/msgset/create.c: New file.
* libmailutils/msgset/free.c: New file.
* libmailutils/msgset/getitr.c: New file.
* libmailutils/msgset/getlist.c: New file.
* libmailutils/msgset/locate.c: New file.
* libmailutils/msgset/parse.c: New file.
* libmailutils/msgset/print.c: New file.
* libmailutils/msgset/sub.c: New file.
* libmailutils/tests/msgset.at: New file.
* libmailutils/tests/msgset.c: New file.
* libmailutils/tests/Makefile.am (noinst_PROGRAMS): Add msgset.
(TESTSUITE_AT): Add msgset.at.
* libmailutils/tests/testsuite.at: Include msgset.at.
* testsuite/msgset.c: New file.
* testsuite/Makefile.am (noinst_PROGRAMS): Add msgset.
1 parent d16a3de5
...@@ -1479,6 +1479,7 @@ AC_CONFIG_FILES([ ...@@ -1479,6 +1479,7 @@ AC_CONFIG_FILES([
1479 libmailutils/mailbox/Makefile 1479 libmailutils/mailbox/Makefile
1480 libmailutils/mailer/Makefile 1480 libmailutils/mailer/Makefile
1481 libmailutils/mime/Makefile 1481 libmailutils/mime/Makefile
1482 libmailutils/msgset/Makefile
1482 libmailutils/property/Makefile 1483 libmailutils/property/Makefile
1483 libmailutils/server/Makefile 1484 libmailutils/server/Makefile
1484 libmailutils/string/Makefile 1485 libmailutils/string/Makefile
......
...@@ -73,6 +73,7 @@ pkginclude_HEADERS = \ ...@@ -73,6 +73,7 @@ pkginclude_HEADERS = \
73 mh.h\ 73 mh.h\
74 mime.h\ 74 mime.h\
75 monitor.h\ 75 monitor.h\
76 msgset.h\
76 mu_auth.h\ 77 mu_auth.h\
77 util.h\ 78 util.h\
78 nls.h\ 79 nls.h\
......
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
18 #ifndef _MAILUTILS_DATETIME_H 18 #ifndef _MAILUTILS_DATETIME_H
19 #define _MAILUTILS_DATETIME_H 19 #define _MAILUTILS_DATETIME_H
20 20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
21 #include <time.h> 25 #include <time.h>
22 #include <mailutils/types.h> 26 #include <mailutils/types.h>
23 27
...@@ -83,4 +87,8 @@ int mu_scan_datetime (const char *input, const char *fmt, struct tm *tm, ...@@ -83,4 +87,8 @@ int mu_scan_datetime (const char *input, const char *fmt, struct tm *tm,
83 #define MU_DATETIME_FORM_RFC822 "%a, %e %b %Y %H:%M:%S %z" 87 #define MU_DATETIME_FORM_RFC822 "%a, %e %b %Y %H:%M:%S %z"
84 #define MU_DATETIME_SCAN_RFC822 "%[%a, %]%e %b %Y %H:%M%[:%S%] %z" 88 #define MU_DATETIME_SCAN_RFC822 "%[%a, %]%e %b %Y %H:%M%[:%S%] %z"
85 89
90 #ifdef __cplusplus
91 }
92 #endif
93
86 #endif 94 #endif
......
...@@ -70,5 +70,6 @@ ...@@ -70,5 +70,6 @@
70 #include <mailutils/prog.h> 70 #include <mailutils/prog.h>
71 #include <mailutils/sockaddr.h> 71 #include <mailutils/sockaddr.h>
72 #include <mailutils/cidr.h> 72 #include <mailutils/cidr.h>
73 #include <mailutils/msgset.h>
73 74
74 /* EOF */ 75 /* EOF */
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #ifndef _MAILUTILS_MSGSET_H
19 #define _MAILUTILS_MSGSET_H
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25 struct mu_msgrange
26 {
27 size_t msg_beg;
28 size_t msg_end;
29 };
30
31 /* Message numbers start with 1. MU_MSGNO_LAST denotes the last
32 message. */
33 #define MU_MSGNO_LAST 0
34
35 #define MU_MSGSET_UID 0x01 /* Message set operates on UIDs */
36
37 int mu_msgset_create (mu_msgset_t *pmsgset, mu_mailbox_t mbox, int flags);
38 int mu_msgset_get_list (mu_msgset_t msgset, mu_list_t *plist);
39 int mu_msgset_get_iterator (mu_msgset_t msgset, mu_iterator_t *pitr);
40
41 int mu_msgset_add_range (mu_msgset_t list, size_t beg, size_t end);
42 int mu_msgset_sub_range (mu_msgset_t list, size_t beg, size_t end);
43 /*int mu_msgset_add_set (mu_msgset_t a, mu_msgset_t b);*/
44 /*int mu_msgset_sub_set (mu_msgset_t a, mu_msgset_t b);*/
45 int mu_msgset_aggregate (mu_msgset_t set);
46 int mu_msgset_clear (mu_msgset_t set);
47 void mu_msgset_free (mu_msgset_t set);
48 void mu_msgset_destroy (mu_msgset_t *set);
49
50 int mu_msgset_parse_imap (mu_msgset_t set, char *s, char **end);
51
52 int mu_msgset_print (mu_stream_t str, mu_msgset_t msgset);
53
54 int mu_msgset_locate (mu_msgset_t msgset, size_t n,
55 struct mu_msgrange const **prange);
56
57 #ifdef __cplusplus
58 }
59 #endif
60
61 #endif
...@@ -44,6 +44,7 @@ sysinclude_HEADERS = \ ...@@ -44,6 +44,7 @@ sysinclude_HEADERS = \
44 message.h\ 44 message.h\
45 mime.h\ 45 mime.h\
46 monitor.h\ 46 monitor.h\
47 msgset.h\
47 nntp.h\ 48 nntp.h\
48 nullstream.h\ 49 nullstream.h\
49 observer.h\ 50 observer.h\
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #ifndef _MAILUTILS_SYS_MSGSET_H
19 # define _MAILUTILS_SYS_MSGSET_H
20
21 #define _MU_MSGSET_AGGREGATED 0x10
22 #define _MU_MSGSET_USERFLAG_MASK 0x0f
23
24 struct _mu_msgset
25 {
26 mu_list_t list; /* List of mu_msgrange structures */
27 mu_mailbox_t mbox; /* Associated mailbox */
28 int flags; /* Message set flags */
29 };
30
31 #endif
...@@ -77,7 +77,8 @@ struct _mu_server; ...@@ -77,7 +77,8 @@ struct _mu_server;
77 struct _mu_tcp_server; 77 struct _mu_tcp_server;
78 struct _mu_dbm_file; 78 struct _mu_dbm_file;
79 struct _mu_imapio; 79 struct _mu_imapio;
80 80 struct _mu_msgset;
81
81 struct mu_sockaddr; /* defined in mailutils/sockaddr.h */ 82 struct mu_sockaddr; /* defined in mailutils/sockaddr.h */
82 struct mu_cidr; /* defined in mailutils/cidr.h */ 83 struct mu_cidr; /* defined in mailutils/cidr.h */
83 84
...@@ -125,6 +126,7 @@ typedef struct _mu_secret *mu_secret_t; ...@@ -125,6 +126,7 @@ typedef struct _mu_secret *mu_secret_t;
125 typedef struct _mu_mime_io_buffer *mu_mime_io_buffer_t; 126 typedef struct _mu_mime_io_buffer *mu_mime_io_buffer_t;
126 typedef struct _mu_dbm_file *mu_dbm_file_t; 127 typedef struct _mu_dbm_file *mu_dbm_file_t;
127 typedef struct _mu_imapio *mu_imapio_t; 128 typedef struct _mu_imapio *mu_imapio_t;
129 typedef struct _mu_msgset *mu_msgset_t;
128 130
129 typedef void (*mu_onexit_t) (void*); 131 typedef void (*mu_onexit_t) (void*);
130 typedef unsigned int mu_debug_handle_t; 132 typedef unsigned int mu_debug_handle_t;
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
18 18
19 SUBDIRS = \ 19 SUBDIRS = \
20 auth base address list sockaddr cidr cfg diag\ 20 auth base address list sockaddr cidr cfg diag\
21 filter mailbox mailer mime server string stream stdstream\ 21 filter mailbox mailer mime msgset server string stream stdstream\
22 property url imapio datetime . tests 22 property url imapio datetime . tests
23 23
24 lib_LTLIBRARIES = libmailutils.la 24 lib_LTLIBRARIES = libmailutils.la
...@@ -41,6 +41,7 @@ libmailutils_la_LIBADD = \ ...@@ -41,6 +41,7 @@ libmailutils_la_LIBADD = \
41 mailbox/libmailbox.la\ 41 mailbox/libmailbox.la\
42 mailer/libmailer.la\ 42 mailer/libmailer.la\
43 mime/libmime.la\ 43 mime/libmime.la\
44 msgset/libmsgset.la\
44 property/libproperty.la\ 45 property/libproperty.la\
45 server/libserver.la\ 46 server/libserver.la\
46 string/libstring.la\ 47 string/libstring.la\
......
1 # GNU Mailutils -- a suite of utilities for electronic mail
2 # Copyright (C) 2011 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 noinst_LTLIBRARIES = libmsgset.la
19
20 libmsgset_la_SOURCES = \
21 add.c\
22 aggr.c\
23 clear.c\
24 create.c\
25 getitr.c\
26 getlist.c\
27 free.c\
28 locate.c\
29 parse.c\
30 print.c\
31 sub.c
32
33 INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
34
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #include <config.h>
18 #include <stdlib.h>
19 #include <mailutils/types.h>
20 #include <mailutils/errno.h>
21 #include <mailutils/list.h>
22 #include <mailutils/msgset.h>
23 #include <mailutils/sys/msgset.h>
24
25 int
26 mu_msgset_add_range (mu_msgset_t mset, size_t beg, size_t end)
27 {
28 int rc;
29 struct mu_msgrange *range;
30
31 if (!mset || beg == 0)
32 return EINVAL;
33 range = calloc (1, sizeof (*range));
34 if (!range)
35 return ENOMEM;
36 range->msg_beg = beg;
37 range->msg_end = end;
38 rc = mu_list_append (mset->list, range);
39 if (rc)
40 free (range);
41 mset->flags &= ~_MU_MSGSET_AGGREGATED;
42 return rc;
43 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #include <config.h>
18 #include <stdlib.h>
19 #include <mailutils/types.h>
20 #include <mailutils/errno.h>
21 #include <mailutils/list.h>
22 #include <mailutils/iterator.h>
23 #include <mailutils/msgset.h>
24 #include <mailutils/sys/msgset.h>
25
26 /* Comparator function for sorting the message set list. */
27 static int
28 compare_msgrange (const void *a, const void *b)
29 {
30 struct mu_msgrange const *sa = a;
31 struct mu_msgrange const *sb = b;
32
33 if (sa->msg_end != sb->msg_end)
34 {
35 if (sa->msg_end == MU_MSGNO_LAST)
36 return 1;
37 if (sb->msg_end == MU_MSGNO_LAST)
38 return -1;
39 }
40
41 if (sa->msg_beg < sb->msg_beg)
42 return -1;
43 if (sa->msg_beg > sb->msg_beg)
44 return 1;
45
46 if (sa->msg_end == sb->msg_end)
47 return 0;
48
49 if (sa->msg_end < sb->msg_end)
50 return -1;
51 return 1;
52 }
53
54 int
55 mu_msgset_aggregate (mu_msgset_t mset)
56 {
57 int rc;
58 mu_iterator_t itr;
59 size_t count;
60 struct mu_msgrange *prev = NULL, *mr;
61 int dir;
62
63 if (!mset)
64 return EINVAL;
65
66 if (mset->flags & _MU_MSGSET_AGGREGATED)
67 return 0; /* nothing to do */
68
69 rc = mu_list_count (mset->list, &count);
70 if (rc)
71 return rc;
72 if (count < 2)
73 return 0;
74
75 mu_list_sort (mset->list, compare_msgrange);
76
77 rc = mu_list_get_iterator (mset->list, &itr);
78 if (rc)
79 return rc;
80 /* Set backward direction */
81 dir = 1;
82 rc = mu_iterator_ctl (itr, mu_itrctl_set_direction, &dir);
83 if (rc)
84 {
85 mu_iterator_destroy (&itr);
86 return rc;
87 }
88
89 mu_iterator_first (itr);
90 mu_iterator_current (itr, (void **)&mr);
91
92 if (mr->msg_end == MU_MSGNO_LAST)
93 {
94 struct mu_msgrange *last = mr;
95
96 for (mu_iterator_next (itr);
97 rc == 0 && !mu_iterator_is_done (itr); mu_iterator_next (itr))
98 {
99 mu_iterator_current (itr, (void **)&mr);
100 if (mr->msg_end == MU_MSGNO_LAST)
101 {
102 last->msg_beg = mr->msg_beg;
103 rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
104 }
105 else if (mr->msg_beg >= last->msg_beg)
106 rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
107 else if (mr->msg_end + 1 >= last->msg_beg)
108 {
109 last->msg_beg = mr->msg_beg;
110 rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
111 }
112 else
113 break;
114 }
115 }
116
117 if (rc == 0)
118 {
119 dir = 0;
120 rc = mu_iterator_ctl (itr, mu_itrctl_set_direction, &dir);
121 if (rc)
122 {
123 mu_iterator_destroy (&itr);
124 return rc;
125 }
126
127 for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
128 mu_iterator_next (itr))
129 {
130 mu_iterator_current (itr, (void **)&mr);
131 if (mr->msg_end == MU_MSGNO_LAST)
132 break;
133 if (prev)
134 {
135 if (prev->msg_beg <= mr->msg_beg && mr->msg_beg <= prev->msg_end)
136 {
137 /* Possible cases:
138 1. mr lies fully within prev:
139 mr->msg_end <= prev->msg_end
140 Action: mr deleted
141 2. mr overlaps with prev:
142 mr->msg_end > prev->msg_end
143 Action: prev->msg_end is set to mr->msg_end; mr deleted
144 */
145 if (mr->msg_end > prev->msg_end)
146 prev->msg_end = mr->msg_end;
147 rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
148 if (rc)
149 break;
150 continue;
151 }
152 else if (prev->msg_end + 1 == mr->msg_beg)
153 {
154 prev->msg_end = mr->msg_end;
155 rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
156 if (rc)
157 break;
158 continue;
159 }
160 }
161 prev = mr;
162 }
163 }
164 mu_iterator_destroy (&itr);
165
166 if (rc == 0)
167 mset->flags |= _MU_MSGSET_AGGREGATED;
168 return rc;
169 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #include <config.h>
18 #include <mailutils/types.h>
19 #include <mailutils/errno.h>
20 #include <mailutils/list.h>
21 #include <mailutils/msgset.h>
22 #include <mailutils/sys/msgset.h>
23
24 int
25 mu_msgset_clear (mu_msgset_t mset)
26 {
27 if (!mset)
28 return EINVAL;
29 mu_list_clear (mset->list);
30 return 0;
31 }
32
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #include <config.h>
18 #include <stdlib.h>
19 #include <mailutils/types.h>
20 #include <mailutils/errno.h>
21 #include <mailutils/list.h>
22 #include <mailutils/msgset.h>
23 #include <mailutils/sys/msgset.h>
24
25 /* Comparator function used to locate a message in the list. Second argument
26 (b) is a pointer to the message number. */
27 static int
28 compare_msgnum (const void *a, const void *b)
29 {
30 struct mu_msgrange const *range = a;
31 size_t msgno = *(size_t*)b;
32
33 if (range->msg_beg <= msgno && msgno <= range->msg_end)
34 return 0;
35 return 1;
36 }
37
38 int
39 mu_msgset_create (mu_msgset_t *pres, mu_mailbox_t mbox, int flags)
40 {
41 mu_msgset_t msgset;
42 int rc;
43
44 msgset = calloc (1, sizeof (*msgset));
45 if (!msgset)
46 return ENOMEM;
47
48 rc = mu_list_create (&msgset->list);
49 if (rc)
50 {
51 free (msgset);
52 return rc;
53 }
54 mu_list_set_destroy_item (msgset->list, mu_list_free_item);
55 mu_list_set_comparator (msgset->list, compare_msgnum);
56 msgset->mbox = mbox;
57 msgset->flags = flags & _MU_MSGSET_USERFLAG_MASK;
58 *pres = msgset;
59 return 0;
60 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #include <config.h>
18 #include <stdlib.h>
19 #include <mailutils/list.h>
20 #include <mailutils/msgset.h>
21 #include <mailutils/sys/msgset.h>
22
23 void
24 mu_msgset_free (mu_msgset_t mset)
25 {
26 if (mset)
27 {
28 mu_list_destroy (&mset->list);
29 free (mset);
30 }
31 }
32
33 void
34 mu_msgset_destroy (mu_msgset_t *pset)
35 {
36 if (pset)
37 {
38 mu_msgset_free (*pset);
39 *pset = NULL;
40 }
41 }
42
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #include <config.h>
18 #include <mailutils/types.h>
19 #include <mailutils/errno.h>
20 #include <mailutils/list.h>
21 #include <mailutils/msgset.h>
22 #include <mailutils/sys/msgset.h>
23
24 int
25 mu_msgset_get_iterator (mu_msgset_t msgset, mu_iterator_t *pitr)
26 {
27 if (!msgset)
28 return EINVAL;
29 return mu_list_get_iterator (msgset->list, pitr);
30 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #include <config.h>
18 #include <mailutils/types.h>
19 #include <mailutils/errno.h>
20 #include <mailutils/list.h>
21 #include <mailutils/msgset.h>
22 #include <mailutils/sys/msgset.h>
23
24 int
25 mu_msgset_get_list (mu_msgset_t msgset, mu_list_t *plist)
26 {
27 if (!msgset)
28 return EINVAL;
29 if (!plist)
30 return MU_ERR_OUT_PTR_NULL;
31 *plist = msgset->list;
32 return 0;
33 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #include <config.h>
18 #include <stdlib.h>
19 #include <mailutils/types.h>
20 #include <mailutils/errno.h>
21 #include <mailutils/list.h>
22 #include <mailutils/msgset.h>
23 #include <mailutils/sys/msgset.h>
24
25 int
26 mu_msgset_locate (mu_msgset_t msgset, size_t n,
27 struct mu_msgrange const **prange)
28 {
29 if (!msgset || n == 0)
30 return EINVAL;
31 return mu_list_locate (msgset->list, &n, (void**)prange);
32 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #include <config.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <limits.h>
21 #include <mailutils/types.h>
22 #include <mailutils/errno.h>
23 #include <mailutils/list.h>
24 #include <mailutils/iterator.h>
25 #include <mailutils/mailbox.h>
26 #include <mailutils/msgset.h>
27 #include <mailutils/sys/msgset.h>
28
29 /* This structure keeps parser state while parsing message set. */
30 struct parse_msgnum_env
31 {
32 char *s; /* Current position in string */
33 size_t minval; /* Min. sequence number or UID */
34 size_t maxval; /* Max. sequence number or UID */
35 mu_msgset_t msgset; /* Message set being built. */
36 };
37
38 /* Get a single message number/UID from env->s and store it into *PN.
39 Return 0 on success and error code on error.
40
41 Advance env->s to the point past the parsed message number.
42 */
43 static int
44 get_msgnum (struct parse_msgnum_env *env, size_t *pn)
45 {
46 size_t msgnum;
47 char *p;
48
49 errno = 0;
50 msgnum = strtoul (env->s, &p, 10);
51 if (msgnum == ULONG_MAX && errno == ERANGE)
52 return MU_ERR_PARSE;
53 env->s = p;
54 if (env->msgset->mbox && env->maxval && msgnum > env->maxval)
55 msgnum = env->maxval;
56 *pn = msgnum;
57 return 0;
58 }
59
60 /* Parse a single message range (A:B). Treat '*' as the largest number/UID
61 in use. */
62 static int
63 parse_msgrange (struct parse_msgnum_env *env)
64 {
65 int rc;
66 struct mu_msgrange msgrange;
67
68 if (*env->s == '*')
69 {
70 msgrange.msg_beg = env->maxval;
71 env->s++;
72 }
73 else if ((rc = get_msgnum (env, &msgrange.msg_beg)))
74 return rc;
75
76 if (*env->s == ':')
77 {
78 if (*++env->s == '*')
79 {
80 msgrange.msg_end = env->maxval;
81 ++env->s;
82 }
83 else if (*env->s == 0)
84 return MU_ERR_PARSE;
85 else if ((rc = get_msgnum (env, &msgrange.msg_end)))
86 return rc;
87 }
88 else
89 msgrange.msg_end = msgrange.msg_beg;
90
91 if (msgrange.msg_end && msgrange.msg_end < msgrange.msg_beg)
92 {
93 size_t tmp = msgrange.msg_end;
94 msgrange.msg_end = msgrange.msg_beg;
95 msgrange.msg_beg = tmp;
96 }
97
98 if ((env->msgset->flags & MU_MSGSET_UID) && env->msgset->mbox)
99 {
100 int rc;
101
102 rc = mu_mailbox_translate (env->msgset->mbox,
103 MU_MAILBOX_UID_TO_MSGNO,
104 msgrange.msg_beg, &msgrange.msg_beg);
105 if (rc == MU_ERR_NOENT)
106 msgrange.msg_beg = env->minval;
107 else if (rc)
108 return rc;
109
110 rc = mu_mailbox_translate (env->msgset->mbox,
111 MU_MAILBOX_UID_TO_MSGNO,
112 msgrange.msg_end, &msgrange.msg_end);
113 if (rc == MU_ERR_NOENT)
114 msgrange.msg_end = env->maxval;
115 else if (rc)
116 return rc;
117 }
118
119 return mu_msgset_add_range (env->msgset, msgrange.msg_beg, msgrange.msg_end);
120 }
121
122 /* Parse IMAP-style message set specification S.
123
124 On success, return 0 and populate MSET with the resulting message ranges.
125 On error, return error code and point END to the position in the input
126 string where parsing has failed. */
127 int
128 mu_msgset_parse_imap (mu_msgset_t mset, char *s, char **end)
129 {
130 int rc;
131 struct parse_msgnum_env env;
132
133 if (!s || !mset)
134 return EINVAL;
135 if (!*s)
136 return MU_ERR_PARSE;
137
138 memset (&env, 0, sizeof (env));
139 env.s = s;
140 env.msgset = mset;
141 env.minval = 1;
142
143 if (end)
144 *end = s;
145 if (mset->mbox)
146 {
147 size_t lastmsgno; /* Max. sequence number. */
148
149 rc = mu_mailbox_messages_count (mset->mbox, &lastmsgno);
150 if (rc == 0)
151 {
152 if (mset->flags & MU_MSGSET_UID)
153 {
154 rc = mu_mailbox_translate (mset->mbox, MU_MAILBOX_MSGNO_TO_UID,
155 lastmsgno, &env.maxval);
156 if (rc == 0)
157 rc = mu_mailbox_translate (mset->mbox, MU_MAILBOX_MSGNO_TO_UID,
158 1, &env.minval);
159 }
160 else
161 env.maxval = lastmsgno;
162 }
163 if (rc)
164 return rc;
165 }
166
167 while ((rc = parse_msgrange (&env)) == 0 && *env.s)
168 {
169 if (*env.s != ',' || *++env.s == 0)
170 {
171 rc = MU_ERR_PARSE;
172 break;
173 }
174 }
175
176 if (end)
177 *end = env.s;
178 return rc;
179 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #include <config.h>
18 #include <stdlib.h>
19 #include <mailutils/types.h>
20 #include <mailutils/errno.h>
21 #include <mailutils/list.h>
22 #include <mailutils/stream.h>
23 #include <mailutils/io.h>
24 #include <mailutils/msgset.h>
25 #include <mailutils/sys/msgset.h>
26
27 struct print_env
28 {
29 mu_stream_t stream;
30 int cont;
31 };
32
33 static int
34 _msgrange_printer (void *item, void *data)
35 {
36 int rc;
37 struct mu_msgrange *range = item;
38 struct print_env *env = data;
39
40 if (env->cont)
41 {
42 rc = mu_stream_write (env->stream, ",", 1, NULL);
43 if (rc)
44 return rc;
45 }
46 else
47 env->cont = 1;
48 if (range->msg_beg == range->msg_end)
49 rc = mu_stream_printf (env->stream, "%lu", (unsigned long) range->msg_beg);
50 else if (range->msg_end == 0)
51 rc = mu_stream_printf (env->stream, "%lu:*",
52 (unsigned long) range->msg_beg);
53 else
54 rc = mu_stream_printf (env->stream, "%lu:%lu",
55 (unsigned long) range->msg_beg,
56 (unsigned long) range->msg_end);
57 return rc;
58 }
59
60 int
61 mu_msgset_print (mu_stream_t str, mu_msgset_t mset)
62 {
63 struct print_env env;
64 int rc;
65
66 if (mu_list_is_empty (mset->list))
67 return MU_ERR_NOENT;
68 rc = mu_msgset_aggregate (mset);
69 if (rc)
70 return rc;
71 env.stream = str;
72 env.cont = 0;
73 return mu_list_foreach (mset->list, _msgrange_printer, &env);
74 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #include <config.h>
18 #include <stdlib.h>
19 #include <mailutils/types.h>
20 #include <mailutils/errno.h>
21 #include <mailutils/list.h>
22 #include <mailutils/iterator.h>
23 #include <mailutils/msgset.h>
24 #include <mailutils/sys/msgset.h>
25
26 /* Remove range R from the set S.
27
28 There are following basic cases:
29
30 1. S does not contain R.
31
32 Return imeediately, there is nothing to do here.
33
34 2. S contains a range X that matches exactly R.
35
36 Action: Remove X entirely and return.
37
38 3. There is a range X in S such that R falls entirely within it.
39
40 Action: Split X into two ranges:
41
42 X.msg_beg : R.msg_beg-1
43 R.msg_end+1 : X.msg_end
44
45 and return.
46 In border cases one of the new ranges may be empty.
47
48 4. There is a range X which contains an initial subrange of R.
49
50 Action: Remove the subrange from X. If the resulting range is
51 empty, remove it. Continue iteration with X.msg_end:R.msg_end
52 in place of R.
53
54 5. There is a range X such that its initial subrange is contained
55 in R.
56
57 Action: Remove X.msg_beg:R.msg_end and return.
58
59 6. There is a range X that is contained within R.
60
61 Action: Remove X and continue.
62
63 There are two special cases. First is when R.msg_end is 0, meaning the last
64 available message number in the mailbox. In this case the problem is reduced
65 to either 2 or a combination of 4 and zero or more 6. It is handled by the
66 sub_msgno_last function below.
67
68 Yet another special case is when the last element of S has msg_end == 0. If
69 so, the problem is reduced to either 2 or 4.
70 */
71
72 static int
73 sub_msgno_last (mu_msgset_t mset, size_t beg)
74 {
75 int rc;
76 struct mu_msgrange *range;
77
78 if (beg == 1)
79 mu_list_clear (mset->list);
80 else
81 {
82 mu_iterator_t itr;
83
84 rc = mu_list_get_iterator (mset->list, &itr);
85 if (rc)
86 return rc;
87 rc = 1;
88 rc = mu_iterator_ctl (itr, mu_itrctl_set_direction, &rc);
89 if (rc)
90 {
91 mu_iterator_destroy (&itr);
92 return rc;
93 }
94
95 for (mu_iterator_first (itr); rc == 0 && !mu_iterator_is_done (itr);
96 mu_iterator_next (itr))
97 {
98 mu_iterator_current (itr, (void **)&range);
99 if (range->msg_beg > beg)
100 rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
101 else if (range->msg_beg == beg)
102 {
103 rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
104 break;
105 }
106 else
107 break;
108 }
109 mu_iterator_destroy (&itr);
110 }
111 return 0;
112 }
113
114 int
115 mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end)
116 {
117 int rc;
118 mu_iterator_t itr;
119 struct mu_msgrange *mr;
120
121 if (!mset)
122 return EINVAL;
123 if (mu_list_is_empty (mset->list))
124 return MU_ERR_NOENT;
125 rc = mu_msgset_aggregate (mset);
126 if (rc)
127 return rc;
128
129 if (end == MU_MSGNO_LAST)
130 return sub_msgno_last (mset, beg);
131
132 /* Test border cases */
133 rc = mu_list_head (mset->list, (void**)&mr);
134 if (rc)
135 return rc;
136 if (end < mr->msg_beg)
137 return 0;
138 if (beg < mr->msg_beg)
139 beg = mr->msg_beg;
140
141 if (rc)
142 return rc;
143 rc = mu_list_tail (mset->list, (void**) &mr);
144 if (mr->msg_end != MU_MSGNO_LAST)
145 {
146 if (beg > mr->msg_end)
147 return 0;
148 if (end > mr->msg_end)
149 end = mr->msg_end;
150 }
151
152 rc = mu_list_get_iterator (mset->list, &itr);
153 if (rc)
154 return rc;
155 for (mu_iterator_first (itr); rc == 0 && !mu_iterator_is_done (itr);
156 mu_iterator_next (itr))
157 {
158 mu_iterator_current (itr, (void **)&mr);
159
160 if (mr->msg_end == MU_MSGNO_LAST)
161 {
162 /* This is the last element in list. */
163 if (mr->msg_beg == beg)
164 rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
165 else if (mr->msg_beg > beg)
166 mr->msg_beg = end + 1;
167 break;
168 }
169
170 if (mr->msg_beg == beg && mr->msg_end == end) /* See case 2 above */
171 {
172 rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
173 break;
174 }
175 else if (mr->msg_beg <= beg && beg <= mr->msg_end)
176 {
177 if (mr->msg_beg <= end && end <= mr->msg_end) /* Case 3 */
178 {
179 /* Split the range */
180 if (end != mr->msg_end)
181 {
182 struct mu_msgrange *newrange = calloc (1,
183 sizeof (*newrange));
184 if (!newrange)
185 {
186 rc = ENOMEM;
187 break;
188 }
189 newrange->msg_beg = end + 1;
190 newrange->msg_end = mr->msg_end;
191 rc = mu_iterator_ctl (itr, mu_itrctl_insert, newrange);
192 if (rc)
193 {
194 free (newrange);
195 break;
196 }
197 }
198
199 if (mr->msg_beg == beg)
200 rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
201 else
202 mr->msg_end = beg - 1;
203 break;
204 }
205 else if (mr->msg_beg == beg) /* Case 4 */
206 {
207 beg = mr->msg_end;
208 rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
209 }
210 else
211 {
212 size_t n = mr->msg_end;
213 mr->msg_end = beg - 1;
214 beg = n;
215 }
216 }
217 else if (mr->msg_beg <= end && end <= mr->msg_end) /* Case 5 */
218 {
219 mr->msg_beg = end + 1;
220 if (mr->msg_beg >= mr->msg_end)
221 rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
222 break;
223 }
224 else if (beg <= mr->msg_beg && mr->msg_beg <= end)
225 {
226 rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
227 }
228 }
229 mu_iterator_destroy (&itr);
230
231 return rc;
232 }
233
...@@ -52,6 +52,7 @@ noinst_PROGRAMS = \ ...@@ -52,6 +52,7 @@ noinst_PROGRAMS = \
52 listop\ 52 listop\
53 mailcap\ 53 mailcap\
54 mimehdr\ 54 mimehdr\
55 msgset\
55 prop\ 56 prop\
56 scantime\ 57 scantime\
57 strftime\ 58 strftime\
...@@ -90,6 +91,7 @@ TESTSUITE_AT = \ ...@@ -90,6 +91,7 @@ TESTSUITE_AT = \
90 list.at\ 91 list.at\
91 mailcap.at\ 92 mailcap.at\
92 mimehdr.at\ 93 mimehdr.at\
94 msgset.at\
93 prop.at\ 95 prop.at\
94 scantime.at\ 96 scantime.at\
95 strftime.at\ 97 strftime.at\
......
1 # This file is part of GNU Mailutils. -*- Autotest -*-
2 # Copyright (C) 2011 Free Software Foundation, Inc.
3 #
4 # GNU Mailutils is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3, or (at
7 # your option) any later version.
8 #
9 # GNU Mailutils is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # 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 AT_BANNER([Message sets])
18
19 dnl ------------------------------------------------------------------
20 dnl MSGSET([NAME], [KW = `'], [OP], [STDOUT = `'], [STDERR = `'])
21 dnl
22 m4_pushdef([MSGSET],[
23 AT_SETUP([$1])
24 AT_KEYWORDS([msgset $2])
25 AT_CHECK([msgset $3],[0],[$4],[$5])
26 AT_CLEANUP
27 ])
28 dnl ------------------------------------------------------------------
29
30 MSGSET([Aggregation: simple],[msgset-aggr-simple msgset-aggr],
31 [-msgset='1,5:11,20:24,80:90,22:30,50:60,4:12,41:50,70:81'],
32 [1,4:12,20:30,41:60,70:90
33 ])
34
35 MSGSET([Aggregation: open range (1)],
36 [msgset-aggr-open-1 msgset-aggr-open msgset-aggr],
37 [-msgset='12:*,1'],
38 [1,12:*
39 ])
40
41 MSGSET([Aggregation: coalescing open ranges],
42 [msgset-aggr-open-2 msgset-aggr-open msgset-aggr],
43 [-msgset='12:*,1,15:*,8:*'],
44 [1,8:*
45 ])
46
47 MSGSET([Aggregation: open range (3)],
48 [msgset-aggr-open-3 msgset-aggr-open msgset-aggr],
49 [-msgset='1,12:*,12:13'],
50 [1,12:*
51 ])
52
53 MSGSET([Aggregation: open range (4)],
54 [msgset-aggr-open-4 msgset-aggr-open msgset-aggr],
55 [-msgset='1,12:*,13:40'],
56 [1,12:*
57 ])
58
59 MSGSET([Aggregation: open range (5)],
60 [msgset-aggr-open-5 msgset-aggr-open msgset-aggr],
61 [-msgset='10:*,3,5:9'],
62 [3,5:*
63 ])
64
65 MSGSET([Create simple set],[msgset-simple msgset-add],
66 [-add=1:10],
67 [1:10
68 ])
69
70 MSGSET([Create complex set],[msgset-complex msgset-add],
71 [-add=1 -add=2 -add=3 -add=4 -add=10:20 -add=15:35 -add=36:40],
72 [1:4,10:40
73 ])
74
75 MSGSET([Subtract: no match],[msgset-sub msgset-sub-1],
76 [-msgset=20:40 -sub=1:10],
77 [20:40
78 ])
79
80 MSGSET([Subtract: exact match],[msgset-sub msgset-sub-2],
81 [-msgset=1,4:9,11 -sub=4:9],
82 [1,11
83 ])
84
85 MSGSET([Subtract: contained range],[msgset-sub msgset-sub-3],
86 [-msgset=1:40 -sub=5:15
87 ],
88 [1:4,16:40
89 ])
90
91 MSGSET([Subtract: contained range (left border case)],
92 [msgset-sub msgset-sub-3 msgset-sub-3-0],
93 [-msgset=1:40 -sub=1:20],
94 [21:40
95 ])
96
97 MSGSET([Subtract: contained range (right border case)],
98 [msgset-sub msgset-sub-3 msgset-sub-3-1],
99 [-msgset=1:40 -sub=30:40],
100 [1:29
101 ])
102
103 MSGSET([Subtract: initial subrange],[msgset-sub msgset-sub-4],
104 [-msgset=1:40,50:60,80:200 -sub=55:65],
105 [1:40,50:54,80:200
106 ])
107
108 MSGSET([Subtract: trailing subrange],[msgset-sub msgset-sub-5],
109 [-msgset=1:40,50:60,80:200 -sub=45:55],
110 [1:40,56:60,80:200
111 ])
112
113 MSGSET([Subtract: overlapping subrange],[msgset-sub msgset-sub-6],
114 [-msgset=1:40,50:60,80:200 -sub=41:70],
115 [1:40,80:200
116 ])
117
118 MSGSET([Subtract: 4, 5 and 6 combined],
119 [msgset-sub msgset-sub-4 msgset-sub-5 msgset-sub-6 msgset-sub-456],
120 [-msgset=1:40,50:60,80:200 -sub=30:100],
121 [1:29,101:200
122 ])
123
124 MSGSET([open range],[msgset-inf],
125 [-msgset='1:*'],
126 [1:*
127 ])
128
129 MSGSET([add to open range],[msgset-inf-add msgset-add],
130 [-msgset='10:*' -add=3 -add=5:9],
131 [3,5:*
132 ])
133
134 MSGSET([subtract from open range],[msgset-inf-sub msgset-sub],
135 [-msgset='3,10:*' -sub=5:11],
136 [3,12:*
137 ])
138
139 MSGSET([subtract from open range an equal range],[msgset-inf-sub-1 msgset-sub],
140 [-msgset='3,10:*' -sub=10:*],
141 [3
142 ])
143
144 MSGSET([subtract from open range a broader range],
145 [msgset-inf-sub-2 msgset-sub],
146 [-msgset='3,10:*' -sub=20:*],
147 [3,10:*
148 ])
149
150 MSGSET([subtract from open range a narrower range],
151 [msgset-inf-sub-3 msgset-sub],
152 [-msgset='3,10:*' -sub=5:*],
153 [3
154 ])
155
156 MSGSET([subtract an open range with matching left boundary],
157 [msgset-inf-sub-4 msgset-sub],
158 [-msgset='3,10:20' -sub=10:*],
159 [3
160 ])
161
162 MSGSET([subtract an open range with greater left boundary],
163 [msgset-inf-sub-4 msgset-sub],
164 [-msgset='3,10:20' -sub=11:*],
165 [3,10:20
166 ])
167
168 MSGSET([subtract an open range with smaller left boundary],
169 [msgset-inf-sub-4 msgset-sub],
170 [-msgset='3,10:20' -sub=8:*],
171 [3
172 ])
173
174 dnl ------------------------------------------------------------------
175 m4_popdef([MSGSET])
...\ No newline at end of file ...\ No newline at end of file
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #include <config.h>
18 #include <stdlib.h>
19 #include <mailutils/mailutils.h>
20
21 static void
22 parse_msgset (char *arg, struct mu_msgrange *range)
23 {
24 size_t msgnum;
25 char *p;
26
27 errno = 0;
28 msgnum = strtoul (arg, &p, 10);
29 range->msg_beg = msgnum;
30 if (*p == ':')
31 {
32 if (*++p == '*')
33 msgnum = 0;
34 else
35 {
36 msgnum = strtoul (p, &p, 10);
37 if (*p)
38 {
39 mu_error ("error in message range near %s", p);
40 exit (1);
41 }
42 }
43 }
44 else if (*p == '*')
45 msgnum = 0;
46 else if (*p)
47 {
48 mu_error ("error in message range near %s", p);
49 exit (1);
50 }
51
52 range->msg_end = msgnum;
53 }
54
55 int
56 main (int argc, char **argv)
57 {
58 int i;
59 char *msgset_string = NULL;
60 mu_msgset_t msgset;
61 int rc;
62
63 mu_set_program_name (argv[0]);
64 for (i = 1; i < argc; i++)
65 {
66 char *arg = argv[i];
67
68 if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0)
69 {
70 mu_printf ("usage: %s [-msgset=SET] [-add X[:Y]] [-del X:[Y]]...\n",
71 mu_program_name);
72 return 0;
73 }
74 else if (strncmp (arg, "-msgset=", 8) == 0)
75 msgset_string = arg + 8;
76 else
77 break;
78 }
79
80 MU_ASSERT (mu_msgset_create (&msgset, NULL, 0));
81 if (msgset_string)
82 {
83 char *end;
84 rc = mu_msgset_parse_imap (msgset, msgset_string, &end);
85 if (rc)
86 {
87 mu_error ("mu_msgset_parse_imap: %s near %s",
88 mu_strerror (rc), end);
89 return 1;
90 }
91 }
92
93 for (; i < argc; i++)
94 {
95 char *arg = argv[i];
96 struct mu_msgrange range;
97
98 if (strncmp (arg, "-add=", 5) == 0)
99 {
100 parse_msgset (arg + 5, &range);
101 MU_ASSERT (mu_msgset_add_range (msgset, range.msg_beg,
102 range.msg_end));
103 }
104 else if (strncmp (arg, "-sub=", 5) == 0)
105 {
106 parse_msgset (arg + 5, &range);
107 MU_ASSERT (mu_msgset_sub_range (msgset, range.msg_beg,
108 range.msg_end));
109 }
110 else
111 {
112 mu_error ("unknown option %s", arg);
113 return 1;
114 }
115 }
116 MU_ASSERT (mu_msgset_print (mu_strout, msgset));
117 mu_printf ("\n");
118 mu_msgset_free (msgset);
119
120 return 0;
121 }
122
123
124
125
...@@ -99,3 +99,5 @@ m4_include([strftime.at]) ...@@ -99,3 +99,5 @@ m4_include([strftime.at])
99 m4_include([fsaf.at]) 99 m4_include([fsaf.at])
100 100
101 m4_include([mimehdr.at]) 101 m4_include([mimehdr.at])
102
103 m4_include([msgset.at])
......
...@@ -54,6 +54,7 @@ noinst_PROGRAMS = \ ...@@ -54,6 +54,7 @@ noinst_PROGRAMS = \
54 fldel\ 54 fldel\
55 lstuid\ 55 lstuid\
56 mbdel\ 56 mbdel\
57 msgset\
57 mimetest\ 58 mimetest\
58 smtpsend\ 59 smtpsend\
59 ufms 60 ufms
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 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 #include <config.h>
18 #include <stdlib.h>
19 #include <mailutils/mailutils.h>
20
21 static void
22 parse_msgset (char *arg, struct mu_msgrange *range)
23 {
24 size_t msgnum;
25 char *p;
26
27 errno = 0;
28 msgnum = strtoul (arg, &p, 10);
29 range->msg_beg = msgnum;
30 if (*p == ':')
31 {
32 if (*++p == '*')
33 msgnum = 0;
34 else
35 {
36 msgnum = strtoul (p, &p, 10);
37 if (*p)
38 {
39 mu_error ("error in message range near %s", p);
40 exit (1);
41 }
42 }
43 }
44 else if (*p == '*')
45 msgnum = 0;
46 else if (*p)
47 {
48 mu_error ("error in message range near %s", p);
49 exit (1);
50 }
51
52 range->msg_end = msgnum;
53 }
54
55 int
56 main (int argc, char **argv)
57 {
58 int i;
59 char *msgset_string = NULL;
60 mu_msgset_t msgset;
61 int rc;
62 int flags = 0;
63 mu_mailbox_t mbox = NULL;
64
65 mu_set_program_name (argv[0]);
66 mu_registrar_record (mu_mbox_record);
67 for (i = 1; i < argc; i++)
68 {
69 char *arg = argv[i];
70
71 if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0)
72 {
73 mu_printf ("usage: %s [-msgset=SET] [-add X[:Y]] [-del X:[Y]]...\n",
74 mu_program_name);
75 return 0;
76 }
77 else if (strncmp (arg, "-msgset=", 8) == 0)
78 msgset_string = arg + 8;
79 else if (strcmp (arg, "-uid") == 0)
80 flags |= MU_MSGSET_UID;
81 else if (strncmp (arg, "-mailbox=", 9) == 0)
82 {
83 MU_ASSERT (mu_mailbox_create (&mbox, arg + 9));
84 MU_ASSERT (mu_mailbox_open (mbox, MU_STREAM_READ));
85 }
86 else
87 break;
88 }
89
90 MU_ASSERT (mu_msgset_create (&msgset, mbox, flags));
91 if (msgset_string)
92 {
93 char *end;
94 rc = mu_msgset_parse_imap (msgset, msgset_string, &end);
95 if (rc)
96 {
97 mu_error ("mu_msgset_parse_imap: %s near %s",
98 mu_strerror (rc), end);
99 return 1;
100 }
101 }
102
103 for (; i < argc; i++)
104 {
105 char *arg = argv[i];
106 struct mu_msgrange range;
107
108 if (strncmp (arg, "-add=", 5) == 0)
109 {
110 parse_msgset (arg + 5, &range);
111 MU_ASSERT (mu_msgset_add_range (msgset, range.msg_beg,
112 range.msg_end));
113 }
114 else if (strncmp (arg, "-sub=", 5) == 0)
115 {
116 parse_msgset (arg + 5, &range);
117 MU_ASSERT (mu_msgset_sub_range (msgset, range.msg_beg,
118 range.msg_end));
119 }
120 else
121 {
122 mu_error ("unknown option %s", arg);
123 return 1;
124 }
125 }
126 MU_ASSERT (mu_msgset_print (mu_strout, msgset));
127 mu_printf ("\n");
128 mu_msgset_free (msgset);
129
130 return 0;
131 }
132
133
134
135