1 /*******************************************************************************
2  * unixoptions.h
3  *
4  * Written by Christoph Hormann <chris_hormann@gmx.de>
5  * based on unix.cpp Elements by Nicolas Calimet
6  *
7  * Processing system for options in povray.conf, command line
8  * and environment variables.
9  *
10  * ---------------------------------------------------------------------------
11  * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
12  * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
13  *
14  * POV-Ray is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU Affero General Public License as
16  * published by the Free Software Foundation, either version 3 of the
17  * License, or (at your option) any later version.
18  *
19  * POV-Ray is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Affero General Public License for more details.
23  *
24  * You should have received a copy of the GNU Affero General Public License
25  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
26  * ---------------------------------------------------------------------------
27  * POV-Ray is based on the popular DKB raytracer version 2.12.
28  * DKBTrace was originally written by David K. Buck.
29  * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
30  * ---------------------------------------------------------------------------
31  * $File: //depot/public/povray/3.x/vfe/unix/unixoptions.h $
32  * $Revision: #1 $
33  * $Change: 6069 $
34  * $DateTime: 2013/11/06 11:59:40 $
35  * $Author: chrisc $
36  *******************************************************************************/
37 
38 #ifndef _OPTIONS_H
39 #define _OPTIONS_H
40 
41 #include "vfe.h"
42 
43 #include <list>
44 #include <vector>
45 #include <iostream>
46 #include <string>
47 #include <boost/algorithm/string.hpp>
48 
49 using boost::to_lower_copy;
50 
51 /*
52  * [NC]
53  * Default values for the location of the povray library and configuration.
54  * These constants don't have to be in config.h .
55  */
56 #ifndef POVLIBDIR
57 # define POVLIBDIR  "/usr/local/share/" PACKAGE "-" VERSION_BASE
58 #endif
59 
60 #ifndef POVCONFDIR
61 # define POVCONFDIR  "/usr/local/etc/" PACKAGE "/" VERSION_BASE
62 #endif
63 
64 #ifndef POVCONFDIR_BACKWARD
65 # define POVCONFDIR_BACKWARD  "/usr/local/etc"
66 #endif
67 
68 
69 namespace vfePlatform
70 {
71 	/**
72 		@brief Processing system for options in povray.conf, command line and environment variables.
73 
74 		@author Christoph Hormann <chris_hormann@gmx.de>
75 
76 		@date June 2006
77 
78 		This class wraps the processing of platform specific options set via
79 
80 			- povray.conf files in the form:
81 
82 				[section]
83 				name=value
84 
85 			- command line options (which have to be removed before the options vector
86 				is passed to the core code for further processing)
87 
88 			- environment variables
89 
90 		It provides access to the settings made with those options to other parts of
91 		the code and allows subsystems like the display classes to register their own
92 		options.
93 
94 		Registering custom options:
95 
96 			even options not registered are read from povray.conf when present and
97 			their values are made available.  To register an options the public method
98 			Register() is provided.  It takes a vector of Option_Info structs containing
99 			the option information.  See disp_text.cpp for an (empty) example.
100 
101 		The option values are currently stored as strings and the system does not
102 		distinguish between different types.
103 
104 		Furthermore it processes the IO-restrictions settings and manages the povray.ini
105 		locations.
106 
107 		Inner workings:
108 
109 			The options are stored in the list m_user_options.
110 
111 			The constructor sets up the locations of the configuration files
112 			(previously unix_create_globals()), adds the standard options to the list
113 			and processes the povray.conf files.  The io-restrictions settings from
114 			those files are read with the old proven system and stored in their own
115 			list (m_permitted_paths).  At the end these are transferred into the
116 			corresponding vfeSession fields.  All unknown options in the povray.conf
117 			files are read into a temporary list (m_custom_conf_options).
118 
119 			The actual options processing is done in ProcessOptions(). There all
120 			options from the povray.conf files are transferred into the list.  Then
121 			the values of all options which can be set via command line and environment
122 			variables are determined.  Environment variables override povray.conf
123 			settings and command line options override environment variables.  The read
124 			command line options are removed from the argument list like previously in
125 			the xwindow code.
126 
127 		An instance of this class is part of vfeUnixSession and can be accesses through
128 		vfeUnixSession::GetUnixOptions().
129 
130 	*/
131 	class UnixOptionsProcessor
132 	{
133 	  public:
134 		/*
135 		 * [NC] structures to handle configuration-related (povray.conf) code.
136 		 */
137 		enum FileIO {IO_UNSET, IO_NONE, IO_READONLY, IO_RESTRICTED, IO_UNKNOWN};
138 		enum ShellOut {SHL_UNSET, SHL_ALLOWED, SHL_FORBIDDEN, SHL_UNKNOWN};
139 
140 		/// permission path for IO restrictions settings
141 		struct UnixPath
142 		{
143 			string str;
144 			bool descend, writable;
145 
strUnixPath146 			UnixPath(const string &s, bool desc = false, bool wrt = false) : str(s), descend(desc), writable(wrt) { }
147 		};
148 
149 		/**
150 			 Option of a povray.conf file of the form
151 			 [Section]
152 			 Name=Value
153 		*/
154 		struct Conf_Option
155 		{
156 			string Section;
157 			string Name;
158 			string Value;
159 
SectionConf_Option160 			Conf_Option(const string &Sect, const string &Nm, const string &Val = "") : Section(Sect), Name(Nm), Value(Val) { }
161 		};
162 
163 		/**
164 			 A platform specific configuration option
165 			 with configuration file settings,
166 			 Command line option (optional) and
167 			 Environment variable (optional)
168 
169 			 This stucture is used by the Display classes to
170 			 provide their own options and by the options
171 			 processor to store the option values
172 		*/
173 		struct Option_Info
174 		{
175 			string Section;
176 			string Name;
177 			string Value;
178 			string CmdOption;
179 			string EnvVariable;
180 			string Comment;
181 			bool has_param;
182 
183 			Option_Info(const string &Sect ,
184 									const string &Nm,
185 									const string &Val = "",
186 									bool par = false,
187 									const string &Cmd = "",
188 									const string &Env = "",
189 									const string &Comm = "")
SectionOption_Info190 				: Section(Sect), Name(Nm), Value(Val), has_param(par), CmdOption(Cmd), EnvVariable(Env), Comment(Comm) { }
191 
192 			/// only checks identity of the option, not of the selected value.
193 			bool operator==(Option_Info const& other) const
194 			{
195 				return to_lower_copy(Section) == to_lower_copy(other.Section) && to_lower_copy(Name) == to_lower_copy(other.Name);
196 			}
197 
198 			/// compares sections (for sorting)
199 			bool operator<(Option_Info const& other) const
200 			{
201 				if (to_lower_copy(other.Section) < to_lower_copy(Section))
202 					return true;
203 				if (to_lower_copy(other.Section) == to_lower_copy(Section))
204 					if (to_lower_copy(other.Name) < to_lower_copy(Name))
205 						return true;
206 				return false;
207 			}
208 		};
209 
210 		UnixOptionsProcessor(vfeSession *session);
~UnixOptionsProcessor()211 		virtual ~UnixOptionsProcessor() {} ;
212 
213 		/**
214 			 called by the Display classes to register their custom options
215 
216 			 @param options Vector of Option_Info structs containing the options
217 		*/
218 		void Register(const Option_Info options[]);
219 
220 		/**
221 			 Converts a file path to standard form replacing
222 			 relative notations.
223 		*/
224 		string CanonicalizePath(const string &path);
225 
226 		/**
227 			 Finds out the default location for temporary files.
228 			 Set by an option, alternatively '/tmp/'.
229 
230 			 @returns temporary path including a trailing slash
231 		*/
232 		string GetTemporaryPath(void);
233 
234 		/**
235 			 Finds the value of a certain option from
236 			 either configuration file, command line
237 			 or environment variable.
238 
239 			 @param option The option to query
240 
241 			 The value is returned in option.Value.
242 		*/
243 		void QueryOption(Option_Info &option);
244 
245 		/**
246 			 Finds the value of a certain option via
247 			 section and option name and returns it as
248 			 a string.
249 		*/
250 		string QueryOptionString(const string &section, const string &name);
251 
252 		/**
253 			 Finds the value of a certain option via
254 			 section and option name and returns it as
255 			 an int.  If the options value is not convertible
256 			 to int dflt is returned instead.
257 		*/
258 		int QueryOptionInt(const string &section, const string &name, const int dflt = 0);
259 
260 		/**
261 			 Finds the value of a certain option via
262 			 section and option name and returns it as
263 			 a float  If the options value is not convertible
264 			 to float dflt is returned instead..
265 		*/
266 		float QueryOptionFloat(const string &section, const string &name, const float dflt = 0.0);
267 
268 		/**
269 			 Check if a certain option has been set
270 			 this is the case if a parameter free option is present of
271 			 if the parameter is 'on', 'yes', 'true' or '1'.
272 
273 			 @returns true if set, false otherwise
274 		*/
275 		bool isOptionSet(const Option_Info &option);
276 		bool isOptionSet(const string &section, const string &name);
277 
278 		/**
279 			 Adds the custom povray.conf options with their values
280 			 to the main options list and reads the environment
281 			 variables and command line options where advised.
282 
283 			 The argument list is replaced with a version
284 			 with the custom options removed.
285 		*/
286 		void ProcessOptions(int *argc, char **argv[]);
287 
288 		/**
289 			 Search for povray.ini at standard locations
290 			 and add it to opts.
291 		*/
292 		void Process_povray_ini(vfeRenderOptions &opts);
293 
294 		/**
295 			 Print all currrently registered command line
296 			 options in an option summary.
297 		*/
298 		void PrintOptions(void);
299 
300 		/**
301 			 Determines if IO restrictions are enabled at compile
302 			 time and via povray.conf settings.
303 
304 			 @param write if false and permissions are 'free read' returns false.
305 		*/
306 		bool isIORestrictionsEnabled(bool write);
307 
308 		/**
309 			 Prints an approriate error message if IO restrictions
310 			 prevent access to a file.
311 
312 			 @param fnm File not permitted to access
313 			 @param write If write acccess was requested
314 			 @param is_user_setting if denial was due to user setting
315 		*/
316 		void IORestrictionsError(const string &fnm, bool write, bool is_user_setting);
317 
ShelloutPermitted(const string & command,const string & parameters)318 		bool ShelloutPermitted(const string& command, const string& parameters) const { return m_shellout == SHL_ALLOWED; }
319 
320 	 protected:
321 		/// list of standard options
322 		static const Option_Info Standard_Options[];
323 
324 		string unix_getcwd(void);
325 		string basename(const string &path);
326 		string dirname(const string &path);
327 		string unix_readlink(const string &path);
328 		string pre_process_conf_line(const string &input);
329 		void add_permitted_path(list<UnixPath> &paths, const string &input, const string &conf_name, unsigned long line_number);
330 		void parse_conf_file(std::istream &Stream, const string &conf_name, bool user_mode);
331 		void process_povray_conf(void);
332 		void remove_arg(int *argc, char *argv[], int index);
333 		bool file_exist(const string &name);
334 
335 		vfeSession *m_Session;
336 		string  m_home;
337 		string  m_user_dir;
338 		string  m_sysconf;                // system conf filename
339 		string  m_userconf;               // user conf filename
340 		string  m_conf;                   // selected conf file
341 		string  m_sysini, m_sysini_old;   // system ini filename
342 		string  m_userini, m_userini_old; // user ini filename
343 		FileIO  m_file_io;
344 		ShellOut m_shellout;
345 		list<UnixPath> m_permitted_paths;
346 		list<Conf_Option> m_custom_conf_options;
347 		list<Option_Info> m_user_options;
348 	};
349 }
350 
351 #endif
352