Commit 59419388 59419388e514e63b61d9a6d696d90c5962e5814e by Sergey Poznyakoff

Retrieve quotas from SQL database

1 parent 425b94c1
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
17 17
18 #include <mail.local.h> 18 #include <mail.local.h>
19 19
20 #ifdef USE_DBM 20 #if defined (USE_DBM) || defined (USE_SQL)
21 21
22 #define DEFRETVAL MQUOTA_UNLIMITED 22 #define DEFRETVAL MQUOTA_UNLIMITED
23 23
...@@ -34,14 +34,17 @@ get_size (char *str, size_t *size, char **endp) ...@@ -34,14 +34,17 @@ get_size (char *str, size_t *size, char **endp)
34 { 34 {
35 case 0: 35 case 0:
36 break; 36 break;
37
37 case 'k': 38 case 'k':
38 case 'K': 39 case 'K':
39 s *= 1024; 40 s *= 1024;
40 break; 41 break;
42
41 case 'm': 43 case 'm':
42 case 'M': 44 case 'M':
43 s *= 1024*1024; 45 s *= 1024*1024;
44 break; 46 break;
47
45 default: 48 default:
46 *endp = str; 49 *endp = str;
47 return -1; 50 return -1;
...@@ -50,18 +53,29 @@ get_size (char *str, size_t *size, char **endp) ...@@ -50,18 +53,29 @@ get_size (char *str, size_t *size, char **endp)
50 return 0; 53 return 0;
51 } 54 }
52 55
56 #define RETR_OK 0
57 #define RETR_UNLIMITED -1
58 #define RETR_FAILURE 1
59
53 int 60 int
54 check_quota (char *name, size_t size, size_t *rest) 61 fail_retrieve_quota (char *name, size_t *quota)
62 {
63 mu_error (_("No quota retrieving mechanism"));
64 return RETR_FAILURE;
65 }
66
67 #ifdef USE_DBM
68 int
69 dbm_retrieve_quota (char *name, size_t *quota)
55 { 70 {
56 DBM_FILE db; 71 DBM_FILE db;
57 DBM_DATUM named, contentd; 72 DBM_DATUM named, contentd;
58 size_t quota;
59 char buffer[64]; 73 char buffer[64];
60 int unlimited = 0; 74 int unlimited = 0;
61 int rc; 75 int rc;
62 76
63 if (!quotadbname || mu_dbm_open (quotadbname, &db, MU_STREAM_READ, 0600)) 77 if (!quotadbname || mu_dbm_open (quotadbname, &db, MU_STREAM_READ, 0600))
64 return DEFRETVAL; 78 return RETR_FAILURE;
65 79
66 memset (&named, 0, sizeof named); 80 memset (&named, 0, sizeof named);
67 memset (&contentd, 0, sizeof contentd); 81 memset (&contentd, 0, sizeof contentd);
...@@ -78,10 +92,10 @@ check_quota (char *name, size_t size, size_t *rest) ...@@ -78,10 +92,10 @@ check_quota (char *name, size_t size, size_t *rest)
78 if (rc) 92 if (rc)
79 { 93 {
80 /*mu_error (_("can't fetch data: %s"), strerror (rc));*/ 94 /*mu_error (_("can't fetch data: %s"), strerror (rc));*/
81 return DEFRETVAL; 95 return RETR_FAILURE;
82 } 96 }
83 if (!MU_DATUM_PTR (contentd)) 97 if (!MU_DATUM_PTR (contentd))
84 return DEFRETVAL; 98 return RETR_FAILURE;
85 } 99 }
86 100
87 if (strncasecmp("none", 101 if (strncasecmp("none",
...@@ -92,7 +106,7 @@ check_quota (char *name, size_t size, size_t *rest) ...@@ -92,7 +106,7 @@ check_quota (char *name, size_t size, size_t *rest)
92 { 106 {
93 mu_error (_("mailbox quota for `%s' is too big: %d digits"), 107 mu_error (_("mailbox quota for `%s' is too big: %d digits"),
94 name, MU_DATUM_SIZE (contentd)); 108 name, MU_DATUM_SIZE (contentd));
95 quota = groupquota; 109 *quota = groupquota;
96 } 110 }
97 else 111 else
98 { 112 {
...@@ -100,24 +114,171 @@ check_quota (char *name, size_t size, size_t *rest) ...@@ -100,24 +114,171 @@ check_quota (char *name, size_t size, size_t *rest)
100 114
101 strncpy(buffer, MU_DATUM_PTR (contentd), MU_DATUM_SIZE (contentd)); 115 strncpy(buffer, MU_DATUM_PTR (contentd), MU_DATUM_SIZE (contentd));
102 buffer[MU_DATUM_SIZE (contentd)] = 0; 116 buffer[MU_DATUM_SIZE (contentd)] = 0;
103 quota = strtoul (buffer, &p, 0); 117 *quota = strtoul (buffer, &p, 0);
104 if (get_size (buffer, &quota, &p)) 118 if (get_size (buffer, quota, &p))
105 { 119 {
106 mu_error (_("bogus mailbox quota for `%s' (near `%s')"), name, p); 120 mu_error (_("bogus mailbox quota for `%s' (near `%s')"), name, p);
107 quota = groupquota; 121 *quota = groupquota;
108 } 122 }
109 } 123 }
110 124
111 mu_dbm_close (db); 125 mu_dbm_close (db);
112 if (unlimited) 126
127 return unlimited ? RETR_UNLIMITED : RETR_OK;
128 }
129
130 # define default_retrieve_quota dbm_retrieve_quota
131 #else
132 # define default_retrieve_quota fail_retrieve_quota
133 #endif
134
135 #ifdef USE_SQL
136 #include <mailutils/sql.h>
137
138 /* FIXME: defined in auth/sql.c */
139 extern int sql_interface;
140 extern char *mu_sql_host;
141 extern char *mu_sql_user;
142 extern char *mu_sql_passwd;
143 extern char *mu_sql_db;
144 extern int mu_sql_port;
145 extern char *mu_sql_expand_query (const char *query, const char *ustr);
146
147 int
148 sql_retrieve_quota (char *name, size_t *quota)
149 {
150 mu_sql_connection_t conn;
151 char *query_str;
152 int rc, status;
153 char *tmp;
154 size_t n;
155
156 query_str = mu_sql_expand_query (quota_query, name);
157 if (!query_str)
158 return RETR_FAILURE;
159
160 status = mu_sql_connection_init (&conn,
161 sql_interface,
162 mu_sql_host,
163 mu_sql_port,
164 mu_sql_user,
165 mu_sql_passwd,
166 mu_sql_db);
167
168 if (status)
169 {
170 mu_error ("%s. SQL error: %s",
171 mu_strerror (status), mu_sql_strerror (conn));
172 mu_sql_connection_destroy (&conn);
173 free (query_str);
174 return RETR_FAILURE;
175 }
176
177 status = mu_sql_connect (conn);
178
179 if (status)
180 {
181 mu_error ("%s. SQL error: %s",
182 mu_strerror (status), mu_sql_strerror (conn));
183 mu_sql_connection_destroy (&conn);
184 free (query_str);
185 return RETR_FAILURE;
186 }
187
188 status = mu_sql_query (conn, query_str);
189 free (query_str);
190
191 if (status)
192 {
193 mu_error (_("SQL Query failed: %s"),
194 (status == MU_ERR_SQL) ? mu_sql_strerror (conn) :
195 mu_strerror (status));
196 mu_sql_connection_destroy (&conn);
197 return RETR_FAILURE;
198 }
199
200 status = mu_sql_store_result (conn);
201
202 if (status)
203 {
204 mu_error (_("cannot store SQL result: %s"),
205 (status == MU_ERR_SQL) ? mu_sql_strerror (conn) :
206 mu_strerror (status));
207 mu_sql_connection_destroy (&conn);
208 return RETR_FAILURE;
209 }
210
211 mu_sql_num_tuples (conn, &n);
212 if (n == 0)
213 {
214 rc = RETR_FAILURE;
215 }
216 else
217 {
218 rc = RETR_OK;
219 status = mu_sql_get_column (conn, 0, 0, &tmp);
220 if (status)
221 {
222 mu_error (_("cannot retrieve SQL quota: %s"),
223 (status == MU_ERR_SQL) ? mu_sql_strerror (conn) :
224 mu_strerror (status));
225 rc = RETR_FAILURE;
226 }
227 else if (strcasecmp (tmp, "none") == 0)
228 rc = RETR_UNLIMITED;
229 else
230 {
231 char *p;
232
233 if (get_size (tmp, quota, &p))
234 {
235 mu_error (_("bogus mailbox quota for `%s' (near `%s')"), name, p);
236 *quota = groupquota;
237 }
238 }
239 }
240
241 mu_sql_release_result (conn);
242 mu_sql_disconnect (conn);
243 mu_sql_connection_destroy (&conn);
244 return rc;
245 }
246 #endif
247
248
249 static int
250 retrieve_quota (char *name, size_t *quota)
251 {
252 #ifdef USE_SQL
253 if (quota_query)
254 return sql_retrieve_quota (name, quota);
255 #endif
256 return default_retrieve_quota (name, quota);
257 }
258
259 int
260 check_quota (char *name, size_t size, size_t *rest)
261 {
262 size_t quota;
263
264 switch (retrieve_quota (name, &quota))
265 {
266 case RETR_FAILURE:
267 return DEFRETVAL;
268
269 case RETR_UNLIMITED:
113 return MQUOTA_UNLIMITED; 270 return MQUOTA_UNLIMITED;
114 else if (quota < size) /* Mailbox full */ 271
272 case RETR_OK:
273 if (quota < size) /* Mailbox full */
115 return MQUOTA_EXCEEDED; 274 return MQUOTA_EXCEEDED;
116 275
117 if (rest) 276 if (rest)
118 *rest = quota - size; 277 *rest = quota - size;
278 }
119 279
120 return MQUOTA_OK; 280 return MQUOTA_OK;
281
121 } 282 }
122 283
123 #endif 284 #endif /* USE_MAIL_QUOTA */
......