XXX -- General things which are missing XXX Consistentify typographical conventions XXX Refactoring to be more readable -- sections will need to be moved. General APIs ~~~~~~~~~~~~ Tags are strings consisting of identifiers separated by "::" XXX How to choose tags? configuration API ~~~~~~~~~~~~~~~~~ A "struct configuration" has several publically accessible methods: const char *get(struct configuration *, const char *tag, const char *default): Return a string value for given tag int geti(struct configuration *, const char *tag, int default) Return an integral value for given tag void set(struct configuration *, const char *tag, const char *value): Save string value at tag void seti(struct configuration *, const char *tag, int value) Save integral value at tag XXX memory ownership not discussed XXX new/delete, read/dump not documented template API ~~~~~~~~~~~~ Initializing a template should be done via the function struct template *template_new(const char * tag). This function takes a tag, and returns an empty template object. A template has the following publically accessible fields: - char *tag: the template's tag - char *type: the template's type, can be one of select, multiselect, string, boolean, note, text and password - struct template_l10n_fields *fields - has following fields: - struct template_l10n_fields *next: NULL or another localized field structure - char *language: ISO code for language (ll or ll_LL) - char *defaultval: the template's default value, as a string - char *choices: if the template's type is choices based, here the choices are listed in a single string, seperated by commas - char *description: a description of the template XXX must be under ... chars? - char *extended_description: a longer description The first template_l10n_fields structure must always be in English, and its ISO code is set to C. XXX not covering "next", I assume it is private XXX not covering memory management or deletion The following functions are supported: XXX there are others const char *template_lget(const struct template *t, const char *lang, const char *field): Return a string value for given field. - If lang is NULL, English field is returned. - If lang is empty, field in the current language is returned. - If lang is not NULL and not empty, or if localized value does not exist, English field is returned. void template_lset(struct template *t, const char *lang, const char *field, const char *value): Save string value at field, see above for details about the lang attribute. question API ~~~~~~~~~~~~ struct questionvariable has the following fields: - char *variable: name - char *value: value - struct questionvariable *: next variable or NULL The following functions are supported: - const char *question_get_variable(const struct question *q, const char *var): Return the value of variable "var" as string XXX list of functions is incomplete XXX what are variables, and does anything use them? XXX only references I've seen are in db modules struct questionowner has the following fields: - char *owner: the owner - struct questionowner *next: next owner or NULL These are documented here because the serializer needs to be able to write all of them out. In general, nothing should directly modify those except via the APIs. struct question has the following public fields: * char *tag: the tag for this question * char *value: the value for this question * struct template *template: the template belonging to this question * unsigned int flags: XXX * struct questionvariable *variables: list of variables * struct questionowner *owners: list of owners * struct question *next, *prev: allows you to put questions in a doubly-linked list (like the default front end functions do, for example) The following functions are supported: - struct question *question_new(const char *tag): allocate and initialize a question - void question_setvalue(struct question *q, const char *value): set the value of a question (note that setvalue must *always* be called with non-translated choices) - const char *question_getvalue(struct question *q, const char *lang); return the value of a question, or default value, otherwise a NULL pointer - void question_owner_add(struct question *q, const char *owner): add an owner - void question_owner_delete(struct question *q, const char *owner) remove an owner - const char *question_get_field(struct question *q, const char *lang, const char *field): return a string field from the question XXX not dealing with variables XXX not dealing with memory management Writing modules ~~~~~~~~~~~~~~~ cdebconf is designed to allow frontend and database modules to be plugged in as needed. Modules can be built to support different database backends (e.g. postgres, ldap, etc) and frontends (e.g. ncurses, gtk, etc). Database modules: ~~~~~~~~~~~~~~~~ database.h defines the database module interface. Each database module needs to export a struct named debconf_database_module of type struct database_module, defined as: struct database_module { dcd_initialize_t initialize; dcd_shutdown_t shutdown; dcd_load_t load; dcd_save_t save; dcd_template_set_t template_set; dcd_template_get_t template_get; dcd_template_remove_t template_remove; dcd_template_lock_t template_lock; dcd_template_unlock_t template_unlock; dcd_template_iterate_t template_iterate; dcd_question_get_t question_get; dcd_question_set_t question_set; dcd_question_disown_t question_disown; dcd_question_disownall_t question_disownall; dcd_question_remove_t question_remove; dcd_question_lock_t question_lock; dcd_question_unlock_t question_unlock; dcd_question_visible_t question_visible; dcd_question_iterate_t question_iterate; }; General ~~~~~~~ In "common.h", two constants are defined: DC_OK and DC_NOTOK. Every method which returns an int, unless specified otherwise, should return DC_OK if it succeeds and DC_NOTOK if it fails. Each of these methods have a signature defined in database.h. All methods have a sensible default implementation (usually doing nothing) so that you only need to override the ones you need. All methods are passed a database object as a first argument. The database, besides the methods, contains the following attributes: const char *modname -- the name of the module this database was loaded from XXX void *handle -- a handle to the shared library. you should probably not use this XXX struct configuration *config -- the configuration of the database. See later about how to use this XXX void *data -- this is a pointer the database can use to keep it's own private data, by allocating some structure and keeping a pointer here on initialization, and deleting it on deletion. Method descriptions: int initialize(struct database *, struct configuration *): initialize data structures, like cache. Get information form the configuration, if you need to. XXX WHY? Can't you get the configuration from database->config int shutdown(struct database *): free data structures, like cache int load(struct database *): read in the database structure from a file (this is to optimize parsing. if you have no parsing to do, just do nothing here) int save(struct database *): save the database structure back to a file This is so not every change will get saved immediately, to optimize deserialization. If saving each change immediately is easier, do nothing here. int template_set(struct database *, struct template *): save the given template (or, just keep all the information for saving later in save()) struct template *template_get(struct database *, char *name): return a newly allocated template with the contents of the template whose name is "name". XXX should return NULL if fails? int template_remove(struct database *, char *name): remove a template from the database int (template|question)_[un]lock(struct database *, char *name): XXX WTF? Nothing implements this right now struct template *template_iterate(struct database *, void **iter): Return "Next template" When beginning to iterate, *iter will be NULL. On consecutive iterations, it will keep its value. It is your responsibility to free any allocated structure when returning NULL, to signify end of iteration. Otherwise, return whatever would have been returned by calling template_get() with the template's name. struct question *question_get(struct database *, const char *name): Return a newly allocated question object, corresponding to the name. int question_set(struct database *, struct question *): Save the data about the question in the database. struct question *question_iterate(struct database *, void **iter): Return "Next question" When beginning to iterate, *iter will be NULL. On consecutive iterations, it will keep its value. It is your reponsibility to free any allocated structure when returning NULL, to signify end of iteration. Otherwise, return whatever would have been returned by calling question_get() with the question's name. struct question *question_disown(struct database *, char *name, char *owner): Remove the owner from the question. XXX - WTF this is done here instead of the caller getting the question, removing the owner and setting the question is a mystery. Perhaps there are cases where it will be much less efficient? struct question *question_disown_all(struct database *, char *owner): Remove the owner from all questions. Semantically, this should be the same as iterating, and for each question removing the owner and resetting it. However, you might be able to avoid iterating on some of the question, if the backend is structured correctly. int question_remove(struct database *, char *name): remove a question from the database (useful while moving a question to a different database) int question_visible(struct database *, char *name, char *priority) XXX - WTF, nothing implements this either. See modules/db/* for some examples. Frontend modules ~~~~~~~~~~~~~~~~ Similarly, frontend modules have an interface defined in frontend.h. Modules export a struct called debconf_frontend_module of type struct frontend_module, defined as: struct frontend_module { dcf_initialize_t initialize; dcf_shutdown_t shutdown; dcf_query_capability_t query_capability; dcf_set_title_t set_title; dcf_add_t add; dcf_go_t go; dcf_clear_t clear; }; All methods will be passed a struct frontend as a first argument. The structure has the following public attributes: * struct configuration *config -- Use this to get configuration information (XXX colors for GTK+ would go here, right?) * void *data -- private data. * struct *question questions -- list of questions to ask * struct *database db -- database object * char *title -- title * XXX: Are the rest of things public? Methods: All methods returning int should be returning DC_OK/DC_NOTOK, as above. * int initialize(struct frontend *, struct configuration *): Initialize the structure. (For example, connect to X server) * int shutdown(struct frontend *) Destroy all resources owned by object * unsigned long query_capability(struct frontend *) Return all capabilities you support, as an | of flags. Currently, the only capability supported is DCF_CAPB_BACKUP, which means the front end is capable of backing up, so return either 0 of DCF_CAPB_BACKUP. * const char * lookup_directive(struct frontend *, const char *) Return the proper value for the given directive. If NULL is returned, the directive is not expanded. The default method always returns "" to remove unhandled directives from queried question fields. * int add(struct frontend *, struct question *): Add question. Default implementation adds the question to "questions" attribute * int go(struct frontend *): Ask all questions you need to, and notify the database object of the answers. * int clear(struct frontend *): Clear queue of pending questions. Default implementation clears the "questions" queue. * int set_title(struct frontend *, char *title): Set the title variable. "title" is owned by caller, so you should copy it. The default implementation sets the title attribute. * int info(struct frontend *, struct question *); Display an informative message, without requiring any acknowledgement from the user. Frontends may choose not to implement this. If they do implement it, they should display the info persistently until some other info comes along. This takes a question rather than a string because the locale could be changed after this command (while the info is still being persistently displayed), and the displayed text should be changed when that happens. The default implementation sets the info attribute. * cangoforward/cangoback -- XXX I don't understand what these do. Each of these methods have a signature defined in frontend.h. All methods have a sensible default implementation (usually doing nothing) so that you only need to override the ones you need. See modules/frontend/* for examples.