OSDN Git Service

deb5656b4ec96d12477ccda768fb09f96f598198
[modchxj/mod_chxj.git] / src / chxj_dbm.c
1 /*
2  * Copyright (C) 2005-2011 Atsushi Konno All rights reserved.
3  * Copyright (C) 2005 QSDN,Inc. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #include "mod_chxj.h"
18 #include "chxj_cookie.h"
19 #include "chxj_dbm.h"
20 #include "chxj_url_encode.h"
21 #include "chxj_apply_convrule.h"
22 #include "chxj_str_util.h"
23
24 #include "ap_release.h"
25
26 #include "apu.h"
27 #include "apr_uuid.h"
28 #include "apr_md5.h"
29 #include "apr_base64.h"
30 #include "apr_uri.h"
31
32 #include <unistd.h>
33
34 int
35 chxj_save_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string)
36 {
37   apr_status_t        retval;
38   apr_datum_t         dbmkey;
39   apr_datum_t         dbmval;
40   apr_dbm_t           *f;
41   apr_file_t          *file;
42
43   DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
44   DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
45
46   file = chxj_cookie_db_lock(r);
47   if (! file) {
48     ERR(r,"REQ[%X] %s:%d mod_chxj: Can't lock cookie db", TO_ADDR(r),__FILE__,__LINE__);
49     DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
50     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
51     return CHXJ_FALSE;
52   }
53
54   retval = apr_dbm_open_ex(&f,
55                            (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
56                            chxj_cookie_db_name_create(r, m->cookie_db_dir),
57                            APR_DBM_RWCREATE,
58                            APR_OS_DEFAULT,
59                            r->pool);
60   if (retval != APR_SUCCESS) {
61     char errstr[256];
62     ERR(r, "REQ[%X] %s:%d could not open dbm (type %s) auth file: %s(%d:%s)",
63             TO_ADDR(r),
64             __FILE__,
65             __LINE__,
66             (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
67             chxj_cookie_db_name_create(r,m->cookie_db_dir),
68             retval,
69             apr_strerror(retval, errstr, 255));
70     chxj_cookie_db_unlock(r, file);
71     DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
72     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
73     return CHXJ_FALSE;
74   }
75
76
77   /*
78    * create key
79    */
80
81   dbmkey.dptr  = apr_pstrdup(r->pool, cookie_id);
82   dbmkey.dsize = strlen(cookie_id);
83   dbmval.dptr  = apr_pstrdup(r->pool, store_string);
84   dbmval.dsize = strlen(store_string);
85
86   /*
87    * store to db
88    */
89   retval = apr_dbm_store(f, dbmkey, dbmval);
90   if (retval != APR_SUCCESS) {
91     char errstr[256];
92     ERR(r, "REQ[%X] %s:%d Cannot store Cookie data to DBM file `%s' tye:[%s] (%d:%s) key:[%s] val:[%s]",
93             TO_ADDR(r),
94             __FILE__,
95             __LINE__,
96             chxj_cookie_db_name_create(r, m->cookie_db_dir),
97             (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
98             retval,
99             apr_strerror(retval, errstr, 255), 
100             dbmkey.dptr,
101             dbmval.dptr);
102     apr_dbm_close(f);
103     chxj_cookie_db_unlock(r, file);
104     DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
105     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
106     return CHXJ_FALSE;
107   }
108
109   apr_dbm_close(f);
110   chxj_cookie_db_unlock(r, file);
111   DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
112   DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
113   return CHXJ_TRUE;
114 }
115
116
117 void
118 chxj_cookie_db_unlock(request_rec *r, apr_file_t *file)
119 {
120   apr_status_t rv;
121
122   rv = apr_file_unlock(file);
123   if (rv != APR_SUCCESS) {
124     ERR(r, "cookie lock file open failed.");
125     return;
126   }
127
128   apr_file_close(file);
129 }
130
131
132 apr_file_t *
133 chxj_cookie_db_lock(request_rec *r)
134 {
135   apr_file_t       *file;
136   apr_status_t     rv;
137   mod_chxj_config  *dconf;
138
139   dconf = (mod_chxj_config*)chxj_get_module_config(r->per_dir_config, &chxj_module);
140
141   rv = apr_file_open(&file,
142                      chxj_cookie_db_lock_name_create(r, dconf->cookie_db_dir),
143                      APR_CREATE|APR_WRITE,
144                      APR_OS_DEFAULT,
145                      r->pool);
146   if (rv != APR_SUCCESS) {
147     ERR(r, "cookie lock file open failed.");
148     return NULL;
149   }
150
151   rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
152   if (rv != APR_SUCCESS) {
153     ERR(r, "cookie lock file open failed.");
154     apr_file_close(file);
155     return NULL;
156   }
157
158   return file;
159 }
160
161
162 char *
163 chxj_cookie_db_name_create(request_rec *r, const char *dir)
164 {
165   char *dst;
166
167   if (!dir) {
168     dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
169   }
170   else {
171     dst = apr_pstrdup(r->pool, dir);
172   }
173
174   if (dst[strlen(dst)-1] != '/') {
175     dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_NAME, NULL);
176   }
177   else {
178     dst = apr_pstrcat(r->pool, dst, COOKIE_DB_NAME, NULL);
179   }
180
181   return dst;
182 }
183
184
185 char *
186 chxj_cookie_db_lock_name_create(request_rec *r, const char *dir)
187 {
188   char *dst;
189   DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
190
191   if (!dir) {
192     dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
193   }
194   else {
195     dst = apr_pstrdup(r->pool, dir);
196   }
197   if (dst[strlen(dst)-1] != '/') {
198     dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_LOCK_NAME, NULL);
199   }
200   else {
201     dst = apr_pstrcat(r->pool, dst, COOKIE_DB_LOCK_NAME, NULL);
202   }
203   DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
204   return dst;
205 }
206
207
208
209 char *
210 chxj_cookie_expire_db_name_create(request_rec *r, const char *dir)
211 {
212   char *dst;
213
214   if (!dir) {
215     dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
216   }
217   else {
218     dst = apr_pstrdup(r->pool, dir);
219   }
220
221   if (dst[strlen(dst)-1] != '/') {
222     dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_NAME, NULL);
223   }
224   else {
225     dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_NAME, NULL);
226   }
227
228   return dst;
229 }
230
231
232 char *
233 chxj_cookie_expire_db_lock_name_create(request_rec *r, const char *dir)
234 {
235   char *dst;
236
237   if (!dir) {
238     dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
239   }
240   else {
241     dst = apr_pstrdup(r->pool, dir);
242   }
243   if (dst[strlen(dst)-1] != '/') {
244     dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
245   }
246   else {
247     dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
248   }
249
250   return dst;
251 }
252
253
254 apr_file_t *
255 chxj_cookie_expire_db_lock(request_rec *r)
256 {
257   apr_file_t       *file;
258   apr_status_t     rv;
259   mod_chxj_config  *dconf;
260
261   dconf = (mod_chxj_config *)chxj_get_module_config(r->per_dir_config, &chxj_module);
262
263   rv = apr_file_open(&file, 
264                      chxj_cookie_expire_db_lock_name_create(r, dconf->cookie_db_dir),
265                      APR_CREATE|APR_WRITE, 
266                      APR_OS_DEFAULT, 
267                      r->pool);
268   if (rv != APR_SUCCESS) {
269     ERR(r, "cookie lock file open failed.");
270     return NULL;
271   }
272
273   rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
274   if (rv != APR_SUCCESS) {
275     ERR(r, "cookie lock file open failed.");
276     apr_file_close(file);
277     return NULL;
278   }
279
280   return file;
281 }
282
283
284 void
285 chxj_cookie_expire_db_unlock(request_rec *r, apr_file_t *file)
286 {
287   apr_status_t rv;
288
289   rv = apr_file_unlock(file);
290   if (rv != APR_SUCCESS) {
291     ERR(r, "cookie lock file open failed.");
292     return;
293   }
294
295   apr_file_close(file);
296 }
297
298 int
299 chxj_update_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string)
300 {
301   apr_dbm_t           *f;
302   apr_file_t          *file;
303   apr_datum_t         dbmkey;
304   apr_datum_t         dbmval;
305   apr_status_t        retval;
306
307   DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
308   DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
309
310   file = chxj_cookie_db_lock(r);
311   if (! file) {
312     ERR(r,"REQ[%X] mod_chxj: Can't lock cookie db",TO_ADDR(r));
313     DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
314     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
315     return CHXJ_FALSE;
316   }
317
318   retval = apr_dbm_open_ex(&f,
319                            (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
320                            chxj_cookie_db_name_create(r, m->cookie_db_dir),
321                            APR_DBM_RWCREATE,
322                            APR_OS_DEFAULT,
323                            r->pool);
324   if (retval != APR_SUCCESS) {
325     ERR(r,"REQ[%X] could not open dbm (type %s) auth file: %s",
326           TO_ADDR(r),
327           (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
328           chxj_cookie_db_name_create(r,m->cookie_db_dir));
329     chxj_cookie_db_unlock(r, file);
330     DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
331     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
332     return CHXJ_FALSE;
333   }
334
335
336   /*
337    * create key
338    */
339
340   dbmkey.dptr  = apr_pstrdup(r->pool, cookie_id);
341   dbmkey.dsize = strlen(cookie_id);
342
343   /*
344    * create val
345    */
346   dbmval.dptr  = apr_pstrdup(r->pool, store_string);
347   dbmval.dsize = strlen(store_string);
348
349   /*
350    * store to db
351    */
352   retval = apr_dbm_store(f, dbmkey, dbmval);
353   if (retval != APR_SUCCESS) {
354     char errstr[256];
355     ERR(r,"REQ[%X] %s:%d Cannot store Cookie data to DBM file `%s' tye:[%s] (%d:%s) key:[%s] val:[%s]",
356           TO_ADDR(r),
357           __FILE__,
358           __LINE__,
359           chxj_cookie_db_name_create(r, m->cookie_db_dir),
360           (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
361           retval,
362           apr_strerror(retval, errstr, 255), 
363           dbmkey.dptr,
364           dbmval.dptr);
365     apr_dbm_close(f);
366     chxj_cookie_db_unlock(r, file);
367     DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
368     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
369     return CHXJ_FALSE;
370   }
371   apr_dbm_close(f);
372   chxj_cookie_db_unlock(r, file);
373   DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
374   DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
375   return CHXJ_TRUE;
376 }
377
378
379 char *
380 chxj_load_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
381 {
382   char                    *load_string = NULL;
383   apr_status_t            retval;
384   apr_dbm_t               *f;
385   apr_file_t              *file;
386   apr_datum_t             dbmval;
387   apr_datum_t             dbmkey;
388
389   DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
390   DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
391   file = chxj_cookie_db_lock(r);
392   if (! file) {
393     ERR(r,"REQ[%X] mod_chxj: Can't lock cookie db", TO_ADDR(r));
394     DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
395     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
396     return NULL;
397   }
398
399   retval = apr_dbm_open_ex(&f,
400                            (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
401                            chxj_cookie_db_name_create(r, m->cookie_db_dir),
402                            APR_DBM_RWCREATE,
403                            APR_OS_DEFAULT,
404                            r->pool);
405   if (retval != APR_SUCCESS) {
406     char errstr[256];
407     ERR(r,
408          "REQ[%X] %s:%d could not open dbm (type %s) auth file: %s (%d:%s)",
409          TO_ADDR(r),
410          __FILE__,
411          __LINE__,
412           (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
413          chxj_cookie_db_name_create(r, m->cookie_db_dir),
414          retval,
415          apr_strerror(retval, errstr, 255));
416     chxj_cookie_db_unlock(r, file);
417     DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
418     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
419     return NULL;
420   }
421
422   /*
423    * create key
424    */
425   dbmkey.dptr  = apr_pstrdup(r->pool, cookie_id);
426   dbmkey.dsize = strlen(dbmkey.dptr);
427
428   if (apr_dbm_exists(f, dbmkey)) {
429     retval = apr_dbm_fetch(f, dbmkey, &dbmval);
430     if (retval != APR_SUCCESS) {
431       char errstr[256];
432       ERR(r,
433           "REQ[%X] %s:%d could not fetch dbm (type %s) auth file: %s(%d:%s)",
434           TO_ADDR(r),
435           __FILE__,
436           __LINE__,
437           (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
438           chxj_cookie_db_name_create(r, m->cookie_db_dir),
439           retval,
440           apr_strerror(retval, errstr, 255));
441       apr_dbm_close(f);
442       chxj_cookie_db_unlock(r, file);
443       DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
444       DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
445       return NULL;
446     }
447     load_string = apr_palloc(r->pool, dbmval.dsize+1);
448
449     memset(load_string, 0, dbmval.dsize+1);
450     memcpy(load_string, dbmval.dptr, dbmval.dsize);
451   }
452   else {
453     DBG(r, "REQ[%X] Not Found cookie_id:[%s]", TO_ADDR(r), cookie_id);
454     load_string = apr_pstrdup(r->pool, "");
455   }
456   apr_dbm_close(f);
457   chxj_cookie_db_unlock(r, file);
458   DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
459   DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
460   return load_string;
461 }
462
463
464 int
465 chxj_delete_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
466 {
467   apr_status_t      retval;
468   apr_file_t        *file;
469   apr_datum_t       dbmkey;
470   apr_dbm_t         *f;
471
472   DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
473   DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
474   file = chxj_cookie_db_lock(r);
475   if (! file) {
476     ERR(r,"REQ[%X] mod_chxj: Can't lock cookie db",TO_ADDR(r));
477     DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
478     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
479     return CHXJ_FALSE;
480   }
481
482   retval = apr_dbm_open_ex(&f,
483                            (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
484                            chxj_cookie_db_name_create(r, m->cookie_db_dir),
485                            APR_DBM_RWCREATE,
486                            APR_OS_DEFAULT,
487                            r->pool);
488   if (retval != APR_SUCCESS) {
489     ERR(r,
490          "REQ[%X] could not open dbm (type %s) auth file: %s",
491          TO_ADDR(r),
492          (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
493          chxj_cookie_db_name_create(r,m->cookie_db_dir));
494     chxj_cookie_db_unlock(r, file);
495     DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
496     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
497     return CHXJ_FALSE;
498   }
499
500   /*
501    * create key
502    */
503   dbmkey.dptr  = apr_pstrdup(r->pool, cookie_id);
504   dbmkey.dsize = strlen(dbmkey.dptr);
505   if (apr_dbm_exists(f, dbmkey)) {
506     apr_dbm_delete(f, dbmkey);
507   }
508   apr_dbm_close(f);
509   chxj_cookie_db_unlock(r, file);
510   DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
511   DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
512   return CHXJ_TRUE;
513 }
514
515
516 int
517 chxj_save_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
518 {
519   apr_status_t            retval;
520   char                    *store_string;
521   apr_file_t              *file;
522   apr_datum_t             dbmkey;
523   apr_datum_t             dbmval;
524   apr_dbm_t               *f;
525
526   DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
527   DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
528   file = chxj_cookie_expire_db_lock(r);
529   if (! file) {
530     ERR(r,"REQ[%X] mod_chxj: Can't lock cookie db",TO_ADDR(r));
531     DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
532     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
533     return CHXJ_FALSE;
534   }
535
536   retval = apr_dbm_open_ex(&f, 
537                            (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
538                            chxj_cookie_expire_db_name_create(r, m->cookie_db_dir), 
539                            APR_DBM_RWCREATE, 
540                            APR_OS_DEFAULT, 
541                            r->pool);
542   if (retval != APR_SUCCESS) {
543     ERR(r, "REQ[%X] could not open dbm (type %s) auth file: %s", 
544            TO_ADDR(r),
545            (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
546            chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
547     chxj_cookie_expire_db_unlock(r, file);
548     DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
549     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
550     return CHXJ_FALSE;
551   }
552   /*
553    * create key
554    */
555
556   dbmkey.dptr  = apr_pstrdup(r->pool, cookie_id);
557   dbmkey.dsize = strlen(cookie_id);
558
559   /*
560    * create val
561    */
562   
563   store_string = apr_psprintf(r->pool, "%d", (int)time(NULL));
564   dbmval.dptr  = store_string;
565   dbmval.dsize = strlen(store_string);
566
567   /*
568    * store to db
569    */
570   retval = apr_dbm_store(f, dbmkey, dbmval);
571   if (retval != APR_SUCCESS) {
572     ERR(r,"REQ[%X] Cannot store Cookie data to DBM file `%s'",
573           TO_ADDR(r),
574           chxj_cookie_db_name_create(r, m->cookie_db_dir));
575     DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
576     apr_dbm_close(f);
577     chxj_cookie_expire_db_unlock(r, file);
578     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
579     return CHXJ_FALSE;
580   }
581
582
583   apr_dbm_close(f);
584   chxj_cookie_expire_db_unlock(r, file);
585   DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
586   DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
587
588   return CHXJ_TRUE;
589 }
590
591
592 int
593 chxj_delete_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
594 {
595   apr_status_t      retval;
596   apr_datum_t       dbmkey;
597   apr_dbm_t         *f;
598   apr_file_t        *file;
599
600   DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
601   DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
602   file = chxj_cookie_expire_db_lock(r);
603   if (! file) {
604     ERR(r,"REQ[%X] mod_chxj: Can't lock cookie db",TO_ADDR(r));
605     DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
606     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
607     return CHXJ_FALSE;
608   }
609   retval = apr_dbm_open_ex(&f,
610                            (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
611                            chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
612                            APR_DBM_RWCREATE,
613                            APR_OS_DEFAULT,
614                            r->pool);
615   if (retval != APR_SUCCESS) {
616     ERR(r,
617          "REQ[%X] could not open dbm (type %s) auth file: %s",
618          TO_ADDR(r),
619          (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
620          chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
621     chxj_cookie_expire_db_unlock(r, file);
622     DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
623     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
624     return CHXJ_FALSE;
625   }
626
627   /*
628  *    * create key
629  *       */
630   dbmkey.dptr  = apr_pstrdup(r->pool, cookie_id);
631   dbmkey.dsize = strlen(dbmkey.dptr);
632   if (apr_dbm_exists(f, dbmkey)) {
633     apr_dbm_delete(f, dbmkey);
634   }
635   apr_dbm_close(f);
636   chxj_cookie_expire_db_unlock(r, file);
637   DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
638   DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
639
640   return CHXJ_TRUE;
641 }
642
643
644 int
645 chxj_cookie_expire_gc_dbm(request_rec *r, mod_chxj_config *m)
646 {
647   apr_status_t      retval;
648   apr_datum_t       dbmkey;
649   apr_datum_t       dbmval;
650   apr_dbm_t         *f;
651   apr_file_t        *file;
652   time_t            now_time;
653
654   DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
655
656   file = chxj_cookie_expire_db_lock(r);
657   if (! file) {
658     ERR(r,"REQ[%X] mod_chxj: Can't lock cookie db",TO_ADDR(r));
659     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
660     return CHXJ_FALSE;
661   }
662
663   retval = apr_dbm_open_ex(&f,
664                            (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
665                            chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
666                            APR_DBM_RWCREATE,
667                            APR_OS_DEFAULT,
668                            r->pool);
669   if (retval != APR_SUCCESS) {
670     ERR(r, 
671          "REQ[%X] could not open dbm (type %s) auth file: %s", 
672          TO_ADDR(r),
673          (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
674          chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
675     chxj_cookie_expire_db_unlock(r, file);
676     DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
677     return CHXJ_FALSE;
678   }
679
680   /*
681    * create key
682    */
683   memset(&dbmkey, 0, sizeof(apr_datum_t));
684
685   now_time = time(NULL);
686
687   retval = apr_dbm_firstkey(f, &dbmkey);
688   if (retval == APR_SUCCESS) {
689     DBG(r,"REQ[%X] firstkey=[%.*s]", TO_ADDR(r),(int)dbmkey.dsize, dbmkey.dptr);
690     do {
691       char* tmp;
692       char* old_cookie_id;
693       int   val_time;
694       int   cmp_time;
695
696       retval = apr_dbm_fetch(f, dbmkey, &dbmval);
697       if (retval != APR_SUCCESS) {
698         break;
699       }
700       tmp = apr_palloc(r->pool, dbmval.dsize+1);
701       memset(tmp, 0, dbmval.dsize+1);
702       memcpy(tmp, dbmval.dptr, dbmval.dsize);
703
704
705       val_time = atoi(tmp);
706
707       if (m->cookie_timeout == 0)
708         cmp_time = now_time - DEFAULT_COOKIE_TIMEOUT;
709       else
710         cmp_time = now_time - m->cookie_timeout;
711
712       DBG(r,"REQ[%X] m->cookie_timeout=[%d]", TO_ADDR(r),(int)m->cookie_timeout);
713       DBG(r,"REQ[%X] key=[%.*s] cmp_time=[%d] val_time=[%d]", TO_ADDR(r),(int)dbmkey.dsize, dbmkey.dptr, cmp_time, val_time);
714       if (cmp_time >= val_time) {
715         apr_dbm_delete(f, dbmkey);
716
717         old_cookie_id = apr_palloc(r->pool, dbmkey.dsize+1);
718         memset(old_cookie_id, 0, dbmkey.dsize+1);
719         memcpy(old_cookie_id, dbmkey.dptr, dbmkey.dsize);
720
721         chxj_delete_cookie(r,old_cookie_id);
722         DBG(r,"REQ[%X] detect timeout cookie [%s]", TO_ADDR(r),old_cookie_id);
723       }
724
725       retval = apr_dbm_nextkey(f, &dbmkey);
726     } while(retval == APR_SUCCESS && dbmkey.dptr != NULL);
727   }
728
729   apr_dbm_close(f);
730   chxj_cookie_expire_db_unlock(r, file);
731   DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
732   return CHXJ_TRUE;
733 }
734
735
736 cookie_lock_t *
737 chxj_cookie_lock_dbm(request_rec *r, mod_chxj_config *UNUSED(m))
738 {
739   cookie_lock_t *ret = apr_palloc(r->pool, sizeof(*ret));
740   ret->file = chxj_cookie_db_lock(r);
741   return ret;
742 }
743
744
745 int
746 chxj_cookie_unlock_dbm(request_rec *r, cookie_lock_t *lock, mod_chxj_config *UNUSED(m))
747 {
748   chxj_cookie_expire_db_unlock(r, lock->file);
749   return 1; /* allways true */
750 }
751 /*
752  * vim:ts=2 et
753  */