clockwerk-opensim-stable – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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 string iniDirName = startupConfig.GetString("inidirectory", "config");
143 string iniDirPath = Path.Combine(Util.configDir(), iniDirName);
144  
145 if (Directory.Exists(iniDirPath))
146 {
147 m_log.InfoFormat("Searching folder {0} for config ini files", iniDirPath);
148  
149 string[] fileEntries = Directory.GetFiles(iniDirName);
150 foreach (string filePath in fileEntries)
151 {
152 if (Path.GetExtension(filePath).ToLower() == ".ini")
153 {
154 if (!sources.Contains(Path.GetFullPath(filePath)))
155 sources.Add(Path.GetFullPath(filePath));
156 }
157 }
158 }
159  
160 m_config = new OpenSimConfigSource();
161 m_config.Source = new IniConfigSource();
162 m_config.Source.Merge(DefaultConfig());
163  
164 m_log.Info("[CONFIG]: Reading configuration settings");
165  
166 if (sources.Count == 0)
167 {
168 m_log.FatalFormat("[CONFIG]: Could not load any configuration");
169 Environment.Exit(1);
170 }
171  
172 for (int i = 0 ; i < sources.Count ; i++)
173 {
174 if (ReadConfig(sources[i]))
175 {
176 iniFileExists = true;
177 AddIncludes(sources);
178 }
179 }
180  
181 if (!iniFileExists)
182 {
183 m_log.FatalFormat("[CONFIG]: Could not load any configuration");
184 m_log.FatalFormat("[CONFIG]: Configuration exists, but there was an error loading it!");
185 Environment.Exit(1);
186 }
187  
188 // Make sure command line options take precedence
189 m_config.Source.Merge(argvSource);
190  
191 IConfig enVars = m_config.Source.Configs["Environment"];
192  
193 if( enVars != null )
194 {
195 string[] env_keys = enVars.GetKeys();
196  
197 foreach ( string key in env_keys )
198 {
199 envConfigSource.AddEnv(key, string.Empty);
200 }
201  
202 envConfigSource.LoadEnv();
203 m_config.Source.Merge(envConfigSource);
204 m_config.Source.ExpandKeyValues();
205 }
206  
207  
208 ReadConfigSettings();
209  
210 return m_config;
211 }
212  
213 /// <summary>
214 /// Adds the included files as ini configuration files
215 /// </summary>
216 /// <param name="sources">List of URL strings or filename strings</param>
217 private void AddIncludes(List<string> sources)
218 {
219 //loop over config sources
220 foreach (IConfig config in m_config.Source.Configs)
221 {
222 // Look for Include-* in the key name
223 string[] keys = config.GetKeys();
224 foreach (string k in keys)
225 {
226 if (k.StartsWith("Include-"))
227 {
228 // read the config file to be included.
229 string file = config.GetString(k);
230 if (IsUri(file))
231 {
232 if (!sources.Contains(file))
233 sources.Add(file);
234 }
235 else
236 {
237 string basepath = Path.GetFullPath(Util.configDir());
238 // Resolve relative paths with wildcards
239 string chunkWithoutWildcards = file;
240 string chunkWithWildcards = string.Empty;
241 int wildcardIndex = file.IndexOfAny(new char[] { '*', '?' });
242 if (wildcardIndex != -1)
243 {
244 chunkWithoutWildcards = file.Substring(0, wildcardIndex);
245 chunkWithWildcards = file.Substring(wildcardIndex);
246 }
247 string path = Path.Combine(basepath, chunkWithoutWildcards);
248 path = Path.GetFullPath(path) + chunkWithWildcards;
249 string[] paths = Util.Glob(path);
250  
251 // If the include path contains no wildcards, then warn the user that it wasn't found.
252 if (wildcardIndex == -1 && paths.Length == 0)
253 {
254 m_log.WarnFormat("[CONFIG]: Could not find include file {0}", path);
255 }
256 else
257 {
258 foreach (string p in paths)
259 {
260 if (!sources.Contains(p))
261 sources.Add(p);
262 }
263 }
264 }
265 }
266 }
267 }
268 }
269 /// <summary>
270 /// Check if we can convert the string to a URI
271 /// </summary>
272 /// <param name="file">String uri to the remote resource</param>
273 /// <returns>true if we can convert the string to a Uri object</returns>
274 bool IsUri(string file)
275 {
276 Uri configUri;
277  
278 return Uri.TryCreate(file, UriKind.Absolute,
279 out configUri) && configUri.Scheme == Uri.UriSchemeHttp;
280 }
281  
282 /// <summary>
283 /// Provide same ini loader functionality for standard ini and master ini - file system or XML over http
284 /// </summary>
285 /// <param name="iniPath">Full path to the ini</param>
286 /// <returns></returns>
287 private bool ReadConfig(string iniPath)
288 {
289 bool success = false;
290  
291 if (!IsUri(iniPath))
292 {
293 m_log.InfoFormat("[CONFIG]: Reading configuration file {0}", Path.GetFullPath(iniPath));
294  
295 m_config.Source.Merge(new IniConfigSource(iniPath));
296 success = true;
297 }
298 else
299 {
300 m_log.InfoFormat("[CONFIG]: {0} is a http:// URI, fetching ...", iniPath);
301  
302 // The ini file path is a http URI
303 // Try to read it
304 try
305 {
306 XmlReader r = XmlReader.Create(iniPath);
307 XmlConfigSource cs = new XmlConfigSource(r);
308 m_config.Source.Merge(cs);
309  
310 success = true;
311 }
312 catch (Exception e)
313 {
314 m_log.FatalFormat("[CONFIG]: Exception reading config from URI {0}\n" + e.ToString(), iniPath);
315 Environment.Exit(1);
316 }
317 }
318 return success;
319 }
320  
321 /// <summary>
322 /// Setup a default config values in case they aren't present in the ini file
323 /// </summary>
324 /// <returns>A Configuration source containing the default configuration</returns>
325 private static IConfigSource DefaultConfig()
326 {
327 IConfigSource defaultConfig = new IniConfigSource();
328  
329 {
330 IConfig config = defaultConfig.Configs["Startup"];
331  
332 if (null == config)
333 config = defaultConfig.AddConfig("Startup");
334  
335 config.Set("region_info_source", "filesystem");
336  
337 config.Set("physics", "OpenDynamicsEngine");
338 config.Set("meshing", "Meshmerizer");
339 config.Set("physical_prim", true);
340 config.Set("serverside_object_permissions", true);
341 config.Set("storage_plugin", "OpenSim.Data.SQLite.dll");
342 config.Set("storage_connection_string", "URI=file:OpenSim.db,version=3");
343 config.Set("storage_prim_inventories", true);
344 config.Set("startup_console_commands_file", String.Empty);
345 config.Set("shutdown_console_commands_file", String.Empty);
346 config.Set("DefaultScriptEngine", "XEngine");
347 config.Set("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll");
348 // life doesn't really work without this
349 config.Set("EventQueue", true);
350 }
351  
352 {
353 IConfig config = defaultConfig.Configs["Network"];
354  
355 if (null == config)
356 config = defaultConfig.AddConfig("Network");
357  
358 config.Set("http_listener_port", ConfigSettings.DefaultRegionHttpPort);
359 }
360  
361 return defaultConfig;
362 }
363  
364 /// <summary>
365 /// Read initial region settings from the ConfigSource
366 /// </summary>
367 protected virtual void ReadConfigSettings()
368 {
369 IConfig startupConfig = m_config.Source.Configs["Startup"];
370 if (startupConfig != null)
371 {
372 m_configSettings.PhysicsEngine = startupConfig.GetString("physics");
373 m_configSettings.MeshEngineName = startupConfig.GetString("meshing");
374 m_configSettings.StorageDll = startupConfig.GetString("storage_plugin");
375  
376 m_configSettings.ClientstackDll
377 = startupConfig.GetString("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll");
378 }
379  
380 m_networkServersInfo.loadFromConfiguration(m_config.Source);
381 }
382 }
383 }