convert express to new config system; add more options to pencrypt and OEncryptStream
This commit is contained in:
parent
04ac1fd281
commit
18ced11d6c
|
|
@ -131,7 +131,7 @@ help() {
|
|||
" encrypted using different passwords (although this requires running\n"
|
||||
" multify multiple times). It is not possible to encrypt the multifile's\n"
|
||||
" table of contents using this interface, but see the pencrypt program to\n"
|
||||
" encrypt the entire multifile after it has been generated).\n\n"
|
||||
" encrypt the entire multifile after it has been generated.\n\n"
|
||||
|
||||
|
||||
" -p \"password\"\n"
|
||||
|
|
|
|||
|
|
@ -46,17 +46,44 @@ usage() {
|
|||
<< " Specifies the password to use for encryption. There are no\n"
|
||||
<< " restrictions on the password length or contents, but longer passwords\n"
|
||||
<< " are more secure. If this is not specified, the user is prompted from\n"
|
||||
<< " standard input.\n\n";
|
||||
<< " standard input.\n\n"
|
||||
|
||||
<< " -a \"algorithm\"\n"
|
||||
<< " Specifies the particular encryption algorithm to use. The complete\n"
|
||||
<< " set of available algorithms is defined by the current version of\n"
|
||||
<< " OpenSSL. The default algorithm is taken from the encryption-\n"
|
||||
<< " algorithm config variable.\n\n"
|
||||
|
||||
<< " -k key_length\n"
|
||||
<< " Specifies the key length, in bits, for the selected encryption\n"
|
||||
<< " algorithm. This only makes sense for those algorithms that support\n"
|
||||
<< " a variable key length. The default value is taken from the\n"
|
||||
<< " encryption-key-length config variable.\n\n"
|
||||
|
||||
<< " -i iteration_count\n"
|
||||
<< " Specifies the number of times the password is hashed to generate\n"
|
||||
<< " a key. The only purpose of this is to make it computationally\n"
|
||||
<< " more expensive for an attacker to search the key space exhaustively.\n"
|
||||
<< " This should be a multiple of 1,000 and should not exceed about 65\n"
|
||||
<< " million; the value 0 indicates just one application of the hashing\n"
|
||||
<< " algorithm. The default value is taken from the encryption-iteration-\n"
|
||||
<< " count config variable.\n\n";
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
const char *optstr = "p:h";
|
||||
const char *optstr = "p:a:k:i:h";
|
||||
|
||||
string password;
|
||||
bool got_password = false;
|
||||
string algorithm;
|
||||
bool got_algorithm = false;
|
||||
int key_length = 0;
|
||||
bool got_key_length = false;
|
||||
int iteration_count = 0;
|
||||
bool got_iteration_count = false;
|
||||
|
||||
int flag = getopt(argc, argv, optstr);
|
||||
|
||||
|
|
@ -67,6 +94,21 @@ main(int argc, char *argv[]) {
|
|||
got_password = true;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
algorithm = optarg;
|
||||
got_algorithm = true;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
key_length = atoi(optarg);
|
||||
got_key_length = true;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
iteration_count = atoi(optarg);
|
||||
got_iteration_count = true;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
default:
|
||||
|
|
@ -119,7 +161,17 @@ main(int argc, char *argv[]) {
|
|||
|
||||
bool fail = false;
|
||||
{
|
||||
OEncryptStream encrypt(&write_stream, false, password);
|
||||
OEncryptStream encrypt;
|
||||
if (got_algorithm) {
|
||||
encrypt.set_algorithm(algorithm);
|
||||
}
|
||||
if (got_key_length) {
|
||||
encrypt.set_key_length(key_length);
|
||||
}
|
||||
if (got_iteration_count) {
|
||||
encrypt.set_iteration_count(iteration_count);
|
||||
}
|
||||
encrypt.open(&write_stream, false, password);
|
||||
|
||||
int ch = read_stream.get();
|
||||
while (!read_stream.eof() && !read_stream.fail()) {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
datagramGenerator.h \
|
||||
datagramIterator.I datagramIterator.h datagramSink.I datagramSink.h \
|
||||
dcast.T dcast.h \
|
||||
encryptStreamBuf.h encryptStream.h encryptStream.I \
|
||||
encryptStreamBuf.h encryptStreamBuf.I encryptStream.h encryptStream.I \
|
||||
error_utils.h \
|
||||
get_config_path.h \
|
||||
hashGeneratorBase.I hashGeneratorBase.h \
|
||||
|
|
@ -144,7 +144,7 @@
|
|||
datagramGenerator.I datagramGenerator.h \
|
||||
datagramIterator.I datagramIterator.h \
|
||||
datagramSink.I datagramSink.h dcast.T dcast.h \
|
||||
encryptStreamBuf.h encryptStream.h encryptStream.I \
|
||||
encryptStreamBuf.h encryptStreamBuf.I encryptStream.h encryptStream.I \
|
||||
error_utils.h get_config_path.h \
|
||||
hashGeneratorBase.I \
|
||||
hashGeneratorBase.h hashVal.I hashVal.h \
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "clockObject.h"
|
||||
#include "config_express.h"
|
||||
#include "configVariableEnum.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
|
|
@ -243,10 +244,12 @@ void ClockObject::
|
|||
make_global_clock() {
|
||||
nassertv(_global_clock == (ClockObject *)NULL);
|
||||
|
||||
// Make sure we have run init_libexpress() by this time. This
|
||||
// function is responsible for initializing the clock_mode Configrc
|
||||
// variable.
|
||||
init_libexpress();
|
||||
ConfigVariableEnum<ClockObject::Mode> clock_mode
|
||||
("clock-mode", ClockObject::M_normal,
|
||||
"Specifies the mode of the global clock. The default mode, normal, "
|
||||
"is a real-time clock; other modes allow non-real-time special "
|
||||
"effects like simulated reduced frame rate. See "
|
||||
"ClockObject::set_mode().");
|
||||
|
||||
_global_clock = new ClockObject;
|
||||
_global_clock->set_mode(clock_mode);
|
||||
|
|
@ -259,3 +262,52 @@ make_global_clock() {
|
|||
void get_time_of_day(TimeVal &tv) {
|
||||
get_true_time_of_day(tv.tv[0], tv.tv[1]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClockObject::Mode ostream operator
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ostream &
|
||||
operator << (ostream &out, ClockObject::Mode mode) {
|
||||
switch (mode) {
|
||||
case ClockObject::M_normal:
|
||||
return out << "normal";
|
||||
|
||||
case ClockObject::M_non_real_time:
|
||||
return out << "non-real-time";
|
||||
|
||||
case ClockObject::M_forced:
|
||||
return out << "forced";
|
||||
|
||||
case ClockObject::M_degrade:
|
||||
return out << "degrade";
|
||||
};
|
||||
|
||||
return out << "**invalid ClockObject::Mode(" << (int)mode << ")**";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClockObject::Mode istream operator
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
istream &
|
||||
operator >> (istream &in, ClockObject::Mode &mode) {
|
||||
string word;
|
||||
in >> word;
|
||||
|
||||
if (word == "normal") {
|
||||
mode = ClockObject::M_normal;
|
||||
} else if (word == "non-real-time") {
|
||||
mode = ClockObject::M_non_real_time;
|
||||
} else if (word == "forced") {
|
||||
mode = ClockObject::M_forced;
|
||||
} else if (word == "degrade") {
|
||||
mode = ClockObject::M_degrade;
|
||||
} else {
|
||||
express_cat.error()
|
||||
<< "Invalid ClockObject::Mode: " << word << "\n";
|
||||
mode = ClockObject::M_normal;
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,6 +132,9 @@ private:
|
|||
static ClockObject *_global_clock;
|
||||
};
|
||||
|
||||
ostream &operator << (ostream &out, ClockObject::Mode mode);
|
||||
istream &operator >> (istream &in, ClockObject::Mode &mode);
|
||||
|
||||
#include "clockObject.I"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -43,83 +43,94 @@ ConfigureFn(config_express) {
|
|||
init_libexpress();
|
||||
}
|
||||
|
||||
const int patchfile_window_size =
|
||||
config_express.GetInt("patchfile-window-size", 16);
|
||||
ConfigVariableInt patchfile_window_size
|
||||
("patchfile-window-size", 16);
|
||||
|
||||
const int patchfile_increment_size =
|
||||
config_express.GetInt("patchfile-increment-size", 8);
|
||||
ConfigVariableInt patchfile_increment_size
|
||||
("patchfile-increment-size", 8);
|
||||
|
||||
const int patchfile_buffer_size =
|
||||
config_express.GetInt("patchfile-buffer-size", 4096);
|
||||
ConfigVariableInt patchfile_buffer_size
|
||||
("patchfile-buffer-size", 4096);
|
||||
|
||||
const int patchfile_zone_size =
|
||||
config_express.GetInt("patchfile-zone-size", 10000);
|
||||
ConfigVariableInt patchfile_zone_size
|
||||
("patchfile-zone-size", 10000);
|
||||
|
||||
// Set this true to keep around the temporary files from downloading,
|
||||
// decompressing, and patching, or false (the default) to delete
|
||||
// these. Mainly useful for debugging when the process goes wrong.
|
||||
const bool keep_temporary_files =
|
||||
config_express.GetBool("keep-temporary-files", false);
|
||||
ConfigVariableBool keep_temporary_files
|
||||
("keep-temporary-files", false,
|
||||
"Set this true to keep around the temporary files from downloading, "
|
||||
"decompressing, and patching, or false (the default) to delete "
|
||||
"these. Mainly useful for debugging when the process goes wrong.");
|
||||
|
||||
const double average_frame_rate_interval =
|
||||
config_express.GetDouble("average-frame-rate-interval", 1.0);
|
||||
ConfigVariableDouble average_frame_rate_interval
|
||||
("average-frame-rate-interval", 1.0);
|
||||
|
||||
ClockObject::Mode clock_mode = ClockObject::M_normal;
|
||||
const double clock_frame_rate =
|
||||
config_express.GetDouble("clock-frame-rate", 1.0);
|
||||
const double clock_degrade_factor =
|
||||
config_express.GetDouble("clock-degrade-factor", 1.0);
|
||||
const double max_dt =
|
||||
config_express.GetDouble("max-dt", -1.0);
|
||||
ConfigVariableDouble clock_frame_rate
|
||||
("clock-frame-rate", 1.0);
|
||||
ConfigVariableDouble clock_degrade_factor
|
||||
("clock-degrade-factor", 1.0);
|
||||
ConfigVariableDouble max_dt
|
||||
("max-dt", -1.0);
|
||||
|
||||
// This is the accuracy within which we can expect select() to return
|
||||
// precisely. That is, if we use select() to request a timeout of 1.0
|
||||
// seconds, we can expect to actually sleep for somewhere between 1.0
|
||||
// and 1.0 + sleep-precision seconds.
|
||||
const double sleep_precision =
|
||||
config_express.GetDouble("sleep-precision", 0.01);
|
||||
ConfigVariableDouble sleep_precision
|
||||
("sleep-precision", 0.01,
|
||||
"This is the accuracy within which we can expect select() to return "
|
||||
"precisely. That is, if we use select() to request a timeout of 1.0 "
|
||||
"seconds, we can expect to actually sleep for somewhere between 1.0 "
|
||||
"and 1.0 + sleep-precision seconds.");
|
||||
|
||||
// This defines the OpenSSL encryption algorithm which is used to
|
||||
// encrypt any streams created by the current runtime. The default is
|
||||
// Blowfish; the complete set of available algorithms is defined by
|
||||
// the current version of OpenSSL. This value is used only to control
|
||||
// encryption; the correct algorithm will automatically be selected on
|
||||
// decryption.
|
||||
const string encryption_algorithm =
|
||||
config_express.GetString("encryption-algorithm", "bf-cbc");
|
||||
ConfigVariableString encryption_algorithm
|
||||
("encryption-algorithm", "bf-cbc",
|
||||
"This defines the OpenSSL encryption algorithm which is used to "
|
||||
"encrypt any streams created by the current runtime. The default is "
|
||||
"Blowfish; the complete set of available algorithms is defined by "
|
||||
"the current version of OpenSSL. This value is used only to control "
|
||||
"encryption; the correct algorithm will automatically be selected on "
|
||||
"decryption.");
|
||||
|
||||
// This defines the key length, in bits, for the selected encryption
|
||||
// algorithm. Some algorithms have a variable key length. Specifying
|
||||
// a value of 0 here means to use the default key length for the
|
||||
// algorithm as defined by OpenSSL. This value is used only to
|
||||
// control encryption; the correct key length will automatically be
|
||||
// selected on decryption.
|
||||
const int encryption_key_length =
|
||||
config_express.GetInt("encryption-key-length", 0);
|
||||
ConfigVariableInt encryption_key_length
|
||||
("encryption-key-length", 0,
|
||||
"This defines the key length, in bits, for the selected encryption "
|
||||
"algorithm. Some algorithms have a variable key length. Specifying "
|
||||
"a value of 0 here means to use the default key length for the "
|
||||
"algorithm as defined by OpenSSL. This value is used only to "
|
||||
"control encryption; the correct key length will automatically be "
|
||||
"selected on decryption.");
|
||||
|
||||
// This defines the number of times a password is hashed to generate a
|
||||
// key when encrypting. Its purpose is to make it computationally
|
||||
// more expensive for an attacker to search the key space
|
||||
// exhaustively. This should be a multiple of 1,000 and should not
|
||||
// exceed about 65 million; the value 0 indicates just one application
|
||||
// of the hashing algorithm. This value is used only to control
|
||||
// encryption; the correct count will automatically be selected on
|
||||
// decryption.
|
||||
const int encryption_iteration_count =
|
||||
config_express.GetInt("encryption-iteration-count", 100000);
|
||||
ConfigVariableInt encryption_iteration_count
|
||||
("encryption-iteration-count", 100000,
|
||||
"This defines the number of times a password is hashed to generate a "
|
||||
"key when encrypting. Its purpose is to make it computationally "
|
||||
"more expensive for an attacker to search the key space "
|
||||
"exhaustively. This should be a multiple of 1,000 and should not "
|
||||
"exceed about 65 million; the value 0 indicates just one application "
|
||||
"of the hashing algorithm. This value is used only to control "
|
||||
"encryption; the correct count will automatically be selected on "
|
||||
"decryption.");
|
||||
|
||||
// Set this true to use the VirtualFileSystem mechanism for loading
|
||||
// models, etc. Since the VirtualFileSystem maps to the same as the
|
||||
// actual file system by default, there is probably no reason to set
|
||||
// this false, except for testing or if you mistrust the new code.
|
||||
const bool use_vfs = config_express.GetBool("use-vfs", true);
|
||||
ConfigVariableInt multifile_encryption_iteration_count
|
||||
("multifile-encryption-iteration-count", 0,
|
||||
"This is a special value of encryption-iteration-count used to encrypt "
|
||||
"subfiles within a multifile. It has a default value of 0 (just one "
|
||||
"application), on the assumption that the files from a multifile must "
|
||||
"be loaded quickly, without paying the cost of an expensive hash on "
|
||||
"each subfile in order to decrypt it.");
|
||||
|
||||
// Set this true to enable accumulation of several small consecutive
|
||||
// TCP datagrams into one large datagram before sending it, to reduce
|
||||
// overhead from the TCP/IP protocol. See
|
||||
// Connection::set_collect_tcp() or SocketStream::set_collect_tcp().
|
||||
const bool collect_tcp = config_express.GetBool("collect-tcp", false);
|
||||
const double collect_tcp_interval = config_express.GetDouble("collect-tcp-interval", 0.2);
|
||||
ConfigVariableBool use_vfs
|
||||
("use-vfs", true,
|
||||
"Set this true to use the VirtualFileSystem mechanism for loading "
|
||||
"models, etc. Since the VirtualFileSystem maps to the same as the "
|
||||
"actual file system by default, there is probably no reason to set "
|
||||
"this false, except for testing or if you mistrust the new code.");
|
||||
|
||||
ConfigVariableBool collect_tcp
|
||||
("collect-tcp", false,
|
||||
"Set this true to enable accumulation of several small consecutive "
|
||||
"TCP datagrams into one large datagram before sending it, to reduce "
|
||||
"overhead from the TCP/IP protocol. See "
|
||||
"Connection::set_collect_tcp() or SocketStream::set_collect_tcp().");
|
||||
|
||||
ConfigVariableDouble collect_tcp_interval
|
||||
("collect-tcp-interval", 0.2);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: init_libexpress
|
||||
|
|
@ -151,115 +162,104 @@ init_libexpress() {
|
|||
VirtualFileSimple::init_type();
|
||||
|
||||
init_system_type_handles();
|
||||
|
||||
string text_encoding = config_express.GetString("text-encoding", "iso8859");
|
||||
if (text_encoding == "iso8859") {
|
||||
TextEncoder::set_default_encoding(TextEncoder::E_iso8859);
|
||||
} else if (text_encoding == "utf8") {
|
||||
TextEncoder::set_default_encoding(TextEncoder::E_utf8);
|
||||
} else if (text_encoding == "unicode") {
|
||||
TextEncoder::set_default_encoding(TextEncoder::E_unicode);
|
||||
} else {
|
||||
express_cat.error()
|
||||
<< "Invalid text-encoding: " << text_encoding << "\n";
|
||||
}
|
||||
|
||||
string clock_mode_str = config_express.GetString("clock-mode", "normal");
|
||||
if (clock_mode_str == "normal") {
|
||||
clock_mode = ClockObject::M_normal;
|
||||
} else if (clock_mode_str == "non-real-time") {
|
||||
clock_mode = ClockObject::M_non_real_time;
|
||||
} else if (clock_mode_str == "forced") {
|
||||
clock_mode = ClockObject::M_forced;
|
||||
} else if (clock_mode_str == "degrade") {
|
||||
clock_mode = ClockObject::M_degrade;
|
||||
} else {
|
||||
express_cat.error()
|
||||
<< "Invalid clock-mode: " << clock_mode_str << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set leak-memory true to disable the actual deletion of
|
||||
// ReferenceCount-derived objects. This is sometimes useful to track
|
||||
// a reference counting bug, since the formerly deleted objects will
|
||||
// still remain (with a reference count of -100) without being
|
||||
// overwritten with a newly-allocated object, and the assertion tests
|
||||
// in ReferenceCount may more accurately detect the first instance of
|
||||
// an error.
|
||||
bool
|
||||
get_leak_memory() {
|
||||
static bool got_leak_memory = false;
|
||||
static bool leak_memory;
|
||||
static ConfigVariableBool *leak_memory = NULL;
|
||||
|
||||
if (!got_leak_memory) {
|
||||
leak_memory = config_express.GetBool("leak-memory", false);
|
||||
got_leak_memory = true;
|
||||
if (leak_memory == (ConfigVariableBool *)NULL) {
|
||||
leak_memory = new ConfigVariableBool
|
||||
("leak-memory", false,
|
||||
"Set leak-memory true to disable the actual deletion of "
|
||||
"ReferenceCount-derived objects. This is sometimes useful to track "
|
||||
"a reference counting bug, since the formerly deleted objects will "
|
||||
"still remain (with a reference count of -100) without being "
|
||||
"overwritten with a newly-allocated object, and the assertion tests "
|
||||
"in ReferenceCount may more accurately detect the first instance of "
|
||||
"an error.");
|
||||
}
|
||||
|
||||
return leak_memory;
|
||||
return *leak_memory;
|
||||
}
|
||||
|
||||
// never-destruct is similar to leak-memory, above, except that not
|
||||
// only will memory not be freed, but the destructor will not even be
|
||||
// called (on ReferenceCount objects, at least). This will leak gobs
|
||||
// of memory, but ensures that every pointer to a ReferenceCount
|
||||
// object will always be valid, and may be useful for tracking down
|
||||
// certain kinds of errors.
|
||||
|
||||
// never-destruct is only respected if leak-memory, above, is true.
|
||||
bool
|
||||
get_never_destruct() {
|
||||
static bool got_never_destruct = false;
|
||||
static bool never_destruct;
|
||||
static ConfigVariableBool *never_destruct = NULL;
|
||||
|
||||
if (!got_never_destruct) {
|
||||
never_destruct = config_express.GetBool("never-destruct", false);
|
||||
got_never_destruct = true;
|
||||
if (never_destruct == (ConfigVariableBool *)NULL) {
|
||||
never_destruct = new ConfigVariableBool
|
||||
("never-destruct", false,
|
||||
"never-destruct is similar to leak-memory, except that not "
|
||||
"only will memory not be freed, but the destructor will not even be "
|
||||
"called (on ReferenceCount objects, at least). This will leak gobs "
|
||||
"of memory, but ensures that every pointer to a ReferenceCount "
|
||||
"object will always be valid, and may be useful for tracking down "
|
||||
"certain kinds of errors. "
|
||||
"never-destruct is only respected if leak-memory is true.");
|
||||
}
|
||||
|
||||
return never_destruct;
|
||||
return *never_destruct;
|
||||
}
|
||||
|
||||
//const bool track_memory_usage = config_express.GetBool("track-memory-usage", false);
|
||||
|
||||
// Set this to false to avoid using the high-precision clock, even if
|
||||
// it is available.
|
||||
bool
|
||||
get_use_high_res_clock() {
|
||||
return config_express.GetBool("use-high-res-clock", true);
|
||||
}
|
||||
static ConfigVariableBool *use_high_res_clock = NULL;
|
||||
|
||||
// Set this to true to double-check the results of the high-resolution
|
||||
// clock against the system clock. This has no effect if NDEBUG is
|
||||
// defined.
|
||||
bool
|
||||
get_paranoid_clock() {
|
||||
return config_express.GetBool("paranoid-clock", false);
|
||||
}
|
||||
|
||||
// Set this to true to double-check the test for inheritance of
|
||||
// TypeHandles, e.g. via is_of_type(). This has no effect if NDEBUG
|
||||
// is defined.
|
||||
bool
|
||||
get_paranoid_inheritance() {
|
||||
return config_express.GetBool("paranoid-inheritance", true);
|
||||
}
|
||||
|
||||
// Set this to true to verify that every attempted DCAST operation in
|
||||
// fact references the correct type, or false otherwise. This has no
|
||||
// effect if NDEBUG is defined, in which case it is never tested.
|
||||
bool
|
||||
get_verify_dcast() {
|
||||
static bool got_verify_dcast = false;
|
||||
static bool verify_dcast;
|
||||
|
||||
if (!got_verify_dcast) {
|
||||
verify_dcast = config_express.GetBool("verify-dcast", true);
|
||||
got_verify_dcast = true;
|
||||
if (use_high_res_clock == (ConfigVariableBool *)NULL) {
|
||||
use_high_res_clock = new ConfigVariableBool
|
||||
("use-high-res-clock", true,
|
||||
"Set this to false to avoid using the high-precision clock, even if "
|
||||
"it is available.");
|
||||
}
|
||||
|
||||
return verify_dcast;
|
||||
return *use_high_res_clock;
|
||||
}
|
||||
|
||||
bool
|
||||
get_paranoid_clock() {
|
||||
static ConfigVariableBool *paranoid_clock = NULL;
|
||||
|
||||
if (paranoid_clock == (ConfigVariableBool *)NULL) {
|
||||
paranoid_clock = new ConfigVariableBool
|
||||
("paranoid-clock", false,
|
||||
"Set this to true to double-check the results of the high-resolution "
|
||||
"clock against the system clock. This has no effect if NDEBUG is "
|
||||
"defined.");
|
||||
}
|
||||
|
||||
return *paranoid_clock;
|
||||
}
|
||||
|
||||
bool
|
||||
get_paranoid_inheritance() {
|
||||
static ConfigVariableBool *paranoid_inheritance = NULL;
|
||||
|
||||
if (paranoid_inheritance == (ConfigVariableBool *)NULL) {
|
||||
paranoid_inheritance = new ConfigVariableBool
|
||||
("paranoid-inheritance", true,
|
||||
"Set this to true to double-check the test for inheritance of "
|
||||
"TypeHandles, e.g. via is_of_type(). This has no effect if NDEBUG "
|
||||
"is defined.");
|
||||
}
|
||||
|
||||
return *paranoid_inheritance;
|
||||
}
|
||||
|
||||
bool
|
||||
get_verify_dcast() {
|
||||
static ConfigVariableBool *verify_dcast = NULL;
|
||||
|
||||
if (verify_dcast == (ConfigVariableBool *)NULL) {
|
||||
verify_dcast = new ConfigVariableBool
|
||||
("verify-dcast", true,
|
||||
"Set this to true to verify that every attempted DCAST operation in "
|
||||
"fact references the correct type, or false otherwise. This has no "
|
||||
"effect if NDEBUG is defined, in which case it is never tested.");
|
||||
}
|
||||
|
||||
return *verify_dcast;
|
||||
}
|
||||
|
||||
// Returns the configure object for accessing config variables from a
|
||||
|
|
|
|||
|
|
@ -59,28 +59,28 @@ EXPCL_PANDAEXPRESS bool get_paranoid_clock();
|
|||
EXPCL_PANDAEXPRESS bool get_paranoid_inheritance();
|
||||
EXPCL_PANDAEXPRESS bool get_verify_dcast();
|
||||
|
||||
extern const int patchfile_window_size;
|
||||
extern const int patchfile_increment_size;
|
||||
extern const int patchfile_buffer_size;
|
||||
extern const int patchfile_zone_size;
|
||||
extern ConfigVariableInt patchfile_window_size;
|
||||
extern ConfigVariableInt patchfile_increment_size;
|
||||
extern ConfigVariableInt patchfile_buffer_size;
|
||||
extern ConfigVariableInt patchfile_zone_size;
|
||||
|
||||
extern const bool keep_temporary_files;
|
||||
extern const double average_frame_rate_interval;
|
||||
extern ConfigVariableBool keep_temporary_files;
|
||||
extern ConfigVariableDouble average_frame_rate_interval;
|
||||
|
||||
extern ClockObject::Mode clock_mode;
|
||||
extern const double clock_frame_rate;
|
||||
extern const double clock_degrade_factor;
|
||||
extern const double max_dt;
|
||||
extern const double sleep_precision;
|
||||
extern ConfigVariableDouble clock_frame_rate;
|
||||
extern ConfigVariableDouble clock_degrade_factor;
|
||||
extern ConfigVariableDouble max_dt;
|
||||
extern ConfigVariableDouble sleep_precision;
|
||||
|
||||
extern const string encryption_algorithm;
|
||||
extern const int encryption_key_length;
|
||||
extern const int encryption_iteration_count;
|
||||
extern ConfigVariableString encryption_algorithm;
|
||||
extern ConfigVariableInt encryption_key_length;
|
||||
extern ConfigVariableInt encryption_iteration_count;
|
||||
extern ConfigVariableInt multifile_encryption_iteration_count;
|
||||
|
||||
extern EXPCL_PANDAEXPRESS const bool use_vfs;
|
||||
extern EXPCL_PANDAEXPRESS ConfigVariableBool use_vfs;
|
||||
|
||||
extern EXPCL_PANDAEXPRESS const bool collect_tcp;
|
||||
extern EXPCL_PANDAEXPRESS const double collect_tcp_interval;
|
||||
extern EXPCL_PANDAEXPRESS ConfigVariableBool collect_tcp;
|
||||
extern EXPCL_PANDAEXPRESS ConfigVariableDouble collect_tcp_interval;
|
||||
|
||||
// Expose the Config variable for Python access.
|
||||
BEGIN_PUBLISH
|
||||
|
|
|
|||
|
|
@ -61,6 +61,38 @@ close() {
|
|||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: IDecryptStream::get_algorithm
|
||||
// Access: Public
|
||||
// Description: Returns the encryption algorithm that was read from
|
||||
// the stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &IDecryptStream::
|
||||
get_algorithm() const {
|
||||
return _buf.get_algorithm();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: IDecryptStream::get_key_length
|
||||
// Access: Public
|
||||
// Description: Returns the encryption key length, in bits, that was
|
||||
// read from the stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int IDecryptStream::
|
||||
get_key_length() const {
|
||||
return _buf.get_key_length();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: IDecryptStream::get_iteration_count
|
||||
// Access: Public
|
||||
// Description: Returns the value that was was read from the stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int IDecryptStream::
|
||||
get_iteration_count() const {
|
||||
return _buf.get_iteration_count();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OEncryptStream::Constructor
|
||||
|
|
@ -107,3 +139,59 @@ close() {
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OEncryptStream::set_algorithm
|
||||
// Access: Public
|
||||
// Description: Specifies the encryption algorithm that should be
|
||||
// used for future calls to open(). The default
|
||||
// is whatever is specified by the encryption-algorithm
|
||||
// config variable. The complete set of available
|
||||
// algorithms is defined by the current version of
|
||||
// OpenSSL.
|
||||
//
|
||||
// If an invalid algorithm is specified, there is no
|
||||
// immediate error return code, but open() will
|
||||
// fail.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void OEncryptStream::
|
||||
set_algorithm(const string &algorithm) {
|
||||
_buf.set_algorithm(algorithm);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OEncryptStream::set_key_length
|
||||
// Access: Public
|
||||
// Description: Specifies the length of the key, in bits, that should
|
||||
// be used to encrypt the stream in future calls to
|
||||
// open(). The default is whatever is specified
|
||||
// by the encryption-key-length config variable.
|
||||
//
|
||||
// If an invalid key_length for the chosen algorithm is
|
||||
// specified, there is no immediate error return code,
|
||||
// but open() will fail.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void OEncryptStream::
|
||||
set_key_length(int key_length) {
|
||||
_buf.set_key_length(key_length);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OEncryptStream::set_iteration_count
|
||||
// Access: Public
|
||||
// Description: Specifies the number of times to repeatedly hash the
|
||||
// key before writing it to the stream in future calls
|
||||
// to open(). Its purpose is to make it
|
||||
// computationally more expensive for an attacker to
|
||||
// search the key space exhaustively. This should be a
|
||||
// multiple of 1,000 and should not exceed about 65
|
||||
// million; the value 0 indicates just one application
|
||||
// of the hashing algorithm.
|
||||
//
|
||||
// The default is whatever is specified by the
|
||||
// encryption-iteration-count config variable.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void OEncryptStream::
|
||||
set_iteration_count(int iteration_count) {
|
||||
_buf.set_iteration_count(iteration_count);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@ public:
|
|||
const string &password);
|
||||
INLINE IDecryptStream &close();
|
||||
|
||||
INLINE const string &get_algorithm() const;
|
||||
INLINE int get_key_length() const;
|
||||
INLINE int get_iteration_count() const;
|
||||
|
||||
private:
|
||||
EncryptStreamBuf _buf;
|
||||
};
|
||||
|
|
@ -73,6 +77,10 @@ public:
|
|||
const string &password);
|
||||
INLINE OEncryptStream &close();
|
||||
|
||||
INLINE void set_algorithm(const string &algorithm);
|
||||
INLINE void set_key_length(int key_length);
|
||||
INLINE void set_iteration_count(int iteration_count);
|
||||
|
||||
private:
|
||||
EncryptStreamBuf _buf;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
// Filename: encryptStreamBuf.I
|
||||
// Created by: drose (09Dec04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EncryptStreamBuf::set_algorithm
|
||||
// Access: Public
|
||||
// Description: Specifies the encryption algorithm that should be
|
||||
// used for future calls to open_write(). The default
|
||||
// is whatever is specified by the encryption-algorithm
|
||||
// config variable. The complete set of available
|
||||
// algorithms is defined by the current version of
|
||||
// OpenSSL.
|
||||
//
|
||||
// If an invalid algorithm is specified, there is no
|
||||
// immediate error return code, but open_write() will
|
||||
// fail.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EncryptStreamBuf::
|
||||
set_algorithm(const string &algorithm) {
|
||||
_algorithm = algorithm;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EncryptStreamBuf::get_algorithm
|
||||
// Access: Public
|
||||
// Description: Returns the encryption algorithm that was specified
|
||||
// by set_algorithm(), or was read from the stream by
|
||||
// the last successful open_read().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &EncryptStreamBuf::
|
||||
get_algorithm() const {
|
||||
return _algorithm;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EncryptStreamBuf::set_key_length
|
||||
// Access: Public
|
||||
// Description: Specifies the length of the key, in bits, that should
|
||||
// be used to encrypt the stream in future calls to
|
||||
// open_write(). The default is whatever is specified
|
||||
// by the encryption-key-length config variable.
|
||||
//
|
||||
// If an invalid key_length for the chosen algorithm is
|
||||
// specified, there is no immediate error return code,
|
||||
// but open_write() will fail.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EncryptStreamBuf::
|
||||
set_key_length(int key_length) {
|
||||
_key_length = key_length;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EncryptStreamBuf::get_key_length
|
||||
// Access: Public
|
||||
// Description: Returns the encryption key length, in bits, that was
|
||||
// specified by set_key_length(), or was read from the
|
||||
// stream by the last successful open_read().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int EncryptStreamBuf::
|
||||
get_key_length() const {
|
||||
return _key_length;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EncryptStreamBuf::set_iteration_count
|
||||
// Access: Public
|
||||
// Description: Specifies the number of times to repeatedly hash the
|
||||
// key before writing it to the stream in future calls
|
||||
// to open_write(). Its purpose is to make it
|
||||
// computationally more expensive for an attacker to
|
||||
// search the key space exhaustively. This should be a
|
||||
// multiple of 1,000 and should not exceed about 65
|
||||
// million; the value 0 indicates just one application
|
||||
// of the hashing algorithm.
|
||||
//
|
||||
// The default is whatever is specified by the
|
||||
// encryption-iteration-count config variable.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EncryptStreamBuf::
|
||||
set_iteration_count(int iteration_count) {
|
||||
_iteration_count = iteration_count;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EncryptStreamBuf::get_iteration_count
|
||||
// Access: Public
|
||||
// Description: Returns the value that was specified by
|
||||
// set_iteration_count(), or was read from the stream by
|
||||
// the last successful open_read().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int EncryptStreamBuf::
|
||||
get_iteration_count() const {
|
||||
return _iteration_count;
|
||||
}
|
||||
|
|
@ -46,6 +46,10 @@ EncryptStreamBuf() {
|
|||
_dest = (ostream *)NULL;
|
||||
_owns_dest = false;
|
||||
|
||||
_algorithm = encryption_algorithm;
|
||||
_key_length = encryption_key_length;
|
||||
_iteration_count = encryption_iteration_count;
|
||||
|
||||
_read_valid = false;
|
||||
_write_valid = false;
|
||||
|
||||
|
|
@ -103,9 +107,17 @@ open_read(istream *source, bool owns_source, const string &password) {
|
|||
return;
|
||||
}
|
||||
|
||||
express_cat.debug()
|
||||
<< "Using decryption algorithm " << OBJ_nid2sn(nid) << " with key length "
|
||||
<< key_length * 8 << " bits.\n";
|
||||
_algorithm = OBJ_nid2sn(nid);
|
||||
_key_length = key_length * 8;
|
||||
_iteration_count = count * iteration_count_factor;
|
||||
|
||||
if (express_cat.is_debug()) {
|
||||
express_cat.debug()
|
||||
<< "Using decryption algorithm " << _algorithm << " with key length "
|
||||
<< _key_length << " bits.\n";
|
||||
express_cat.debug()
|
||||
<< "Key is hashed " << _iteration_count << " extra times.\n";
|
||||
}
|
||||
|
||||
int iv_length = EVP_CIPHER_iv_length(cipher);
|
||||
_read_block_size = EVP_CIPHER_block_size(cipher);
|
||||
|
|
@ -186,11 +198,11 @@ open_write(ostream *dest, bool owns_dest, const string &password) {
|
|||
_write_valid = false;
|
||||
|
||||
const EVP_CIPHER *cipher =
|
||||
EVP_get_cipherbyname(encryption_algorithm.c_str());
|
||||
EVP_get_cipherbyname(_algorithm.c_str());
|
||||
|
||||
if (cipher == NULL) {
|
||||
express_cat.error()
|
||||
<< "Unknown encryption algorithm: " << encryption_algorithm << "\n";
|
||||
<< "Unknown encryption algorithm: " << _algorithm << "\n";
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
@ -210,7 +222,7 @@ open_write(ostream *dest, bool owns_dest, const string &password) {
|
|||
nassertv(result > 0);
|
||||
|
||||
// Store the appropriate key length in the context.
|
||||
int key_length = (encryption_key_length + 7) / 8;
|
||||
int key_length = (_key_length + 7) / 8;
|
||||
if (key_length == 0) {
|
||||
key_length = EVP_CIPHER_CTX_key_length(cipher);
|
||||
}
|
||||
|
|
@ -223,12 +235,18 @@ open_write(ostream *dest, bool owns_dest, const string &password) {
|
|||
return;
|
||||
}
|
||||
|
||||
express_cat.debug()
|
||||
<< "Using encryption algorithm " << OBJ_nid2sn(nid) << " with key length "
|
||||
<< key_length * 8 << " bits.\n";
|
||||
int count = _iteration_count / iteration_count_factor;
|
||||
|
||||
if (express_cat.is_debug()) {
|
||||
express_cat.debug()
|
||||
<< "Using encryption algorithm " << OBJ_nid2sn(nid) << " with key length "
|
||||
<< key_length * 8 << " bits.\n";
|
||||
express_cat.debug()
|
||||
<< "Hashing key " << count * iteration_count_factor
|
||||
<< " extra times.\n";
|
||||
}
|
||||
|
||||
// Hash the supplied password into a key of the appropriate length.
|
||||
int count = encryption_iteration_count / iteration_count_factor;
|
||||
unsigned char *key = (unsigned char *)alloca(key_length);
|
||||
result =
|
||||
PKCS5_PBKDF2_HMAC_SHA1((const char *)password.data(), password.length(),
|
||||
|
|
|
|||
|
|
@ -42,6 +42,15 @@ public:
|
|||
void open_write(ostream *dest, bool owns_dest, const string &password);
|
||||
void close_write();
|
||||
|
||||
INLINE void set_algorithm(const string &algorithm);
|
||||
INLINE const string &get_algorithm() const;
|
||||
|
||||
INLINE void set_key_length(int key_length);
|
||||
INLINE int get_key_length() const;
|
||||
|
||||
INLINE void set_iteration_count(int iteration_count);
|
||||
INLINE int get_iteration_count() const;
|
||||
|
||||
protected:
|
||||
virtual int overflow(int c);
|
||||
virtual int sync(void);
|
||||
|
|
@ -57,6 +66,10 @@ private:
|
|||
|
||||
ostream *_dest;
|
||||
bool _owns_dest;
|
||||
|
||||
string _algorithm;
|
||||
int _key_length;
|
||||
int _iteration_count;
|
||||
|
||||
bool _read_valid;
|
||||
EVP_CIPHER_CTX _read_ctx;
|
||||
|
|
@ -69,6 +82,8 @@ private:
|
|||
size_t _write_block_size;
|
||||
};
|
||||
|
||||
#include "encryptStreamBuf.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -379,19 +379,19 @@ MemoryUsage() {
|
|||
// time, and who knows when the code in config_express will be
|
||||
// executed.
|
||||
|
||||
// track-memory-usage should be true to enable full-force tracking
|
||||
// of C++ allocations and recordkeeping by type. It's quite
|
||||
// expensive.
|
||||
_track_memory_usage =
|
||||
config_express.GetBool("track-memory-usage", false);
|
||||
_track_memory_usage = ConfigVariableBool
|
||||
("track-memory-usage", false,
|
||||
"Set this to true to enable full-force tracking of C++ allocations "
|
||||
"and recordkeeping by type. It's quite expensive.");
|
||||
|
||||
// count-memory-usage is a much lighter-weight version, and only
|
||||
// tracks the total memory allocation. However, it only works for
|
||||
// certain build environments (in particular, only in an Opt1 or
|
||||
// Opt2 build on Windows).
|
||||
#if defined(WIN32_VC) && defined(_DEBUG)
|
||||
_count_memory_usage = config_express.GetBool("count-memory-usage",
|
||||
_track_memory_usage);
|
||||
_count_memory_usage = ConfigVariableBool
|
||||
("count-memory-usage", _track_memory_usage,
|
||||
"This is a much lighter-weight version of track-memory-usage, and it "
|
||||
"only tracks the total memory allocation. However, it only exists in "
|
||||
"certain build environments (in particular, only in an Opt1 or "
|
||||
"Opt2 build on Windows.");
|
||||
|
||||
#else
|
||||
_count_memory_usage = false;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1573,8 +1573,11 @@ write_data(ostream &write, istream *read, streampos fpos,
|
|||
#else // HAVE_ZLIB
|
||||
if ((_flags & SF_encrypted) != 0) {
|
||||
// Write it encrypted.
|
||||
putter = new OEncryptStream(putter, delete_putter,
|
||||
multifile->_encryption_password);
|
||||
OEncryptStream *encrypt = new OEncryptStream;
|
||||
encrypt->set_iteration_count(multifile_encryption_iteration_count);
|
||||
encrypt->open(putter, delete_putter, multifile->_encryption_password);
|
||||
|
||||
putter = encrypt;
|
||||
delete_putter = true;
|
||||
|
||||
// Also write the encrypt_header to the beginning of the
|
||||
|
|
|
|||
|
|
@ -21,7 +21,10 @@
|
|||
#include "unicodeLatinMap.h"
|
||||
|
||||
TypeHandle TextEncoder::_type_handle;
|
||||
TextEncoder::Encoding TextEncoder::_default_encoding;
|
||||
ConfigVariableEnum<TextEncoder::Encoding> TextEncoder::_default_encoding
|
||||
("default-encoding", TextEncoder::E_iso8859,
|
||||
"Specifies how international characters are represented in strings "
|
||||
"of 8-byte characters presented to Panda. See TextEncoder::set_encoding().");
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextEncoder::make_upper
|
||||
|
|
@ -321,3 +324,47 @@ expand_amp_sequence(StringDecoder &decoder) const {
|
|||
}
|
||||
*/
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextEncoder::Encoding ostream operator
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ostream &
|
||||
operator << (ostream &out, TextEncoder::Encoding encoding) {
|
||||
switch (encoding) {
|
||||
case TextEncoder::E_iso8859:
|
||||
return out << "iso8859";
|
||||
|
||||
case TextEncoder::E_utf8:
|
||||
return out << "utf8";
|
||||
|
||||
case TextEncoder::E_unicode:
|
||||
return out << "unicode";
|
||||
};
|
||||
|
||||
return out << "**invalid TextEncoder::Encoding(" << (int)encoding << ")**";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextEncoder::Encoding istream operator
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
istream &
|
||||
operator >> (istream &in, TextEncoder::Encoding &encoding) {
|
||||
string word;
|
||||
in >> word;
|
||||
|
||||
if (word == "iso8859") {
|
||||
encoding = TextEncoder::E_iso8859;
|
||||
} else if (word == "utf8") {
|
||||
encoding = TextEncoder::E_utf8;
|
||||
} else if (word == "unicode") {
|
||||
encoding = TextEncoder::E_unicode;
|
||||
} else {
|
||||
express_cat.error()
|
||||
<< "Invalid TextEncoder::Encoding: " << word << "\n";
|
||||
encoding = TextEncoder::E_iso8859;
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
#include "unicodeLatinMap.h"
|
||||
#include "configVariableEnum.h"
|
||||
|
||||
class StringDecoder;
|
||||
|
||||
|
|
@ -112,7 +113,7 @@ private:
|
|||
string _text;
|
||||
wstring _wtext;
|
||||
|
||||
static Encoding _default_encoding;
|
||||
static ConfigVariableEnum<Encoding> _default_encoding;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
@ -126,6 +127,9 @@ private:
|
|||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
ostream &operator << (ostream &out, TextEncoder::Encoding encoding);
|
||||
istream &operator >> (istream &in, TextEncoder::Encoding &encoding);
|
||||
|
||||
#include "textEncoder.I"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -504,72 +504,67 @@ get_global_ptr() {
|
|||
_global_ptr->chdir(ExecutionEnvironment::get_cwd());
|
||||
|
||||
// Then, we add whatever mounts are listed in the Configrc file.
|
||||
Config::ConfigTable::Symbol mounts;
|
||||
config_express.GetAll("vfs-mount", mounts);
|
||||
ConfigVariableList mounts
|
||||
("vfs-mount",
|
||||
"vfs-mount system-filename mount-point [options]");
|
||||
|
||||
// When we use GetAll(), we might inadvertently read duplicate
|
||||
// lines. Filter them out with a set.
|
||||
pset<string> already_read;
|
||||
int num_unique_values = mounts.get_num_unique_values();
|
||||
for (int i = 0; i < num_unique_values; i++) {
|
||||
string mount_desc = mounts.get_unique_value(i);
|
||||
|
||||
Config::ConfigTable::Symbol::iterator si;
|
||||
for (si = mounts.begin(); si != mounts.end(); ++si) {
|
||||
string mount_desc = (*si).Val();
|
||||
if (already_read.insert(mount_desc).second) {
|
||||
|
||||
// The vfs-mount syntax is:
|
||||
|
||||
// vfs-mount system-filename mount-point [options]
|
||||
|
||||
// The last two spaces mark the beginning of the mount point,
|
||||
// and of the options, respectively. There might be multiple
|
||||
// spaces in the system filename, which are part of the
|
||||
// filename.
|
||||
|
||||
// The last space marks the beginning of the mount point.
|
||||
// Spaces before that are part of the system filename.
|
||||
size_t space = mount_desc.rfind(' ');
|
||||
if (space == string::npos) {
|
||||
express_cat.warning()
|
||||
<< "No space in vfs-mount descriptor: " << mount_desc << "\n";
|
||||
|
||||
} else {
|
||||
string mount_point = mount_desc.substr(space + 1);
|
||||
// The vfs-mount syntax is:
|
||||
|
||||
// vfs-mount system-filename mount-point [options]
|
||||
|
||||
// The last two spaces mark the beginning of the mount point,
|
||||
// and of the options, respectively. There might be multiple
|
||||
// spaces in the system filename, which are part of the
|
||||
// filename.
|
||||
|
||||
// The last space marks the beginning of the mount point.
|
||||
// Spaces before that are part of the system filename.
|
||||
size_t space = mount_desc.rfind(' ');
|
||||
if (space == string::npos) {
|
||||
express_cat.warning()
|
||||
<< "No space in vfs-mount descriptor: " << mount_desc << "\n";
|
||||
|
||||
} else {
|
||||
string mount_point = mount_desc.substr(space + 1);
|
||||
while (space > 0 && isspace(mount_desc[space - 1])) {
|
||||
space--;
|
||||
}
|
||||
mount_desc = mount_desc.substr(0, space);
|
||||
string options;
|
||||
|
||||
space = mount_desc.rfind(' ');
|
||||
if (space != string::npos) {
|
||||
// If there's another space, we have the optional options field.
|
||||
options = mount_point;
|
||||
mount_point = mount_desc.substr(space + 1);
|
||||
while (space > 0 && isspace(mount_desc[space - 1])) {
|
||||
space--;
|
||||
}
|
||||
mount_desc = mount_desc.substr(0, space);
|
||||
string options;
|
||||
|
||||
space = mount_desc.rfind(' ');
|
||||
if (space != string::npos) {
|
||||
// If there's another space, we have the optional options field.
|
||||
options = mount_point;
|
||||
mount_point = mount_desc.substr(space + 1);
|
||||
while (space > 0 && isspace(mount_desc[space - 1])) {
|
||||
space--;
|
||||
}
|
||||
mount_desc = mount_desc.substr(0, space);
|
||||
}
|
||||
|
||||
mount_desc = ExecutionEnvironment::expand_string(mount_desc);
|
||||
Filename physical_filename = Filename::from_os_specific(mount_desc);
|
||||
|
||||
int flags = 0;
|
||||
string password;
|
||||
|
||||
// Split the options up by commas.
|
||||
size_t p = 0;
|
||||
size_t q = options.find(',', p);
|
||||
while (q != string::npos) {
|
||||
parse_option(options.substr(p, q - p),
|
||||
flags, password);
|
||||
p = q + 1;
|
||||
q = options.find(',', p);
|
||||
}
|
||||
parse_option(options.substr(p), flags, password);
|
||||
|
||||
_global_ptr->mount(physical_filename, mount_point, flags, password);
|
||||
}
|
||||
|
||||
mount_desc = ExecutionEnvironment::expand_string(mount_desc);
|
||||
Filename physical_filename = Filename::from_os_specific(mount_desc);
|
||||
|
||||
int flags = 0;
|
||||
string password;
|
||||
|
||||
// Split the options up by commas.
|
||||
size_t p = 0;
|
||||
size_t q = options.find(',', p);
|
||||
while (q != string::npos) {
|
||||
parse_option(options.substr(p, q - p),
|
||||
flags, password);
|
||||
p = q + 1;
|
||||
q = options.find(',', p);
|
||||
}
|
||||
parse_option(options.substr(p), flags, password);
|
||||
|
||||
_global_ptr->mount(physical_filename, mount_point, flags, password);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue