Commit c51fa40b c51fa40b04c2b6cc8c0ef0693b8b2df89ac3119c by Sergey Poznyakoff

* include/mailutils/property.h: Update

* libproto/include/property0.h (struct property_item): Remove
key, set and next.
(struct _mu_property): Use mu_assoc_t to keep the items.
* mailbox/property.c: Rewrite using mu_assoc_t for storage.

* mailbox/parsedate.y (DATE_SET): Take an additional argument
specifying upper limit for the value. Bail out if val is out of
range. All callers updated.
(SET_.*): Rewrite via __SET_.*
1 parent dbd734c2
1 2008-01-02 Sergey Poznyakoff <gray@gnu.org.ua>
2
3 * include/mailutils/property.h: Update
4 * libproto/include/property0.h (struct property_item): Remove
5 key, set and next.
6 (struct _mu_property): Use mu_assoc_t to keep the items.
7 * mailbox/property.c: Rewrite using mu_assoc_t for storage.
8
9 * mailbox/parsedate.y (DATE_SET): Take an additional argument
10 specifying upper limit for the value. Bail out if val is out of
11 range. All callers updated.
12 (SET_.*): Rewrite via __SET_.*
13
1 2007-12-30 Sergey Poznyakoff <gray@gnu.org.ua> 14 2007-12-30 Sergey Poznyakoff <gray@gnu.org.ua>
2 15
3 * comsat/comsat.c: New config statement require-tty. 16 * comsat/comsat.c: New config statement require-tty.
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2005, 2007 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2001, 2005, 2007, 2008
3 Free Software Foundation, Inc.
3 4
4 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2007 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2001, 2007, 2008 Free Software Foundation, Inc.
3 3
4 This library is free software; you can redistribute it and/or 4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public 5 modify it under the terms of the GNU Lesser General Public
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
29 29
30 #include <mailutils/property.h> 30 #include <mailutils/property.h>
31 #include <mailutils/monitor.h> 31 #include <mailutils/monitor.h>
32 #include <mailutils/assoc.h>
32 33
33 #ifdef __cplusplus 34 #ifdef __cplusplus
34 extern "C" { 35 extern "C" {
...@@ -36,15 +37,12 @@ extern "C" { ...@@ -36,15 +37,12 @@ extern "C" {
36 37
37 struct property_item 38 struct property_item
38 { 39 {
39 char *key;
40 char *value; 40 char *value;
41 int set;
42 struct property_item *next;
43 }; 41 };
44 42
45 struct _mu_property 43 struct _mu_property
46 { 44 {
47 struct property_item *items; 45 mu_assoc_t assoc;
48 void *owner; 46 void *owner;
49 mu_monitor_t lock; 47 mu_monitor_t lock;
50 }; 48 };
......
1 %{ 1 %{
2 /* GNU Mailutils -- a suite of utilities for electronic mail 2 /* GNU Mailutils -- a suite of utilities for electronic mail
3 Copyright (C) 2003, 2007 Free Software Foundation, Inc. 3 Copyright (C) 2003, 2007, 2008 Free Software Foundation, Inc.
4 4
5 GNU Mailutils is free software; you can redistribute it and/or modify 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 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) 7 the Free Software Foundation; either version 2, or (at your option)
8 any later version. 8 any later version.
9 9
10 GNU Mailutils is distributed in the hope that it will be useful, 10 GNU Mailutils is distributed in the hope that it will be useful,
...@@ -14,8 +14,7 @@ ...@@ -14,8 +14,7 @@
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with GNU Mailutils; if not, write to the Free Software 16 along with GNU Mailutils; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18 MA 02110-1301 USA */
19 18
20 /* A heavily modified version of the well-known public domain getdate.y. 19 /* A heavily modified version of the well-known public domain getdate.y.
21 It was originally written by Steven M. Bellovin <smb@research.att.com> 20 It was originally written by Steven M. Bellovin <smb@research.att.com>
...@@ -127,19 +126,35 @@ struct pd_date ...@@ -127,19 +126,35 @@ struct pd_date
127 }; 126 };
128 127
129 #define DATE_INIT(date) memset(&(date), 0, sizeof(date)) 128 #define DATE_INIT(date) memset(&(date), 0, sizeof(date))
130 #define DATE_SET(date, memb, m, val) \ 129 #define DATE_SET(date, memb, m, val, lim, onerror) \
131 do { date . memb = val; date.mask |= m; } while (0) 130 do \
132 131 { \
133 #define SET_SECOND(d,v) DATE_SET(d,second,PD_MASK_SECOND,v) 132 if (val < 0 || (lim && val >= lim)) onerror; \
134 #define SET_MINUTE(d,v) DATE_SET(d,minute,PD_MASK_MINUTE,v) 133 date . memb = val; date.mask |= m; \
135 #define SET_HOUR(d,v) DATE_SET(d,hour,PD_MASK_HOUR,v) 134 } \
136 #define SET_DAY(d,v) DATE_SET(d,day,PD_MASK_DAY,v) 135 while (0)
137 #define SET_MONTH(d,v) DATE_SET(d,month,PD_MASK_MONTH,v) 136
138 #define SET_YEAR(d,v) DATE_SET(d,year,PD_MASK_YEAR,v) 137 #define __SET_SECOND(d,v,a) DATE_SET(d,second,PD_MASK_SECOND,v,60,a)
139 #define SET_TZ(d,v) DATE_SET(d,tz,PD_MASK_TZ,v) 138 #define __SET_MINUTE(d,v,a) DATE_SET(d,minute,PD_MASK_MINUTE,v,60,a)
140 #define SET_MERIDIAN(d,v) DATE_SET(d,meridian,PD_MASK_MERIDIAN,v) 139 #define __SET_HOUR(d,v,a) DATE_SET(d,hour,PD_MASK_HOUR,v,24,a)
141 #define SET_ORDINAL(d,v) DATE_SET(d,ordinal,PD_MASK_ORDINAL,v) 140 #define __SET_DAY(d,v,a) DATE_SET(d,day,PD_MASK_DAY,v,31,a)
142 #define SET_NUMBER(d,v) DATE_SET(d,number,PD_MASK_NUMBER,v) 141 #define __SET_MONTH(d,v,a) DATE_SET(d,month,PD_MASK_MONTH,v,12,a)
142 #define __SET_YEAR(d,v,a) DATE_SET(d,year,PD_MASK_YEAR,v,0,a)
143 #define __SET_TZ(d,v,a) DATE_SET(d,tz,PD_MASK_TZ,v,0,a)
144 #define __SET_MERIDIAN(d,v,a) DATE_SET(d,meridian,PD_MASK_MERIDIAN,v,MER24+1,a)
145 #define __SET_ORDINAL(d,v,a) DATE_SET(d,ordinal,PD_MASK_ORDINAL,v,0,a)
146 #define __SET_NUMBER(d,v,a) DATE_SET(d,number,PD_MASK_NUMBER,v,0,a)
147
148 #define SET_SECOND(d,v) __SET_SECOND(d,v,YYERROR)
149 #define SET_MINUTE(d,v) __SET_MINUTE(d,v,YYERROR)
150 #define SET_HOUR(d,v) __SET_HOUR(d,v,YYERROR)
151 #define SET_DAY(d,v) __SET_DAY(d,v,YYERROR)
152 #define SET_MONTH(d,v) __SET_MONTH(d,v,YYERROR)
153 #define SET_YEAR(d,v) __SET_YEAR(d,v,YYERROR)
154 #define SET_TZ(d,v) __SET_TZ(d,v,YYERROR)
155 #define SET_MERIDIAN(d,v) __SET_MERIDIAN(d,v,YYERROR)
156 #define SET_ORDINAL(d,v) __SET_ORDINAL(d,v,YYERROR)
157 #define SET_NUMBER(d,v) __SET_NUMBER(d,v,YYERROR)
143 158
144 int 159 int
145 pd_date_union (struct pd_date *a, struct pd_date *b) 160 pd_date_union (struct pd_date *a, struct pd_date *b)
...@@ -1057,19 +1072,19 @@ mu_parse_date (const char *p, time_t *rettime, const time_t *now) ...@@ -1057,19 +1072,19 @@ mu_parse_date (const char *p, time_t *rettime, const time_t *now)
1057 return -1; 1072 return -1;
1058 1073
1059 if (!MASK_IS_SET (pd.date.mask, PD_MASK_YEAR)) 1074 if (!MASK_IS_SET (pd.date.mask, PD_MASK_YEAR))
1060 SET_YEAR (pd.date, tmp->tm_year + TM_YEAR_ORIGIN); 1075 __SET_YEAR (pd.date, tmp->tm_year + TM_YEAR_ORIGIN, return -1);
1061 if (!MASK_IS_SET (pd.date.mask, PD_MASK_MONTH)) 1076 if (!MASK_IS_SET (pd.date.mask, PD_MASK_MONTH))
1062 SET_MONTH (pd.date, tmp->tm_mon + 1); 1077 __SET_MONTH (pd.date, tmp->tm_mon + 1, return -1);
1063 if (!MASK_IS_SET (pd.date.mask, PD_MASK_DAY)) 1078 if (!MASK_IS_SET (pd.date.mask, PD_MASK_DAY))
1064 SET_DAY (pd.date, tmp->tm_mday); 1079 __SET_DAY (pd.date, tmp->tm_mday, return -1);
1065 if (!MASK_IS_SET (pd.date.mask, PD_MASK_HOUR)) 1080 if (!MASK_IS_SET (pd.date.mask, PD_MASK_HOUR))
1066 SET_HOUR (pd.date, tmp->tm_hour); 1081 __SET_HOUR (pd.date, tmp->tm_hour, return -1);
1067 if (!MASK_IS_SET (pd.date.mask, PD_MASK_MERIDIAN)) 1082 if (!MASK_IS_SET (pd.date.mask, PD_MASK_MERIDIAN))
1068 SET_MERIDIAN (pd.date, MER24); 1083 __SET_MERIDIAN (pd.date, MER24, return -1);
1069 if (!MASK_IS_SET (pd.date.mask, PD_MASK_MINUTE)) 1084 if (!MASK_IS_SET (pd.date.mask, PD_MASK_MINUTE))
1070 SET_MINUTE (pd.date, tmp->tm_min); 1085 __SET_MINUTE (pd.date, tmp->tm_min, return -1);
1071 if (!MASK_IS_SET (pd.date.mask, PD_MASK_SECOND)) 1086 if (!MASK_IS_SET (pd.date.mask, PD_MASK_SECOND))
1072 SET_SECOND (pd.date, tmp->tm_sec); 1087 __SET_SECOND (pd.date, tmp->tm_sec, return -1);
1073 1088
1074 tm.tm_year = norm_year (pd.date.year) - TM_YEAR_ORIGIN + pd.rel.year; 1089 tm.tm_year = norm_year (pd.date.year) - TM_YEAR_ORIGIN + pd.rel.year;
1075 tm.tm_mon = pd.date.month - 1 + pd.rel.month; 1090 tm.tm_mon = pd.date.month - 1 + pd.rel.month;
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007 2 Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
...@@ -24,23 +24,35 @@ ...@@ -24,23 +24,35 @@
24 # include <strings.h> 24 # include <strings.h>
25 #endif 25 #endif
26 26
27 #include <mailutils/errno.h>
28 #include <property0.h> 27 #include <property0.h>
28 #include <mailutils/errno.h>
29 #include <mailutils/assoc.h>
30 #include <stdlib.h>
29 31
30 #undef min 32 static void
31 #define min(a,b) ((a) < (b) ? (a) : (b)) 33 prop_free_value (void *data)
32 34 {
33 static int property_find (mu_property_t, const char *, struct property_item **); 35 struct property_item *item = data;
36 free (item->value);
37 }
34 38
35 int 39 int
36 mu_property_create (mu_property_t *pp, void *owner) 40 mu_property_create (mu_property_t *pp, void *owner)
37 { 41 {
42 int rc;
38 mu_property_t prop; 43 mu_property_t prop;
39 if (pp == NULL) 44 if (pp == NULL)
40 return MU_ERR_OUT_PTR_NULL; 45 return MU_ERR_OUT_PTR_NULL;
41 prop = calloc (1, sizeof *prop); 46 prop = calloc (1, sizeof *prop);
42 if (prop == NULL) 47 if (prop == NULL)
43 return ENOMEM; 48 return ENOMEM;
49 rc = mu_assoc_create (&prop->assoc, sizeof (struct property_item), 0);
50 if (rc)
51 {
52 free (prop);
53 return rc;
54 }
55 mu_assoc_set_free (prop->assoc, prop_free_value);
44 mu_monitor_create (&prop->lock, 0, prop); 56 mu_monitor_create (&prop->lock, 0, prop);
45 prop->owner = owner; 57 prop->owner = owner;
46 *pp = prop; 58 *pp = prop;
...@@ -55,18 +67,9 @@ mu_property_destroy (mu_property_t *pp, void *owner) ...@@ -55,18 +67,9 @@ mu_property_destroy (mu_property_t *pp, void *owner)
55 mu_property_t prop = *pp; 67 mu_property_t prop = *pp;
56 if (prop->owner == owner) 68 if (prop->owner == owner)
57 { 69 {
58 struct property_item *item, *cur;
59 /* Destroy the list and is properties. */ 70 /* Destroy the list and is properties. */
60 mu_monitor_wrlock (prop->lock); 71 mu_monitor_wrlock (prop->lock);
61 for (item = prop->items; item; item = cur) 72 mu_assoc_destroy (&prop->assoc);
62 {
63 if (item->key)
64 free (item->key);
65 if (item->value)
66 free (item->value);
67 cur = item->next;
68 free (item);
69 }
70 mu_monitor_unlock (prop->lock); 73 mu_monitor_unlock (prop->lock);
71 mu_monitor_destroy (&prop->lock, prop); 74 mu_monitor_destroy (&prop->lock, prop);
72 free (prop); 75 free (prop);
...@@ -82,167 +85,108 @@ mu_property_get_owner (mu_property_t prop) ...@@ -82,167 +85,108 @@ mu_property_get_owner (mu_property_t prop)
82 } 85 }
83 86
84 int 87 int
85 mu_property_set_value (mu_property_t prop, const char *key, const char *value, 88 mu_property_set_value (mu_property_t prop, const char *key, const char *value,
86 int overwrite) 89 int overwrite)
87 { 90 {
88 struct property_item *item; 91 struct property_item *item;
89 int status = property_find (prop, key, &item); 92 int rc;
90 if (status != 0)
91 return status;
92 93
93 if (item->set) 94 if (!prop)
95 return EINVAL;
96 rc = mu_assoc_ref_install (prop->assoc, key, (void **)&item);
97 if (rc == MU_ERR_NOENT)
94 { 98 {
95 if (overwrite) 99 item->value = strdup (value);
96 {
97 item->set = 0;
98 if (item->value)
99 free (item->value);
100 item->value = NULL;
101 if (value)
102 {
103 item->set = 1;
104 item->value = strdup (value);
105 if (item->value == NULL)
106 status = ENOMEM;
107 }
108 }
109 } 100 }
110 else 101 else if (overwrite)
111 { 102 {
112 item->set = 1; 103 free (item->value);
113 if (item->value) 104 item->value = strdup (value);
114 free (item->value);
115 if (value)
116 {
117 item->value = strdup (value);
118 if (item->value == NULL)
119 status = ENOMEM;
120 }
121 } 105 }
122 return status; 106 else
123 } 107 return 0;
124 108
125 int 109 if (!item->value)
126 mu_property_get_value (mu_property_t prop, const char *key, char *buffer,
127 size_t buflen, size_t *n)
128 {
129 struct property_item *item = NULL;
130 int status;
131 size_t len;
132
133 status = property_find (prop, key, &item);
134 if (status != 0)
135 return status;
136
137 len = (item->value) ? strlen (item->value) : 0;
138 if (buffer && buflen != 0)
139 { 110 {
140 buflen--; 111 mu_assoc_remove (prop->assoc, key);
141 len = min (buflen, len); 112 return ENOMEM;
142 strncpy (buffer, item->value, len)[len] = '\0';
143 } 113 }
144 if (n) 114
145 *n = len;
146 return 0; 115 return 0;
147 } 116 }
148 117
149 int 118 int
150 mu_property_sget_value (mu_property_t prop, const char *key, 119 mu_property_sget_value (mu_property_t prop, const char *key,
151 const char **buffer) 120 const char **buffer)
152 { 121 {
153 struct property_item *item = NULL; 122 struct property_item *item;
154 int status;
155 123
156 status = property_find (prop, key, &item); 124 if (!prop)
157 if (status == 0) 125 return EINVAL;
126 item = mu_assoc_ref (prop->assoc, key);
127 if (item == NULL)
128 return MU_ERR_NOENT;
129 if (buffer)
158 *buffer = item->value; 130 *buffer = item->value;
159 return status; 131 return 0;
160 } 132 }
161 133
162 int 134 int
163 mu_property_aget_value (mu_property_t prop, const char *key, 135 mu_property_aget_value (mu_property_t prop, const char *key,
164 char **buffer) 136 char **buffer)
165 { 137 {
166 struct property_item *item = NULL; 138 const char *value;
167 int status; 139 int rc = mu_property_sget_value (prop, key, &value);
168 140 if (rc == 0)
169 status = property_find (prop, key, &item);
170 if (status == 0)
171 { 141 {
172 *buffer = strdup (item->value); 142 if ((*buffer = strdup (value)) == NULL)
173 if (!*buffer) 143 return ENOMEM;
174 status = ENOMEM;
175 } 144 }
176 return status; 145 return rc;
177 } 146 }
178 147
179 int 148 int
180 mu_property_set (mu_property_t prop, const char *k) 149 mu_property_get_value (mu_property_t prop, const char *key, char *buffer,
150 size_t buflen, size_t *n)
181 { 151 {
182 struct property_item *item = NULL; 152 size_t len = 0;
183 int status = property_find (prop, k, &item); 153 const char *value;
184 if (status != 0) 154 int rc = mu_property_sget_value (prop, key, &value);
185 return status; 155 if (rc == 0)
186 item->set = 1; 156 {
187 return 0; 157 len = strlen (value) + 1;
158 if (buffer && buflen)
159 {
160 if (buflen < len)
161 len = buflen;
162 len--;
163 memcpy (buffer, value, len);
164 buffer[len] = 0;
165 }
166 }
167 if (n)
168 *n = len;
169 return rc;
188 } 170 }
189 171
190 int 172 int
191 mu_property_unset (mu_property_t prop, const char *k) 173 mu_property_is_set (mu_property_t prop, const char *key)
192 { 174 {
193 struct property_item *item = NULL; 175 struct property_item *item = mu_assoc_ref (prop->assoc, key);
194 int status = property_find (prop, k, &item); 176 return (item == NULL) ? 0 : 1;
195 if (status != 0)
196 return status;
197 item->set = 0;
198 return 0;
199 } 177 }
200 178
201 int 179 int
202 mu_property_is_set (mu_property_t prop, const char *k) 180 mu_property_set (mu_property_t prop, const char *key)
203 { 181 {
204 struct property_item *item = NULL; 182 return mu_property_set_value (prop, key, "", 1);
205 int status = property_find (prop, k, &item);
206 if (status != 0)
207 return 0;
208 return item->set;
209 } 183 }
210 184
211 static int 185 int
212 property_find (mu_property_t prop, const char *key, struct property_item **item) 186 mu_property_unset (mu_property_t prop, const char *key)
213 { 187 {
214 size_t len = 0; 188 if (!prop)
215 struct property_item *cur = NULL;
216
217 if (prop == NULL || key == NULL)
218 return EINVAL; 189 return EINVAL;
219 190 return mu_assoc_remove (prop->assoc, key);
220 mu_monitor_wrlock (prop->lock);
221 for (len = strlen (key), cur = prop->items; cur; cur = cur->next)
222 {
223 if (strlen (cur->key) == len && !strcmp (key, cur->key))
224 break;
225 }
226
227 if (cur == NULL)
228 {
229 cur = calloc (1, sizeof *cur);
230 if (cur == NULL)
231 {
232 mu_monitor_unlock (prop->lock);
233 return ENOMEM;
234 }
235 cur->key = strdup (key);
236 if (cur->key == NULL)
237 {
238 mu_monitor_unlock (prop->lock);
239 free (cur);
240 return ENOMEM;
241 }
242 cur->next = prop->items;
243 prop->items = cur;
244 }
245 *item = cur;
246 mu_monitor_unlock (prop->lock);
247 return 0;
248 } 191 }
192
......