1 /* GNU Mailutils -- a suite of utilities for electronic mail
2    Copyright (C) 1999-2021 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
mu_property_create(mu_property_t * pprop)27 mu_property_create (mu_property_t *pprop)
28 {
29   mu_property_t prop = calloc (1, sizeof (prop[0]));
30   if (!prop)
31     return ENOMEM;
32   *pprop = prop;
33   return 0;
34 }
35 
36 int
mu_property_create_init(mu_property_t * pprop,int (* initfun)(mu_property_t),void * initdata)37 mu_property_create_init (mu_property_t *pprop,
38 			 int (*initfun) (mu_property_t), void *initdata)
39 {
40   mu_property_t prop;
41   int rc = mu_property_create (&prop);
42   if (rc == 0)
43     {
44       mu_property_set_init (prop, initfun, initdata);
45       if (initdata)
46 	{
47 	  rc = mu_property_init (prop);
48 	  if (rc)
49 	    return rc;
50 	}
51       *pprop = prop;
52     }
53   return rc;
54 }
55 
56 int
mu_property_set_init(mu_property_t prop,int (* initfun)(mu_property_t),void * initdata)57 mu_property_set_init (mu_property_t prop,
58 		      int (*initfun) (mu_property_t), void *initdata)
59 {
60   if (!prop)
61     return ENOMEM;
62   if (prop->_prop_flags & MU_PROP_INIT)
63     return MU_ERR_SEQ;
64   prop->_prop_init = initfun;
65   prop->_prop_init_data = initdata;
66   return 0;
67 }
68 
69 int
mu_property_set_init_data(mu_property_t prop,void * data,void ** old_data)70 mu_property_set_init_data (mu_property_t prop, void *data, void **old_data)
71 {
72   if (!prop)
73     return ENOMEM;
74   if (prop->_prop_flags & MU_PROP_INIT)
75     return MU_ERR_SEQ;
76   if (old_data)
77     *old_data = prop->_prop_init_data;
78   prop->_prop_init_data = data;
79   return 0;
80 }
81 
82 void
mu_property_destroy(mu_property_t * pprop)83 mu_property_destroy (mu_property_t *pprop)
84 {
85   if (pprop)
86     {
87       mu_property_t prop = *pprop;
88       if (prop && (prop->_prop_ref_count == 0 || --prop->_prop_ref_count == 0))
89 	{
90 	  mu_property_save (prop);
91 	  if (prop->_prop_done)
92 	    prop->_prop_done (prop);
93 	  free (prop);
94 	  *pprop = NULL;
95 	}
96     }
97 }
98 
99 void
mu_property_ref(mu_property_t prop)100 mu_property_ref (mu_property_t prop)
101 {
102   if (prop)
103     prop->_prop_ref_count++;
104 }
105 
106 void
mu_property_unref(mu_property_t prop)107 mu_property_unref (mu_property_t prop)
108 {
109   mu_property_destroy (&prop);
110 }
111 
112 int
mu_property_save(mu_property_t prop)113 mu_property_save (mu_property_t prop)
114 {
115   int rc = 0;
116 
117   if (!prop)
118     return EINVAL;
119   if (prop->_prop_flags & MU_PROP_MODIFIED)
120     {
121       if (prop->_prop_save)
122 	rc = prop->_prop_save (prop);
123 
124       if (rc == 0)
125 	prop->_prop_flags &= ~MU_PROP_MODIFIED;
126     }
127   return rc;
128 }
129 
130 int
mu_property_init(mu_property_t prop)131 mu_property_init (mu_property_t prop)
132 {
133   int rc = 0;
134   if (!(prop->_prop_flags & MU_PROP_INIT))
135     {
136       if (prop->_prop_init)
137 	rc = prop->_prop_init (prop);
138       if (rc == 0)
139 	prop->_prop_flags |= MU_PROP_INIT;
140     }
141   return rc;
142 }
143 
144 static int
_mu_property_fill(mu_property_t prop)145 _mu_property_fill (mu_property_t prop)
146 {
147   int rc = 0;
148   if (!(prop->_prop_flags & MU_PROP_FILL))
149     {
150       if (prop->_prop_fill)
151 	rc = prop->_prop_fill (prop);
152       if (rc == 0)
153 	prop->_prop_flags |= MU_PROP_FILL;
154     }
155   return rc;
156 }
157 
158 int
_mu_property_check(mu_property_t prop)159 _mu_property_check (mu_property_t prop)
160 {
161   int rc;
162 
163   if (!prop)
164     return EINVAL;
165   rc = mu_property_init (prop);
166   if (rc == 0)
167     rc = _mu_property_fill (prop);
168   return rc;
169 }
170 
171 
172