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