Added a (not yet implemented) plugin_t method to reload plugin configuration
[strongswan.git] / src / libcharon / plugins / tnc_imc / tnc_imc_plugin.c
1 /*
2 * Copyright (C) 2010 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "tnc_imc_plugin.h"
17 #include "tnc_imc_manager.h"
18 #include "tnc_imc.h"
19
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/mman.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <fcntl.h>
26
27 #include <daemon.h>
28 #include <utils/lexparser.h>
29
30 /**
31 * load IMCs from a configuration file
32 */
33 static bool load_imcs(char *filename)
34 {
35 int fd, line_nr = 0;
36 chunk_t src, line;
37 struct stat sb;
38 void *addr;
39
40 DBG1(DBG_TNC, "loading IMCs from '%s'", filename);
41 fd = open(filename, O_RDONLY);
42 if (fd == -1)
43 {
44 DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename,
45 strerror(errno));
46 return FALSE;
47 }
48 if (fstat(fd, &sb) == -1)
49 {
50 DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename,
51 strerror(errno));
52 close(fd);
53 return FALSE;
54 }
55 addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
56 if (addr == MAP_FAILED)
57 {
58 DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno));
59 close(fd);
60 return FALSE;
61 }
62 src = chunk_create(addr, sb.st_size);
63
64 while (fetchline(&src, &line))
65 {
66 char *name, *path;
67 chunk_t token;
68 imc_t *imc;
69
70 line_nr++;
71
72 /* skip comments or empty lines */
73 if (*line.ptr == '#' || !eat_whitespace(&line))
74 {
75 continue;
76 }
77
78 /* determine keyword */
79 if (!extract_token(&token, ' ', &line))
80 {
81 DBG1(DBG_TNC, "line %d: keyword must be followed by a space",
82 line_nr);
83 return FALSE;
84 }
85
86 /* only interested in IMCs */
87 if (!match("IMC", &token))
88 {
89 continue;
90 }
91
92 /* advance to the IMC name and extract it */
93 if (!extract_token(&token, '"', &line) ||
94 !extract_token(&token, '"', &line))
95 {
96 DBG1(DBG_TNC, "line %d: IMC name must be set in double quotes",
97 line_nr);
98 return FALSE;
99 }
100
101 /* copy the IMC name */
102 name = malloc(token.len + 1);
103 memcpy(name, token.ptr, token.len);
104 name[token.len] = '\0';
105
106 /* advance to the IMC path and extract it */
107 if (!eat_whitespace(&line))
108 {
109 DBG1(DBG_TNC, "line %d: IMC path is missing", line_nr);
110 free(name);
111 return FALSE;
112 }
113 if (!extract_token(&token, ' ', &line))
114 {
115 token = line;
116 }
117
118 /* copy the IMC path */
119 path = malloc(token.len + 1);
120 memcpy(path, token.ptr, token.len);
121 path[token.len] = '\0';
122
123 /* load and register IMC instance */
124 imc = tnc_imc_create(name, path);
125 if (!imc)
126 {
127 free(name);
128 free(path);
129 return FALSE;
130 }
131 if (!charon->imcs->add(charon->imcs, imc))
132 {
133 imc->destroy(imc);
134 return FALSE;
135 }
136 DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc),
137 name, path);
138 }
139 munmap(addr, sb.st_size);
140 close(fd);
141 return TRUE;
142 }
143
144 METHOD(plugin_t, get_name, char*,
145 tnc_imc_plugin_t *this)
146 {
147 return "tnc-imc";
148 }
149
150 METHOD(plugin_t, destroy, void,
151 tnc_imc_plugin_t *this)
152 {
153 charon->imcs->destroy(charon->imcs);
154 free(this);
155 }
156
157 /*
158 * see header file
159 */
160 plugin_t *tnc_imc_plugin_create()
161 {
162 char *tnc_config;
163 tnc_imc_plugin_t *this;
164
165 INIT(this,
166 .plugin = {
167 .get_name = _get_name,
168 .reload = (void*)return_false,
169 .destroy = _destroy,
170 },
171 );
172
173 /* Create IMC manager */
174 charon->imcs = tnc_imc_manager_create();
175
176 /* Load IMCs and abort if not all instances initalize successfully */
177 tnc_config = lib->settings->get_str(lib->settings,
178 "charon.plugins.tnc-imc.tnc_config", "/etc/tnc_config");
179 if (!load_imcs(tnc_config))
180 {
181 charon->imcs->destroy(charon->imcs);
182 charon->imcs = NULL;
183 free(this);
184 return NULL;
185 }
186 return &this->plugin;
187 }
188