8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 03:20:39 +01:00
firebird-mirror/src/common/config/dir_list.cpp

266 lines
5.7 KiB
C++
Raw Normal View History

/*
* PROGRAM: Client/Server Common Code
* MODULE: dir_list.cpp
* DESCRIPTION: Directory listing config file operation
*
* The contents of this file are subject to the Interbase Public
* License Version 1.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.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Created by: Alex Peshkov <AlexPeshkov@users.sourceforge.net>
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
2003-03-15 21:20:42 +01:00
#include "firebird.h"
#include "../common/config/config.h"
#include "../common/config/dir_list.h"
#include "../jrd/os/path_utils.h"
#include "../jrd/gds_proto.h"
#include "../jrd/TempSpace.h"
2004-03-14 14:14:58 +01:00
namespace Firebird {
2008-12-05 02:20:14 +01:00
void ParsedPath::parse(const PathName& path)
{
2004-03-14 14:14:58 +01:00
clear();
if (path.length() == 1) {
2004-03-14 14:14:58 +01:00
add(path);
return;
}
2004-03-14 14:14:58 +01:00
PathName oldpath = path;
do {
2004-03-14 14:14:58 +01:00
PathName newpath, elem;
PathUtils::splitLastComponent(newpath, elem, oldpath);
oldpath = newpath;
2004-03-14 14:14:58 +01:00
insert(0, elem);
} while (oldpath.length() > 0);
}
2008-12-05 02:20:14 +01:00
PathName ParsedPath::subPath(size_t n) const
{
2004-03-14 14:14:58 +01:00
PathName rc = (*this)[0];
if (PathUtils::isRelative(rc + PathUtils::dir_sep))
rc = PathUtils::dir_sep + rc;
for (size_t i = 1; i < n; i++) {
2004-03-14 14:14:58 +01:00
PathName newpath;
PathUtils::concatPath(newpath, rc, (*this)[i]);
rc = newpath;
}
return rc;
}
2008-12-05 02:20:14 +01:00
ParsedPath::operator PathName() const
{
2004-03-14 14:14:58 +01:00
if (!getCount())
return "";
2004-03-14 14:14:58 +01:00
return subPath(getCount());
}
2008-12-05 02:20:14 +01:00
bool ParsedPath::contains(const ParsedPath& pPath) const
{
2004-08-26 20:28:12 +02:00
size_t nFullElem = getCount();
2004-03-14 14:14:58 +01:00
if (nFullElem > 1 && (*this)[nFullElem - 1].length() == 0)
nFullElem--;
2004-03-14 14:14:58 +01:00
if (pPath.getCount() < nFullElem) {
return false;
}
2008-12-05 02:20:14 +01:00
size_t i;
for (i = 0; i < nFullElem; i++) {
2004-03-14 14:14:58 +01:00
if (pPath[i] != (*this)[i]) {
return false;
}
}
for (i = nFullElem + 1; i <= pPath.getCount(); i++) {
2004-03-14 14:14:58 +01:00
PathName x = pPath.subPath(i);
if (PathUtils::isSymLink(x)) {
return false;
}
}
return true;
}
2004-03-14 14:14:58 +01:00
bool DirectoryList::keyword(
2008-12-05 02:20:14 +01:00
const ListMode keyMode,
PathName& value,
PathName key,
PathName next)
{
2004-03-14 14:14:58 +01:00
if (value.length() < key.length()) {
return false;
}
2004-03-14 14:14:58 +01:00
PathName keyValue = value.substr(0, key.length());
if (keyValue != key) {
return false;
}
2004-03-14 14:14:58 +01:00
if (next.length() > 0) {
if (value.length() == key.length()) {
return false;
}
2004-03-14 14:14:58 +01:00
keyValue = value.substr(key.length());
if (next.find(keyValue[0]) == PathName::npos) {
return false;
}
2004-03-14 14:14:58 +01:00
PathName::size_type startPos = keyValue.find_first_not_of(next);
if (startPos == PathName::npos) {
return false;
}
2004-03-14 14:14:58 +01:00
value = keyValue.substr(startPos);
}
else {
2004-03-14 14:14:58 +01:00
if (value.length() > key.length()) {
return false;
}
2004-03-14 14:14:58 +01:00
value.erase();
}
2004-03-14 14:14:58 +01:00
mode = keyMode;
return true;
}
2008-12-05 02:20:14 +01:00
void DirectoryList::initialize(bool simple_mode)
{
2004-03-14 14:14:58 +01:00
if (mode != NotInitialized)
2003-05-01 14:20:40 +02:00
return;
2004-03-14 14:14:58 +01:00
clear();
2004-03-14 14:14:58 +01:00
PathName val = getConfigString();
2003-05-01 14:20:40 +02:00
if (simple_mode) {
2004-03-14 14:14:58 +01:00
mode = SimpleList;
}
2003-05-01 14:20:40 +02:00
else {
2008-12-05 02:20:14 +01:00
if (keyword(None, val, "None", "") ||
2004-03-14 14:14:58 +01:00
keyword(Full, val, "Full", "")) {
2003-05-01 14:20:40 +02:00
return;
}
2004-03-14 14:14:58 +01:00
if (! keyword(Restrict, val, "Restrict", " \t")) {
2003-05-01 14:20:40 +02:00
gds__log("DirectoryList: unknown parameter '%s', "
"defaulting to None", val.c_str());
2004-03-14 14:14:58 +01:00
mode = None;
2003-05-01 14:20:40 +02:00
return;
}
}
size_t last = 0;
2004-03-14 14:14:58 +01:00
PathName root = Config::getRootDirectory();
2004-03-25 07:50:50 +01:00
size_t i;
2004-03-15 20:35:00 +01:00
for (i = 0; i < val.length(); i++) {
if (val[i] == ';') {
2004-03-14 14:14:58 +01:00
PathName dir = "";
if (i > last) {
dir = val.substr(last, i - last);
dir.trim();
}
if (PathUtils::isRelative(dir)) {
2004-03-14 14:14:58 +01:00
PathName newdir;
PathUtils::concatPath(newdir, root, dir);
dir = newdir;
}
2004-03-14 14:14:58 +01:00
add(ParsedPath(dir));
last = i + 1;
}
}
2004-03-14 14:14:58 +01:00
PathName dir = "";
if (i > last) {
dir = val.substr(last, i - last);
dir.trim();
}
if (PathUtils::isRelative(dir)) {
2004-03-14 14:14:58 +01:00
PathName newdir;
PathUtils::concatPath(newdir, root, dir);
dir = newdir;
}
2004-03-14 14:14:58 +01:00
add(ParsedPath(dir));
}
2008-12-05 02:20:14 +01:00
bool DirectoryList::isPathInList(const PathName& path) const
{
#ifdef BOOT_BUILD
return true;
#else //BOOT_BUILD
2004-03-14 14:14:58 +01:00
fb_assert(mode != NotInitialized);
// Handle special cases
switch (mode) {
case None:
return false;
case Full:
return true;
}
// Disable any up-dir(..) references - in case our path_utils
// and OS handle paths in slightly different ways,
// this is "wonderful" potential hole for hacks
// Example of IIS attack attempt:
// "GET /scripts/..%252f../winnt/system32/cmd.exe?/c+dir HTTP/1.0"
// (live from apache access.log :)
2004-03-14 14:14:58 +01:00
if (path.find(PathUtils::up_dir_link) != PathName::npos)
return false;
2004-03-14 14:14:58 +01:00
PathName varpath(path);
if (PathUtils::isRelative(path)) {
2008-12-05 02:20:14 +01:00
PathUtils::concatPath(varpath,
2004-03-14 14:14:58 +01:00
PathName(Config::getRootDirectory()), path);
}
2005-08-22 11:16:31 +02:00
ParsedPath pPath(varpath);
bool rc = false;
2004-08-26 20:28:12 +02:00
for (size_t i = 0; i < getCount(); i++) {
2004-03-14 14:14:58 +01:00
if ((*this)[i].contains(pPath)) {
rc = true;
break;
}
}
return rc;
#endif //BOOT_BUILD
}
2008-12-05 02:20:14 +01:00
bool DirectoryList::expandFileName(PathName& path, const PathName& name) const
{
2004-03-14 14:14:58 +01:00
fb_assert(mode != NotInitialized);
2004-08-26 20:28:12 +02:00
for (size_t i = 0; i < getCount(); i++) {
2004-03-14 14:14:58 +01:00
PathUtils::concatPath(path, (*this)[i], name);
if (PathUtils::canAccess(path, 4)) {
return true;
}
}
2004-03-14 14:14:58 +01:00
path = name;
return false;
}
2008-10-28 01:16:20 +01:00
bool DirectoryList::defaultName(PathName& path, const PathName& name) const
{
fb_assert(mode != NotInitialized);
if (! getCount())
{
return false;
}
PathUtils::concatPath(path, (*this)[0], name);
return true;
}
2003-05-01 14:20:40 +02:00
2004-03-14 14:14:58 +01:00
const PathName TempDirectoryList::getConfigString() const
2003-05-01 14:20:40 +02:00
{
const char* value = Config::getTempDirectories();
if (!value) {
2003-05-01 14:20:40 +02:00
// Temporary directory configuration has not been defined.
// Let's make default configuration.
return TempFile::getTempPath();
2003-05-01 14:20:40 +02:00
}
2004-03-14 14:14:58 +01:00
return PathName(value);
2003-05-01 14:20:40 +02:00
}
2004-03-15 20:35:00 +01:00
} //namespace Firebird