| /* | |
| * Licensed to the Apache Software Foundation (ASF) under one or more | |
| * contributor license agreements. See the NOTICE file distributed with | |
| * this work for additional information regarding copyright ownership. | |
| * The ASF licenses this file to You under the Apache License, Version 2.0 | |
| * (the "License"); you may not use this file except in compliance with | |
| * the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| #include <log4cxx/logstring.h> | |
| #include <log4cxx/helpers/system.h> | |
| #include <log4cxx/helpers/filesystempath.h> | |
| #include <log4cxx/helpers/transcoder.h> | |
| #include <log4cxx/helpers/pool.h> | |
| #include <log4cxx/helpers/properties.h> | |
| #include <log4cxx/helpers/loglog.h> | |
| #include <log4cxx/helpers/stringhelper.h> | |
| #include <apr_file_io.h> | |
| #include <apr_user.h> | |
| #include <apr_env.h> | |
| #ifdef _WIN32 | |
| #include <windows.h> | |
| #elif __APPLE__ | |
| #include <mach-o/dyld.h> | |
| #elif (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) | |
| #include <unistd.h> // getpid | |
| #endif | |
| #include <sstream> | |
| using namespace LOG4CXX_NS; | |
| using namespace LOG4CXX_NS::helpers; | |
| LogString System::getProperty(const LogString& lkey) | |
| { | |
| if (lkey.empty()) | |
| { | |
| throw IllegalArgumentException(LOG4CXX_STR("key is empty")); | |
| } | |
| LogString rv; | |
| if (lkey == LOG4CXX_STR("java.io.tmpdir")) | |
| { | |
| Pool p; | |
| const char* dir = NULL; | |
| apr_status_t stat = apr_temp_dir_get(&dir, p.getAPRPool()); | |
| if (stat == APR_SUCCESS) | |
| { | |
| Transcoder::decode(dir, rv); | |
| } | |
| return rv; | |
| } | |
| if (lkey == LOG4CXX_STR("user.dir")) | |
| { | |
| Pool p; | |
| char* dir = NULL; | |
| apr_status_t stat = apr_filepath_get(&dir, APR_FILEPATH_NATIVE, | |
| p.getAPRPool()); | |
| if (stat == APR_SUCCESS) | |
| { | |
| Transcoder::decode(dir, rv); | |
| } | |
| return rv; | |
| } | |
| #if APR_HAS_USER | |
| if (lkey == LOG4CXX_STR("user.home") || lkey == LOG4CXX_STR("user.name")) | |
| { | |
| Pool pool; | |
| apr_uid_t userid; | |
| apr_gid_t groupid; | |
| apr_pool_t* p = pool.getAPRPool(); | |
| apr_status_t stat = apr_uid_current(&userid, &groupid, p); | |
| if (stat == APR_SUCCESS) | |
| { | |
| char* username = NULL; | |
| stat = apr_uid_name_get(&username, userid, p); | |
| if (stat == APR_SUCCESS) | |
| { | |
| if (lkey == LOG4CXX_STR("user.name")) | |
| { | |
| Transcoder::decode(username, rv); | |
| } | |
| else | |
| { | |
| char* dirname = NULL; | |
| stat = apr_uid_homepath_get(&dirname, username, p); | |
| if (stat == APR_SUCCESS) | |
| { | |
| Transcoder::decode(dirname, rv); | |
| } | |
| } | |
| } | |
| } | |
| return rv; | |
| } | |
| #endif | |
| LOG4CXX_ENCODE_CHAR(key, lkey); | |
| Pool p; | |
| char* value = NULL; | |
| apr_status_t stat = apr_env_get(&value, key.c_str(), | |
| p.getAPRPool()); | |
| if (stat == APR_SUCCESS) | |
| { | |
| Transcoder::decode((const char*) value, rv); | |
| } | |
| return rv; | |
| } | |
| void System::addProgramFilePathComponents(Properties& props) | |
| { | |
| // Find the executable file name | |
| static const int bufSize = 4096; | |
| char buf[bufSize+1] = {0}, pathSepar = '/'; | |
| #if defined(_WIN32) | |
| if (0 == GetModuleFileName(NULL, buf, bufSize)) | |
| { | |
| LogString lsErrorCode; | |
| StringHelper::toString((int)GetLastError(), lsErrorCode); | |
| LogLog::warn(LOG4CXX_STR("GetModuleFileName error ") + lsErrorCode); | |
| return; | |
| } | |
| pathSepar = '\\'; | |
| #elif defined(__APPLE__) | |
| uint32_t bufCount = bufSize; | |
| if (0 != _NSGetExecutablePath(buf, &bufCount)) | |
| { | |
| LogLog::warn(LOG4CXX_STR("_NSGetExecutablePath failed")); | |
| return; | |
| } | |
| #elif (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) | |
| int bufCount = 0; | |
| std::ostringstream exeLink; | |
| exeLink << "/proc/" << getpid() << "/exe"; | |
| if ((bufCount = readlink(exeLink.str().c_str(), buf, bufSize)) <= 0) | |
| { | |
| LOG4CXX_DECODE_CHAR(lsExeLink, exeLink.str()); | |
| LogLog::warn(LOG4CXX_STR("Failed to read ") + lsExeLink); | |
| return; | |
| } | |
| if (bufSize < bufCount) | |
| buf[bufSize] = 0; | |
| else | |
| buf[bufCount] = 0; | |
| #else | |
| LogLog::warn(LOG4CXX_STR("Unable to determine the name of the executable file on this system")); | |
| return; | |
| #endif | |
| // Add the path to the properties | |
| std::string programFileName(buf); | |
| if (programFileName.empty()) | |
| { | |
| LogLog::warn(LOG4CXX_STR("Current executable's file name is empty")); | |
| return; | |
| } | |
| LOG4CXX_DECODE_CHAR(lsProgramFileName, programFileName); | |
| LogString prefix{ LOG4CXX_STR("PROGRAM_FILE_PATH") }; | |
| props.setProperty(prefix, lsProgramFileName); | |
| #if LOG4CXX_HAS_FILESYSTEM_PATH | |
| // Add the path components to the properties | |
| prefix += '.'; | |
| FilesystemPath programPath(programFileName); | |
| #if LOG4CXX_LOGCHAR_IS_WCHAR | |
| auto root_name = programPath.root_name().wstring(); | |
| if (!root_name.empty()) | |
| props.setProperty(prefix + LOG4CXX_STR("ROOT_NAME"), root_name); | |
| auto root_directory = programPath.root_directory().wstring(); | |
| props.setProperty(prefix + LOG4CXX_STR("ROOT_DIRECTORY"),root_directory); | |
| auto root_path = programPath.root_path().wstring(); | |
| props.setProperty(prefix + LOG4CXX_STR("ROOT_PATH"), root_path); | |
| auto relative_path = programPath.relative_path().wstring(); | |
| props.setProperty(prefix + LOG4CXX_STR("RELATIVE_PATH"), relative_path); | |
| auto parent_path = programPath.parent_path().wstring(); | |
| props.setProperty(prefix + LOG4CXX_STR("PARENT_PATH"), parent_path); | |
| auto filename = programPath.filename().wstring(); | |
| props.setProperty(prefix + LOG4CXX_STR("FILENAME"), filename); | |
| auto stem = programPath.stem().wstring(); | |
| props.setProperty(prefix + LOG4CXX_STR("STEM"), stem); | |
| auto extension = programPath.extension().wstring(); | |
| if (!extension.empty()) | |
| props.setProperty(prefix + LOG4CXX_STR("EXTENSION"), extension); | |
| #else | |
| LOG4CXX_DECODE_CHAR(root_name, programPath.root_name().string()); | |
| if (!root_name.empty()) | |
| props.setProperty(prefix + LOG4CXX_STR("ROOT_NAME"), root_name); | |
| LOG4CXX_DECODE_CHAR(root_directory, programPath.root_directory().string()); | |
| props.setProperty(prefix + LOG4CXX_STR("ROOT_DIRECTORY"),root_directory); | |
| LOG4CXX_DECODE_CHAR(root_path, programPath.root_path().string()); | |
| props.setProperty(prefix + LOG4CXX_STR("ROOT_PATH"), root_path); | |
| LOG4CXX_DECODE_CHAR(relative_path, programPath.relative_path().string()); | |
| props.setProperty(prefix + LOG4CXX_STR("RELATIVE_PATH"), relative_path); | |
| LOG4CXX_DECODE_CHAR(parent_path, programPath.parent_path().string()); | |
| props.setProperty(prefix + LOG4CXX_STR("PARENT_PATH"), parent_path); | |
| LOG4CXX_DECODE_CHAR(filename, programPath.filename().string()); | |
| props.setProperty(prefix + LOG4CXX_STR("FILENAME"), filename); | |
| LOG4CXX_DECODE_CHAR(stem, programPath.stem().string()); | |
| props.setProperty(prefix + LOG4CXX_STR("STEM"), stem); | |
| LOG4CXX_DECODE_CHAR(extension, programPath.extension().string()); | |
| if (!extension.empty()) | |
| props.setProperty(prefix + LOG4CXX_STR("EXTENSION"), extension); | |
| #endif | |
| #endif // LOG4CXX_HAS_FILESYSTEM_PATH | |
| } |