|
Packit |
a4aae4 |
// -*- mode: c++; c-basic-offset:4 -*-
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
|
|
Packit |
a4aae4 |
// Access Protocol.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Copyright (c) 2002,2003 OPeNDAP, Inc.
|
|
Packit |
a4aae4 |
// Author: Jose Garcia <jgarcia@ucar.edu>
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is free software; you can redistribute it and/or
|
|
Packit |
a4aae4 |
// modify it under the terms of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License as published by the Free Software Foundation; either
|
|
Packit |
a4aae4 |
// version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is distributed in the hope that it will be useful,
|
|
Packit |
a4aae4 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
a4aae4 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
a4aae4 |
// Lesser General Public License for more details.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You should have received a copy of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License along with this library; if not, write to the Free Software
|
|
Packit |
a4aae4 |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// (c) COPYRIGHT URI/MIT 2001,2002
|
|
Packit |
a4aae4 |
// Please read the full copyright statement in the file COPYRIGHT_URI.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// Authors:
|
|
Packit |
a4aae4 |
// jose Jose Garcia <jgarcia@ucar.edu>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** A singleton which reads and parses the .dodsrc file. This code was
|
|
Packit |
a4aae4 |
extracted from Connect (which has since changed considerably).
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@author: jose */
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// #define DODS_DEBUG
|
|
Packit |
a4aae4 |
#include "config.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <cstring>
|
|
Packit |
a4aae4 |
#include <cstdlib>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <unistd.h> // for stat
|
|
Packit |
a4aae4 |
#include <sys/types.h>
|
|
Packit |
a4aae4 |
#include <sys/stat.h>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#ifdef WIN32
|
|
Packit |
a4aae4 |
#define FALSE 0
|
|
Packit |
a4aae4 |
// Win32 does not define F_OK. 08/21/02 jhrg
|
|
Packit |
a4aae4 |
#define F_OK 0
|
|
Packit |
a4aae4 |
#define DIR_SEP_STRING "\\"
|
|
Packit |
a4aae4 |
#define DIR_SEP_CHAR '\\'
|
|
Packit |
a4aae4 |
#include <direct.h>
|
|
Packit |
a4aae4 |
#else
|
|
Packit |
a4aae4 |
#define DIR_SEP_STRING "/"
|
|
Packit |
a4aae4 |
#define DIR_SEP_CHAR '/'
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <pthread.h>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <fstream>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "debug.h"
|
|
Packit |
a4aae4 |
#include "RCReader.h"
|
|
Packit |
a4aae4 |
#include "Error.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
using namespace std;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
RCReader* RCReader::_instance = 0;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// This variable (instance_control) is used to ensure that in a MT
|
|
Packit |
a4aae4 |
// environment _instance is correctly initialized. See the get_instance
|
|
Packit |
a4aae4 |
// method. 08/07/02 jhrg
|
|
Packit |
a4aae4 |
static pthread_once_t instance_control = PTHREAD_ONCE_INIT;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Using values from this instance of RCReader, write out values for a
|
|
Packit |
a4aae4 |
default .dodsrc file. Nominally this will use the defaults for each thing
|
|
Packit |
a4aae4 |
that might be read from the configuration file. */
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool RCReader::write_rc_file(const string &pathname)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBG(cerr << "Writing the RC file to " << pathname << endl);
|
|
Packit |
a4aae4 |
ofstream fpo(pathname.c_str());
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// If the file couldn't be created. Nothing needs to be done here,
|
|
Packit |
a4aae4 |
// the program will simply use the defaults.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (fpo) {
|
|
Packit |
a4aae4 |
// This means we just created the file. We will now save
|
|
Packit |
a4aae4 |
// the defaults in it for future use.
|
|
Packit |
a4aae4 |
fpo << "# OPeNDAP client configuration file. See the OPeNDAP" << endl;
|
|
Packit |
a4aae4 |
fpo << "# users guide for information." << endl;
|
|
Packit |
a4aae4 |
fpo << "USE_CACHE=" << _dods_use_cache << endl;
|
|
Packit |
a4aae4 |
fpo << "# Cache and object size are given in megabytes (20 ==> 20Mb)." << endl;
|
|
Packit |
a4aae4 |
fpo << "MAX_CACHE_SIZE=" << _dods_cache_max << endl;
|
|
Packit |
a4aae4 |
fpo << "MAX_CACHED_OBJ=" << _dods_cached_obj << endl;
|
|
Packit |
a4aae4 |
fpo << "IGNORE_EXPIRES=" << _dods_ign_expires << endl;
|
|
Packit |
a4aae4 |
fpo << "CACHE_ROOT=" << d_cache_root << endl;
|
|
Packit |
a4aae4 |
fpo << "DEFAULT_EXPIRES=" << _dods_default_expires << endl;
|
|
Packit |
a4aae4 |
fpo << "ALWAYS_VALIDATE=" << _dods_always_validate << endl;
|
|
Packit |
a4aae4 |
fpo << "# Request servers compress responses if possible?" << endl;
|
|
Packit |
a4aae4 |
fpo << "# 1 (yes) or 0 (false)." << endl;
|
|
Packit |
a4aae4 |
fpo << "DEFLATE=" << _dods_deflate << endl;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fpo << "# Should SSL certificates and hosts be validated? SSL" << endl;
|
|
Packit |
a4aae4 |
fpo << "# will only work with signed certificates." << endl;
|
|
Packit |
a4aae4 |
fpo << "VALIDATE_SSL=" << d_validate_ssl << endl;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fpo << "# Proxy configuration (optional parts in []s)." << endl;
|
|
Packit |
a4aae4 |
fpo << "# You may also use the 'http_proxy' environment variable" << endl;
|
|
Packit |
a4aae4 |
fpo << "# but a value in this file will override that env variable." << endl;
|
|
Packit |
a4aae4 |
fpo << "# PROXY_SERVER=[http://][username:password@]host[:port]" << endl;
|
|
Packit |
a4aae4 |
if (!d_dods_proxy_server_host.empty()) {
|
|
Packit |
a4aae4 |
fpo << "PROXY_SERVER=" << d_dods_proxy_server_protocol << "://"
|
|
Packit |
a4aae4 |
<< (d_dods_proxy_server_userpw.empty() ? "" : d_dods_proxy_server_userpw + "@")
|
|
Packit |
a4aae4 |
+ d_dods_proxy_server_host + ":" + long_to_string(d_dods_proxy_server_port) << endl;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fpo << "# NO_PROXY_FOR=<host|domain>" << endl;
|
|
Packit |
a4aae4 |
if (!d_dods_no_proxy_for_host.empty()) {
|
|
Packit |
a4aae4 |
fpo << "NO_PROXY_FOR=" << d_dods_no_proxy_for_host << endl;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fpo << "# AIS_DATABASE=<file or url>" << endl;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fpo << "# COOKIE_JAR=.dods_cookies" << endl;
|
|
Packit |
a4aae4 |
fpo << "# The cookie jar is a file that holds cookies sent from" << endl;
|
|
Packit |
a4aae4 |
fpo << "# servers such as single signon systems. Uncomment this" << endl;
|
|
Packit |
a4aae4 |
fpo << "# option and provide a file name to activate this feature." << endl;
|
|
Packit |
a4aae4 |
fpo << "# If the value is a filename, it will be created in this" << endl;
|
|
Packit |
a4aae4 |
fpo << "# directory; a full pathname can be used to force a specific" << endl;
|
|
Packit |
a4aae4 |
fpo << "# location." << endl;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fpo.close();
|
|
Packit |
a4aae4 |
return true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool RCReader::read_rc_file(const string &pathname)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBG(cerr << "Reading the RC file from " << pathname << endl);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
ifstream fpi(pathname.c_str());
|
|
Packit |
a4aae4 |
if (fpi) {
|
|
Packit |
a4aae4 |
// The file exists and we may now begin to parse it.
|
|
Packit |
a4aae4 |
// Defaults are already stored in the variables, if the correct
|
|
Packit |
a4aae4 |
// tokens are found in the file then those defaults will be
|
|
Packit |
a4aae4 |
// overwritten.
|
|
Packit |
a4aae4 |
char *value;
|
|
Packit |
a4aae4 |
// TODO Replace with a vector<char>
|
|
Packit |
a4aae4 |
//char *tempstr = new char[1024];
|
|
Packit |
a4aae4 |
vector<char> tempstr(1024);
|
|
Packit |
a4aae4 |
int tokenlength;
|
|
Packit |
a4aae4 |
while (true) {
|
|
Packit |
a4aae4 |
fpi.getline(&tempstr[0], 1023);
|
|
Packit |
a4aae4 |
if (!fpi.good()) break;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
value = strchr(&tempstr[0], '=');
|
|
Packit |
a4aae4 |
if (!value) continue;
|
|
Packit |
a4aae4 |
tokenlength = value - &tempstr[0];
|
|
Packit |
a4aae4 |
value++;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if ((strncmp(&tempstr[0], "USE_CACHE", 9) == 0) && tokenlength == 9) {
|
|
Packit |
a4aae4 |
_dods_use_cache = atoi(value) ? true : false;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if ((strncmp(&tempstr[0], "MAX_CACHE_SIZE", 14) == 0) && tokenlength == 14) {
|
|
Packit |
a4aae4 |
_dods_cache_max = atoi(value);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if ((strncmp(&tempstr[0], "MAX_CACHED_OBJ", 14) == 0) && tokenlength == 14) {
|
|
Packit |
a4aae4 |
_dods_cached_obj = atoi(value);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if ((strncmp(&tempstr[0], "IGNORE_EXPIRES", 14) == 0) && tokenlength == 14) {
|
|
Packit |
a4aae4 |
_dods_ign_expires = atoi(value);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if ((strncmp(&tempstr[0], "DEFLATE", 7) == 0) && tokenlength == 7) {
|
|
Packit |
a4aae4 |
_dods_deflate = atoi(value) ? true : false;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if ((strncmp(&tempstr[0], "CACHE_ROOT", 10) == 0) && tokenlength == 10) {
|
|
Packit |
a4aae4 |
d_cache_root = value;
|
|
Packit |
a4aae4 |
if (d_cache_root[d_cache_root.length() - 1] != DIR_SEP_CHAR) d_cache_root += string(DIR_SEP_STRING);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if ((strncmp(&tempstr[0], "DEFAULT_EXPIRES", 15) == 0) && tokenlength == 15) {
|
|
Packit |
a4aae4 |
_dods_default_expires = atoi(value);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if ((strncmp(&tempstr[0], "ALWAYS_VALIDATE", 15) == 0) && tokenlength == 15) {
|
|
Packit |
a4aae4 |
_dods_always_validate = atoi(value);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if ((strncmp(&tempstr[0], "VALIDATE_SSL", 12) == 0) && tokenlength == 12) {
|
|
Packit |
a4aae4 |
d_validate_ssl = atoi(value);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if (strncmp(&tempstr[0], "AIS_DATABASE", 12) == 0 && tokenlength == 12) {
|
|
Packit |
a4aae4 |
d_ais_database = value;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if (strncmp(&tempstr[0], "COOKIE_JAR", 10) == 0 && tokenlength == 10) {
|
|
Packit |
a4aae4 |
// if the value of COOKIE_JAR starts with a slash, use it as
|
|
Packit |
a4aae4 |
// is. However, if it does not start with a slash, prefix it
|
|
Packit |
a4aae4 |
// with the directory that contains the .dodsrc file.
|
|
Packit |
a4aae4 |
if (value[0] == '/') {
|
|
Packit |
a4aae4 |
d_cookie_jar = value;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
d_cookie_jar = d_rc_file_path.substr(0, d_rc_file_path.find(".dodsrc")) + string(value);
|
|
Packit |
a4aae4 |
} DBG(cerr << "set cookie jar to: " << d_cookie_jar << endl);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if ((strncmp(&tempstr[0], "PROXY_SERVER", 12) == 0) && tokenlength == 12) {
|
|
Packit |
a4aae4 |
// Setup a proxy server for all requests.
|
|
Packit |
a4aae4 |
// The original syntax was <protocol>,<machine> where the
|
|
Packit |
a4aae4 |
// machine could also contain the user/pass and port info.
|
|
Packit |
a4aae4 |
// Support that but also support machine prefixed by
|
|
Packit |
a4aae4 |
// 'http://' with and without the '<protocol>,' prefix. jhrg
|
|
Packit |
a4aae4 |
// 4/21/08 (see bug 1095).
|
|
Packit |
a4aae4 |
string proxy = value;
|
|
Packit |
a4aae4 |
string::size_type comma = proxy.find(',');
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Since the <protocol> is now optional, the comma might be
|
|
Packit |
a4aae4 |
// here. If it is, check that the protocol given is http.
|
|
Packit |
a4aae4 |
if (comma != string::npos) {
|
|
Packit |
a4aae4 |
d_dods_proxy_server_protocol = proxy.substr(0, comma);
|
|
Packit |
a4aae4 |
downcase(d_dods_proxy_server_protocol);
|
|
Packit |
a4aae4 |
if (d_dods_proxy_server_protocol != "http")
|
|
Packit |
a4aae4 |
throw Error("The only supported protocol for a proxy server is \"HTTP\". Correct your \".dodsrc\" file.");
|
|
Packit |
a4aae4 |
proxy = proxy.substr(comma + 1);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
d_dods_proxy_server_protocol = "http";
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Look for a 'protocol://' prefix; skip if found
|
|
Packit |
a4aae4 |
string::size_type protocol = proxy.find("://");
|
|
Packit |
a4aae4 |
if (protocol != string::npos) {
|
|
Packit |
a4aae4 |
proxy = proxy.substr(protocol + 3);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Break apart into userpw, host and port.
|
|
Packit |
a4aae4 |
string::size_type at_sign = proxy.find('@');
|
|
Packit |
a4aae4 |
if (at_sign != string::npos) { // has userpw
|
|
Packit |
a4aae4 |
d_dods_proxy_server_userpw = proxy.substr(0, at_sign);
|
|
Packit |
a4aae4 |
proxy = proxy.substr(at_sign + 1);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else
|
|
Packit |
a4aae4 |
d_dods_proxy_server_userpw = "";
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Get host and look for a port number
|
|
Packit |
a4aae4 |
string::size_type colon = proxy.find(':');
|
|
Packit |
a4aae4 |
if (colon != string::npos) {
|
|
Packit |
a4aae4 |
d_dods_proxy_server_host = proxy.substr(0, colon);
|
|
Packit |
a4aae4 |
d_dods_proxy_server_port = strtol(proxy.substr(colon + 1).c_str(), 0, 0);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
d_dods_proxy_server_host = proxy;
|
|
Packit |
a4aae4 |
d_dods_proxy_server_port = 80;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if ((strncmp(&tempstr[0], "NO_PROXY_FOR", 12) == 0) && tokenlength == 12) {
|
|
Packit |
a4aae4 |
// Setup a proxy server for all requests.
|
|
Packit |
a4aae4 |
string no_proxy = value;
|
|
Packit |
a4aae4 |
string::size_type comma = no_proxy.find(',');
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Since the protocol is required, the comma *must* be
|
|
Packit |
a4aae4 |
// present. We could throw an Error on the malformed line...
|
|
Packit |
a4aae4 |
if (comma == string::npos) {
|
|
Packit |
a4aae4 |
d_dods_no_proxy_for_protocol = "http";
|
|
Packit |
a4aae4 |
d_dods_no_proxy_for_host = no_proxy;
|
|
Packit |
a4aae4 |
d_dods_no_proxy_for = true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
d_dods_no_proxy_for_protocol = no_proxy.substr(0, comma);
|
|
Packit |
a4aae4 |
d_dods_no_proxy_for_host = no_proxy.substr(comma + 1);
|
|
Packit |
a4aae4 |
d_dods_no_proxy_for = true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
//delete [] tempstr; tempstr = 0;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
fpi.close(); // Close the .dodsrc file. 12/14/99 jhrg
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return true;
|
|
Packit |
a4aae4 |
} // End of cache file parsing.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Helper for check_env_var(). This is its main logic, separated out for the
|
|
Packit |
a4aae4 |
// cases under WIN32 where we don't use an environment variable. 09/19/03
|
|
Packit |
a4aae4 |
// jhrg
|
|
Packit |
a4aae4 |
string RCReader::check_string(string env_var)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBG(cerr << "Entering check_string... (" << env_var << ")" << endl);
|
|
Packit |
a4aae4 |
struct stat stat_info;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (stat(env_var.c_str(), &stat_info) != 0) {
|
|
Packit |
a4aae4 |
DBG(cerr << "stat returned non-zero" << endl);
|
|
Packit |
a4aae4 |
return ""; // ENV VAR not a file or dir, bail
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (S_ISREG(stat_info.st_mode)) {
|
|
Packit |
a4aae4 |
DBG(cerr << "S_ISREG: " << S_ISREG(stat_info.st_mode) << endl);
|
|
Packit |
a4aae4 |
return env_var; // ENV VAR is a file, use it
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// ENV VAR is a directory, does it contain .dodsrc? Can we create
|
|
Packit |
a4aae4 |
// .dodsrc if it's not there?
|
|
Packit |
a4aae4 |
if (S_ISDIR(stat_info.st_mode)) {
|
|
Packit |
a4aae4 |
DBG(cerr << "S_ISDIR: " << S_ISDIR(stat_info.st_mode) << endl);
|
|
Packit |
a4aae4 |
if (*env_var.rbegin() != DIR_SEP_CHAR) // Add trailing / if missing
|
|
Packit |
a4aae4 |
env_var += DIR_SEP_STRING;
|
|
Packit |
a4aae4 |
// Trick: set d_cache_root here in case we're going to create the
|
|
Packit |
a4aae4 |
// .dodsrc later on. If the .dodsrc file exists, its value will
|
|
Packit |
a4aae4 |
// overwrite this value, if not write_rc_file() will use the correct
|
|
Packit |
a4aae4 |
// value. 09/19/03 jhrg
|
|
Packit |
a4aae4 |
d_cache_root = env_var + string(".dods_cache") + DIR_SEP_STRING;
|
|
Packit |
a4aae4 |
env_var += ".dodsrc";
|
|
Packit |
a4aae4 |
if (stat(env_var.c_str(), &stat_info) == 0 && S_ISREG(stat_info.st_mode)) {
|
|
Packit |
a4aae4 |
DBG(cerr << "Found .dodsrc in \"" << env_var << "\"" << endl);
|
|
Packit |
a4aae4 |
return env_var; // Found .dodsrc in ENV VAR
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Didn't find .dodsrc in ENV VAR and ENV VAR is a directory; try to
|
|
Packit |
a4aae4 |
// create it. Note write_rc_file uses d_cache_root (set above) when
|
|
Packit |
a4aae4 |
// it creates the RC file's contents.
|
|
Packit |
a4aae4 |
if (write_rc_file(env_var)) {
|
|
Packit |
a4aae4 |
DBG(cerr << "Wrote .dodsrc in \"" << env_var << "\"" << endl);
|
|
Packit |
a4aae4 |
return env_var;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// If we're here, then we've neither found nor created the RC file.
|
|
Packit |
a4aae4 |
DBG(cerr << "could neither find nor create a .dodsrc file" << endl);
|
|
Packit |
a4aae4 |
return "";
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Examine an environment variable. If the env variable is set, then if
|
|
Packit |
a4aae4 |
this is the name of a file, use that as the name of the RC file. If this
|
|
Packit |
a4aae4 |
is the name of a directory, look in that directory for a file called
|
|
Packit |
a4aae4 |
.dodsrc. If there's no such file, create it using default values for its
|
|
Packit |
a4aae4 |
parameters. In the last case, write the .dodsrc so that the .dods_cache
|
|
Packit |
a4aae4 |
directory is located in the directory named by DODS_CONF.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@return The pathname to the RC file or "" if another variable/method
|
|
Packit |
a4aae4 |
should be used to find/create the RC file. */
|
|
Packit |
a4aae4 |
string RCReader::check_env_var(const string &variable_name)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
char *ev = getenv(variable_name.c_str());
|
|
Packit |
a4aae4 |
if (!ev || strlen(ev) == 0) return "";
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return check_string(ev);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
RCReader::RCReader() // throw (Error) jhrg 7/2/15
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
d_rc_file_path = "";
|
|
Packit |
a4aae4 |
d_cache_root = "";
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// ** Set default values **
|
|
Packit |
a4aae4 |
// Users must explicitly turn caching on.
|
|
Packit |
a4aae4 |
_dods_use_cache = false;
|
|
Packit |
a4aae4 |
_dods_cache_max = 20;
|
|
Packit |
a4aae4 |
_dods_cached_obj = 5;
|
|
Packit |
a4aae4 |
_dods_ign_expires = 0;
|
|
Packit |
a4aae4 |
_dods_default_expires = 86400;
|
|
Packit |
a4aae4 |
_dods_always_validate = 0;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
_dods_deflate = 0;
|
|
Packit |
a4aae4 |
d_validate_ssl = 1;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
//flags for PROXY_SERVER=<protocol>,<host url>
|
|
Packit |
a4aae4 |
// New syntax PROXY_SERVER=[http://][user:pw@]host[:port]
|
|
Packit |
a4aae4 |
d_dods_proxy_server_protocol = "";
|
|
Packit |
a4aae4 |
d_dods_proxy_server_host = "";
|
|
Packit |
a4aae4 |
d_dods_proxy_server_port = 0;
|
|
Packit |
a4aae4 |
d_dods_proxy_server_userpw = "";
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
_dods_proxy_server_host_url = ""; // deprecated
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// PROXY_FOR is deprecated.
|
|
Packit |
a4aae4 |
// flags for PROXY_FOR=<regex>,<proxy host url>,<flags>
|
|
Packit |
a4aae4 |
_dods_proxy_for = false; // true if proxy_for is used.
|
|
Packit |
a4aae4 |
_dods_proxy_for_regexp = "";
|
|
Packit |
a4aae4 |
_dods_proxy_for_proxy_host_url = "";
|
|
Packit |
a4aae4 |
_dods_proxy_for_regexp_flags = 0;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
//flags for NO_PROXY_FOR=<protocol>,<host>,<port>
|
|
Packit |
a4aae4 |
// New syntax NO_PROXY_FOR=<host|domain>
|
|
Packit |
a4aae4 |
d_dods_no_proxy_for = false;
|
|
Packit |
a4aae4 |
d_dods_no_proxy_for_protocol = ""; // deprecated
|
|
Packit |
a4aae4 |
d_dods_no_proxy_for_host = "";
|
|
Packit |
a4aae4 |
// default to port 0 if not specified. This means all ports. Using 80
|
|
Packit |
a4aae4 |
// will fail when the URL does not contain the port number. That's
|
|
Packit |
a4aae4 |
// probably a bug in libwww. 10/23/2000 jhrg
|
|
Packit |
a4aae4 |
_dods_no_proxy_for_port = 0; // deprecated
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
d_cookie_jar = "";
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#ifdef WIN32
|
|
Packit |
a4aae4 |
string homedir = string("C:") + string(DIR_SEP_STRING) + string("Dods");
|
|
Packit |
a4aae4 |
d_rc_file_path = check_string(homedir);
|
|
Packit |
a4aae4 |
if (d_rc_file_path.empty()) {
|
|
Packit |
a4aae4 |
homedir = string("C:") + string(DIR_SEP_STRING) + string("opendap");
|
|
Packit |
a4aae4 |
d_rc_file_path = check_string(homedir);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
// Normally, I'd prefer this for WinNT-based systems.
|
|
Packit |
a4aae4 |
if (d_rc_file_path.empty())
|
|
Packit |
a4aae4 |
d_rc_file_path = check_env_var("APPDATA");
|
|
Packit |
a4aae4 |
if (d_rc_file_path.empty())
|
|
Packit |
a4aae4 |
d_rc_file_path = check_env_var("TEMP");
|
|
Packit |
a4aae4 |
if (d_rc_file_path.empty())
|
|
Packit |
a4aae4 |
d_rc_file_path = check_env_var("TMP");
|
|
Packit |
a4aae4 |
#else
|
|
Packit |
a4aae4 |
d_rc_file_path = check_env_var("DODS_CONF");
|
|
Packit |
a4aae4 |
if (d_rc_file_path.empty()) d_rc_file_path = check_env_var("HOME");
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
DBG(cerr << "Looking for .dodsrc in: " << d_rc_file_path << endl);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (!d_rc_file_path.empty()) read_rc_file(d_rc_file_path);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
RCReader::~RCReader()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Static void private method. */
|
|
Packit |
a4aae4 |
void RCReader::delete_instance()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (RCReader::_instance) {
|
|
Packit |
a4aae4 |
delete RCReader::_instance;
|
|
Packit |
a4aae4 |
RCReader::_instance = 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Static void private method. */
|
|
Packit |
a4aae4 |
void RCReader::initialize_instance()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBGN(cerr << "RCReader::initialize_instance() ... ");
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
RCReader::_instance = new RCReader;
|
|
Packit |
a4aae4 |
atexit(RCReader::delete_instance);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
DBG(cerr << "exiting." << endl);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
RCReader*
|
|
Packit |
a4aae4 |
RCReader::instance()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBG(cerr << "Entring RCReader::instance" << endl);
|
|
Packit |
a4aae4 |
// The instance_control variable is defined at the top of this file.
|
|
Packit |
a4aae4 |
// 08/07/02 jhrg
|
|
Packit |
a4aae4 |
pthread_once(&instance_control, initialize_instance);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
DBG(cerr << "Instance value: " << hex << _instance << dec << endl);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return _instance;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#if 0
|
|
Packit |
a4aae4 |
RCReader*
|
|
Packit |
a4aae4 |
RCReader::instance(const string &rc_file_path)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBG(cerr << "Entring RCReader::instance" << endl);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
d_rc_file_path = rc_file_path;
|
|
Packit |
a4aae4 |
// The instance_control variable is defined at the top of this file.
|
|
Packit |
a4aae4 |
// 08/07/02 jhrg
|
|
Packit |
a4aae4 |
pthread_once(&instance_control, initialize_instance);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
DBG(cerr << "Instance value: " << hex << _instance << dec << endl);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return _instance;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
} // namespace libdap
|