|
88 |
|
88 |
|
89 |
DB *dbp; |
89 |
DB *dbp; |
90 |
DBC *dbc_cur = NULL; |
90 |
DBC *dbc_cur = NULL; |
|
|
91 |
#ifdef WITH_DB42 |
91 |
DB_ENV *dbenvp; |
92 |
DB_ENV *dbenvp; |
|
|
93 |
#endif |
92 |
static FILE *lock_fp=NULL; |
94 |
static FILE *lock_fp=NULL; |
93 |
|
95 |
|
|
|
96 |
#ifdef WITH_DB42 |
94 |
static void cache_panic_call(DB_ENV *dbenvp, int errval) |
97 |
static void cache_panic_call(DB_ENV *dbenvp, int errval) |
95 |
{ |
98 |
{ |
96 |
exit(1); |
99 |
exit(1); |
97 |
} |
100 |
} |
|
|
101 |
#endif |
98 |
|
102 |
|
99 |
char* _convert_to_lower(char *dn) |
103 |
char* _convert_to_lower(char *dn) |
100 |
{ |
104 |
{ |
|
112 |
return lower_dn; |
116 |
return lower_dn; |
113 |
} |
117 |
} |
114 |
|
118 |
|
115 |
static void cache_error_message(const DB_ENV *dbenvp, const char *errpfx, const char *msg) |
119 |
static void cache_error_message(const char *errpfx, char *msg) |
116 |
{ |
120 |
{ |
117 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
121 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
118 |
"database error: %s", msg); |
122 |
"database error: %s", msg); |
|
142 |
} |
146 |
} |
143 |
lockf(fileno(lock_fp), F_LOCK, 0); |
147 |
lockf(fileno(lock_fp), F_LOCK, 0); |
144 |
|
148 |
|
|
|
149 |
#ifdef WITH_DB42 |
145 |
if ((rv = db_env_create(&dbenvp, 0)) != 0) { |
150 |
if ((rv = db_env_create(&dbenvp, 0)) != 0) { |
146 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
151 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
147 |
"creating database environment failed"); |
152 |
"creating database environment failed"); |
|
171 |
// FIXME: free dbp |
176 |
// FIXME: free dbp |
172 |
return rv; |
177 |
return rv; |
173 |
} |
178 |
} |
|
|
179 |
#else |
180 |
if ((rv = db_create(&dbp, NULL, 0)) != 0) { |
181 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
182 |
"creating database handle failed"); |
183 |
return rv; |
184 |
} |
185 |
if ((rv = dbp->open(dbp, file, NULL, DB_BTREE, DB_CREATE, 0600)) != 0) { |
186 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
187 |
"opening database failed"); |
188 |
dbp->err(dbp, rv, "open"); |
189 |
// FIXME: free dbp |
190 |
return rv; |
191 |
} |
192 |
dbp->set_errcall(dbp, cache_error_message); |
193 |
#endif |
174 |
return 0; |
194 |
return 0; |
175 |
} |
195 |
} |
176 |
|
196 |
|
|
229 |
return fclose(fp); |
249 |
return fclose(fp); |
230 |
} |
250 |
} |
231 |
|
251 |
|
|
|
252 |
#ifdef WITH_DB42 |
232 |
int cache_get_master_entry(CacheMasterEntry *master_entry) |
253 |
int cache_get_master_entry(CacheMasterEntry *master_entry) |
233 |
{ |
254 |
{ |
234 |
DBT key, data; |
255 |
DBT key, data; |
|
277 |
data.data=(void*)master_entry; |
298 |
data.data=(void*)master_entry; |
278 |
data.size=sizeof(CacheMasterEntry); |
299 |
data.size=sizeof(CacheMasterEntry); |
279 |
|
300 |
|
|
|
301 |
#ifdef WITH_DB42 |
280 |
if (dbtxnp == NULL) |
302 |
if (dbtxnp == NULL) |
281 |
flags = DB_AUTO_COMMIT; |
303 |
flags = DB_AUTO_COMMIT; |
282 |
else |
304 |
else |
|
|
305 |
#endif |
283 |
flags = 0; |
306 |
flags = 0; |
284 |
|
307 |
|
285 |
if ((rv=dbp->put(dbp, dbtxnp, &key, &data, flags)) != 0) { |
308 |
if ((rv=dbp->put(dbp, dbtxnp, &key, &data, flags)) != 0) { |
|
295 |
|
318 |
|
296 |
return 0; |
319 |
return 0; |
297 |
} |
320 |
} |
|
|
321 |
#endif |
298 |
|
322 |
|
299 |
DB_TXN* cache_new_transaction(NotifierID id, char *dn) |
323 |
DB_TXN* cache_new_transaction(NotifierID id, char *dn) |
300 |
{ |
324 |
{ |
|
|
325 |
#ifdef WITH_DB42 |
301 |
DB_TXN *dbtxnp; |
326 |
DB_TXN *dbtxnp; |
302 |
CacheMasterEntry master_entry; |
327 |
CacheMasterEntry master_entry; |
303 |
NotifierID *old_id; |
328 |
NotifierID *old_id; |
|
315 |
else |
340 |
else |
316 |
old_id = &master_entry.id; |
341 |
old_id = &master_entry.id; |
317 |
|
342 |
|
318 |
if (*old_id > id) { |
343 |
if (*old_id >= id) { |
319 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "New ID (%ld) is lower than old ID (%ld): %s", id, *old_id, dn); |
344 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
|
|
345 |
"New ID (%ld) is not greater than old" |
346 |
" ID (%ld): %s", id, *old_id, dn); |
320 |
dbtxnp->abort(dbtxnp); |
347 |
dbtxnp->abort(dbtxnp); |
321 |
return NULL; |
348 |
return NULL; |
322 |
} else if ( *old_id < id ) { |
349 |
} else |
323 |
*old_id = id; |
350 |
*old_id = id; |
324 |
|
|
|
325 |
if (cache_update_master_entry(&master_entry, dbtxnp) != 0) { |
326 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "cache_new_transaction: cache_update_master_entry failed"); |
327 |
dbtxnp->abort(dbtxnp); |
328 |
return NULL; |
329 |
} |
330 |
|
351 |
|
|
|
352 |
if (cache_update_master_entry(&master_entry, dbtxnp) != 0) { |
353 |
dbtxnp->abort(dbtxnp); |
354 |
return NULL; |
331 |
} |
355 |
} |
332 |
} |
356 |
} |
333 |
|
357 |
|
334 |
return dbtxnp; |
358 |
return dbtxnp; |
|
|
359 |
#else |
360 |
return NULL; |
361 |
#endif |
335 |
} |
362 |
} |
336 |
|
363 |
|
337 |
|
364 |
|
338 |
/* XXX: The NotifierID is passed for future use. Once the journal is |
365 |
/* XXX: The NotifierID is passed for future use. Once the journal is |
339 |
implemented, entries other than the most recent one can be returned. |
366 |
implemented, entries other than the most recent one can be returned. |
340 |
At the moment, the id parameters for cache_update_entry, and |
367 |
At the moment, the id parameters for cache_update_entry, and |
341 |
cache_delete_entry do nothing (at least if WITH_DB48 is undefined) */ |
368 |
cache_delete_entry do nothing (at least if WITH_DB42 is undefined) */ |
342 |
inline int cache_update_entry(NotifierID id, char *dn, CacheEntry *entry) |
369 |
inline int cache_update_entry(NotifierID id, char *dn, CacheEntry *entry) |
343 |
{ |
370 |
{ |
344 |
DBT key, data; |
371 |
DBT key, data; |
|
357 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "put %d bytes", data.size); |
384 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "put %d bytes", data.size); |
358 |
|
385 |
|
359 |
signals_block(); |
386 |
signals_block(); |
|
|
387 |
#ifdef WITH_DB42 |
360 |
dbtxnp = cache_new_transaction(id, dn); |
388 |
dbtxnp = cache_new_transaction(id, dn); |
361 |
if (dbtxnp == NULL) { |
389 |
if (dbtxnp == NULL) { |
362 |
signals_unblock(); |
390 |
signals_unblock(); |
363 |
free(data.data); |
391 |
free(data.data); |
364 |
return 1; |
392 |
return 1; |
365 |
} |
393 |
} |
|
|
394 |
#else |
395 |
dbtxnp = NULL; |
396 |
#endif |
366 |
|
397 |
|
367 |
key.data=dn; |
398 |
key.data=dn; |
368 |
key.size=strlen(dn)+1; |
399 |
key.size=strlen(dn)+1; |
|
372 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
403 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
373 |
"storing entry in database failed: %s", dn); |
404 |
"storing entry in database failed: %s", dn); |
374 |
dbp->err(dbp, rv, "put"); |
405 |
dbp->err(dbp, rv, "put"); |
|
|
406 |
#ifdef WITH_DB42 |
375 |
dbtxnp->abort(dbtxnp); |
407 |
dbtxnp->abort(dbtxnp); |
|
|
408 |
#endif |
376 |
free(data.data); |
409 |
free(data.data); |
377 |
return rv; |
410 |
return rv; |
378 |
} |
411 |
} |
379 |
|
412 |
|
|
|
413 |
#ifdef WITH_DB42 |
380 |
dbtxnp->commit(dbtxnp, 0); |
414 |
dbtxnp->commit(dbtxnp, 0); |
|
|
415 |
#endif |
381 |
if ( !INIT_ONLY ) { |
416 |
if ( !INIT_ONLY ) { |
382 |
dbp->sync(dbp, 0); |
417 |
dbp->sync(dbp, 0); |
383 |
} |
418 |
} |
|
411 |
key.size=strlen(dn)+1; |
446 |
key.size=strlen(dn)+1; |
412 |
|
447 |
|
413 |
signals_block(); |
448 |
signals_block(); |
|
|
449 |
#ifdef WITH_DB42 |
414 |
dbtxnp = cache_new_transaction(id, dn); |
450 |
dbtxnp = cache_new_transaction(id, dn); |
415 |
if (dbtxnp == NULL) { |
451 |
if (dbtxnp == NULL) { |
416 |
signals_unblock(); |
452 |
signals_unblock(); |
417 |
return 1; |
453 |
return 1; |
418 |
} |
454 |
} |
|
|
455 |
#else |
456 |
dbtxnp = NULL; |
457 |
#endif |
419 |
|
458 |
|
420 |
if ((rv=dbp->del(dbp, dbtxnp, &key, 0)) != 0 && rv != DB_NOTFOUND) { |
459 |
if ((rv=dbp->del(dbp, dbtxnp, &key, 0)) != 0 && rv != DB_NOTFOUND) { |
421 |
signals_unblock(); |
460 |
signals_unblock(); |
|
424 |
dbp->err(dbp, rv, "del"); |
463 |
dbp->err(dbp, rv, "del"); |
425 |
} |
464 |
} |
426 |
|
465 |
|
|
|
466 |
#ifdef WITH_DB42 |
427 |
dbtxnp->commit(dbtxnp, 0); |
467 |
dbtxnp->commit(dbtxnp, 0); |
|
|
468 |
#endif |
428 |
if ( !INIT_ONLY ) { |
469 |
if ( !INIT_ONLY ) { |
429 |
dbp->sync(dbp, 0); |
470 |
dbp->sync(dbp, 0); |
430 |
} |
471 |
} |
|
622 |
if ((rv = dbp->close(dbp, 0)) != 0) { |
663 |
if ((rv = dbp->close(dbp, 0)) != 0) { |
623 |
dbp->err(dbp, rv, "close"); |
664 |
dbp->err(dbp, rv, "close"); |
624 |
} |
665 |
} |
|
|
666 |
#ifdef WITH_DB42 |
625 |
if ((rv = dbenvp->close(dbenvp, 0)) != 0) { |
667 |
if ((rv = dbenvp->close(dbenvp, 0)) != 0) { |
626 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
668 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
627 |
"closing database environment failed"); |
669 |
"closing database environment failed"); |
628 |
} |
670 |
} |
|
|
671 |
#endif |
629 |
if (lock_fp != NULL) { |
672 |
if (lock_fp != NULL) { |
630 |
int rc=lockf(fileno(lock_fp), F_ULOCK, 0); |
673 |
int rc=lockf(fileno(lock_fp), F_ULOCK, 0); |
631 |
if (rc == 0) { |
674 |
if (rc == 0) { |