]> git.ipfire.org Git - thirdparty/util-linux.git/blob - libblkid/src/config.c
110251a92f36c5e2fdb71ddb95c607895ca65d52
[thirdparty/util-linux.git] / libblkid / src / config.c
1 /*
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
29 static 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;
52 err:
53 DBG(DEBUG_CONFIG, printf(
54 "config file: unknown evaluation method '%s'.\n", s));
55 return -1;
56 }
57
58 static 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 = blkid_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 */
113 struct 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 }
144 dflt:
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 = blkid_strdup(BLKID_CACHE_FILE);
152 if (conf->uevent == -1)
153 conf->uevent = TRUE;
154 if (f)
155 fclose(f);
156 return conf;
157 err:
158 free(conf);
159 fclose(f);
160 return NULL;
161 }
162
163 void 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 */
175 int 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