1 #include "compat.h" 2 #include "libconfig.h" 3 #include "libconfig_private.h" 4 #include "conf_section.h" 5 6 #ifdef HAVE_STDIO_H 7 #include <stdio.h> 8 #endif 9 10 #ifdef HAVE_STRING_H 11 #include <string.h> 12 #endif 13 14 int lc_process_conf_section(const char *appname, const char *configfile) { 15 LC_FILE *configfp = NULL; 16 const char *local_lc_errfile; 17 char linebuf[LC_LINEBUF_LEN] = {0}, *linebuf_ptr = NULL; 18 char qualifbuf[LC_LINEBUF_LEN] = {0}; 19 char *cmd = NULL, *value = NULL, *sep = NULL, *cmdend = NULL; 20 char *currsection = NULL; 21 char *fgetsret = NULL; 22 int lcpvret = -1; 23 int invalid_section = 1, ignore_section = 0; 24 int local_lc_errline; 25 int retval = 0; 26 lc_err_t save_lc_errno = LC_ERR_NONE; 27 28 local_lc_errfile = configfile; 29 local_lc_errline = 0; 30 31 if (appname == NULL || configfile == NULL) { 32 lc_errfile = local_lc_errfile; 33 lc_errline = local_lc_errline; 34 lc_errno = LC_ERR_INVDATA; 35 return(-1); 36 } 37 38 configfp = lc_fopen(configfile, "r"); 39 40 if (configfp == NULL) { 41 lc_errfile = local_lc_errfile; 42 lc_errline = local_lc_errline; 43 lc_errno = LC_ERR_CANTOPEN; 44 return(-1); 45 } 46 47 while (1) { 48 fgetsret = lc_fgets(linebuf, sizeof(linebuf) - 1, configfp); 49 if (fgetsret == NULL) { 50 break; 51 } 52 if (lc_feof(configfp)) { 53 break; 54 } 55 56 local_lc_errline++; 57 58 /* Remove trailing crap (but not spaces). */ 59 linebuf_ptr = &linebuf[strlen(linebuf) - 1]; 60 while (*linebuf_ptr < ' ' && linebuf_ptr >= linebuf) { 61 *linebuf_ptr = '\0'; 62 linebuf_ptr--; 63 } 64 65 /* Handle section header. */ 66 if (linebuf[0] == '[' && linebuf[strlen(linebuf) - 1] == ']') { 67 linebuf[strlen(linebuf) - 1] = '\0'; 68 linebuf_ptr = &linebuf[1]; 69 70 /* If a section was open, close it. */ 71 if (currsection != NULL) { 72 lcpvret = lc_process_var(currsection, NULL, NULL, LC_FLAGS_SECTIONEND); 73 if (lcpvret < 0) { 74 #ifdef DEBUG 75 fprintf(stderr, "Invalid section terminating: \"%s\"\n", currsection); 76 #endif 77 } 78 free(currsection); 79 } 80 81 /* Open new section. */ 82 currsection = strdup(linebuf_ptr); 83 lcpvret = lc_process_var(currsection, NULL, NULL, LC_FLAGS_SECTIONSTART); 84 if (lcpvret < 0) { 85 #ifdef DEBUG 86 fprintf(stderr, "Invalid section: \"%s\"\n", currsection); 87 #endif 88 invalid_section = 1; 89 lc_errfile = local_lc_errfile; 90 lc_errline = local_lc_errline; 91 lc_errno = LC_ERR_INVSECTION; 92 retval = -1; 93 } else { 94 invalid_section = 0; 95 ignore_section = 0; 96 } 97 98 if (lcpvret == LC_CBRET_IGNORESECTION) { 99 ignore_section = 1; 100 } 101 continue; 102 } 103 104 /* Remove leading spaces. */ 105 linebuf_ptr = &linebuf[0]; 106 while (*linebuf_ptr == ' ') { 107 linebuf_ptr++; 108 } 109 110 /* Drop comments and blank lines. */ 111 if (*linebuf_ptr == ';' || *linebuf_ptr == '\0') { 112 continue; 113 } 114 115 /* Don't handle things for a section that doesn't exist. */ 116 if (invalid_section == 1) { 117 #ifdef DEBUG 118 fprintf(stderr, "Ignoring line (because invalid section): %s\n", linebuf); 119 #endif 120 continue; 121 } 122 123 /* Don't process commands if this section is specifically ignored. */ 124 if (ignore_section == 1) { 125 #ifdef DEBUG 126 fprintf(stderr, "Ignoring line (because ignored section): %s\n", linebuf); 127 #endif 128 continue; 129 } 130 131 /* Find the command and the data in the line. */ 132 cmdend = sep = strpbrk(linebuf_ptr, "="); 133 if (sep == NULL) { 134 #ifdef DEBUG 135 fprintf(stderr, "Invalid line: \"%s\"\n", linebuf); 136 #endif 137 continue; 138 } 139 140 /* Delete space at the end of the command. */ 141 cmdend--; /* It currently derefs to the seperator.. */ 142 while (*cmdend <= ' ' && cmdend >= sep) { 143 *cmdend = '\0'; 144 cmdend--; 145 } 146 147 cmd = linebuf_ptr; 148 149 /* Delete the seperator char and any leading space. */ 150 *sep = '\0'; 151 sep++; 152 while (*sep == ' ' || *sep == '\t') { 153 sep++; 154 } 155 value = sep; 156 157 /* Create the fully qualified variable name. */ 158 if (currsection == NULL) { 159 strncpy(qualifbuf, cmd, sizeof(qualifbuf) - 1); 160 } else { 161 snprintf(qualifbuf, sizeof(qualifbuf) - 1, "%s.%s", currsection, cmd); 162 } 163 164 /* Call the parent and tell them we have data. */ 165 save_lc_errno = lc_errno; 166 lc_errno = LC_ERR_NONE; 167 lcpvret = lc_process_var(qualifbuf, NULL, value, LC_FLAGS_VAR); 168 if (lcpvret < 0) { 169 if (lc_errno == LC_ERR_NONE) { 170 #ifdef DEBUG 171 fprintf(stderr, "Invalid command: \"%s\"\n", cmd); 172 #endif 173 lc_errno = LC_ERR_INVCMD; 174 } else { 175 #ifdef DEBUG 176 fprintf(stderr, "Error processing command (command was valid, but an error occured, errno was set)\n"); 177 #endif 178 } 179 lc_errfile = local_lc_errfile; 180 lc_errline = local_lc_errline; 181 retval = -1; 182 } else { 183 lc_errno = save_lc_errno; 184 } 185 } 186 187 /* Close any open section, and clean-up. */ 188 if (currsection != NULL) { 189 lcpvret = lc_process_var(currsection, NULL, NULL, LC_FLAGS_SECTIONEND); 190 if (lcpvret < 0) { 191 #ifdef DEBUG 192 fprintf(stderr, "Invalid section terminating: \"%s\"\n", currsection); 193 #endif 194 } 195 free(currsection); 196 } 197 198 lc_fclose(configfp); 199 200 return(retval); 201 } |