source: trunk/icedtea-web/plugin/icedteanp/IcedTeaParseProperties.cc@ 450

Last change on this file since 450 was 437, checked in by dmik, 11 years ago

icedtea-web: Override getpwuid on OS/2.

This is because kLIBC doesn't provide a working version (yet). This override fixes detection of the user home directory.

File size: 10.6 KB
Line 
1/* IcedTeaRunnable.cc
2
3 Copyright (C) 2013 Red Hat
4
5This file is part of IcedTea.
6
7IcedTea is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12IcedTea is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with IcedTea; see the file COPYING. If not, write to the
19Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2002110-1301 USA.
21
22Linking this library statically or dynamically with other modules is
23making a combined work based on this library. Thus, the terms and
24conditions of the GNU General Public License cover the whole
25combination.
26
27As a special exception, the copyright holders of this library give you
28permission to link this library with independent modules to produce an
29executable, regardless of the license terms of these independent
30modules, and to copy and distribute the resulting executable under
31terms of your choice, provided that you also meet, for each linked
32independent module, the terms and conditions of the license of that
33module. An independent module is a module which is not derived from
34or based on this library. If you modify this library, you may extend
35this exception to your version of the library, but you are not
36obligated to do so. If you do not wish to do so, delete this
37exception statement from your version. */
38
39#include <unistd.h>
40#include <sys/types.h>
41#include <pwd.h>
42#include <cstdio>
43#include <cstdlib>
44#include <string>
45#include <functional>
46#include <cctype>
47#include <locale>
48#include <iostream>
49#include <fstream>
50
51
52#include "IcedTeaPluginUtils.h"
53#include "IcedTeaNPPlugin.h"
54#include "IcedTeaParseProperties.h"
55/*
56 The public api is nearly impossible to test due to "hardcoded paths"
57 All public methods have theirs equivalents wit set-up-able files, and those are
58 tested.
59*/
60
61#ifdef __EMX__
62// getpwuid isn't fully implemented yet, let the env vars override it
63struct passwd *my_getpwuid(uid_t uid)
64{
65 static struct passwd pw_buf;
66
67 struct passwd *pw = getpwuid(uid);
68 if (pw)
69 memcpy(&pw_buf, pw, sizeof(struct passwd));
70 else
71 return 0;
72
73 char *env_var;
74 env_var = getenv("HOME");
75 if (env_var && env_var[0]) {
76 pw_buf.pw_dir = env_var;
77 while (*env_var) {
78 if (*env_var == '\\')
79 *env_var = '/';
80 ++env_var;
81 }
82 }
83
84 return &pw_buf;
85}
86#undef getpwuid
87#define getpwuid my_getpwuid
88#endif
89
90using namespace std;
91//private api
92
93void remove_all_spaces(string& str);
94bool get_property_value(string c, string& dest);
95bool starts_with(string c1, string c2);
96string user_properties_file();
97string main_properties_file();
98string default_java_properties_file();
99//for passing three dummy files
100bool find_system_config_file(string main_file, string custom_jre_file, bool usecustom_jre, string default_java_file, string& dest);
101bool find_property(string filename, string property, string& dest);
102//for passing two dummy files
103bool read_deploy_property_value(string user_file, string system_file, bool usesystem_file, string property, string& dest);
104//for passing two dummy files
105bool find_custom_jre(string user_file, string main_file,string& dest);
106//end of non-public IcedTeaParseProperties api
107const std::string default_file_ITW_deploy_props_name = "deployment.properties";
108const std::string default_itw_log_dir_name = "log";
109const std::string custom_jre_key = "deployment.jre.dir";
110
111void remove_all_spaces(string& str)
112{
113 for(int i=0; i<str.length(); i++){
114 if(str[i] == ' ' || str[i] == '\n' || str[i] == '\t') {
115 str.erase(i,1);
116 i--;
117 }
118 }
119}
120
121bool get_property_value(string c, string& dest){
122 int i = c.find("=");
123 if (i < 0) return false;
124 int l = c.length();
125 dest = c.substr(i+1, l-i);
126 IcedTeaPluginUtilities::trim(dest);
127 return true;
128}
129
130
131bool starts_with(string c1, string c2){
132 return (c1.find(c2) == 0);
133}
134
135
136string user_properties_file(){
137 int myuid = getuid();
138 struct passwd *mypasswd = getpwuid(myuid);
139 // try pre 1.5 file location
140 string old_name = string(mypasswd->pw_dir)+"/.icedtea/"+default_file_ITW_deploy_props_name;
141 //exists? then itw was not yet migrated. Use it
142 if (IcedTeaPluginUtilities::file_exists(old_name)) {
143 PLUGIN_ERROR("IcedTea-Web plugin is using out-dated configuration\n");
144 return old_name;
145 }
146 //we are probably on XDG specification now
147 //is specified custom value?
148 if (getenv ("XDG_CONFIG_HOME") != NULL){
149 return string(getenv ("XDG_CONFIG_HOME"))+"/icedtea-web/"+default_file_ITW_deploy_props_name;
150 }
151 //if not then use default
152 return string(mypasswd->pw_dir)+"/.config/icedtea-web/"+default_file_ITW_deploy_props_name;
153}
154
155string get_log_dir(){
156 string value;
157 if (!read_deploy_property_value("deployment.user.logdir", value)) {
158 string config_dir;
159 if (getenv ("XDG_CONFIG_HOME") != NULL){
160 config_dir = string(getenv("XDG_CONFIG_HOME"));
161 } else {
162 int myuid = getuid();
163 struct passwd *mypasswd = getpwuid(myuid);
164 config_dir = string(mypasswd->pw_dir) + "/.config";
165 }
166 string itw_dir = config_dir+"/icedtea-web";
167 string log_dir = itw_dir+"/"+default_itw_log_dir_name;
168 mkdir_checked(itw_dir);
169 mkdir_checked(log_dir);
170 return log_dir;
171 }
172 return value;
173}
174
175void mkdir_checked(string dir){
176 if (!IcedTeaPluginUtilities::file_exists(dir))
177 {
178 const int PERMISSIONS_MASK = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; // 0755
179 int stat = g_mkdir(dir.c_str(), PERMISSIONS_MASK);
180 if (stat != 0)
181 {
182 PLUGIN_DEBUG("WARNING: Creation of directory %s failed: %s\n", dir.c_str(), strerror(errno));
183 }
184 }
185}
186
187string main_properties_file(){
188 return "/etc/.java/deployment/"+default_file_ITW_deploy_props_name;
189}
190
191string default_java_properties_file(){
192 return ICEDTEA_WEB_JRE "/lib/"+default_file_ITW_deploy_props_name;
193}
194
195
196/* this is the same search done by icedtea-web settings:
197 try the main file in /etc/.java/deployment
198 if found, then return this file
199 try to find setUp jre
200 if found, then try if this file exists and end
201 if no jre custom jvm is set, then tries default jre
202 if its deploy file exists, then return
203 not found otherwise*/
204bool find_system_config_file(string& dest){
205 string jdest;
206 bool found = find_custom_jre(jdest);
207 if (found) {
208 jdest = jdest + "/lib/"+default_file_ITW_deploy_props_name;
209 }
210 return find_system_config_file(main_properties_file(), jdest, found, default_java_properties_file(), dest);
211}
212
213bool is_java_console_enabled(){
214 string value;
215 if (!read_deploy_property_value("deployment.console.startup.mode", value)) {
216 return true;
217 }
218 if (value == "DISABLE") {
219 return false;
220 } else {
221 return true;
222 }
223}
224
225bool read_bool_property(string key, bool defaultValue){
226 string value;
227 if (!read_deploy_property_value(key, value)) {
228 return defaultValue;
229 }
230 if (value == "true") {
231 return true;
232 } else {
233 return false;
234 }
235}
236
237bool is_debug_on(){
238 return read_bool_property("deployment.log",false);
239}
240bool is_debug_header_on(){
241 return read_bool_property("deployment.log.headers",false);
242}
243bool is_logging_to_file(){
244 return read_bool_property("deployment.log.file",false);
245}
246bool is_logging_to_stds(){
247 return read_bool_property("deployment.log.stdstreams",true);
248}
249bool is_logging_to_system(){
250 return read_bool_property("deployment.log.system",true);
251}
252
253
254//abstraction for testing purposes
255bool find_system_config_file(string main_file, string custom_jre_file, bool usecustom_jre, string default_java_file, string& dest){
256 if (IcedTeaPluginUtilities::file_exists(main_file)) {
257 dest = main_file;
258 return true;
259 } else {
260 if (usecustom_jre){
261 if(IcedTeaPluginUtilities::file_exists(custom_jre_file) ) {
262 dest = custom_jre_file;
263 return true;
264 }
265 } else {
266 if(IcedTeaPluginUtilities::file_exists(default_java_file)) {
267 dest = default_java_file;
268 return true;
269 }
270 }
271 }
272return false; //nothing of above found
273}
274
275//Returns whether property was found, if found stores result in 'dest'
276bool find_property(string filename, string property, string& dest){
277 string property_matcher(property);
278 IcedTeaPluginUtilities::trim( property_matcher);
279 property_matcher= property_matcher+"=";
280 ifstream input( filename.c_str() );
281 for( string line; getline( input, line ); ){ /* read a line */
282 string copy = line;
283 //java tolerates spaces around = char, remove them for matching
284 remove_all_spaces(copy);
285 if (starts_with(copy, property_matcher)) {
286 //provide non-spaced value, trimming is done in get_property_value
287 get_property_value(line, dest);
288 return true;
289 }
290 }
291
292 return false;
293 }
294
295
296/* this is reimplementation of itw-settings operations
297 first check in user's settings, if found, return
298 then check in global file (see the magic of find_system_config_file)*/
299bool read_deploy_property_value(string property, string& dest){
300 string futurefile;
301 bool found = find_system_config_file(futurefile);
302 return read_deploy_property_value(user_properties_file(), futurefile, found, property, dest);
303}
304//abstraction for testing purposes
305bool read_deploy_property_value(string user_file, string system_file, bool usesystem_file, string property, string& dest){
306 //is it in user's file?
307 bool found = find_property(user_file, property, dest);
308 if (found) {
309 return true;
310 }
311 //is it in global file?
312 if (usesystem_file) {
313 return find_property(system_file, property, dest);
314 }
315 return false;
316}
317
318//This is different from common get property, as it is avoiding to search in *java*
319//properties files
320bool find_custom_jre(string& dest){
321 return find_custom_jre(user_properties_file(), main_properties_file(), dest);
322}
323//abstraction for testing purposes
324bool find_custom_jre(string user_file, string main_file,string& dest){
325 string key = custom_jre_key;
326 if(IcedTeaPluginUtilities::file_exists(user_file)) {
327 bool a = find_property(user_file, key, dest);
328 if (a) {
329 return true;
330 }
331 }
332 if(IcedTeaPluginUtilities::file_exists(main_file)) {
333 return find_property(main_file, key, dest);
334 }
335return false;
336}
337
338
339
340int test_main(void){
341 cout << ("user's settings file\n");
342 cout << user_properties_file();
343 cout << ("\nmain settings file:\n");
344 cout << (main_properties_file());
345 cout << ("\njava settings file \n");
346 cout << (default_java_properties_file());
347 cout << ("\nsystem config file\n");
348 string a1;
349 find_system_config_file(a1);
350 cout << a1;
351 cout << ("\ncustom jre\n");
352 string a2;
353 find_custom_jre(a2);
354 cout << a2;
355 cout << ("\nsome custom property\n");
356 string a3;
357 read_deploy_property_value("deployment.security.level", a3);
358 cout << a3;
359 cout << ("\n");
360 return 0;
361}
Note: See TracBrowser for help on using the repository browser.