"Fossies" - the Fresh Open Source Software Archive 
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 #include "conf.h"
2 #include "connection.h"
3 #include "xlib.h"
4 #include "defaults.h"
5 #include "dir.h"
6
7 #include <stdio.h>
8
9 unsigned long poll_frequency = DEFAULT_POLL_FREQUENCY;
10
11 static const char *conf_base = "/";
12
13 void conf_set_base(const char* s) {
14 conf_base = xstrdup(s);
15 }
16
17 static void parse_error(const char* s1, const char *s2, const char *s3) {
18 xerror("%s%s%s%s%s",
19 s1,
20 (s2 ? ": " : ""), (s2 ? s2 : ""),
21 (s3 ? ": " : ""), (s3 ? s3 : "")
22 );
23 }
24
25 static char *slurp_data_string(FILE *f) {
26 int used = 0;
27 int avail = 64;
28 char *ret;
29
30 ret = xmalloc(avail);
31
32 for(;;) {
33 int ch;
34
35 if(used == avail) {
36 avail *= 2;
37 ret = xrealloc(ret, avail);
38 }
39
40 ch = getc(f);
41 if(ch == EOF) {
42 ret[used] = '\0';
43 return ret;
44 }
45
46 ret[used++] = ch;
47 }
48 }
49
50 static char *read_data_string(const char *name) {
51 FILE *f;
52 char *ret;
53
54 f = fopen(name, "r");
55 if(!f)
56 return NULL;
57
58 ret = slurp_data_string(f);
59
60 if(ferror(f)) {
61 fclose(f);
62 return NULL;
63 }
64
65 fclose(f);
66 return ret;
67 }
68
69 static int conf_add_update(Connection *c, const char *s) {
70 const Action *a;
71
72 if(c->nupdates == MAX_CONNECTION_UPDATES) {
73 parse_error(c->name,"too many update actions",0);
74 return -1;
75 }
76
77 a = action_find(s);
78 if(!a) {
79 parse_error(c->name,"no such action",s);
80 return -1;
81 }
82
83 c->updates[c->nupdates++] = a;
84 return 0;
85 }
86
87 static int conf_add_reset(Connection *c, const char *s) {
88 const Action *a;
89
90 if(c->nresets == MAX_CONNECTION_RESETS) {
91 parse_error(c->name,"too many reset actions",0);
92 return -1;
93 }
94
95 a = action_find(s);
96 if(!a) {
97 parse_error(c->name,"no such action",s);
98 return -1;
99 }
100
101 c->resets[c->nresets++] = a;
102 return 0;
103 }
104
105 static int conf_add_folder(Connection *c, const char *s) {
106 if(c->nfolders == MAX_CONNECTION_FOLDERS) {
107 parse_error(c->name,"too many folders",0);
108 return -1;
109 }
110
111 c->folders[c->nfolders].name = xstrdup(s);
112 c->folders[c->nfolders].biffed = 0;
113 c->nfolders++;
114 return 0;
115 }
116
117 static int conf_add_action(const char *rel, const char *full) {
118 char *cmd;
119
120 cmd = read_data_string(full);
121 if(!cmd) {
122 parse_error(full,"unable to read data",xsyserr());
123 return -1;
124 }
125
126 action_add(ActionShell, rel, cmd);
127
128 free(cmd);
129 return 0;
130 }
131
132 static int read_data_list(const char* name,
133 int (*cb)(Connection *,const char *), Connection *conn) {
134 FILE *f;
135 char buf[4096];
136
137 f = fopen(name, "r");
138 if(!f)
139 return -1;
140
141 while(fgets(buf, sizeof(buf), f)) {
142 xchomp(buf);
143 if(cb(conn, buf) < 0) {
144 fclose(f);
145 return -1;
146 }
147 }
148
149 fclose(f);
150 return 0;
151 }
152
153 static int conf_add_connection(const char *rel, const char *full) {
154 char buf[PATH_MAX];
155 Connection *c;
156
157 c = connections + nconnections;
158 connection_init(c);
159 c->name = xstrdup(rel);
160
161 make_path(buf, full, "command");
162 c->command = read_data_string(buf);
163 if(!c->command) {
164 parse_error(buf,"cannot read command data",xsyserr());
165 return -1;
166 }
167
168 make_path(buf, full, "update");
169 if(read_data_list(buf, conf_add_update, c) < 0) {
170 parse_error(buf,"unable to read update data",xsyserr());
171 return -1;
172 }
173
174 make_path(buf, full, "reset");
175 if(read_data_list(buf, conf_add_reset, c) < 0) {
176 parse_error(buf,"unable to read reset data",xsyserr());
177 return -1;
178 }
179
180 make_path(buf, full, "folders");
181 if(read_data_list(buf, conf_add_folder, c) < 0) {
182 parse_error(buf,"unable to read folder data",xsyserr());
183 return -1;
184 }
185
186 make_path(buf, full, "secret");
187 if(!dir_is_protected(buf)) {
188 parse_error(buf,"\"secret\" directory has loose permissions",0);
189 return -1;
190 }
191
192 nconnections++;
193 return 0;
194 }
195
196 static int
197 conf_dir_foreach(const char *s, int (*cb)(const char *, const char *)) {
198 int e;
199 e = dir_foreach(s, cb);
200 if(e < 0) {
201 parse_error(s,"unable to open directory",xsyserr());
202 return -1;
203 }
204 else if(e > 0)
205 return -1;
206 else
207 return 0;
208 }
209
210 int conf_read_actions(void) {
211 char buf[PATH_MAX];
212 make_path(buf, conf_base, "actions");
213 return conf_dir_foreach(buf, conf_add_action);
214 }
215
216 int conf_read_connections(void) {
217 char buf[PATH_MAX];
218 make_path(buf, conf_base, "connections");
219 return conf_dir_foreach(buf, conf_add_connection);
220 }
221
222 int conf_read_options(void) {
223 char buf[PATH_MAX];
224 char *data;
225
226 make_path(buf, conf_base, "frequency");
227 data = read_data_string(buf);
228 if(data) {
229 poll_frequency = atoi(data);
230 free(data);
231 }
232
233 return 0;
234 }
235
236 static void strip_newlines(char *in) {
237 char *out;
238
239 out = in;
240 for(;;) {
241 switch(*in) {
242 case '\0':
243 *out = *in;
244 return;
245 case '\n':
246 in++;
247 break;
248 default:
249 *out++ = *in++;
250 break;
251 }
252 }
253 }
254
255 char *conf_read_data(const char *tag, const char *item) {
256 char buf[PATH_MAX];
257 char *d;
258
259 make_path(buf, conf_base, "connections");
260 make_path(buf, buf, tag);
261 make_path(buf, buf, item);
262
263 d = read_data_string(buf);
264 if(d)
265 strip_newlines(d);
266
267 return d;
268 }