opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 1 /*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27  
28 using System;
29 using System.Collections.Generic;
30 using System.IO;
31 using System.Reflection;
32 using System.Threading;
33 using System.Xml;
34 using log4net;
35 using Nini.Config;
36 using OpenSim.Framework;
37  
38 namespace OpenSim
39 {
40 /// <summary>
41 /// Loads the Configuration files into nIni
42 /// </summary>
43 public class ConfigurationLoader
44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46  
47 /// <summary>
48 /// Various Config settings the region needs to start
49 /// Physics Engine, Mesh Engine, GridMode, PhysicsPrim allowed, Neighbor,
50 /// StorageDLL, Storage Connection String, Estate connection String, Client Stack
51 /// Standalone settings.
52 /// </summary>
53 protected ConfigSettings m_configSettings;
54  
55 /// <summary>
56 /// A source of Configuration data
57 /// </summary>
58 protected OpenSimConfigSource m_config;
59  
60 /// <summary>
61 /// Grid Service Information. This refers to classes and addresses of the grid service
62 /// </summary>
63 protected NetworkServersInfo m_networkServersInfo;
64  
65 /// <summary>
66 /// Loads the region configuration
67 /// </summary>
68 /// <param name="argvSource">Parameters passed into the process when started</param>
69 /// <param name="configSettings"></param>
70 /// <param name="networkInfo"></param>
71 /// <returns>A configuration that gets passed to modules</returns>
72 public OpenSimConfigSource LoadConfigSettings(
73 IConfigSource argvSource, EnvConfigSource envConfigSource, out ConfigSettings configSettings,
74 out NetworkServersInfo networkInfo)
75 {
76 m_configSettings = configSettings = new ConfigSettings();
77 m_networkServersInfo = networkInfo = new NetworkServersInfo();
78  
79 bool iniFileExists = false;
80  
81 IConfig startupConfig = argvSource.Configs["Startup"];
82  
83 List<string> sources = new List<string>();
84  
85 string masterFileName =
86 startupConfig.GetString("inimaster", "OpenSimDefaults.ini");
87  
88 if (masterFileName == "none")
89 masterFileName = String.Empty;
90  
91 if (IsUri(masterFileName))
92 {
93 if (!sources.Contains(masterFileName))
94 sources.Add(masterFileName);
95 }
96 else
97 {
98 string masterFilePath = Path.GetFullPath(
99 Path.Combine(Util.configDir(), masterFileName));
100  
101 if (masterFileName != String.Empty)
102 {
103 if (File.Exists(masterFilePath))
104 {
105 if (!sources.Contains(masterFilePath))
106 sources.Add(masterFilePath);
107 }
108 else
109 {
110 m_log.ErrorFormat("Master ini file {0} not found", Path.GetFullPath(masterFilePath));
111 Environment.Exit(1);
112 }
113 }
114 }
115  
116 string iniFileName = startupConfig.GetString("inifile", "OpenSim.ini");
117  
118 if (IsUri(iniFileName))
119 {
120 if (!sources.Contains(iniFileName))
121 sources.Add(iniFileName);
122 Application.iniFilePath = iniFileName;
123 }
124 else
125 {
126 Application.iniFilePath = Path.GetFullPath(
127 Path.Combine(Util.configDir(), iniFileName));
128  
129 if (!File.Exists(Application.iniFilePath))
130 {
131 iniFileName = "OpenSim.xml";
132 Application.iniFilePath = Path.GetFullPath(Path.Combine(Util.configDir(), iniFileName));
133 }
134  
135 if (File.Exists(Application.iniFilePath))
136 {
137 if (!sources.Contains(Application.iniFilePath))
138 sources.Add(Application.iniFilePath);
139 }
140 }
141  
142 m_config = new OpenSimConfigSource();
143 m_config.Source = new IniConfigSource();
144 m_config.Source.Merge(DefaultConfig());
145  
146 m_log.Info("[CONFIG]: Reading configuration settings");
147  
148 for (int i = 0 ; i < sources.Count ; i++)
149 {
150 if (ReadConfig(m_config, sources[i]))
151 {
152 iniFileExists = true;
153 AddIncludes(m_config, sources);
154 }
155 }
156  
157 // Override distro settings with contents of inidirectory
158 string iniDirName = startupConfig.GetString("inidirectory", "config");
159 string iniDirPath = Path.Combine(Util.configDir(), iniDirName);
160  
161 if (Directory.Exists(iniDirPath))
162 {
163 m_log.InfoFormat("[CONFIG]: Searching folder {0} for config ini files", iniDirPath);
164 List<string> overrideSources = new List<string>();
165  
166 string[] fileEntries = Directory.GetFiles(iniDirName);
167 foreach (string filePath in fileEntries)
168 {
169 if (Path.GetExtension(filePath).ToLower() == ".ini")
170 {
171 if (!sources.Contains(Path.GetFullPath(filePath)))
172 {
173 overrideSources.Add(Path.GetFullPath(filePath));
174 // put it in sources too, to avoid circularity
175 sources.Add(Path.GetFullPath(filePath));
176 }
177 }
178 }
179  
180  
181 if (overrideSources.Count > 0)
182 {
183 OpenSimConfigSource overrideConfig = new OpenSimConfigSource();
184 overrideConfig.Source = new IniConfigSource();
185  
186 for (int i = 0 ; i < overrideSources.Count ; i++)
187 {
188 if (ReadConfig(overrideConfig, overrideSources[i]))
189 {
190 iniFileExists = true;
191 AddIncludes(overrideConfig, overrideSources);
192 }
193 }
194 m_config.Source.Merge(overrideConfig.Source);
195 }
196 }
197  
198 if (sources.Count == 0)
199 {
200 m_log.FatalFormat("[CONFIG]: Could not load any configuration");
201 Environment.Exit(1);
202 }
203 else if (!iniFileExists)
204 {
205 m_log.FatalFormat("[CONFIG]: Could not load any configuration");
206 m_log.FatalFormat("[CONFIG]: Configuration exists, but there was an error loading it!");
207 Environment.Exit(1);
208 }
209  
210 // Make sure command line options take precedence
211 m_config.Source.Merge(argvSource);
212  
213 IConfig enVars = m_config.Source.Configs["Environment"];
214  
215 if( enVars != null )
216 {
217 string[] env_keys = enVars.GetKeys();
218  
219 foreach ( string key in env_keys )
220 {
221 envConfigSource.AddEnv(key, string.Empty);
222 }
223  
224 envConfigSource.LoadEnv();
225 m_config.Source.Merge(envConfigSource);
226 }
227  
228 m_config.Source.ExpandKeyValues();
229  
230 ReadConfigSettings();
231  
232 return m_config;
233 }
234  
235 /// <summary>
236 /// Adds the included files as ini configuration files
237 /// </summary>
238 /// <param name="sources">List of URL strings or filename strings</param>
239 private void AddIncludes(OpenSimConfigSource configSource, List<string> sources)
240 {
241 //loop over config sources
242 foreach (IConfig config in configSource.Source.Configs)
243 {
244 // Look for Include-* in the key name
245 string[] keys = config.GetKeys();
246 foreach (string k in keys)
247 {
248 if (k.StartsWith("Include-"))
249 {
250 // read the config file to be included.
251 string file = config.GetString(k);
252 if (IsUri(file))
253 {
254 if (!sources.Contains(file))
255 sources.Add(file);
256 }
257 else
258 {
259 string basepath = Path.GetFullPath(Util.configDir());
260 // Resolve relative paths with wildcards
261 string chunkWithoutWildcards = file;
262 string chunkWithWildcards = string.Empty;
263 int wildcardIndex = file.IndexOfAny(new char[] { '*', '?' });
264 if (wildcardIndex != -1)
265 {
266 chunkWithoutWildcards = file.Substring(0, wildcardIndex);
267 chunkWithWildcards = file.Substring(wildcardIndex);
268 }
269 string path = Path.Combine(basepath, chunkWithoutWildcards);
270 path = Path.GetFullPath(path) + chunkWithWildcards;
271 string[] paths = Util.Glob(path);
272  
273 // If the include path contains no wildcards, then warn the user that it wasn't found.
274 if (wildcardIndex == -1 && paths.Length == 0)
275 {
276 m_log.WarnFormat("[CONFIG]: Could not find include file {0}", path);
277 }
278 else
279 {
280 foreach (string p in paths)
281 {
282 if (!sources.Contains(p))
283 sources.Add(p);
284 }
285 }
286 }
287 }
288 }
289 }
290 }
291 /// <summary>
292 /// Check if we can convert the string to a URI
293 /// </summary>
294 /// <param name="file">String uri to the remote resource</param>
295 /// <returns>true if we can convert the string to a Uri object</returns>
296 bool IsUri(string file)
297 {
298 Uri configUri;
299  
300 return Uri.TryCreate(file, UriKind.Absolute,
301 out configUri) && configUri.Scheme == Uri.UriSchemeHttp;
302 }
303  
304 /// <summary>
305 /// Provide same ini loader functionality for standard ini and master ini - file system or XML over http
306 /// </summary>
307 /// <param name="iniPath">Full path to the ini</param>
308 /// <returns></returns>
309 private bool ReadConfig(OpenSimConfigSource configSource, string iniPath)
310 {
311 bool success = false;
312  
313 if (!IsUri(iniPath))
314 {
315 m_log.InfoFormat("[CONFIG]: Reading configuration file {0}", Path.GetFullPath(iniPath));
316  
317 configSource.Source.Merge(new IniConfigSource(iniPath));
318 success = true;
319 }
320 else
321 {
322 m_log.InfoFormat("[CONFIG]: {0} is a http:// URI, fetching ...", iniPath);
323  
324 // The ini file path is a http URI
325 // Try to read it
326 try
327 {
328 XmlReader r = XmlReader.Create(iniPath);
329 XmlConfigSource cs = new XmlConfigSource(r);
330 configSource.Source.Merge(cs);
331  
332 success = true;
333 }
334 catch (Exception e)
335 {
336 m_log.FatalFormat("[CONFIG]: Exception reading config from URI {0}\n" + e.ToString(), iniPath);
337 Environment.Exit(1);
338 }
339 }
340 return success;
341 }
342  
343 /// <summary>
344 /// Setup a default config values in case they aren't present in the ini file
345 /// </summary>
346 /// <returns>A Configuration source containing the default configuration</returns>
347 private static IConfigSource DefaultConfig()
348 {
349 IConfigSource defaultConfig = new IniConfigSource();
350  
351 {
352 IConfig config = defaultConfig.Configs["Startup"];
353  
354 if (null == config)
355 config = defaultConfig.AddConfig("Startup");
356  
357 config.Set("region_info_source", "filesystem");
358  
359 config.Set("physics", "OpenDynamicsEngine");
360 config.Set("meshing", "Meshmerizer");
361 config.Set("physical_prim", true);
362 config.Set("serverside_object_permissions", true);
363 config.Set("storage_prim_inventories", true);
364 config.Set("startup_console_commands_file", String.Empty);
365 config.Set("shutdown_console_commands_file", String.Empty);
366 config.Set("DefaultScriptEngine", "XEngine");
367 config.Set("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll");
368 // life doesn't really work without this
369 config.Set("EventQueue", true);
370 }
371  
372 {
373 IConfig config = defaultConfig.Configs["Network"];
374  
375 if (null == config)
376 config = defaultConfig.AddConfig("Network");
377  
378 config.Set("http_listener_port", ConfigSettings.DefaultRegionHttpPort);
379 }
380  
381 return defaultConfig;
382 }
383  
384 /// <summary>
385 /// Read initial region settings from the ConfigSource
386 /// </summary>
387 protected virtual void ReadConfigSettings()
388 {
389 IConfig startupConfig = m_config.Source.Configs["Startup"];
390 if (startupConfig != null)
391 {
392 m_configSettings.PhysicsEngine = startupConfig.GetString("physics");
393 m_configSettings.MeshEngineName = startupConfig.GetString("meshing");
394  
395 m_configSettings.ClientstackDll
396 = startupConfig.GetString("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll");
397 }
398  
399 m_networkServersInfo.loadFromConfiguration(m_config.Source);
400 }
401 }
402 }