pmlag

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

config.c (6156B)


      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.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         break;
     74       }
     75     }
     76 
     77     if (i == handler_count) {
     78       // Here = not found
     79       fprintf(stderr, "Unknown directive: %s\n", dir->name);
     80       return CFG_RET_ERROR;
     81     }
     82   }
     83 
     84   // Cleanup here
     85   if (dir) cnf_directive_free(dir);
     86 
     87   return CFG_RET_OK;
     88 }
     89 
     90 // #include <stdio.h>
     91 // #include <stdlib.h>
     92 // #include <string.h>
     93 
     94 // #include "config.h"
     95 
     96 // #include "benhoyt/inih.h"
     97 // #include "finwo/mindex.h"
     98 
     99 // int mindex_bond_cmp(const void *a, const void *b, void *udata) {
    100 //   (void)udata;
    101 //   const struct pmlag_configuration_bond *_a = a;
    102 //   const struct pmlag_configuration_bond *_b = b;
    103 //   return strcmp(_a->name, _b->name);
    104 // }
    105 
    106 // void mindex_bond_purge(void *item, void *udata) {
    107 //   struct pmlag_configuration_bond *bond = item;
    108 //   (void)udata;
    109 //   if (!item) return;
    110 //   if (bond->name) free(bond->name);
    111 // }
    112 
    113 // #ifndef MIN
    114 // #define MIN(a,b) ((a)<(b)?(a):(b))
    115 // #endif
    116 
    117 // static int config_load_handler(
    118 //   void *user,
    119 //   const char *section,
    120 //   const char *name,
    121 //   const char *value
    122 // ) {
    123 //   // struct pmlag_bond  *bond  = NULL;
    124 //   // struct pmlag_iface *iface = NULL;
    125 //   // int bond_index = 0;
    126 //   // int iface_index = 0;
    127 //   struct pmlag_configuration* config = (struct pmlag_configuration *) user;
    128 
    129 //   // Detect invalid entries
    130 //   int i, l;
    131 //   for( i = 0, l = strlen(name) ; i < l ; i++ ) {
    132 //     if (name[i] == 0x5F                   ) continue; // '_'
    133 //     if (name[i] >= 0x30 && name[i] <= 0x39) continue; // 0-9
    134 //     if (name[i] >= 0x41 && name[i] <= 0x5A) continue; // A-Z
    135 //     if (name[i] >= 0x61 && name[i] <= 0x7A) continue; // a-z
    136 //     return 0; // Reject
    137 //   }
    138 
    139 //   // Strip # comments from values
    140 //   char *found_comment = strstr(value, "#");
    141 //   if (found_comment) {
    142 //     for(; found_comment > (value + 1) ;) {
    143 //       if ( *(found_comment) >= 0x21 && *(found_comment-1) <= 0x7E ) break;
    144 //       found_comment--;
    145 //     }
    146 //     *found_comment = 0x00;
    147 //   }
    148 
    149 //   // Find or create bond
    150 //   struct pmlag_configuration_bond *config_bond = mindex_get(config->bonds, (&(struct pmlag_configuration_bond){ .name = (char *)section }));
    151 //   if (!config_bond) {
    152 //     config_bond = calloc(1, sizeof(struct pmlag_configuration_bond));
    153 //     config_bond->name = strdup(section);
    154 //     mindex_set(config->bonds, config_bond);
    155 //   }
    156 
    157 //   // // Find the bond
    158 //   // struct pmlag_configuration_bond *config_bond = NULL;
    159 //   // for( i = 0 ; i < config->bond_len ; i++ ) {
    160 //   //   if (!strcmp(config->bonds[i].name, section)) {
    161 //   //     config_bond = &(config->bonds[i]);
    162 //   //     break;
    163 //   //   }
    164 //   // }
    165 //   // printf("%s:%d\n", __FILE__, __LINE__);
    166 //   // // Build new bond if missing
    167 //   // if (!config_bond) {
    168 //   //   // Expand array size if needed
    169 //   //   if ((config->bond_len+1) > config->bond_cap) {
    170 //   //     config->bond_cap = MIN(1, config->bond_cap*2);
    171 //   //     config->bonds = realloc(config->bonds, config->bond_cap * sizeof(struct pmlag_configuration_bond));
    172 //   //   }
    173 //   //   // Append new entry to list
    174 //   //   memset(&(config->bonds[config->bond_len]), 0, sizeof(struct pmlag_configuration_bond));
    175 //   //   config_bond = &(config->bonds[config->bond_len]);
    176 //   //   config->bond_len++;
    177 //   // }
    178 
    179 //   // Detect # comments and remove them
    180 
    181 //   return 1;
    182 // }
    183 
    184 // struct pmlag_configuration * config_load(char * filepath, struct pmlag_configuration *config) {
    185 //   // Load config, entry-by-entry
    186 //   if (!config) {
    187 //     config = calloc(1, sizeof(struct pmlag_configuration));
    188 //   }
    189 //   if (!config->bonds) {
    190 //     config->bonds = mindex_init(mindex_bond_cmp, mindex_bond_purge, NULL);
    191 //   }
    192 
    193 //   if (ini_parse(filepath, config_load_handler, config) < 0) {
    194 //     fprintf(stderr, "Can not load %s\n", filepath);
    195 //     return NULL;
    196 //   }
    197 
    198 //   printf("bond_len: %ld\n", mindex_length(config->bonds));
    199 //   printf("\n");
    200 //   printf("bonds:\n");
    201 //   int l = mindex_length(config->bonds);
    202 //   for(int i = 0 ; i < l ; i++) {
    203 //     struct pmlag_configuration_bond *bond = mindex_nth(config->bonds, i);
    204 //     printf("  - %s\n", bond->name);
    205 //   }
    206 //   printf("\n");
    207 
    208 //   return config;
    209 // }