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 // }