2004-12-08 05:14:05 +01:00
|
|
|
/*
|
|
|
|
* PROGRAM: JRD FileSystem Path Handler
|
|
|
|
* MODULE: path_utils.cpp
|
|
|
|
* DESCRIPTION: POSIX_specific class for file path management
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Initial
|
|
|
|
* Developer's 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.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed AS IS,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing rights
|
|
|
|
* and limitations under the License.
|
|
|
|
*
|
|
|
|
* The Original Code was created by John Bellardo
|
|
|
|
* for the Firebird Open Source RDBMS project.
|
|
|
|
*
|
|
|
|
* Copyright (c) 2002 John Bellardo <bellardo at cs.ucsd.edu>
|
|
|
|
* and all contributors signed below.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2002-04-10 01:23:36 +02:00
|
|
|
#include "../jrd/os/path_utils.h"
|
|
|
|
#include <sys/types.h>
|
2003-03-15 21:20:41 +01:00
|
|
|
#include <sys/stat.h>
|
2002-04-10 01:23:36 +02:00
|
|
|
#include <dirent.h>
|
2003-03-23 17:50:54 +01:00
|
|
|
#include <unistd.h>
|
2002-04-10 01:23:36 +02:00
|
|
|
|
|
|
|
/// The POSIX implementation of the path_utils abstraction.
|
|
|
|
|
|
|
|
const char PathUtils::dir_sep = '/';
|
2004-02-08 19:47:47 +01:00
|
|
|
const char* PathUtils::up_dir_link = "..";
|
2002-04-10 01:23:36 +02:00
|
|
|
|
|
|
|
class PosixDirItr : public PathUtils::dir_iterator
|
|
|
|
{
|
|
|
|
public:
|
2004-03-16 18:35:03 +01:00
|
|
|
PosixDirItr(MemoryPool& p, const Firebird::PathName& path)
|
2004-12-09 03:53:19 +01:00
|
|
|
: dir_iterator(p, path), dir(0), file(p), done(false)
|
2004-03-16 18:35:03 +01:00
|
|
|
{
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
PosixDirItr(const Firebird::PathName& path)
|
2004-12-09 03:53:19 +01:00
|
|
|
: dir_iterator(path), dir(0), done(false)
|
2004-03-16 18:35:03 +01:00
|
|
|
{
|
|
|
|
init();
|
|
|
|
}
|
2002-04-10 01:23:36 +02:00
|
|
|
~PosixDirItr();
|
|
|
|
const PosixDirItr& operator++();
|
2004-02-08 19:47:47 +01:00
|
|
|
const Firebird::PathName& operator*() { return file; }
|
2002-04-10 01:23:36 +02:00
|
|
|
operator bool() { return !done; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
DIR *dir;
|
2004-02-08 19:47:47 +01:00
|
|
|
Firebird::PathName file;
|
2004-12-09 03:53:19 +01:00
|
|
|
bool done;
|
2004-03-16 18:35:03 +01:00
|
|
|
void init();
|
2002-04-10 01:23:36 +02:00
|
|
|
};
|
|
|
|
|
2004-03-16 18:35:03 +01:00
|
|
|
void PosixDirItr::init()
|
2002-04-10 01:23:36 +02:00
|
|
|
{
|
|
|
|
dir = opendir(dirPrefix.c_str());
|
|
|
|
if (!dir)
|
2004-12-09 03:53:19 +01:00
|
|
|
done = true;
|
2002-04-10 01:23:36 +02:00
|
|
|
else
|
|
|
|
++(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
PosixDirItr::~PosixDirItr()
|
|
|
|
{
|
|
|
|
if (dir)
|
|
|
|
closedir(dir);
|
|
|
|
dir = 0;
|
2004-12-09 03:53:19 +01:00
|
|
|
done = true;
|
2002-04-10 01:23:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const PosixDirItr& PosixDirItr::operator++()
|
|
|
|
{
|
|
|
|
if (done)
|
|
|
|
return *this;
|
|
|
|
struct dirent *ent = readdir(dir);
|
|
|
|
if (ent == NULL)
|
|
|
|
{
|
2004-12-09 03:53:19 +01:00
|
|
|
done = true;
|
2002-04-10 01:23:36 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PathUtils::concatPath(file, dirPrefix, ent->d_name);
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2004-02-08 19:47:47 +01:00
|
|
|
PathUtils::dir_iterator *PathUtils::newDirItr(MemoryPool& p, const Firebird::PathName& path)
|
2002-04-10 01:23:36 +02:00
|
|
|
{
|
2004-03-22 16:13:05 +01:00
|
|
|
return FB_NEW(p) PosixDirItr(p, path);
|
2002-04-10 01:23:36 +02:00
|
|
|
}
|
|
|
|
|
2004-02-08 19:47:47 +01:00
|
|
|
void PathUtils::splitLastComponent(Firebird::PathName& path, Firebird::PathName& file,
|
|
|
|
const Firebird::PathName& orgPath)
|
2002-04-10 01:23:36 +02:00
|
|
|
{
|
2004-12-06 11:17:00 +01:00
|
|
|
Firebird::PathName::size_type pos = orgPath.rfind(dir_sep);
|
2004-02-08 19:47:47 +01:00
|
|
|
if (pos == Firebird::PathName::npos)
|
2002-04-10 01:23:36 +02:00
|
|
|
{
|
|
|
|
path = "";
|
|
|
|
file = orgPath;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
path.erase();
|
|
|
|
path.append(orgPath, 0, pos); // skip the directory separator
|
|
|
|
file.erase();
|
2004-11-30 07:18:39 +01:00
|
|
|
file.append(orgPath, pos + 1, orgPath.length() - pos - 1);
|
2002-04-10 01:23:36 +02:00
|
|
|
}
|
|
|
|
|
2004-02-08 19:47:47 +01:00
|
|
|
void PathUtils::concatPath(Firebird::PathName& result,
|
|
|
|
const Firebird::PathName& first,
|
|
|
|
const Firebird::PathName& second)
|
2002-04-10 01:23:36 +02:00
|
|
|
{
|
|
|
|
if (second.length() == 0)
|
|
|
|
{
|
|
|
|
result = first;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (first.length() == 0)
|
|
|
|
{
|
|
|
|
result = second;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-12-06 11:17:00 +01:00
|
|
|
if (first[first.length() - 1] != dir_sep &&
|
2002-04-10 01:23:36 +02:00
|
|
|
second[0] != dir_sep)
|
|
|
|
{
|
|
|
|
result = first + dir_sep + second;
|
|
|
|
return;
|
|
|
|
}
|
2004-12-06 11:17:00 +01:00
|
|
|
if (first[first.length() - 1] == dir_sep &&
|
2002-04-10 01:23:36 +02:00
|
|
|
second[0] == dir_sep)
|
|
|
|
{
|
|
|
|
result = first;
|
|
|
|
result.append(second, 1, second.length() - 1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = first + second;
|
|
|
|
}
|
|
|
|
|
2004-02-08 19:47:47 +01:00
|
|
|
bool PathUtils::isRelative(const Firebird::PathName& path)
|
2002-04-10 01:23:36 +02:00
|
|
|
{
|
|
|
|
if (path.length() > 0)
|
|
|
|
return path[0] != dir_sep;
|
|
|
|
return false;
|
|
|
|
}
|
2003-03-15 21:20:41 +01:00
|
|
|
|
2004-02-08 19:47:47 +01:00
|
|
|
bool PathUtils::isSymLink(const Firebird::PathName& path)
|
2003-03-15 21:20:41 +01:00
|
|
|
{
|
|
|
|
struct stat st, lst;
|
|
|
|
if (stat(path.c_str(), &st) != 0)
|
|
|
|
return false;
|
|
|
|
if (lstat(path.c_str(), &lst) != 0)
|
|
|
|
return false;
|
|
|
|
return st.st_ino != lst.st_ino;
|
|
|
|
}
|
|
|
|
|
2004-12-06 11:17:00 +01:00
|
|
|
bool PathUtils::canAccess(const Firebird::PathName& path, int mode)
|
|
|
|
{
|
2003-03-23 17:50:54 +01:00
|
|
|
return access(path.c_str(), mode) == 0;
|
|
|
|
}
|
2004-12-06 11:17:00 +01:00
|
|
|
|