Logo Search packages:      
Sourcecode: debfoster version File versions  Download package

conffile.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#include "AVLTree.h"
#include "error.h"
#include "conffile.h"
#include "status.h"
#include "config.h"
#include "intl.h"

#define READBUF 4096

/* Various files */
#define KEEPERS VAR"/lib/debfoster/keepers"
#define STATUSFILE VAR"/lib/dpkg/status"
#define AVAILABLEFILE VAR"/lib/dpkg/available"
#define CONFIG_FILE ETC"/debfoster.conf"

/* Only simple space-separated arguments can be given */
#define INSTALLCOMMAND "apt-get install"
#define REMOVECOMMAND "apt-get --purge remove"
#define INFOCOMMAND "dpkg -s"

/* Default policies for packages */
#define MAXPRIORITY "standard"

static AVLTree *options = NULL;

static void set_string(const char **holder, const char *val) {
      if(*holder) free((char *)*holder);
      *holder = xstrdup(val);
}

#define StringConfigVal(s) const char *s = NULL; \
      static void set_##s(const char *str) { set_string(&s, str); }

static void set_bool(int *holder, const char *val) {
      if(!strcasecmp(val, "y") || !strcasecmp(val, "yes")
      || !strcasecmp(val, "t") || !strcasecmp(val, "true")
      || !strcasecmp(val, "1") || !strcasecmp(val, "on"))
            *holder = 1;
      else if(!strcasecmp(val, "n") || !strcasecmp(val, "no")
           || !strcasecmp(val, "f") || !strcasecmp(val, "false")
           || !strcasecmp(val, "0") || !strcasecmp(val, "off"))
            *holder = 0;
      else error_exit(ERROR_CONFIG, _("Not a truth value: \"%s\"\n"), val);
}

#define BoolConfigVal(b) int b = 0; \
      static void set_##b(const char *str) { set_bool(&b, str); }

StringConfigVal(KeeperFile)
StringConfigVal(DpkgStatus)
StringConfigVal(DpkgAvailable)
StringConfigVal(InstallCmd)
StringConfigVal(RemoveCmd)
StringConfigVal(InfoCmd)
StringConfigVal(MaxPriority)
StringConfigVal(KeepSections)
StringConfigVal(NokeepSections)
StringConfigVal(GuessDepends)

BoolConfigVal(UseHold)
BoolConfigVal(UseEssential)
BoolConfigVal(UsePreDepends)
BoolConfigVal(UseRecommends)
BoolConfigVal(UseSuggests)
BoolConfigVal(UseTasks)

BoolConfigVal(NegativeKeepers)

BoolConfigVal(Quiet)
BoolConfigVal(Force)
BoolConfigVal(Verbose)

static int optcmp(const option_t a, const option_t b) {
      return strcasecmp(a->key, b->key);
}

option_t find_option(const char *key) {
      struct option_t o;
      AVLNode *c;

      o.key = key;

      c = AVLSearch(options, &o);

      return c?c->item:NULL;
}

static void add_option(const char *key, void (*set)(const char *), const char *def) {
      option_t o;
      o = xmalloc(sizeof *o);
      o->key = xstrdup(key);
      o->set = set;
      set(def);
      if(!AVLInsert(options, o))
            perror_exit(ERROR_CONFIG, key);
}

static void free_option(option_t opt) {
      if(opt) {
            if(opt->key)
                  free((char *)opt->key);
            free(opt);
      }
}

void readconfig(const char *config) {
      FILE *f;
      unsigned char buf[READBUF];
      option_t o;
      char *key, *value;
      int lineno = 0;

      if(!config)
            config = CONFIG_FILE;

      if(options)
            AVLFreeNodes(options);
      else
            options = AVLAllocTree((AVLCompare)optcmp, (AVLFreeItem)free_option);

      /* Seed tree with defaults for all options */
      add_option("KeeperFile",    set_KeeperFile,    KEEPERS);
      add_option("DpkgStatus",    set_DpkgStatus,    STATUSFILE);
      add_option("DpkgAvailable", set_DpkgAvailable, AVAILABLEFILE);
      add_option("InstallCmd",    set_InstallCmd,    INSTALLCOMMAND);
      add_option("RemoveCmd",     set_RemoveCmd,     REMOVECOMMAND);
      add_option("InfoCmd",       set_InfoCmd,       INFOCOMMAND);
      add_option("MaxPriority",   set_MaxPriority,   MAXPRIORITY);
      add_option("KeepSections",  set_KeepSections,  "");
      add_option("NokeepSections",  set_NokeepSections, "");
      add_option("GuessDepends",  set_GuessDepends, "");

      add_option("UseHold",       set_UseHold,       "yes");
      add_option("UseEssential",  set_UseEssential,  "yes");
      add_option("UsePreDepends", set_UsePreDepends, "yes");
      add_option("UseRecommends", set_UseRecommends, "yes");
      add_option("UseSuggests",   set_UseSuggests,   "no");
      add_option("UseTasks",      set_UseTasks,      "no");

      add_option("NegativeKeepers", set_NegativeKeepers, "yes");

      add_option("Quiet",         set_Quiet,         "no");
      add_option("Force",         set_Force,         "no");
      add_option("Verbose",       set_Verbose,       "no");

      /* Read the options but fail if there's no default for it */
      f = fopen(config, "r");
      if(f) {
            while(fgets(buf, READBUF, f)) {
                  lineno++;
                  key = chop(buf);
                  if(*key && *key != '#') {
                        value = strchr(key, '=');
                        if(!value)
                              error_exit(ERROR_CONFIG, _("Syntax error in %s:%d\n"), CONFIG_FILE, lineno);
                        *value++ = '\0';
                        key = chop(key);
                        if(!(o = find_option(key)))
                              error_exit(ERROR_CONFIG, _("Unknown option `%s' at %s:%d\n"), key, CONFIG_FILE, lineno);
                        o->set(chop(value));
                  }
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index