OSDN Git Service

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