/src/MapServer/src/mapserv-config.cpp
Line | Count | Source |
1 | | /********************************************************************** |
2 | | * $id$ |
3 | | * |
4 | | * Project: MapServer |
5 | | * Purpose: Config File Support |
6 | | * Author: Steve Lime and the MapServer team. |
7 | | * |
8 | | ********************************************************************** |
9 | | * Copyright (c) 1996-2005 Regents of the University of Minnesota. |
10 | | * |
11 | | * Permission is hereby granted, free of charge, to any person obtaining a |
12 | | * copy of this software and associated documentation files (the "Software"), |
13 | | * to deal in the Software without restriction, including without limitation |
14 | | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
15 | | * and/or sell copies of the Software, and to permit persons to whom the |
16 | | * Software is furnished to do so, subject to the following conditions: |
17 | | * |
18 | | * The above copyright notice and this permission notice shall be included in |
19 | | * all copies of this Software or works derived from this Software. |
20 | | * |
21 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
22 | | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
23 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
24 | | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
25 | | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
26 | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
27 | | ****************************************************************************/ |
28 | | #include "mapserver.h" |
29 | | #include "mapfile.h" // format shares a couple of tokens |
30 | | |
31 | | #include "cpl_conv.h" |
32 | | |
33 | | #include <string> |
34 | | |
35 | | extern "C" int msyylex(void); |
36 | | extern "C" void msyyrestart(FILE *); |
37 | | |
38 | | extern "C" FILE *msyyin; |
39 | | extern "C" int msyystate; |
40 | | extern "C" int msyylineno; |
41 | | extern "C" char *msyystring_buffer; |
42 | | |
43 | 2.53k | static int initConfig(configObj *config) { |
44 | 2.53k | if (config == NULL) { |
45 | 0 | msSetError(MS_MEMERR, "Config object is NULL.", "initConfig()"); |
46 | 0 | return MS_FAILURE; |
47 | 0 | } |
48 | | |
49 | 2.53k | if (initHashTable(&(config->env)) != MS_SUCCESS) |
50 | 0 | return MS_FAILURE; |
51 | 2.53k | if (initHashTable(&(config->maps)) != MS_SUCCESS) |
52 | 0 | return MS_FAILURE; |
53 | 2.53k | if (initHashTable(&(config->plugins)) != MS_SUCCESS) |
54 | 0 | return MS_FAILURE; |
55 | | |
56 | 2.53k | return MS_SUCCESS; |
57 | 2.53k | } |
58 | | |
59 | 2.97k | void msFreeConfig(configObj *config) { |
60 | 2.97k | if (config == NULL) |
61 | 434 | return; |
62 | 2.53k | msFreeHashItems(&(config->env)); |
63 | 2.53k | msFreeHashItems(&(config->maps)); |
64 | 2.53k | msFreeHashItems(&(config->plugins)); |
65 | | |
66 | 2.53k | msFree(config); |
67 | 2.53k | } |
68 | | |
69 | 2.53k | static int loadConfig(configObj *config) { |
70 | 2.53k | int token; |
71 | | |
72 | 2.53k | if (config == NULL) |
73 | 0 | return MS_FAILURE; |
74 | | |
75 | 2.53k | token = msyylex(); |
76 | 2.53k | if (token != MS_CONFIG_SECTION) { |
77 | 143 | msSetError(MS_IDENTERR, |
78 | 143 | "First token must be CONFIG, this doesn't look like a mapserver " |
79 | 143 | "config file.", |
80 | 143 | "msLoadConfig()"); |
81 | 143 | return MS_FAILURE; |
82 | 143 | } |
83 | | |
84 | 4.73k | for (;;) { |
85 | 4.73k | switch (msyylex()) { |
86 | 2.32k | case (MS_CONFIG_SECTION_ENV): { |
87 | 2.32k | if (loadHashTable(&(config->env)) != MS_SUCCESS) |
88 | 112 | return MS_FAILURE; |
89 | 2.21k | break; |
90 | 2.32k | } |
91 | 2.21k | case (MS_CONFIG_SECTION_MAPS): |
92 | 57 | if (loadHashTable(&config->maps) != MS_SUCCESS) |
93 | 9 | return MS_FAILURE; |
94 | 48 | break; |
95 | 93 | case (MS_CONFIG_SECTION_PLUGINS): |
96 | 93 | if (loadHashTable(&config->plugins) != MS_SUCCESS) |
97 | 12 | return MS_FAILURE; |
98 | 81 | break; |
99 | 81 | case (EOF): |
100 | 28 | msSetError(MS_EOFERR, NULL, "msLoadConfig()"); |
101 | 28 | return MS_FAILURE; |
102 | 2.10k | case (END): |
103 | 2.10k | if (msyyin) { |
104 | 2.10k | fclose(msyyin); |
105 | 2.10k | msyyin = NULL; |
106 | 2.10k | } |
107 | 2.10k | return MS_SUCCESS; |
108 | 0 | break; |
109 | 130 | default: |
110 | 130 | msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", |
111 | 130 | "msLoadConfig()", msyystring_buffer, msyylineno); |
112 | 130 | return MS_FAILURE; |
113 | 4.73k | } |
114 | 4.73k | } |
115 | 2.39k | } |
116 | | |
117 | 7.23k | static void msConfigSetConfigOption(const char *key, const char *value) { |
118 | 7.23k | CPLSetConfigOption(key, value); |
119 | 7.23k | if (strcasecmp(key, "PROJ_DATA") == 0 || strcasecmp(key, "PROJ_LIB") == 0) { |
120 | 351 | msSetPROJ_DATA(value, nullptr); |
121 | 351 | } |
122 | 7.23k | } |
123 | | |
124 | 0 | std::string msGetMapserverConfigFilePath() { |
125 | |
|
126 | 0 | const char *config_path = CPLGetConfigOption("MAPSERVER_CONFIG_FILE", NULL); |
127 | 0 | if (config_path != nullptr) { |
128 | 0 | return std::string(config_path); |
129 | 0 | } |
130 | | |
131 | 0 | const char *env_file = getenv("MAPSERVER_CONFIG_FILE"); |
132 | 0 | if (env_file != nullptr) { |
133 | | // get config filename from environment |
134 | 0 | return std::string(env_file); |
135 | 0 | } |
136 | | |
137 | 0 | if (MAPSERVER_CONFIG_FILE[0] != '\0') { |
138 | | // fallback to hardcoded file name |
139 | 0 | return std::string(MAPSERVER_CONFIG_FILE); |
140 | 0 | } |
141 | 0 | return std::string(); |
142 | 0 | } |
143 | | |
144 | 2.53k | configObj *msLoadConfig(const char *ms_config_file) { |
145 | 2.53k | configObj *config = NULL; |
146 | | |
147 | 2.53k | std::string config_path; |
148 | | |
149 | 2.53k | if (ms_config_file == NULL) { |
150 | 0 | config_path = msGetMapserverConfigFilePath(); |
151 | 0 | if (config_path.empty()) { |
152 | 0 | msSetError(MS_MISCERR, "No config file set.", "msLoadConfig()"); |
153 | 0 | return NULL; |
154 | 0 | } |
155 | 0 | ms_config_file = config_path.c_str(); |
156 | 0 | } |
157 | | |
158 | 2.53k | config = (configObj *)calloc(1, sizeof(configObj)); |
159 | 2.53k | MS_CHECK_ALLOC(config, sizeof(configObj), NULL); |
160 | | |
161 | 2.53k | if (initConfig(config) != MS_SUCCESS) { |
162 | 0 | msFreeConfig(config); |
163 | 0 | return NULL; |
164 | 0 | } |
165 | | |
166 | 2.53k | msAcquireLock(TLOCK_PARSER); |
167 | | |
168 | 2.53k | if ((msyyin = fopen(ms_config_file, "r")) == NULL) { |
169 | 0 | msDebug("Cannot open configuration file %s.\n", ms_config_file); |
170 | 0 | msSetError(MS_IOERR, |
171 | 0 | "See mapserver.org/mapfile/config.html for more information.", |
172 | 0 | "msLoadConfig()"); |
173 | 0 | msReleaseLock(TLOCK_PARSER); |
174 | 0 | msFreeConfig(config); |
175 | 0 | return NULL; |
176 | 0 | } |
177 | | |
178 | 2.53k | msyystate = MS_TOKENIZE_CONFIG; |
179 | 2.53k | msyylex(); // sets things up, but doesn't process any tokens |
180 | | |
181 | 2.53k | msyyrestart(msyyin); // start at line 1 |
182 | 2.53k | msyylineno = 1; |
183 | | |
184 | 2.53k | if (loadConfig(config) != MS_SUCCESS) { |
185 | 434 | msFreeConfig(config); |
186 | 434 | msReleaseLock(TLOCK_PARSER); |
187 | 434 | if (msyyin) { |
188 | 434 | fclose(msyyin); |
189 | 434 | msyyin = NULL; |
190 | 434 | } |
191 | 434 | return NULL; |
192 | 434 | } |
193 | 2.10k | msReleaseLock(TLOCK_PARSER); |
194 | | |
195 | | // load all env key/values using CPLSetConfigOption() - only do this *after* |
196 | | // we have a good config |
197 | 2.10k | const char *key = msFirstKeyFromHashTable(&config->env); |
198 | 2.10k | if (key != NULL) { |
199 | 2.09k | msConfigSetConfigOption(key, msLookupHashTable(&config->env, key)); |
200 | | |
201 | 2.09k | const char *last_key = key; |
202 | 5.13k | while ((key = msNextKeyFromHashTable(&config->env, last_key)) != NULL) { |
203 | 3.03k | msConfigSetConfigOption(key, msLookupHashTable(&config->env, key)); |
204 | 3.03k | last_key = key; |
205 | 3.03k | } |
206 | 2.09k | } |
207 | | |
208 | | // also store the path to the CONFIG file |
209 | 2.10k | msConfigSetConfigOption("MAPSERVER_CONFIG_FILE", ms_config_file); |
210 | | |
211 | 2.10k | return config; |
212 | 2.53k | } |
213 | | |
214 | 0 | const char *msConfigGetEnv(const configObj *config, const char *key) { |
215 | 0 | if (config == NULL || key == NULL) |
216 | 0 | return NULL; |
217 | 0 | return msLookupHashTable(&config->env, key); |
218 | 0 | } |
219 | | |
220 | | /** |
221 | | * Get the path to a Mapfile, from the MapServer CONFIG file using |
222 | | * its key. If the path is relative then the CONFIG file location |
223 | | * is used to determine the absolute path. |
224 | | * The provided pszReturnPath must be at least MS_MAXPATHLEN long. |
225 | | */ |
226 | | const char *msConfigGetMap(const configObj *config, const char *key, |
227 | 0 | char *pszReturnPath) { |
228 | 0 | if (config == NULL || key == NULL || pszReturnPath == NULL) |
229 | 0 | return NULL; |
230 | | |
231 | 0 | const char *mapFile = msLookupHashTable(&config->maps, key); |
232 | 0 | if (!mapFile) |
233 | 0 | return NULL; |
234 | | |
235 | | // check for relative Mapfile paths |
236 | 0 | if (CPLIsFilenameRelative(mapFile)) { |
237 | |
|
238 | 0 | std::string config_path = msGetMapserverConfigFilePath(); |
239 | 0 | if (config_path.empty()) { |
240 | 0 | return NULL; |
241 | 0 | } |
242 | 0 | char *configPath = msGetPath(config_path.c_str()); |
243 | |
|
244 | 0 | if (!configPath) |
245 | 0 | return NULL; |
246 | | |
247 | 0 | if (msBuildPath(pszReturnPath, configPath, mapFile) == NULL) { |
248 | 0 | free(configPath); |
249 | 0 | return NULL; |
250 | 0 | } |
251 | 0 | free(configPath); |
252 | 0 | } else { |
253 | | // just copy absolute path directly |
254 | 0 | strlcpy(pszReturnPath, mapFile, MS_MAXPATHLEN); |
255 | 0 | } |
256 | 0 | return pszReturnPath; |
257 | 0 | } |
258 | | |
259 | 0 | const char *msConfigGetPlugin(const configObj *config, const char *key) { |
260 | 0 | if (config == NULL || key == NULL) |
261 | 0 | return NULL; |
262 | 0 | return msLookupHashTable(&config->plugins, key); |
263 | 0 | } |