1 /* John McCutchan <ttb@tentacle.dhs.org> 2005 */
2 
3 #include "server_config.h"
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <unistd.h>
9 #include <string.h>
10 #include <errno.h>
11 #include <glib.h>
12 
13 #include "gam_error.h"
14 #include "gam_conf.h"
15 #include "gam_fs.h"
16 #include "gam_excludes.h"
17 
18 static gam_fs_mon_type
gam_conf_string_to_mon_type(const char * method)19 gam_conf_string_to_mon_type (const char *method)
20 {
21 	if (!strcasecmp(method, "kernel"))
22 		return GFS_MT_KERNEL;
23 	if (!strcasecmp(method, "poll"))
24 		return GFS_MT_POLL;
25 
26 	return GFS_MT_NONE;
27 }
28 
29 static void
gam_conf_read_internal(const char * filename)30 gam_conf_read_internal (const char *filename)
31 {
32 	gchar *path;
33 	gchar *contents, **lines, *line, **words;
34 	gsize len;
35 	int x, y;
36 	int exclude = 1;
37 
38 	g_file_get_contents(filename, &contents, &len, NULL);
39 	if (contents == NULL)
40 		return;
41 	lines = g_strsplit(contents, "\n", 0);
42 	if (lines != NULL) {
43 		for (x = 0; lines[x] != NULL ; x++) {
44 			line = lines[x];
45 			if ((line[0] == 0) || (line[0] == '#'))
46 				continue;
47 			words = g_strsplit(line, " ", 0);
48 			if (words == NULL)
49 				continue;
50 
51 			if (!strcmp(words[0], "fsset")) {
52 				gam_fs_mon_type mon_type = GFS_MT_KERNEL;
53 				gint poll_timeout = 0;
54 				/* We need: fsset <fsname> <method> [poll timeout] */
55 				/* fsname */
56 				if (!words[1] || !words[1][0]) {
57 					g_strfreev(words);
58 					continue;
59 				}
60 				/* method name */
61 				if (!words[2] || !words[2][0]) {
62 					g_strfreev(words);
63 					continue;
64 				}
65 				mon_type = gam_conf_string_to_mon_type (words[2]);
66 				/* The poll timeout value is optional, if it isn't provided, the default value will be used */
67 				if (!words[3] || !words[3][0])
68 					poll_timeout = -1;
69 				else
70 					poll_timeout = atoi (words[3]);
71 				gam_fs_set (words[1], mon_type, poll_timeout);
72 				g_strfreev(words);
73 				continue;
74 			}
75 			if (!strcmp(words[0], "poll")) {
76 				exclude = 1;
77 			} else if (!strcmp(words[0], "notify")) {
78 				exclude = 0;
79 			} else {
80 				g_strfreev(words);
81 				continue;
82 			}
83 
84 			for (y = 1; words[y] != NULL ; y++) {
85 				if (words[y][0] == 0)
86 						continue;
87 				if (words[y][0] == '#')
88 					break;
89 				if (words[y][0] == '~') {
90 					path = g_strconcat(g_get_home_dir(), &(words[y][1]), NULL);
91 					if (path != NULL) {
92 						gam_exclude_add (path, exclude);
93 						g_free(path);
94 					}
95 					continue;
96 				}
97 				if (words[y][0] != '/')
98 					continue;
99 				gam_exclude_add (words[y], exclude);
100 			}
101 			g_strfreev(words);
102 		}
103 		g_strfreev(lines);
104 	}
105 	g_free(contents);
106 }
107 
108 void
gam_conf_read(void)109 gam_conf_read (void)
110 {
111 	const char *globalconf = "/usr/local/etc/gamin/gaminrc";
112 	const char *mandatory = "/usr/local/etc/gamin/mandatory_gaminrc";
113 	gchar *userconf = NULL;
114 	userconf = g_strconcat(g_get_home_dir(), "/.gaminrc", NULL);
115 	if (userconf == NULL) {
116 		gam_conf_read_internal (globalconf);
117 		return;
118 	}
119 
120 	/* We read three config files in this order,
121 	 * 1) System
122 	 * 2) User config
123 	 * 3) System mandatory
124 	 *
125 	 * We read the system mandatory last, so that the system administrator
126 	 * can override potentially dangerous options
127 	 */
128 	gam_conf_read_internal (globalconf);
129 	gam_conf_read_internal (userconf);
130 	gam_conf_read_internal (mandatory);
131 
132 	g_free (userconf);
133 }
134