#include #include #include #include #include #include "common.h" #include "configuration.h" #include "database.h" #include "question.h" #include "template.h" static int debug = 0; static int checkonly = 0; static int unseen = 0; static struct option params[] = { { "help", 0, NULL, 'h' }, { "verbose", 0, &debug, 'v' }, { "checkonly", 0, &checkonly, 'c' }, { "unseen", 0, &unseen, 'u' }, { 0, 0, 0, 0 } }; static const char * known_types[] = { "select", "boolean", "string", "multiselect", "note", "password", "text", "title", NULL }; static void usage(const char *exename) { printf("%s [-vcu] [file]\n", exename); puts("\t-v, --verbose verbose output\n" "\t-c, --checkonly only check the input file format\n" "\t-u, --unseen do not set the 'seen' flag when preseeding values\n"); exit(0); } static void load_answer(const char *owner, const char *label, const char * type, const char *content, struct question_db *qdb, struct template_db *tdb) { if (debug) fprintf(stderr, "info: Loading answer for '%s'\n", label); struct template *tp = tdb->methods.get(tdb, label); if (!tp) { tp = template_new(label); template_lset(tp, NULL, "type", type); template_lset(tp, NULL, "description", "Dummy template"); template_lset(tp, NULL, "extended_description", "This is a fake template used to pre-seed the debconf database. " "If you are seeing this, something is probably wrong."); } else { template_lset(tp, NULL, "default", content); template_lset(tp, NULL, "type", type); } tdb->methods.set(tdb, tp); template_deref(tp); struct question *q = qdb->methods.get(qdb, label); if (!q) { fprintf(stderr, "Cannot find a question for %s\n", label); return; } question_owner_add(q, owner); question_setvalue(q, content); if (!unseen) question_set_flag(q, DC_QFLAG_SEEN); qdb->methods.set(qdb, q); question_deref(q); } static void set_flag(const char *label, const char *flag, const char *content, struct question_db *qdb) { if (debug) fprintf(stderr, "info: Setting %s flag\n", flag); struct question *q = qdb->methods.get(qdb, label); if (!q) { fprintf(stderr, "Cannot find a question for %s\n", label); return; } if (0 == strcmp(content, "true")) question_set_flag(q, flag); else if (0 == strcmp(content, "false")) question_clear_flag(q, flag); qdb->methods.set(qdb, q); question_deref(q); } static int is_known_type(const char *type) { int i; if (!type) return 0; for (i = 0; known_types[i] != NULL; i++) { if (0 == strcmp(known_types[i], type)) return 1; } return 0; } static size_t strlenmunge(char *buf, int *line) { size_t tmplen = strlen(buf); if (buf[tmplen - 1] == '\n') { (*line)++; if (tmplen >= 2 && buf[tmplen - 2] == '\r') { buf[tmplen - 1] = '\0'; buf[tmplen - 2] = '\n'; tmplen -= 1; } if (tmplen >= 2 && buf[tmplen - 2] == '\\') { buf[tmplen - 2] = '\0'; tmplen -= 2; } } return tmplen; } #define BUFFERSIZE 2048 #define IS_SPACE(c) ((c == ' ') || (c == '\t')) #define NOT_SET(var) (!var || *var == ' ' || *var == '\t') int main(int argc, char **argv) { int bufsize = BUFFERSIZE; char *buf; FILE *stream = stdin; struct configuration *config; struct template_db *tdb; struct question_db *qdb; int c, line = 0; setlocale(LC_ALL, ""); config = config_new(); while ((c = getopt_long(argc, argv, "hvcu:", params, NULL)) >= 0) { switch (c) { case 'h': usage(argv[0]); break; case 'v': debug = 1; break; case 'c': checkonly = 1; break; case 'u': unseen = 1; break; default: break; } } if (optind < argc) { stream = fopen(argv[optind], "r"); if (!stream) { fprintf(stderr, "Can't open %s\n", argv[optind]); return 1; } } /* parse the configuration info */ if (config->read(config, DEBCONFCONFIG) == 0) DIE("Error reading configuration information"); /* initialize database modules */ if ((tdb = template_db_new(config, NULL)) == 0) DIE("Cannot initialize DebConf template database"); if ((qdb = question_db_new(config, tdb, NULL)) == 0) DIE("Cannot initialize DebConf config database"); /* load database */ tdb->methods.load(tdb); qdb->methods.load(qdb); buf = (char *)malloc(bufsize * sizeof(*buf)); while (fgets(buf, bufsize, stream)) { size_t tmplen = strlenmunge(buf, &line); while (buf[tmplen-1] != '\n') { bufsize += BUFFERSIZE; buf = realloc(buf, bufsize * sizeof(*buf)); if (!buf) DIE("Could not allocate memory !"); if (!fgets(buf + tmplen, bufsize - tmplen, stream)) break; tmplen = strlenmunge(buf, &line); } CHOMP(buf); { char *ch = buf; char *owner = NULL, *label = NULL, *type = NULL, *content = NULL; while (IS_SPACE(*ch)) ch++; owner = ch; while (*ch && NOT_SET(content)) { if (IS_SPACE(*ch)) { *ch = '\0'; if (NOT_SET(label)) label = ch+1; else if (NOT_SET(type)) type = ch+1; else if (NOT_SET(content)) content = ch+1; } ch++; } if (owner && owner[0] && owner[0] != '#' && label && label[0] && type && type[0] && content) { if (strcmp(type, DC_QFLAG_SEEN) == 0) { if (debug) fprintf(stderr, "info: Trying to set %s flag to %s\n", type, content); set_flag(label, type, content, qdb); } else if (is_known_type(type)) { if (debug) fprintf(stderr, "info: Trying to set '%s' [%s] to '%s'\n", label, type, content); load_answer(owner, label, type, content, qdb, tdb); } else fprintf(stderr, "warning: Unknown type %s, skipping line %i\n", type, line); } } } fclose(stream); if (!checkonly) { qdb->methods.save(qdb); tdb->methods.save(tdb); } free(buf); question_db_delete(qdb); template_db_delete(tdb); config_delete(config); return 0; }