pmlag

Poor man's link aggregation
git clone git://git.finwo.net/app/pmlag
Log | Files | Refs | LICENSE

config-root.c (6155B)


      1 #include <glob.h>
      2 #include <libgen.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 #include <strings.h>
      6 #include <unistd.h>
      7 
      8 #include "config-root.h"
      9 
     10 #define CFG_MAX_REG 256
     11 
     12 static int               handler_count = 0;
     13 static const char       *handler_name[CFG_MAX_REG];
     14 static cfg_directive_fn  handler_fn[CFG_MAX_REG];
     15 
     16 void cfg_register_directive(const char *name, cfg_directive_fn fn) {
     17   handler_name[handler_count] = name;
     18   handler_fn  [handler_count] = fn;
     19   handler_count++;
     20 }
     21 
     22 int cfg_parse(const char *wd, FILE *fd, void *user) {
     23   struct cnf_directive *dir = NULL;
     24   glob_t globbuf;
     25   int globflags;
     26   int i;
     27 
     28   char *strtmp = NULL;
     29   FILE *nfd;
     30 
     31   for(;;) {
     32     if (dir) cnf_directive_free(dir);
     33     dir = cnf_directive_read(fd);
     34     if (!dir) break; // EOF = done
     35 
     36 cfg_parse_reparse:
     37 
     38     // Core handlers
     39     if (!strcasecmp("include", dir->name)) {
     40       globflags = GLOB_ERR;
     41       for ( i = 0 ; i < dir->argc ; i++ ) {
     42         strtmp = malloc(snprintf(NULL, 0, "%s/%s", wd, dir->argv[i])+1);
     43         sprintf(strtmp, "%s/%s", wd, dir->argv[i]);
     44         glob(strtmp, globflags, NULL, &globbuf);
     45         free(strtmp);
     46         globflags = GLOB_ERR | GLOB_APPEND;
     47       }
     48       for( i = 0 ; i < globbuf.gl_pathc ; i++ ) {
     49         strtmp = calloc(strlen(globbuf.gl_pathv[i])+1, 1);
     50         strcpy(strtmp, globbuf.gl_pathv[i]);
     51         dirname(strtmp);
     52         nfd = fopen(globbuf.gl_pathv[i], "r");
     53         if (!nfd) {
     54           perror("Could not open config file for reading");
     55           return CFG_RET_ERROR;
     56         }
     57         if (cfg_parse(strtmp, nfd, user) < 0) {
     58           fprintf(stderr, "Error during reading configuration from %s\n", globbuf.gl_pathv[i]);
     59           return CFG_RET_ERROR;
     60         }
     61         fclose(nfd);
     62         free(strtmp);
     63       }
     64       globfree(&globbuf);
     65       continue;
     66     }
     67 
     68     // Dynamic handlers
     69     for(i = 0 ; i < handler_count ; i++) {
     70       if (!strcasecmp(handler_name[i], dir->name)) {
     71         dir = handler_fn[i](fd, dir, user);
     72         if (dir) goto cfg_parse_reparse;
     73         goto cfg_parse_cleanup;
     74       }
     75     }
     76 
     77     // Here = not found
     78     fprintf(stderr, "Unknown directive: %s\n", dir->name);
     79     return CFG_RET_ERROR;
     80   }
     81 
     82   // Cleanup here
     83 cfg_parse_cleanup:
     84   if (dir) cnf_directive_free(dir);
     85 
     86   return CFG_RET_OK;
     87 }
     88 
     89 // #include <stdio.h>
     90 // #include <stdlib.h>
     91 // #include <string.h>
     92 
     93 // #include "config.h"
     94 
     95 // #include "benhoyt/inih.h"
     96 // #include "finwo/mindex.h"
     97 
     98 // int mindex_bond_cmp(const void *a, const void *b, void *udata) {
     99 //   (void)udata;
    100 //   const struct pmlag_configuration_bond *_a = a;
    101 //   const struct pmlag_configuration_bond *_b = b;
    102 //   return strcmp(_a->name, _b->name);
    103 // }
    104 
    105 // void mindex_bond_purge(void *item, void *udata) {
    106 //   struct pmlag_configuration_bond *bond = item;
    107 //   (void)udata;
    108 //   if (!item) return;
    109 //   if (bond->name) free(bond->name);
    110 // }
    111 
    112 // #ifndef MIN
    113 // #define MIN(a,b) ((a)<(b)?(a):(b))
    114 // #endif
    115 
    116 // static int config_load_handler(
    117 //   void *user,
    118 //   const char *section,
    119 //   const char *name,
    120 //   const char *value
    121 // ) {
    122 //   // struct pmlag_bond  *bond  = NULL;
    123 //   // struct pmlag_iface *iface = NULL;
    124 //   // int bond_index = 0;
    125 //   // int iface_index = 0;
    126 //   struct pmlag_configuration* config = (struct pmlag_configuration *) user;
    127 
    128 //   // Detect invalid entries
    129 //   int i, l;
    130 //   for( i = 0, l = strlen(name) ; i < l ; i++ ) {
    131 //     if (name[i] == 0x5F                   ) continue; // '_'
    132 //     if (name[i] >= 0x30 && name[i] <= 0x39) continue; // 0-9
    133 //     if (name[i] >= 0x41 && name[i] <= 0x5A) continue; // A-Z
    134 //     if (name[i] >= 0x61 && name[i] <= 0x7A) continue; // a-z
    135 //     return 0; // Reject
    136 //   }
    137 
    138 //   // Strip # comments from values
    139 //   char *found_comment = strstr(value, "#");
    140 //   if (found_comment) {
    141 //     for(; found_comment > (value + 1) ;) {
    142 //       if ( *(found_comment) >= 0x21 && *(found_comment-1) <= 0x7E ) break;
    143 //       found_comment--;
    144 //     }
    145 //     *found_comment = 0x00;
    146 //   }
    147 
    148 //   // Find or create bond
    149 //   struct pmlag_configuration_bond *config_bond = mindex_get(config->bonds, (&(struct pmlag_configuration_bond){ .name = (char *)section }));
    150 //   if (!config_bond) {
    151 //     config_bond = calloc(1, sizeof(struct pmlag_configuration_bond));
    152 //     config_bond->name = strdup(section);
    153 //     mindex_set(config->bonds, config_bond);
    154 //   }
    155 
    156 //   // // Find the bond
    157 //   // struct pmlag_configuration_bond *config_bond = NULL;
    158 //   // for( i = 0 ; i < config->bond_len ; i++ ) {
    159 //   //   if (!strcmp(config->bonds[i].name, section)) {
    160 //   //     config_bond = &(config->bonds[i]);
    161 //   //     break;
    162 //   //   }
    163 //   // }
    164 //   // printf("%s:%d\n", __FILE__, __LINE__);
    165 //   // // Build new bond if missing
    166 //   // if (!config_bond) {
    167 //   //   // Expand array size if needed
    168 //   //   if ((config->bond_len+1) > config->bond_cap) {
    169 //   //     config->bond_cap = MIN(1, config->bond_cap*2);
    170 //   //     config->bonds = realloc(config->bonds, config->bond_cap * sizeof(struct pmlag_configuration_bond));
    171 //   //   }
    172 //   //   // Append new entry to list
    173 //   //   memset(&(config->bonds[config->bond_len]), 0, sizeof(struct pmlag_configuration_bond));
    174 //   //   config_bond = &(config->bonds[config->bond_len]);
    175 //   //   config->bond_len++;
    176 //   // }
    177 
    178 //   // Detect # comments and remove them
    179 
    180 //   return 1;
    181 // }
    182 
    183 // struct pmlag_configuration * config_load(char * filepath, struct pmlag_configuration *config) {
    184 //   // Load config, entry-by-entry
    185 //   if (!config) {
    186 //     config = calloc(1, sizeof(struct pmlag_configuration));
    187 //   }
    188 //   if (!config->bonds) {
    189 //     config->bonds = mindex_init(mindex_bond_cmp, mindex_bond_purge, NULL);
    190 //   }
    191 
    192 //   if (ini_parse(filepath, config_load_handler, config) < 0) {
    193 //     fprintf(stderr, "Can not load %s\n", filepath);
    194 //     return NULL;
    195 //   }
    196 
    197 //   printf("bond_len: %ld\n", mindex_length(config->bonds));
    198 //   printf("\n");
    199 //   printf("bonds:\n");
    200 //   int l = mindex_length(config->bonds);
    201 //   for(int i = 0 ; i < l ; i++) {
    202 //     struct pmlag_configuration_bond *bond = mindex_nth(config->bonds, i);
    203 //     printf("  - %s\n", bond->name);
    204 //   }
    205 //   printf("\n");
    206 
    207 //   return config;
    208 // }