]> git.ipfire.org Git - thirdparty/util-linux.git/blob - libblkid/src/config.c
Merge branch 'libuuid-range' of https://github.com/UQ-RCC/util-linux
[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(CONFIG, ul_debug(
54 "config file: unknown evaluation method '%s'.", 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(CONFIG, ul_debug(
75 "config file: missing newline at line '%s'.",
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 += 12;
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(CONFIG, ul_debug(
106 "config file: unknown option '%s'.", 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 = calloc(1, sizeof(*conf));
124 if (!conf)
125 return NULL;
126 conf->uevent = -1;
127
128 DBG(CONFIG, ul_debug("reading config file: %s.", filename));
129
130 f = fopen(filename, "r" UL_CLOEXECSTR);
131 if (!f) {
132 DBG(CONFIG, ul_debug("%s: does not exist, using built-in default", filename));
133 goto dflt;
134 }
135 while (!feof(f)) {
136 if (parse_next(f, conf)) {
137 DBG(CONFIG, ul_debug("%s: parse error", filename));
138 goto err;
139 }
140 }
141 dflt:
142 if (!conf->nevals) {
143 conf->eval[0] = BLKID_EVAL_UDEV;
144 conf->eval[1] = BLKID_EVAL_SCAN;
145 conf->nevals = 2;
146 }
147 if (!conf->cachefile)
148 conf->cachefile = strdup(BLKID_CACHE_FILE);
149 if (conf->uevent == -1)
150 conf->uevent = TRUE;
151 if (f)
152 fclose(f);
153 return conf;
154 err:
155 free(conf);
156 fclose(f);
157 return NULL;
158 }
159
160 void blkid_free_config(struct blkid_config *conf)
161 {
162 if (!conf)
163 return;
164 free(conf->cachefile);
165 free(conf);
166 }
167
168 #ifdef TEST_PROGRAM
169 /*
170 * usage: tst_config [<filename>]
171 */
172 int main(int argc, char *argv[])
173 {
174 int i;
175 struct blkid_config *conf;
176 char *filename = NULL;
177
178 blkid_init_debug(BLKID_DEBUG_ALL);
179
180 if (argc == 2)
181 filename = argv[1];
182
183 conf = blkid_read_config(filename);
184 if (!conf)
185 return EXIT_FAILURE;
186
187 printf("EVALUATE: ");
188 for (i = 0; i < conf->nevals; i++)
189 printf("%s ", conf->eval[i] == BLKID_EVAL_UDEV ? "udev" : "scan");
190 printf("\n");
191
192 printf("SEND UEVENT: %s\n", conf->uevent ? "TRUE" : "FALSE");
193 printf("CACHE_FILE: %s\n", conf->cachefile);
194
195 blkid_free_config(conf);
196 return EXIT_SUCCESS;
197 }
198 #endif