/[public]/psiconv/trunk/lib/psiconv/configuration.c
ViewVC logotype

Diff of /psiconv/trunk/lib/psiconv/configuration.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 176 Revision 180
18*/ 18*/
19 19
20#include "config.h" 20#include "config.h"
21#include "error.h" 21#include "error.h"
22#include "compat.h" 22#include "compat.h"
23
23#include <stdio.h> 24#include <stdio.h>
24#include <stdlib.h> 25#include <stdlib.h>
25#include <string.h> 26#include <string.h>
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <unistd.h>
30#include <fcntl.h>
26 31
27#include "configuration.h" 32#include "configuration.h"
28 33
29#ifdef DMALLOC 34#ifdef DMALLOC
30#include <dmalloc.h> 35#include <dmalloc.h>
31#endif 36#endif
32 37
33#ifndef CONFIGURATION_SEARCH_PATH 38#ifndef CONFIGURATION_SEARCH_PATH
34#define CONFIGURATION_SEARCH_PATH "/etc/psiconv.conf:~/.psiconv.conf" 39#define CONFIGURATION_SEARCH_PATH "/etc/psiconv.conf:~/.psiconv.conf"
35#endif 40#endif
36struct psiconv_config_s default_config = 41static struct psiconv_config_s default_config =
37 { PSICONV_VERB_WARN, 2, 0,0,0,psiconv_bool_false,NULL }; 42 { PSICONV_VERB_WARN, 2, 0,0,0,psiconv_bool_false,NULL };
38 43
39psiconv_config psiconv_config_read(const char *extra_config_file) 44static void psiconv_config_parse_statement(const char *filename,
45 int linenr,
46 const char *var, int value,
47 psiconv_config *config);
48
49static void psiconv_config_parse_line(const char *filename, int linenr,
50 const char *line, psiconv_config *config);
51
52static void psiconv_config_parse_file(const char *filename,
53 psiconv_config *config);
54
55psiconv_config psiconv_config_default(void)
40{ 56{
41 psiconv_config config; 57 psiconv_config result;
42 if (!(config = malloc(sizeof(*config)))) 58 result = malloc(sizeof(*result));
59 *result = default_config;
60 return result;
61}
62
63void psiconv_config_parse_statement(const char *filename,
64 int linenr,
65 const char *var, int value,
66 psiconv_config *config)
67{
68 if (!(strcasecmp(var,"verbosity"))) {
69 if ((value >= 1) && (value <= 4))
70 (*config)->verbosity = value;
71 else
72 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: "
73 "Verbosity should be between 1 and 4",filename,linenr);
74 } else if (!(strcasecmp(var,"color"))) {
75 if ((value == 0) || (value == 1))
76 (*config)->color = value;
77 else
78 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: "
79 "Color should be 0 or 1",filename,linenr);
80 } else if (!(strcasecmp(var,"colordepth"))) {
81 if ((value > 0) && (value <= 32))
82 (*config)->colordepth = value;
83 else
84 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: "
85 "ColorDepth should be between 1 and 32",filename,linenr);
86 } else if (!(strcasecmp(var,"redbits"))) {
87 if ((value >= 0) && (value <= 32))
88 (*config)->redbits = value;
89 else
90 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: "
91 "RedBits should be between 1 and 32 or 0",filename,linenr);
92 } else if (!(strcasecmp(var,"greenbits"))) {
93 if ((value >= 0) && (value <= 32))
94 (*config)->greenbits = value;
95 else
96 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: "
97 "GreenBits should be between 1 and 32 or 0",filename,linenr);
98 } else if (!(strcasecmp(var,"bluebits"))) {
99 if ((value >= 0) && (value <= 32))
100 (*config)->bluebits = value;
101 else
102 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: "
103 "BlueBits should be between 1 and 32 or 0",filename,linenr);
104 } else {
105 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: "
106 "Unknown variable %s",filename,linenr,var);
107 }
108 psiconv_debug(*config,0,0,"Configuration file %s, line %d: "
109 "Set variable %s to %d",filename,linenr,var,value);
110}
111
112
113void psiconv_config_parse_line(const char *filename, int linenr,
114 const char *line, psiconv_config *config)
115{
116
117 int sovar,eovar,soval,eoval,eol;
118 char *var;
119 long val;
120
121 psiconv_debug(*config,0,0,"Going to parse line %d: %s",linenr,line);
122 sovar = 0;
123 while (line[sovar] && (line[sovar] < 32))
124 sovar ++;
125 if (!line[sovar] || line[sovar] == '#')
43 return NULL; 126 return;
44 memcpy(config,&default_config,sizeof(*config)); 127 eovar = sovar;
45 return config; 128 while (line[eovar] && (((line[eovar] >= 'A') && (line[eovar] <= 'Z')) ||
46} 129 ((line[eovar] >= 'a') && (line[eovar] <= 'z'))))
130 eovar ++;
131 if (sovar == eovar)
132 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: "
133 "Syntax error (no variable found)",filename,linenr);
134 soval = eovar;
135 while (line[soval] && (line[soval] <= 32))
136 soval ++;
137 if (line[soval] != '=')
138 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: "
139 "Syntax error (no = token found)",filename,linenr);
140 soval ++;
141 while (line[soval] && (line[soval] <= 32))
142 soval ++;
143 eoval = soval;
144 while (line[eoval] && ((line[eoval] >= '0') && (line[eovar] <= '9')))
145 eoval ++;
146 if (eoval == soval)
147 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: "
148 "Syntax error (no value found)",filename,linenr);
149 if (soval - eoval > 7)
150 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: "
151 "Syntax error (value too large)",filename,linenr);
152 eol = eoval;
153 while (line[eol] && (line[eol] < 32))
154 eol ++;
155 if (line[eol])
156 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: "
157 "Syntax error (trailing garbage)",filename,linenr);
47 158
48/*TO DO */ 159 var = malloc(eovar - sovar + 1);
160 memcpy(var,line + sovar, eovar - sovar);
161 var[eovar-sovar] = 0;
49 162
50#if 0 163 val = atol(line + soval);
51 164
52/* I hate string manipulation in C */ 165 psiconv_config_parse_statement(filename,linenr,var,val,config);
53psiconv_config_t psiconv_config_read(const char *extra_config_files) 166 free(var);
167}
168
169
170void psiconv_config_parse_file(const char *filename, psiconv_config *config)
54{ 171{
55 psiconv_config_t result = default_config;
56 char *path,pathptr;
57 int file; 172 int file,linenr;
58 struct stat stat_buf; 173 struct stat stat_buf;
174 off_t filesize,bytes_left,bytes_read,sol,eol;
175 char *filebuffer,*filebuffer_ptr;
176
177 psiconv_progress(*config,0,0,
178 "Going to access configuration file %s",filename);
179
180 /* Try to open the file; it may fail, if it does not exist for example */
181 if ((file = open(filename,O_RDONLY)) == -1)
182 return;
183
184 /* Read the contents of the file into filebuffer. This may fail */
185 if (fstat(file,&stat_buf)) {
186 if (close(file))
187 psiconv_fatal(*config,0,0,"Configuration file %s: "
188 "Couldn't close file",filename);
189 return;
190 }
191
192 filesize = stat_buf.st_size;
193 if (!(filebuffer = malloc(filesize + 1)))
194 psiconv_fatal(*config,0,0,"Configuration file %s: "
195 "Out of memory error",filename);
196 filebuffer_ptr = filebuffer;
197 bytes_left = filesize;
198 bytes_read = 1; /* Dummy for the first time through the loop */
199 while ((bytes_read > 0) && bytes_left) {
200 bytes_read = read(file,filebuffer_ptr,bytes_left);
201 if (bytes_read > 0) {
202 filebuffer_ptr += bytes_read;
203 bytes_left -= bytes_read;
204 }
205 }
206
207 /* On NFS, the first read may fail and this is not fatal */
208 if (bytes_left && (bytes_left != filesize)) {
209 psiconv_fatal(*config,0,0,"Configuration file %s: "
210 "Couldn't read file into memory",filename);
211 }
212
213 if (close(file))
214 psiconv_fatal(*config,0,0,"Configuration file %s: "
215 "Couldn't close file",filename);
216
217 psiconv_progress(*config,0,0,
218 "Going to parse configuration file %s: ",filename);
219 /* Now we walk through the file to isolate lines */
220 linenr = 0;
221 sol = 0;
222
223 while (sol < filesize) {
224 linenr ++;
225 eol = sol;
226 while ((eol < filesize) && (filebuffer[eol] != 13) &&
227 (filebuffer[eol] != 10) && (filebuffer[eol] != 0))
228 eol ++;
229
230 if ((eol < filesize) && (filebuffer[eol] == 0))
231 psiconv_fatal(*config,0,0,"Configuration file %s, line %d: "
232 "Unexpected character \000 found",filename,linenr);
233 if ((eol < filesize + 1) &&
234 (((filebuffer[eol] == 13) && (filebuffer[eol+1] == 10)) ||
235 ((filebuffer[eol] == 10) && (filebuffer[eol+1] == 13)))) {
236 filebuffer[eol] = 0;
237 eol ++;
238 }
239 filebuffer[eol] = 0;
240 psiconv_config_parse_line(filename,linenr,filebuffer + sol,config);
241 sol = eol+1;
242 }
243 free(filebuffer);
244}
245
246void psiconv_config_read(const char *extra_config_files,
247 psiconv_config *config)
248{
249 char *path,*pathptr,*filename,*filename_old;
250 const char *home;
251 int filename_len;
59 252
60 /* Make path be the complete search path, colon separated */ 253 /* Make path be the complete search path, colon separated */
61 if (extra_config_files && strlen(extra_config_files)) { 254 if (extra_config_files && strlen(extra_config_files)) {
62 path = malloc(strlen(CONFIGURATION_SEARCH_PATH) + 255 path = malloc(strlen(CONFIGURATION_SEARCH_PATH) +
63 strlen(extra_config_files) + 2); 256 strlen(extra_config_files) + 2);
64 strcpy(path,CONFIGURATION_SEARCH_PATH); 257 strcpy(path,CONFIGURATION_SEARCH_PATH);
65 strcat(path,":"); 258 strcat(path,":");
66 strcat(path,extra_config_files) 259 strcat(path,extra_config_files);
67 } else { 260 } else {
68 path = strdup(CONFIGURATION_SEARCH_PATH) 261 path = strdup(CONFIGURATION_SEARCH_PATH);
69 } 262 }
70 263
71 pathptr = path; 264 pathptr = path;
72 while (strlen(pathptr)) { 265 while (strlen(pathptr)) {
73 /* Isolate the next filename */ 266 /* Isolate the next filename */
74 filename_len = (path - index(':',path)) || strlen(path); 267 filename_len = (index(pathptr,':')?(index(pathptr,':') - pathptr):
268 strlen(pathptr));
75 filename = malloc(filename_len + 1); 269 filename = malloc(filename_len + 1);
76 filename = strncpy(filename,path,filename_len); 270 filename = strncpy(filename,pathptr,filename_len);
77 filename[filename_len + 1] = 0; 271 filename[filename_len] = 0;
78 pathptr += filename_len; 272 pathptr += filename_len;
79 if (strlen(pathptr)) 273 if (strlen(pathptr))
80 pathptr ++; 274 pathptr ++;
81
82 /* Try to open the file; it may fail, if it does not exist for example */
83 if ((file = open(filename,O_RDONLY)) == -1)
84 continue;
85 275
86 /* Read the contents of the file into filebuffer */ 276 /* Do ~ substitution */
87 if (!fstat(file,&stat_buf)) 277 if ((filename[0] == '~') && ((filename[1] == '/') || filename[1] == 0)) {
88 continue; 278 home = getenv("HOME");
89 filesize = stat_buf.off_t; 279 if (home) {
90 filebuffer = malloc(filesize + 1); 280 filename_old = filename;
91 filebuffer_ptr = filebuffer; 281 filename = malloc(strlen(filename_old) + strlen(home));
92 bytes_left = filesize; 282 strcpy(filename,home);
93 bytes_read = 1 /* Dummy for the first time through the loop */ 283 strcpy(filename + strlen(filename),filename_old+1);
94 while ((bytes_read > 0) && bytes_left) { 284 free(filename_old);
95 bytes_read = read(file,filebuffer_ptr,bytes_left);
96 if (bytes_read == -1) {
97 filebuffer_ptr += bytes_read;
98 bytes_left -= bytes_read;
99 } 285 }
100 } 286 }
101 if (bytes_left) 287
102 continue; 288 psiconv_config_parse_file(filename,config);
103 289 free(filename);
104 /* Try to parse the filebuffer */
105 filebuffer_ptr = file_buffer;
106 bytes_left = filesize;
107 while (bytes_left) {
108 /* Parse a line */
109 line_length = index(''
110
111 } 290 }
112} 291}
113
114#endif
115

Legend:
Removed from v.176  
changed lines
  Added in v.180

frodo@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26