[libmultipath] fix regfree fix in config.c:find_hwe()
[platform/upstream/multipath-tools.git] / libmultipath / config.c
1 #include <stdio.h>
2 #include <string.h>
3
4 #include "regex.h"
5 #include "memory.h"
6 #include "util.h"
7 #include "debug.h"
8 #include "parser.h"
9 #include "dict.h"
10 #include "hwtable.h"
11 #include "vector.h"
12 #include "blacklist.h"
13 #include "defaults.h"
14 #include "config.h"
15
16 #include "../libcheckers/checkers.h"
17
18 struct hwentry *
19 find_hwe (vector hwtable, char * vendor, char * product)
20 {
21         int i;
22         struct hwentry *hwe, *ret = NULL;
23         regex_t vre, pre;
24
25         vector_foreach_slot (hwtable, hwe, i) {
26                 if (regcomp(&vre, hwe->vendor, REG_EXTENDED|REG_NOSUB))
27                         break;
28                 if (regcomp(&pre, hwe->product, REG_EXTENDED|REG_NOSUB)) {
29                         regfree(&vre);
30                         break;
31                 }
32                 if (!regexec(&vre, vendor, 0, NULL, 0) &&
33                     !regexec(&pre, product, 0, NULL, 0))
34                         ret = hwe;
35                 
36                 regfree(&pre);
37                 regfree(&vre);
38
39                 if (ret)
40                         break;
41         }
42         return ret;
43 }
44
45 extern struct mpentry *
46 find_mpe (char * wwid)
47 {
48         int i;
49         struct mpentry * mpe;
50
51         if (!wwid)
52                 return NULL;
53
54         vector_foreach_slot (conf->mptable, mpe, i)
55                 if (mpe->wwid && !strcmp(mpe->wwid, wwid))
56                         return mpe;
57
58         return NULL;
59 }
60
61 extern char *
62 get_mpe_wwid (char * alias)
63 {
64         int i;
65         struct mpentry * mpe;
66
67         if (!alias)
68                 return NULL;
69
70         vector_foreach_slot (conf->mptable, mpe, i)
71                 if (mpe->alias && strcmp(mpe->alias, alias) == 0)
72                         return mpe->wwid;
73
74         return NULL;
75 }
76
77 void
78 free_hwe (struct hwentry * hwe)
79 {
80         if (!hwe)
81                 return;
82
83         if (hwe->vendor)
84                 FREE(hwe->vendor);
85
86         if (hwe->product)
87                 FREE(hwe->product);
88
89         if (hwe->selector)
90                 FREE(hwe->selector);
91
92         if (hwe->getuid)
93                 FREE(hwe->getuid);
94
95         if (hwe->getprio)
96                 FREE(hwe->getprio);
97
98         if (hwe->features)
99                 FREE(hwe->features);
100
101         if (hwe->hwhandler)
102                 FREE(hwe->hwhandler);
103
104         FREE(hwe);
105 }
106
107 void
108 free_hwtable (vector hwtable)
109 {
110         int i;
111         struct hwentry * hwe;
112
113         if (!hwtable)
114                 return;
115
116         vector_foreach_slot (hwtable, hwe, i)
117                 free_hwe(hwe);
118
119         vector_free(hwtable);
120 }
121
122 void
123 free_mpe (struct mpentry * mpe)
124 {
125         if (!mpe)
126                 return;
127
128         if (mpe->wwid)
129                 FREE(mpe->wwid);
130
131         if (mpe->selector)
132                 FREE(mpe->selector);
133
134         if (mpe->getuid)
135                 FREE(mpe->getuid);
136
137         if (mpe->alias)
138                 FREE(mpe->alias);
139
140         FREE(mpe);
141 }
142
143 void
144 free_mptable (vector mptable)
145 {
146         int i;
147         struct mpentry * mpe;
148
149         if (!mptable)
150                 return;
151
152         vector_foreach_slot (mptable, mpe, i)
153                 free_mpe(mpe);
154
155         vector_free(mptable);
156 }
157
158 struct mpentry *
159 alloc_mpe (void)
160 {
161         struct mpentry * mpe = (struct mpentry *)
162                                 MALLOC(sizeof(struct mpentry));
163
164         return mpe;
165 }
166
167 static struct hwentry *
168 alloc_hwe (void)
169 {
170         struct hwentry * hwe = (struct hwentry *)
171                                 MALLOC(sizeof(struct hwentry));
172
173         return hwe;
174 }
175
176 static char *
177 set_param_str(char * str)
178 {
179         char * dst;
180         int len;
181
182         if (!str)
183                 return NULL;
184
185         len = strlen(str);
186
187         if (!len)
188                 return NULL;
189
190         dst = (char *)MALLOC(len + 1);
191
192         if (!dst)
193                 return NULL;
194
195         strcpy(dst, str);
196         return dst;
197 }
198
199 static int
200 dup_hwe (vector hwtable, char * vendor, char * product)
201 {
202         struct hwentry * hwe = find_hwe(hwtable, vendor, product);
203
204         if (hwe)
205                 return 1;
206
207         return 0;
208 }
209
210 int
211 store_hwe (vector hwtable, char * vendor, char * product, int pgp,
212            char * getuid)
213 {
214         struct hwentry * hwe;
215
216         if (dup_hwe(hwtable, vendor, product))
217                 return 0;
218
219         hwe = alloc_hwe();
220
221         if (!hwe)
222                 return 1;
223
224         hwe->vendor = set_param_str(vendor);
225
226         if (!hwe->vendor)
227                 goto out;
228         
229         hwe->product = set_param_str(product);
230
231         if (!hwe->product)
232                 goto out;
233         
234         if (pgp)
235                 hwe->pgpolicy = pgp;
236
237         if (getuid)
238                 hwe->getuid = set_param_str(getuid);
239         else
240                 hwe->getuid = set_default(DEFAULT_GETUID);
241
242         if (!hwe->getuid)
243                 goto out;
244         
245         if (!vector_alloc_slot(hwtable))
246                 goto out;
247
248         vector_set_slot(hwtable, hwe);
249         return 0;
250 out:
251         free_hwe(hwe);
252         return 1;
253 }
254
255 int
256 store_hwe_ext (vector hwtable, char * vendor, char * product, int pgp,
257            char * getuid, char * getprio, char * hwhandler,
258            char * features, char * checker, int pgfailback)
259 {
260         struct hwentry * hwe;
261
262         if (dup_hwe(hwtable, vendor, product))
263                 return 0;
264         
265         hwe = alloc_hwe();
266
267         if (!hwe)
268                 return 1;
269
270         hwe->vendor = set_param_str(vendor);
271
272         if (!hwe->vendor)
273                 goto out;
274         
275         hwe->product = set_param_str(product);
276
277         if (!hwe->product)
278                 goto out;
279         
280         if (pgp)
281                 hwe->pgpolicy = pgp;
282
283         if (getuid)
284                 hwe->getuid = set_param_str(getuid);
285         else
286                 hwe->getuid = set_default(DEFAULT_GETUID);
287
288         if (!hwe->getuid)
289                 goto out;
290         
291         if (getprio)
292                 hwe->getprio = set_param_str(getprio);
293         else
294                 hwe->getprio = NULL;
295
296         if (hwhandler)  
297                 hwe->hwhandler = set_param_str(hwhandler);
298         else
299                 hwe->hwhandler = set_default(DEFAULT_HWHANDLER);
300
301         if (!hwe->hwhandler)
302                 goto out;
303
304         if (features)
305                 hwe->features = set_param_str(features);
306         else
307                 hwe->features = set_default(DEFAULT_FEATURES);
308
309         if (!hwe->features)
310                 goto out;
311
312         if (checker)
313                 hwe->checker_index = get_checker_id(checker);
314         else
315                 hwe->checker_index = get_checker_id(DEFAULT_CHECKER);
316
317         hwe->pgfailback = pgfailback;
318
319         if (!vector_alloc_slot(hwtable))
320                 goto out;
321
322         vector_set_slot(hwtable, hwe);
323         return 0;
324 out:
325         free_hwe(hwe);
326         return 1;
327 }
328
329 struct config *
330 alloc_config (void)
331 {
332         return (struct config *)MALLOC(sizeof(struct config));
333 }
334
335 void
336 free_config (struct config * conf)
337 {
338         if (!conf)
339                 return;
340
341         if (conf->dev)
342                 FREE(conf->dev);
343
344         if (conf->udev_dir)
345                 FREE(conf->udev_dir);
346
347         if (conf->selector)
348                 FREE(conf->selector);
349
350         if (conf->default_getuid)
351                 FREE(conf->default_getuid);
352
353         if (conf->default_getprio)
354                 FREE(conf->default_getprio);
355
356         if (conf->features)
357                 FREE(conf->features);
358
359         if (conf->default_hwhandler)
360                 FREE(conf->default_hwhandler);
361
362         free_blacklist(conf->blist);
363         free_mptable(conf->mptable);
364         free_hwtable(conf->hwtable);
365
366         FREE(conf);
367 }
368
369 int
370 load_config (char * file)
371 {
372         if (!conf)
373                 conf = alloc_config();
374
375         if (!conf)
376                 return 1;
377
378         /*
379          * internal defaults
380          */
381         if (!conf->verbosity)
382                 conf->verbosity = 2;
383
384         conf->dev_type = DEV_NONE;
385         conf->minio = 1000;
386         conf->bindings_file = DEFAULT_BINDINGS_FILE;
387
388         /*
389          * read the config file
390          */
391         if (filepresent(file)) {
392                 if (init_data(file, init_keywords)) {
393                         condlog(0, "error parsing config file");
394                         goto out;
395                 }
396         }
397         
398         /*
399          * fill the voids left in the config file
400          */
401         if (conf->hwtable == NULL) {
402                 conf->hwtable = vector_alloc();
403                 
404                 if (!conf->hwtable)
405                         goto out;
406                 
407         }
408         if (setup_default_hwtable(conf->hwtable))
409                 goto out;
410
411         if (conf->blist == NULL) {
412                 conf->blist = vector_alloc();
413                 
414                 if (!conf->blist)
415                         goto out;
416                 
417                 if (setup_default_blist(conf->blist))
418                         goto out;
419         }
420         if (conf->mptable == NULL) {
421                 conf->mptable = vector_alloc();
422
423                 if (!conf->mptable)
424                         goto out;
425         }
426         if (conf->selector == NULL)
427                 conf->selector = set_default(DEFAULT_SELECTOR);
428
429         if (conf->udev_dir == NULL)
430                 conf->udev_dir = set_default(DEFAULT_UDEVDIR);
431
432         if (conf->default_getuid == NULL)
433                 conf->default_getuid = set_default(DEFAULT_GETUID);
434
435         if (conf->features == NULL)
436                 conf->features = set_default(DEFAULT_FEATURES);
437
438         if (conf->default_hwhandler == NULL)
439                 conf->default_hwhandler = set_default(DEFAULT_HWHANDLER);
440
441         if (!conf->selector  || !conf->udev_dir         ||
442             !conf->default_getuid    || !conf->features ||
443             !conf->default_hwhandler)
444                 goto out;
445
446         if (!conf->default_checker_index)
447                 conf->default_checker_index = READSECTOR0;
448
449         return 0;
450 out:
451         free_config(conf);
452         return 1;
453 }
454