blob: edad6cd7ccabb62211c55ef4c4acf0db9a3682d4 [file] [log] [blame]
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001/*
2 * config.c - blkid.conf routines
3 *
4 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
5 *
6 * This file may be redistributed under the terms of the
7 * GNU Lesser General Public License.
8 */
9
10#include <stdio.h>
11#include <string.h>
12#include <stdlib.h>
13#include <unistd.h>
14#include <fcntl.h>
15#include <ctype.h>
16#include <sys/types.h>
17#ifdef HAVE_SYS_STAT_H
18#include <sys/stat.h>
19#endif
20#ifdef HAVE_ERRNO_H
21#include <errno.h>
22#endif
23#include <stdint.h>
24#include <stdarg.h>
25
26#include "blkidP.h"
27#include "env.h"
28
29static int parse_evaluate(struct blkid_config *conf, char *s)
30{
31 while(s && *s) {
32 char *sep;
33
34 if (conf->nevals >= __BLKID_EVAL_LAST)
35 goto err;
36 sep = strchr(s, ',');
37 if (sep)
38 *sep = '\0';
39 if (strcmp(s, "udev") == 0)
40 conf->eval[conf->nevals] = BLKID_EVAL_UDEV;
41 else if (strcmp(s, "scan") == 0)
42 conf->eval[conf->nevals] = BLKID_EVAL_SCAN;
43 else
44 goto err;
45 conf->nevals++;
46 if (sep)
47 s = sep + 1;
48 else
49 break;
50 }
51 return 0;
52err:
53 DBG(DEBUG_CONFIG, printf(
54 "config file: unknown evaluation method '%s'.\n", s));
55 return -1;
56}
57
58static int parse_next(FILE *fd, struct blkid_config *conf)
59{
60 char buf[BUFSIZ];
61 char *s;
62
63 /* read the next non-blank non-comment line */
64 do {
65 if (fgets (buf, sizeof(buf), fd) == NULL)
66 return feof(fd) ? 0 : -1;
67 s = strchr (buf, '\n');
68 if (!s) {
69 /* Missing final newline? Otherwise extremely */
70 /* long line - assume file was corrupted */
71 if (feof(fd))
72 s = strchr (buf, '\0');
73 else {
74 DBG(DEBUG_CONFIG, fprintf(stderr,
75 "libblkid: config file: missing newline at line '%s'.\n",
76 buf));
77 return -1;
78 }
79 }
80 *s = '\0';
81 if (--s >= buf && *s == '\r')
82 *s = '\0';
83
84 s = buf;
85 while (*s == ' ' || *s == '\t') /* skip space */
86 s++;
87
88 } while (*s == '\0' || *s == '#');
89
90 if (!strncmp(s, "SEND_UEVENT=", 12)) {
91 s += 13;
92 if (*s && !strcasecmp(s, "yes"))
93 conf->uevent = TRUE;
94 else if (*s)
95 conf->uevent = FALSE;
96 } else if (!strncmp(s, "CACHE_FILE=", 11)) {
97 s += 11;
98 if (*s)
99 conf->cachefile = strdup(s);
100 } else if (!strncmp(s, "EVALUATE=", 9)) {
101 s += 9;
102 if (*s && parse_evaluate(conf, s) == -1)
103 return -1;
104 } else {
105 DBG(DEBUG_CONFIG, printf(
106 "config file: unknown option '%s'.\n", s));
107 return -1;
108 }
109 return 0;
110}
111
112/* return real config data or built-in default */
113struct blkid_config *blkid_read_config(const char *filename)
114{
115 struct blkid_config *conf;
116 FILE *f;
117
118 if (!filename)
119 filename = safe_getenv("BLKID_CONF");
120 if (!filename)
121 filename = BLKID_CONFIG_FILE;
122
123 conf = (struct blkid_config *) calloc(1, sizeof(*conf));
124 if (!conf)
125 return NULL;
126 conf->uevent = -1;
127
128 DBG(DEBUG_CONFIG, fprintf(stderr,
129 "reading config file: %s.\n", filename));
130
131 f = fopen(filename, "r");
132 if (!f) {
133 DBG(DEBUG_CONFIG, fprintf(stderr,
134 "%s: does not exist, using built-in default\n", filename));
135 goto dflt;
136 }
137 while (!feof(f)) {
138 if (parse_next(f, conf)) {
139 DBG(DEBUG_CONFIG, fprintf(stderr,
140 "%s: parse error\n", filename));
141 goto err;
142 }
143 }
144dflt:
145 if (!conf->nevals) {
146 conf->eval[0] = BLKID_EVAL_UDEV;
147 conf->eval[1] = BLKID_EVAL_SCAN;
148 conf->nevals = 2;
149 }
150 if (!conf->cachefile)
151 conf->cachefile = strdup(BLKID_CACHE_FILE);
152 if (conf->uevent == -1)
153 conf->uevent = TRUE;
154 if (f)
155 fclose(f);
156 return conf;
157err:
158 free(conf);
159 fclose(f);
160 return NULL;
161}
162
163void blkid_free_config(struct blkid_config *conf)
164{
165 if (!conf)
166 return;
167 free(conf->cachefile);
168 free(conf);
169}
170
171#ifdef TEST_PROGRAM
172/*
173 * usage: tst_config [<filename>]
174 */
175int main(int argc, char *argv[])
176{
177 int i;
178 struct blkid_config *conf;
179 char *filename = NULL;
180
181 blkid_init_debug(DEBUG_ALL);
182
183 if (argc == 2)
184 filename = argv[1];
185
186 conf = blkid_read_config(filename);
187 if (!conf)
188 return EXIT_FAILURE;
189
190 printf("EVALUATE: ");
191 for (i = 0; i < conf->nevals; i++)
192 printf("%s ", conf->eval[i] == BLKID_EVAL_UDEV ? "udev" : "scan");
193 printf("\n");
194
195 printf("SEND UEVENT: %s\n", conf->uevent ? "TRUE" : "FALSE");
196 printf("CACHE_FILE: %s\n", conf->cachefile);
197
198 blkid_free_config(conf);
199 return EXIT_SUCCESS;
200}
201#endif