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