OSDN Git Service

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