* Add a remove method to the question database; use this to migrate
questions to the correct stacked database in the event that their types
change (fixes preseeded passwords ending up in questions.dat on the
installed system in some cases).
r35410
Colin Watson
18 years ago
23 | 23 | * Reset question template pointers whenever they change, not just when the |
24 | 24 | tag changes; do this in X_LOADTEMPLATEFILE and dpkg-reconfigure as well |
25 | 25 | as debconf-loadtemplate. |
26 | * Add a remove method to the question database; use this to migrate | |
27 | questions to the correct stacked database in the event that their types | |
28 | change (fixes preseeded passwords ending up in questions.dat on the | |
29 | installed system in some cases). | |
26 | 30 | |
27 | 31 | -- Attilio Fiandrotti <fiandro@tiscali.it> Wed, 8 Mar 2006 22:40:40 +0100 |
28 | 32 |
146 | 146 | dcd_question_set_t question_set; |
147 | 147 | dcd_question_disown_t question_disown; |
148 | 148 | dcd_question_disownall_t question_disownall; |
149 | dcd_question_remove_t question_remove; | |
149 | 150 | dcd_question_lock_t question_lock; |
150 | 151 | dcd_question_unlock_t question_unlock; |
151 | 152 | dcd_question_visible_t question_visible; |
203 | 204 | name is "name". |
204 | 205 | XXX should return NULL if fails? |
205 | 206 | |
206 | int *template_remove(struct database *, char *name): | |
207 | int template_remove(struct database *, char *name): | |
207 | 208 | remove a template from the database |
208 | 209 | |
209 | int *(template|question)_[un]lock(struct database *, char *name): | |
210 | int (template|question)_[un]lock(struct database *, char *name): | |
210 | 211 | XXX WTF? Nothing implements this right now |
211 | 212 | |
212 | 213 | struct template *template_iterate(struct database *, void **iter): |
244 | 245 | Semantically, this should be the same as iterating, and for each question |
245 | 246 | removing the owner and resetting it. However, you might be able to avoid |
246 | 247 | iterating on some of the question, if the backend is structured correctly. |
248 | ||
249 | int question_remove(struct database *, char *name): | |
250 | remove a question from the database (useful while moving a question to a | |
251 | different database) | |
247 | 252 | |
248 | 253 | int question_visible(struct database *, char *name, char *priority) |
249 | 254 | XXX - WTF, nothing implements this either. |
254 | 254 | question_deref(q); |
255 | 255 | } |
256 | 256 | return 0; |
257 | } | |
258 | ||
259 | static int question_db_remove(struct question_db *db, const char *name) | |
260 | { | |
261 | return DC_NOTIMPL; | |
257 | 262 | } |
258 | 263 | |
259 | 264 | static int question_db_lock(struct question_db *db, const char *name) |
422 | 427 | SETMETHOD(get); |
423 | 428 | SETMETHOD(disown); |
424 | 429 | SETMETHOD(disownall); |
430 | SETMETHOD(remove); | |
425 | 431 | SETMETHOD(lock); |
426 | 432 | SETMETHOD(unlock); |
427 | 433 | SETMETHOD(is_visible); |
43 | 43 | struct question *(*get)(struct question_db *db, const char *name); |
44 | 44 | int (*disown)(struct question_db *, const char *name, const char *owner); |
45 | 45 | int (*disownall)(struct question_db *, const char *owner); |
46 | int (*remove)(struct question_db *, const char *name); | |
46 | 47 | int (*lock)(struct question_db *, const char *name); |
47 | 48 | int (*unlock)(struct question_db *, const char *name); |
48 | 49 | int (*is_visible)(struct question_db *, const char *name, const char *priority); |
300 | 300 | return DC_OK; |
301 | 301 | } |
302 | 302 | |
303 | /* FIXME b0rken */ | |
304 | 303 | static int rfc822db_template_remove(struct template_db *db, const char *tag) |
305 | 304 | { |
306 | 305 | struct template_db_cache *dbdata = db->data; |
308 | 307 | |
309 | 308 | INFO(INFO_VERBOSE, "rfc822db_template_remove(db,tag=%s)",tag); |
310 | 309 | |
310 | memset(&t2, 0, sizeof (struct template)); | |
311 | 311 | t2.tag = (char*) tag; |
312 | t = tdelete(&t, &dbdata->root, nodetemplatecomp); | |
312 | t = tfind(&t2, &dbdata->root, nodetemplatecomp); | |
313 | 313 | |
314 | 314 | if (t) |
315 | 315 | { |
316 | t = *(struct template **) t; | |
317 | tdelete(t, &dbdata->root, nodetemplatecomp); | |
316 | 318 | template_deref(t); |
317 | 319 | return DC_OK; |
318 | 320 | } |
602 | 604 | return DC_OK; |
603 | 605 | } |
604 | 606 | |
607 | static int rfc822db_question_remove(struct question_db *db, const char *tag) | |
608 | { | |
609 | struct question_db_cache *dbdata = db->data; | |
610 | struct question *q, q2; | |
611 | ||
612 | INFO(INFO_VERBOSE, "rfc822db_question_remove(db,tag=%s)", tag); | |
613 | ||
614 | memset(&q2, 0, sizeof (struct question)); | |
615 | q2.tag = (char*) tag; | |
616 | q = tfind(&q2, &dbdata->root, nodequestioncomp); | |
617 | if (q != NULL) { | |
618 | q = *(struct question **) q; | |
619 | tdelete(q, &dbdata->root, nodequestioncomp); | |
620 | question_deref(q); | |
621 | return DC_OK; | |
622 | } | |
623 | return DC_NOTOK; | |
624 | } | |
625 | ||
605 | 626 | /* TODO: This is an ugly hack because there's no better way to do this |
606 | 627 | * within the constraints of twalk() (since there's no user-data argument). |
607 | 628 | * If we ever switch to some other tree API, this should go away |
672 | 693 | set: rfc822db_question_set, |
673 | 694 | get: rfc822db_question_get, |
674 | 695 | disown: rfc822db_question_disown, |
696 | remove: rfc822db_question_remove, | |
675 | 697 | iterate: rfc822db_question_iterate, |
676 | 698 | }; |
677 | 699 |
128 | 128 | while (tstack) { |
129 | 129 | ret = tstack->db->methods.accept(tstack->db, t->tag, t->type); |
130 | 130 | if (ret == DC_REJECT) { |
131 | tstack->db->methods.remove(tstack->db, t->tag); | |
131 | 132 | tstack = tstack->next; |
132 | 133 | continue; |
133 | 134 | } |
138 | 139 | case DC_NOTOK: |
139 | 140 | return DC_NOTOK; |
140 | 141 | case DC_REJECT: /* obsolete as return code from set() */ |
142 | tstack->db->methods.remove(tstack->db, t->tag); | |
141 | 143 | tstack = tstack->next; |
142 | 144 | continue; |
143 | 145 | } |
288 | 290 | const char *type = t->template ? t->template->type : ""; |
289 | 291 | ret = qstack->db->methods.accept(qstack->db, t->tag, type); |
290 | 292 | if (ret == DC_REJECT) { |
293 | qstack->db->methods.remove(qstack->db, t->tag); | |
291 | 294 | qstack = qstack->next; |
292 | 295 | continue; |
293 | 296 | } |
298 | 301 | case DC_NOTOK: |
299 | 302 | return DC_NOTOK; |
300 | 303 | case DC_REJECT: /* obsolete as return code from set() */ |
304 | qstack->db->methods.remove(qstack->db, t->tag); | |
301 | 305 | qstack = qstack->next; |
302 | 306 | continue; |
303 | 307 | } |
349 | 353 | qstack = qstack->next; |
350 | 354 | } |
351 | 355 | return DC_OK; |
356 | } | |
357 | ||
358 | static int stack_question_db_remove(struct question_db *db, const char *name) | |
359 | { | |
360 | struct question_stack *qstack = (struct question_stack *)db->data; | |
361 | struct question *q; | |
362 | while (qstack) { | |
363 | q = qstack->db->methods.get(qstack->db, name); | |
364 | if (q) { | |
365 | question_deref(q); | |
366 | return qstack->db->methods.remove(qstack->db, name); | |
367 | } | |
368 | qstack = qstack->next; | |
369 | } | |
370 | /* nobody had it? fail. */ | |
371 | return DC_NOTOK; | |
352 | 372 | } |
353 | 373 | |
354 | 374 | static int stack_question_db_lock(struct question_db *db, const char *name) |
409 | 429 | get: stack_question_db_get, |
410 | 430 | disown: stack_question_db_disown, |
411 | 431 | disownall: stack_question_db_disownall, |
432 | remove: stack_question_db_remove, | |
412 | 433 | iterate: stack_question_db_iterate, |
413 | 434 | lock: stack_question_db_lock, |
414 | 435 | unlock: stack_question_db_unlock, |
380 | 380 | return DC_OK; |
381 | 381 | } |
382 | 382 | |
383 | static int textdb_question_remove(struct question_db *db, const char *tag) | |
384 | { | |
385 | char *filename; | |
386 | ||
387 | if (tag == NULL) return DC_NOTOK; | |
388 | ||
389 | /* questions are not cached at present */ | |
390 | ||
391 | filename = question_filename(db, tag); | |
392 | if (unlink(filename) == 0) | |
393 | return DC_OK; | |
394 | else | |
395 | return DC_NOTOK; | |
396 | } | |
397 | ||
383 | 398 | static struct question *textdb_question_iterate(struct question_db *db, |
384 | 399 | void **iter) |
385 | 400 | { |
435 | 450 | set: textdb_question_set, |
436 | 451 | get: textdb_question_get, |
437 | 452 | disown: textdb_question_disown, |
453 | remove: textdb_question_remove, | |
438 | 454 | iterate: textdb_question_iterate, |
439 | 455 | }; |
440 | 456 |