29 #include "prc_parameters.h"    34 #ifdef PRC_PUBLIC_KEYS_INCLUDE    35 #include PRC_PUBLIC_KEYS_INCLUDE    57   _loaded_implicit = 
false;
    58   _currently_loading = 
false;
    61 #ifdef PRC_PUBLIC_KEYS_INCLUDE    63   PrcKeyRegistry::get_global_ptr()->record_keys(prc_pubkeys, num_prc_pubkeys);
    64 #endif  // PRC_PUBLIC_KEYS_INCLUDE    72 ~ConfigPageManager() {
    74     << 
"Internal error--ConfigPageManager destructor called!\n";
    86   if (_currently_loading) {
    91   _currently_loading = 
true;
    95   for (pi = _implicit_pages.begin(); pi != _implicit_pages.end(); ++pi) {
    98   _implicit_pages.clear();
   103     uint64_t blob_offset;
   106     uint16_t num_pointers;
   110     const void *module_table;
   111     const char *prc_data;
   112     const char *default_prc_dir;
   113     const char *prc_dir_envvars;
   114     const char *prc_path_envvars;
   115     const char *prc_patterns;
   116     const char *prc_encrypted_patterns;
   117     const char *prc_encryption_key;
   118     const char *prc_executable_patterns;
   119     const char *prc_executable_args_envvar;
   120     const char *main_dir;
   121     const char *log_filename;
   124   const BlobInfo *blobinfo = (
const BlobInfo *)GetProcAddress(GetModuleHandle(NULL), 
"blobinfo");
   125 #elif defined(RTLD_MAIN_ONLY)   126   const BlobInfo *blobinfo = (
const BlobInfo *)dlsym(RTLD_MAIN_ONLY, 
"blobinfo");
   130   const BlobInfo *blobinfo = (
const BlobInfo *)dlsym(dlopen(NULL, RTLD_NOW), 
"blobinfo");
   132   if (blobinfo == 
nullptr) {
   137   } 
else if (blobinfo->version == 0 || blobinfo->num_pointers < 10) {
   141   if (blobinfo != 
nullptr) {
   142     if (blobinfo->num_pointers >= 11 && blobinfo->main_dir != 
nullptr) {
   153   _prc_patterns.clear();
   155   string prc_patterns = PRC_PATTERNS;
   156   if (blobinfo != 
nullptr && blobinfo->prc_patterns != 
nullptr) {
   157     prc_patterns = blobinfo->prc_patterns;
   159   if (!prc_patterns.empty()) {
   160     vector_string pat_list;
   162     _prc_patterns.reserve(pat_list.size());
   163     for (
size_t i = 0; i < pat_list.size(); ++i) {
   170       _prc_patterns.push_back(glob);
   175   _prc_encrypted_patterns.clear();
   177   string prc_encrypted_patterns = PRC_ENCRYPTED_PATTERNS;
   178   if (blobinfo != 
nullptr && blobinfo->prc_encrypted_patterns != 
nullptr) {
   179     prc_encrypted_patterns = blobinfo->prc_encrypted_patterns;
   181   if (!prc_encrypted_patterns.empty()) {
   182     vector_string pat_list;
   184     _prc_encrypted_patterns.reserve(pat_list.size());
   185     for (
size_t i = 0; i < pat_list.size(); ++i) {
   190       _prc_encrypted_patterns.push_back(glob);
   195   _prc_executable_patterns.clear();
   197   string prc_executable_patterns = PRC_EXECUTABLE_PATTERNS;
   198   if (blobinfo != 
nullptr && blobinfo->prc_executable_patterns != 
nullptr) {
   199     prc_executable_patterns = blobinfo->prc_executable_patterns;
   201   if (!prc_executable_patterns.empty()) {
   202     vector_string pat_list;
   204     _prc_executable_patterns.reserve(pat_list.size());
   205     for (
size_t i = 0; i < pat_list.size(); ++i) {
   210       _prc_executable_patterns.push_back(glob);
   215   _search_path.
clear();
   220   string prc_dir_envvars = PRC_DIR_ENVVARS;
   221   if (blobinfo != 
nullptr && blobinfo->prc_dir_envvars != 
nullptr) {
   222     prc_dir_envvars = blobinfo->prc_dir_envvars;
   224   if (!prc_dir_envvars.empty()) {
   225     vector_string prc_dir_envvar_list;
   227     for (
size_t i = 0; i < prc_dir_envvar_list.size(); ++i) {
   229       if (!prc_dir.empty()) {
   232         if (scan_auto_prc_dir(prc_dir_filename)) {
   242   string prc_path_envvars = PRC_PATH_ENVVARS;
   243   if (blobinfo != 
nullptr && blobinfo->prc_path_envvars != 
nullptr) {
   244     prc_path_envvars = blobinfo->prc_path_envvars;
   246   if (!prc_path_envvars.empty()) {
   247     vector_string prc_path_envvar_list;
   249     for (
size_t i = 0; i < prc_path_envvar_list.size(); ++i) {
   252       while (p < path.length()) {
   253         size_t q = path.find_first_of(DEFAULT_PATHSEP, p);
   254         if (q == string::npos) {
   259         if (scan_auto_prc_dir(prc_dir_filename)) {
   276   string prc_path2_envvars = PRC_PATH2_ENVVARS;
   277   if (!prc_path2_envvars.empty() && blobinfo == 
nullptr) {
   278     vector_string prc_path_envvar_list;
   280     for (
size_t i = 0; i < prc_path_envvar_list.size(); ++i) {
   283       while (p < path.length()) {
   284         size_t q = path.find_first_of(
' ', p);
   285         if (q == string::npos) {
   288         Filename prc_dir_filename = path.substr(p, q - p);
   289         if (scan_auto_prc_dir(prc_dir_filename)) {
   300     string default_prc_dir = DEFAULT_PRC_DIR;
   301     if (blobinfo != 
nullptr && blobinfo->default_prc_dir != 
nullptr) {
   302       default_prc_dir = blobinfo->default_prc_dir;
   304     if (!default_prc_dir.empty()) {
   306       Filename prc_dir_filename = default_prc_dir;
   307       if (scan_auto_prc_dir(prc_dir_filename)) {
   315   ConfigFiles config_files;
   319   std::set<Filename> unique_dirnames;
   328       if (unique_dirnames.insert(canonical).second) {
   337         vector_string::reverse_iterator fi;
   338         for (fi = files.rbegin(); fi != files.rend(); ++fi) {
   340           Globs::const_iterator gi;
   341           for (gi = _prc_patterns.begin();
   342                gi != _prc_patterns.end();
   344             if ((*gi).matches(*fi)) {
   345               file_flags |= FF_read;
   349           for (gi = _prc_encrypted_patterns.begin();
   350                gi != _prc_encrypted_patterns.end();
   352             if ((*gi).matches(*fi)) {
   353               file_flags |= FF_read | FF_decrypt;
   357           for (gi = _prc_executable_patterns.begin();
   358                gi != _prc_executable_patterns.end();
   360             if ((*gi).matches(*fi)) {
   361               file_flags |= FF_execute;
   365           if (file_flags != 0) {
   367             file._file_flags = file_flags;
   368             file._filename = 
Filename(directory, (*fi));
   369             config_files.push_back(file);
   379   if (blobinfo != 
nullptr && blobinfo->prc_data != 
nullptr) {
   382     _implicit_pages.push_back(page);
   383     _pages_sorted = 
false;
   385     std::istringstream in(blobinfo->prc_data);
   393   ConfigFiles::reverse_iterator ci;
   394   for (ci = config_files.rbegin(); ci != config_files.rend(); ++ci) {
   395     const ConfigFile &file = (*ci);
   398     if ((file._file_flags & FF_execute) != 0 &&
   403       string envvar = PRC_EXECUTABLE_ARGS_ENVVAR;
   404       if (blobinfo != 
nullptr && blobinfo->prc_executable_args_envvar != 
nullptr) {
   405         envvar = blobinfo->prc_executable_args_envvar;
   407       if (!envvar.empty()) {
   418       _implicit_pages.push_back(page);
   419       _pages_sorted = 
false;
   423     } 
else if ((file._file_flags & FF_decrypt) != 0) {
   430           << 
"Unable to read " << filename << 
"\n";
   434         _implicit_pages.push_back(page);
   435         _pages_sorted = 
false;
   437         if (blobinfo != 
nullptr && blobinfo->prc_encryption_key != 
nullptr) {
   444     } 
else if ((file._file_flags & FF_read) != 0) {
   451           << 
"Unable to read " << filename << 
"\n";
   455         _implicit_pages.push_back(page);
   456         _pages_sorted = 
false;
   463   if (!_loaded_implicit) {
   464     config_initialized();
   465     _loaded_implicit = 
true;
   468   _currently_loading = 
false;
   471 #ifdef USE_PANDAFILESTREAM   475     (
"newline-mode", PandaFileStreamBuf::NM_native,
   476      PRC_DESC(
"Controls how newlines are written by Panda applications writing "   477               "to a text file.  The default, \"native\", means to write newlines "   478               "appropriate to the current platform.  You may also specify \"binary\", "   479               "to avoid molesting the file data, or one of \"msdos\", \"unix\", "   481   PandaFileStreamBuf::_newline_mode = newline_mode;
   482 #endif  // USE_PANDAFILESTREAM   488     (
"show-dll-error-dialog", 
false,
   489      PRC_DESC(
"Set this true to enable the Windows system dialog that pops "   490               "up when a DLL fails to load, or false to disable it.  It is "   491               "normally false, but it may be useful to set it true to debug "   492               "why a DLL is not loading.  (Note that this actually disables "   493               "*all* critical error messages, and that it's a global setting "   494               "that some other libraries might un-set.)"));
   495   if (show_dll_error_dialog) {
   498     SetErrorMode(SEM_FAILCRITICALERRORS);
   513   _explicit_pages.push_back(page);
   514   _pages_sorted = 
false;
   529   for (pi = _explicit_pages.begin(); pi != _explicit_pages.end(); ++pi) {
   531       _explicit_pages.erase(pi);
   543 void ConfigPageManager::
   544 output(std::ostream &out)
 const {
   545   out << 
"ConfigPageManager, "   546       << _explicit_pages.size() + _implicit_pages.size()
   553 void ConfigPageManager::
   554 write(std::ostream &out)
 const {
   556   out << _explicit_pages.size() << 
" explicit pages:\n";
   558   Pages::const_iterator pi;
   559   for (pi = _explicit_pages.begin(); pi != _explicit_pages.end(); ++pi) {
   567       out << 
"  (invalid signature: ";
   575   out << 
"\n" << _implicit_pages.size() << 
" implicit pages:\n";
   576   for (pi = _implicit_pages.begin(); pi != _implicit_pages.end(); ++pi) {
   584       out << 
"  (invalid signature: ";
   598   if (_global_ptr == 
nullptr) {
   605 class CompareConfigPages {
   616 void ConfigPageManager::
   618   sort(_implicit_pages.begin(), _implicit_pages.end(), CompareConfigPages());
   619   sort(_explicit_pages.begin(), _explicit_pages.end(), CompareConfigPages());
   621   _pages_sorted = 
true;
   634 bool ConfigPageManager::
   635 scan_auto_prc_dir(
Filename &prc_dir)
 const {
   636   string prc_dir_string = prc_dir;
   637   if (prc_dir_string.substr(0, 6) == 
"<auto>") {
   638     Filename suffix = prc_dir_string.substr(6);
   644     if (scan_up_from(prc_dir, dir, suffix)) {
   650     if (scan_up_from(prc_dir, dir, suffix)) {
   655     std::cerr << 
"Warning: unable to auto-locate config files in directory named by \""   656          << prc_dir << 
"\".\n";
   672 bool ConfigPageManager::
   678   if (consider.is_directory()) {
   679     if (consider.scan_directory(files)) {
   680       vector_string::const_iterator fi;
   681       for (fi = files.begin(); fi != files.end(); ++fi) {
   682         Globs::const_iterator gi;
   683         for (gi = _prc_patterns.begin();
   684              gi != _prc_patterns.end();
   686           if ((*gi).matches(*fi)) {
   692         for (gi = _prc_executable_patterns.begin();
   693              gi != _prc_executable_patterns.end();
   695           if ((*gi).matches(*fi)) {
   712   return scan_up_from(result, parent, suffix);
   721 void ConfigPageManager::
   722 config_initialized() {
   727     (
"panda-package-version", 
"local_dev",
   728      PRC_DESC(
"This can be used to specify the value returned by "   729               "PandaSystem::get_package_version_str(), in development mode only, "   730               "and only if another value has not already been compiled in.  This "   731               "is intended for developer convenience, to masquerade a development "   732               "build of Panda as a different runtime version.  Use with caution."));
   734     (
"panda-package-host-url", 
"",
   735      PRC_DESC(
"This can be used to specify the value returned by "   736               "PandaSystem::get_package_host_url(), in development mode only, "   737               "and only if another value has not already been compiled in.  This "   738               "is intended for developer convenience, to masquerade a development "   739               "build of Panda as a different runtime version.  Use with caution."));
   742   panda_sys->set_package_version_string(panda_package_version);
   743   panda_sys->set_package_host_url(panda_package_host_url);
   748     (
"text-encoding", TextEncoder::E_utf8,
   749      PRC_DESC(
"Specifies how international characters are represented in strings "   750               "of 8-byte characters presented to Panda.  See TextEncoder::set_encoding()."));
   754     (
"filesystem-encoding", TextEncoder::E_utf8,
   755      PRC_DESC(
"Specifies the default encoding used for wide-character filenames."));
 static PandaSystem * get_global_ptr()
Returns the global PandaSystem object.
std::string get_dirname() const
Returns the directory part of the filename.
get_name
Returns the name of the page.
static size_t extract_words(const std::string &str, vector_string &words)
Divides the string into a number of words according to whitespace.
This class is used as a namespace to group several global properties of Panda.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
set_case_sensitive
Sets whether the match is case sensitive (true) or case insensitive (false).
This is a convenience class to specialize ConfigVariable as a boolean type.
void clear()
Removes all the directories from the search list.
void set_binary()
Indicates that the filename represents a binary file.
void set_text()
Indicates that the filename represents a text file.
bool open_read(std::ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
bool read_encrypted_prc(std::istream &in, const std::string &password)
Automatically decrypts and reads the stream, given the indicated password.
bool is_empty() const
Returns true if the search list is empty, false otherwise.
get_signature
Returns the raw binary signature that was found in the prc file, if any.
set_default_encoding
Specifies the default encoding to be used for all subsequently created TextEncoder objects.
bool make_canonical()
Converts this filename to a canonical name by replacing the directory part with the fully-qualified d...
bool make_true_case()
On a case-insensitive operating system (e.g.
get_dtool_name
Returns the name of the libdtool DLL that is used in this program, if it can be determined.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void append_directory(const Filename &directory)
Adds a new directory to the end of the search list.
static std::ostream & out()
A convenient way to get the ostream that should be written to for a Notify- type message.
get_trust_level
Returns the trust level associated with this page.
bool read_prc(std::istream &in)
Reads the contents of a complete prc file, as returned by the indicated istream, into the current pag...
static Notify * ptr()
Returns the pointer to the global Notify object.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A global object that maintains the set of ConfigPages everywhere in the world, and keeps them in sort...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void set_filesystem_encoding(TextEncoder::Encoding encoding)
Specifies the default encoding to be used for all subsequent Filenames.
get_num_directories
Returns the number of directories on the search list.
bool is_executable() const
Returns true if the filename exists and is executable.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The name of a file, such as a texture file or an Egg file.
This is a convenience class to specialize ConfigVariable as a string type.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void reload_implicit_pages()
Searches the PRC_DIR and/or PRC_PATH directories for *.prc files and loads them in as pages.
ConfigPage * make_explicit_page(const std::string &name)
Creates and returns a new, empty ConfigPage.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class specializes ConfigVariable as an enumerated type.
A page of ConfigDeclarations that may be loaded or unloaded.
bool is_directory() const
Returns true if the filename exists and is a directory name, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void config_initialized()
Intended to be called only by Config, this is a callback that indicates to Notify when Config has don...
get_directory
Returns the nth directory on the search list.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool scan_directory(vector_string &contents) const
Attempts to open the named filename as if it were a directory and looks for the non-hidden files with...
static void set_notify_ptr(std::ostream *ptr)
Sets the ostream that is used to write error messages to.
set_environment_variable
Changes the definition of the indicated environment variable.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool delete_explicit_page(ConfigPage *page)
Removes a previously-constructed ConfigPage from the set of active pages, and deletes it.
std::string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void output_brief_signature(std::ostream &out) const
Outputs the first few hex digits of the signature.
static Filename from_os_specific(const std::string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes,...
This class can be used to test for string matches against standard Unix- shell filename globbing conv...
get_environment_variable
Returns the definition of the indicated environment variable, or the empty string if the variable is ...