OSDN Git Service

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