50#define DIR_SEP_STRING "\\"
51#define DIR_SEP_CHAR '\\'
54#define DIR_SEP_STRING "/"
55#define DIR_SEP_CHAR '/'
70RCReader* RCReader::_instance = 0;
75static pthread_once_t instance_control = PTHREAD_ONCE_INIT;
81bool RCReader::write_rc_file(
const string &pathname)
83 DBG(cerr <<
"Writing the RC file to " << pathname << endl);
84 ofstream fpo(pathname.c_str());
92 fpo <<
"# OPeNDAP client configuration file. See the OPeNDAP" << endl;
93 fpo <<
"# users guide for information." << endl;
94 fpo <<
"USE_CACHE=" << _dods_use_cache << endl;
95 fpo <<
"# Cache and object size are given in megabytes (20 ==> 20Mb)." << endl;
96 fpo <<
"MAX_CACHE_SIZE=" << _dods_cache_max << endl;
97 fpo <<
"MAX_CACHED_OBJ=" << _dods_cached_obj << endl;
98 fpo <<
"IGNORE_EXPIRES=" << _dods_ign_expires << endl;
99 fpo <<
"CACHE_ROOT=" << d_cache_root << endl;
100 fpo <<
"DEFAULT_EXPIRES=" << _dods_default_expires << endl;
101 fpo <<
"ALWAYS_VALIDATE=" << _dods_always_validate << endl;
102 fpo <<
"# Request servers compress responses if possible?" << endl;
103 fpo <<
"# 1 (yes) or 0 (false)." << endl;
104 fpo <<
"DEFLATE=" << _dods_deflate << endl;
106 fpo <<
"# Should SSL certificates and hosts be validated? SSL" << endl;
107 fpo <<
"# will only work with signed certificates." << endl;
108 fpo <<
"VALIDATE_SSL=" << d_validate_ssl << endl;
110 fpo <<
"# Proxy configuration (optional parts in []s)." << endl;
111 fpo <<
"# You may also use the 'http_proxy' environment variable" << endl;
112 fpo <<
"# but a value in this file will override that env variable." << endl;
113 fpo <<
"# PROXY_SERVER=[http://][username:password@]host[:port]" << endl;
114 if (!d_dods_proxy_server_host.empty()) {
115 fpo <<
"PROXY_SERVER=" << d_dods_proxy_server_protocol <<
"://"
116 << (d_dods_proxy_server_userpw.empty() ?
"" : d_dods_proxy_server_userpw +
"@")
117 + d_dods_proxy_server_host +
":" + long_to_string(d_dods_proxy_server_port) << endl;
120 fpo <<
"# NO_PROXY_FOR=<host|domain>" << endl;
121 if (!d_dods_no_proxy_for_host.empty()) {
122 fpo <<
"NO_PROXY_FOR=" << d_dods_no_proxy_for_host << endl;
125 fpo <<
"# AIS_DATABASE=<file or url>" << endl;
127 fpo <<
"# COOKIE_JAR=.dods_cookies" << endl;
128 fpo <<
"# The cookie jar is a file that holds cookies sent from" << endl;
129 fpo <<
"# servers such as single signon systems. Uncomment this" << endl;
130 fpo <<
"# option and provide a file name to activate this feature." << endl;
131 fpo <<
"# If the value is a filename, it will be created in this" << endl;
132 fpo <<
"# directory; a full pathname can be used to force a specific" << endl;
133 fpo <<
"# location." << endl;
142bool RCReader::read_rc_file(
const string &pathname)
144 DBG(cerr <<
"Reading the RC file from " << pathname << endl);
146 ifstream fpi(pathname.c_str());
155 vector<char> tempstr(1024);
158 fpi.getline(tempstr.data(), 1023);
159 if (!fpi.good())
break;
161 value = strchr(tempstr.data(),
'=');
162 if (!value)
continue;
163 tokenlength = value - tempstr.data();
166 if ((strncmp(tempstr.data(),
"USE_CACHE", 9) == 0) && tokenlength == 9) {
167 _dods_use_cache = atoi(value) ? true :
false;
169 else if ((strncmp(tempstr.data(),
"MAX_CACHE_SIZE", 14) == 0) && tokenlength == 14) {
170 _dods_cache_max = atoi(value);
172 else if ((strncmp(tempstr.data(),
"MAX_CACHED_OBJ", 14) == 0) && tokenlength == 14) {
173 _dods_cached_obj = atoi(value);
175 else if ((strncmp(tempstr.data(),
"IGNORE_EXPIRES", 14) == 0) && tokenlength == 14) {
176 _dods_ign_expires = atoi(value);
178 else if ((strncmp(tempstr.data(),
"DEFLATE", 7) == 0) && tokenlength == 7) {
179 _dods_deflate = atoi(value) ? true :
false;
181 else if ((strncmp(tempstr.data(),
"CACHE_ROOT", 10) == 0) && tokenlength == 10) {
182 d_cache_root = value;
183 if (d_cache_root[d_cache_root.length() - 1] != DIR_SEP_CHAR) d_cache_root += string(DIR_SEP_STRING);
185 else if ((strncmp(tempstr.data(),
"DEFAULT_EXPIRES", 15) == 0) && tokenlength == 15) {
186 _dods_default_expires = atoi(value);
188 else if ((strncmp(tempstr.data(),
"ALWAYS_VALIDATE", 15) == 0) && tokenlength == 15) {
189 _dods_always_validate = atoi(value);
191 else if ((strncmp(tempstr.data(),
"VALIDATE_SSL", 12) == 0) && tokenlength == 12) {
192 d_validate_ssl = atoi(value);
194 else if (strncmp(tempstr.data(),
"AIS_DATABASE", 12) == 0 && tokenlength == 12) {
195 d_ais_database = value;
197 else if (strncmp(tempstr.data(),
"COOKIE_JAR", 10) == 0 && tokenlength == 10) {
201 if (value[0] ==
'/') {
202 d_cookie_jar = value;
205 d_cookie_jar = d_rc_file_path.substr(0, d_rc_file_path.find(
".dodsrc")) + string(value);
206 } DBG(cerr <<
"set cookie jar to: " << d_cookie_jar << endl);
208 else if ((strncmp(tempstr.data(),
"PROXY_SERVER", 12) == 0) && tokenlength == 12) {
215 string proxy = value;
216 string::size_type comma = proxy.find(
',');
220 if (comma != string::npos) {
221 d_dods_proxy_server_protocol = proxy.substr(0, comma);
222 downcase(d_dods_proxy_server_protocol);
223 if (d_dods_proxy_server_protocol !=
"http")
224 throw Error(
"The only supported protocol for a proxy server is \"HTTP\". Correct your \".dodsrc\" file.");
225 proxy = proxy.substr(comma + 1);
228 d_dods_proxy_server_protocol =
"http";
232 string::size_type protocol = proxy.find(
"://");
233 if (protocol != string::npos) {
234 proxy = proxy.substr(protocol + 3);
238 string::size_type at_sign = proxy.find(
'@');
239 if (at_sign != string::npos) {
240 d_dods_proxy_server_userpw = proxy.substr(0, at_sign);
241 proxy = proxy.substr(at_sign + 1);
244 d_dods_proxy_server_userpw =
"";
247 string::size_type colon = proxy.find(
':');
248 if (colon != string::npos) {
249 d_dods_proxy_server_host = proxy.substr(0, colon);
250 d_dods_proxy_server_port = strtol(proxy.substr(colon + 1).c_str(), 0, 0);
253 d_dods_proxy_server_host = proxy;
254 d_dods_proxy_server_port = 80;
257 else if ((strncmp(tempstr.data(),
"NO_PROXY_FOR", 12) == 0) && tokenlength == 12) {
259 string no_proxy = value;
260 string::size_type comma = no_proxy.find(
',');
264 if (comma == string::npos) {
265 d_dods_no_proxy_for_protocol =
"http";
266 d_dods_no_proxy_for_host = no_proxy;
267 d_dods_no_proxy_for =
true;
270 d_dods_no_proxy_for_protocol = no_proxy.substr(0, comma);
271 d_dods_no_proxy_for_host = no_proxy.substr(comma + 1);
272 d_dods_no_proxy_for =
true;
290string RCReader::check_string(
string env_var)
292 DBG(cerr <<
"Entering check_string... (" << env_var <<
")" << endl);
293 struct stat stat_info;
295 if (stat(env_var.c_str(), &stat_info) != 0) {
296 DBG(cerr <<
"stat returned non-zero" << endl);
300 if (S_ISREG(stat_info.st_mode)) {
301 DBG(cerr <<
"S_ISREG: " << S_ISREG(stat_info.st_mode) << endl);
307 if (S_ISDIR(stat_info.st_mode)) {
308 DBG(cerr <<
"S_ISDIR: " << S_ISDIR(stat_info.st_mode) << endl);
309 if (*env_var.rbegin() != DIR_SEP_CHAR)
310 env_var += DIR_SEP_STRING;
315 d_cache_root = env_var + string(
".dods_cache") + DIR_SEP_STRING;
316 env_var +=
".dodsrc";
317 if (stat(env_var.c_str(), &stat_info) == 0 && S_ISREG(stat_info.st_mode)) {
318 DBG(cerr <<
"Found .dodsrc in \"" << env_var <<
"\"" << endl);
325 if (write_rc_file(env_var)) {
326 DBG(cerr <<
"Wrote .dodsrc in \"" << env_var <<
"\"" << endl);
332 DBG(cerr <<
"could neither find nor create a .dodsrc file" << endl);
345string RCReader::check_env_var(
const string &variable_name)
347 char *ev = getenv(variable_name.c_str());
348 if (!ev || strlen(ev) == 0)
return "";
350 return check_string(ev);
360 _dods_use_cache =
false;
361 _dods_cache_max = 20;
362 _dods_cached_obj = 5;
363 _dods_ign_expires = 0;
364 _dods_default_expires = 86400;
365 _dods_always_validate = 0;
372 d_dods_proxy_server_protocol =
"";
373 d_dods_proxy_server_host =
"";
374 d_dods_proxy_server_port = 0;
375 d_dods_proxy_server_userpw =
"";
377 _dods_proxy_server_host_url =
"";
381 _dods_proxy_for =
false;
382 _dods_proxy_for_regexp =
"";
383 _dods_proxy_for_proxy_host_url =
"";
384 _dods_proxy_for_regexp_flags = 0;
388 d_dods_no_proxy_for =
false;
389 d_dods_no_proxy_for_protocol =
"";
390 d_dods_no_proxy_for_host =
"";
394 _dods_no_proxy_for_port = 0;
399 string homedir = string(
"C:") + string(DIR_SEP_STRING) + string(
"Dods");
400 d_rc_file_path = check_string(homedir);
401 if (d_rc_file_path.empty()) {
402 homedir = string(
"C:") + string(DIR_SEP_STRING) + string(
"opendap");
403 d_rc_file_path = check_string(homedir);
406 if (d_rc_file_path.empty())
407 d_rc_file_path = check_env_var(
"APPDATA");
408 if (d_rc_file_path.empty())
409 d_rc_file_path = check_env_var(
"TEMP");
410 if (d_rc_file_path.empty())
411 d_rc_file_path = check_env_var(
"TMP");
413 d_rc_file_path = check_env_var(
"DODS_CONF");
414 if (d_rc_file_path.empty()) d_rc_file_path = check_env_var(
"HOME");
416 DBG(cerr <<
"Looking for .dodsrc in: " << d_rc_file_path << endl);
418 if (!d_rc_file_path.empty()) read_rc_file(d_rc_file_path);
426void RCReader::delete_instance()
428 if (RCReader::_instance) {
429 delete RCReader::_instance;
430 RCReader::_instance = 0;
435void RCReader::initialize_instance()
437 DBGN(cerr <<
"RCReader::initialize_instance() ... ");
439 RCReader::_instance =
new RCReader;
440 atexit(RCReader::delete_instance);
442 DBG(cerr <<
"exiting." << endl);
448 DBG(cerr <<
"Entring RCReader::instance" << endl);
451 pthread_once(&instance_control, initialize_instance);
453 DBG(cerr <<
"Instance value: " << hex << _instance << dec << endl);
460RCReader::instance(
const string &rc_file_path)
462 DBG(cerr <<
"Entring RCReader::instance" << endl);
464 d_rc_file_path = rc_file_path;
467 pthread_once(&instance_control, initialize_instance);
469 DBG(cerr <<
"Instance value: " << hex << _instance << dec << endl);
top level DAP object to house generic methods