1 /*
2  * Copyright (c) 2011 Tim van der Molen <tim@kariliq.nl>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /* For FreeBSD. */
18 #define _WITH_GETLINE
19 
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 
28 #include "siren.h"
29 
30 static char *conf_dir;
31 
32 void
33 conf_end(void)
34 {
35 	free(conf_dir);
36 }
37 
38 void
39 conf_init(const char *dir)
40 {
41 	char *home;
42 
43 	if (dir != NULL)
44 		conf_dir = path_normalise(dir);
45 	else {
46 		if ((home = path_get_home_dir(NULL)) == NULL)
47 			xasprintf(&conf_dir, "/%s", CONF_DIR);
48 		else {
49 			xasprintf(&conf_dir, "%s/%s", home, CONF_DIR);
50 			free(home);
51 		}
52 	}
53 
54 	if (mkdir(conf_dir, S_IRWXU | S_IRWXG | S_IRWXO) == -1 &&
55 	    errno != EEXIST) {
56 		LOG_ERR("mkdir: %s", conf_dir);
57 		msg_err("Cannot create configuration directory: %s", conf_dir);
58 	}
59 }
60 
61 char *
62 conf_get_path(const char *file)
63 {
64 	char *path;
65 
66 	xasprintf(&path, "%s/%s", conf_dir, file);
67 	return path;
68 }
69 
70 void
71 conf_read_file(void)
72 {
73 	char *file;
74 
75 	file = conf_get_path(CONF_FILE);
76 	if (access(file, F_OK) == 0 || errno != ENOENT)
77 		conf_source_file(file);
78 	free(file);
79 }
80 
81 void
82 conf_source_file(const char *file)
83 {
84 	FILE	*fp;
85 	size_t	 lineno, size;
86 	ssize_t	 len;
87 	char	*error, *line;
88 
89 	if ((fp = fopen(file, "r")) == NULL) {
90 		LOG_ERR("fopen: %s", file);
91 		msg_err("Cannot open %s", file);
92 		return;
93 	}
94 
95 	line = NULL;
96 	size = 0;
97 	for (lineno = 1; (len = getline(&line, &size, fp)) != -1; lineno++) {
98 		if (len > 0 && line[len - 1] == '\n')
99 			line[len - 1] = '\0';
100 
101 		if (command_process(line, &error) == -1) {
102 			msg_errx("%s:%zu: %s", file, lineno, error);
103 			free(error);
104 		}
105 	}
106 	if (ferror(fp)) {
107 		LOG_ERR("getline: %s", file);
108 		msg_err("Cannot read configuration file");
109 	}
110 	free(line);
111 
112 	fclose(fp);
113 }
114