1
0
Fork 0
arangodb/lib/Basics/files.h

445 lines
19 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_BASICS_FILES_H
#define ARANGODB_BASICS_FILES_H 1
#ifdef _WIN32
#include "Basics/win-utils.h"
#endif
#include <openssl/sha.h>
#include "Basics/Common.h"
#include "Basics/StringUtils.h"
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the size of a file
///
/// Will return a negative error number on error
////////////////////////////////////////////////////////////////////////////////
int64_t TRI_SizeFile(char const* path);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if file or directory is writable
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsWritable(char const* path);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if path is a directory
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsDirectory(char const* path);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if path is a regular file
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsRegularFile(char const* path);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if path is a symbolic link
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsSymbolicLink(char const* path);
////////////////////////////////////////////////////////////////////////////////
/// @brief resolves a symbolic link
////////////////////////////////////////////////////////////////////////////////
std::string TRI_ResolveSymbolicLink(std::string path, bool& hadError, bool recursive = true);
std::string TRI_ResolveSymbolicLink(std::string path, bool recursive = true);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if file or directory exists
////////////////////////////////////////////////////////////////////////////////
bool TRI_ExistsFile(char const* path);
////////////////////////////////////////////////////////////////////////////////
/// @brief sets the desired mode on a file, returns errno on error.
////////////////////////////////////////////////////////////////////////////////
int TRI_ChMod(char const* path, long mode, std::string& err);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the last modification date of a file
////////////////////////////////////////////////////////////////////////////////
int TRI_MTimeFile(char const* path, int64_t* mtime);
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a directory, recursively
////////////////////////////////////////////////////////////////////////////////
int TRI_CreateRecursiveDirectory(char const* path, long& systemError,
std::string& systemErrorStr);
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a directory
////////////////////////////////////////////////////////////////////////////////
int TRI_CreateDirectory(char const* path, long& systemError, std::string& systemErrorStr);
////////////////////////////////////////////////////////////////////////////////
/// @brief removes an empty directory
////////////////////////////////////////////////////////////////////////////////
int TRI_RemoveEmptyDirectory(char const* filename);
////////////////////////////////////////////////////////////////////////////////
/// @brief removes a directory recursively, using file order provided by
/// the file system
////////////////////////////////////////////////////////////////////////////////
int TRI_RemoveDirectory(char const* filename);
////////////////////////////////////////////////////////////////////////////////
/// @brief removes a directory recursively, using a deterministic order of files
////////////////////////////////////////////////////////////////////////////////
int TRI_RemoveDirectoryDeterministic(char const* filename);
////////////////////////////////////////////////////////////////////////////////
/// @brief extracts the dirname
////////////////////////////////////////////////////////////////////////////////
std::string TRI_Dirname(std::string const& path);
////////////////////////////////////////////////////////////////////////////////
/// @brief extracts the basename
////////////////////////////////////////////////////////////////////////////////
std::string TRI_Basename(char const* path);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns a list of files in path
////////////////////////////////////////////////////////////////////////////////
std::vector<std::string> TRI_FilesDirectory(char const* path);
////////////////////////////////////////////////////////////////////////////////
/// @brief lists the directory tree including files and directories
////////////////////////////////////////////////////////////////////////////////
std::vector<std::string> TRI_FullTreeDirectory(char const* path);
////////////////////////////////////////////////////////////////////////////////
/// @brief renames a file
////////////////////////////////////////////////////////////////////////////////
int TRI_RenameFile(char const* old, char const* filename, long* systemError = nullptr,
std::string* systemErrorStr = nullptr);
////////////////////////////////////////////////////////////////////////////////
/// @brief unlinks a file
////////////////////////////////////////////////////////////////////////////////
int TRI_UnlinkFile(char const* filename);
////////////////////////////////////////////////////////////////////////////////
/// @brief reads into a buffer from a file
////////////////////////////////////////////////////////////////////////////////
bool TRI_ReadPointer(int fd, void* buffer, size_t length);
////////////////////////////////////////////////////////////////////////////////
/// @brief writes buffer to a file
////////////////////////////////////////////////////////////////////////////////
bool TRI_WritePointer(int fd, void const* buffer, size_t length);
////////////////////////////////////////////////////////////////////////////////
/// @brief saves data to a file
////////////////////////////////////////////////////////////////////////////////
int TRI_WriteFile(char const*, char const*, size_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief fsyncs a file
////////////////////////////////////////////////////////////////////////////////
bool TRI_fsync(int fd);
////////////////////////////////////////////////////////////////////////////////
/// @brief slurps in a file
////////////////////////////////////////////////////////////////////////////////
char* TRI_SlurpFile(char const* filename, size_t* length);
////////////////////////////////////////////////////////////////////////////////
/// @brief read file and pass blocks to user function
////////////////////////////////////////////////////////////////////////////////
bool TRI_ProcessFile(char const* filename, std::function<bool(char const* block, size_t size)> const& reader);
////////////////////////////////////////////////////////////////////////////////
/// @brief slurps in a file that is compressed and return uncompressed contents
////////////////////////////////////////////////////////////////////////////////
char* TRI_SlurpGzipFile(char const* filename, size_t* length);
#ifdef USE_ENTERPRISE
////////////////////////////////////////////////////////////////////////////////
/// @brief slurps in a file that is encrypted and return unencrypted contents
////////////////////////////////////////////////////////////////////////////////
char* TRI_SlurpDecryptFile(char const* filename, char const * keyfile, size_t* length);
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a lock file based on the PID
///
/// Creates a file containing a the current process identifier and locks
/// that file. Under Unix the call uses the @FN{open} system call with
/// O_EXCL to ensure that the file is created atomically. Then the
/// file is filled with the process identifier as decimal number and a
/// lock on the file is obtained using @FN{flock}.
///
/// On success @ref TRI_ERROR_NO_ERROR is returned.
///
/// Internally, the functions keeps a list of open pid files. Calling the
/// function twice with the same @FA{filename} will succeed and will not
/// create a new entry in this list. The system uses @FN{atexit} to release
/// all open locks upon exit.
////////////////////////////////////////////////////////////////////////////////
int TRI_CreateLockFile(char const* filename);
////////////////////////////////////////////////////////////////////////////////
/// @brief verifies a lock file based on the PID
///
/// The function checks if the file named @FA{filename} exists. If the
/// file exists, then the following checks are performed:
///
/// - Does the file contain a valid decimal number?
/// - Does this number belong to a living process?
/// - Is it possible to lock the file using @FN{flock}. This should failed.
/// If the lock can be obtained, then it is assume that the lock is invalid.
///
/// If the verification returns an error, than @FN{TRI_UnlinkFile} should be
/// used to remove the lock file. If the verification returns @ref
/// TRI_ERROR_NO_ERROR than the file is locked and the lock is valid.
////////////////////////////////////////////////////////////////////////////////
int TRI_VerifyLockFile(char const* filename);
////////////////////////////////////////////////////////////////////////////////
/// @brief releases a lock file based on the PID
////////////////////////////////////////////////////////////////////////////////
int TRI_DestroyLockFile(char const* filename);
////////////////////////////////////////////////////////////////////////////////
/// @brief return the filename component of a file (without path)
////////////////////////////////////////////////////////////////////////////////
std::string TRI_GetFilename(std::string const&);
////////////////////////////////////////////////////////////////////////////////
/// @brief return the absolute path of a file
/// It is the caller's responsibility to free the string created by this
/// function
////////////////////////////////////////////////////////////////////////////////
std::string TRI_GetAbsolutePath(std::string const& fileName,
std::string const& currentWorkingDirectory);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the binary name without any path or suffix
////////////////////////////////////////////////////////////////////////////////
std::string TRI_BinaryName(char const* argv0);
////////////////////////////////////////////////////////////////////////////////
/// @brief locates the directory containing the program
////////////////////////////////////////////////////////////////////////////////
std::string TRI_LocateBinaryPath(char const* argv0);
////////////////////////////////////////////////////////////////////////////////
/// @brief locates toplevel install directory
/// tries to substract InstallBinaryPath righthandside from binaryPath
/// (if equal) and returns either "/" if not, or the part of binaryPath
/// that is left of InstallBinaryPath:
/// /opt/usr/bin /usr/bin/ => /opt/
////////////////////////////////////////////////////////////////////////////////
std::string TRI_GetInstallRoot(std::string const& binaryPath, char const* installBinaryPath);
////////////////////////////////////////////////////////////////////////////////
/// @brief locates the home directory
////////////////////////////////////////////////////////////////////////////////
std::string TRI_HomeDirectory();
////////////////////////////////////////////////////////////////////////////////
/// @brief calculate the crc32 checksum of a file
////////////////////////////////////////////////////////////////////////////////
int TRI_Crc32File(char const*, uint32_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief set the application's name
////////////////////////////////////////////////////////////////////////////////
void TRI_SetApplicationName(std::string const& name);
////////////////////////////////////////////////////////////////////////////////
/// @brief get the system's temporary path
////////////////////////////////////////////////////////////////////////////////
std::string TRI_GetTempPath();
////////////////////////////////////////////////////////////////////////////////
/// @brief set the system's temporary path - WARN: The directory is not created
////////////////////////////////////////////////////////////////////////////////
void TRI_SetTempPath(std::string const& path);
////////////////////////////////////////////////////////////////////////////////
/// @brief get a temporary file name
////////////////////////////////////////////////////////////////////////////////
int TRI_GetTempName(char const* directory, std::string& result, bool createFile,
long& systemError, std::string& errorMessage);
////////////////////////////////////////////////////////////////////////////////
/// @brief copies a file from source to dest.
////////////////////////////////////////////////////////////////////////////////
bool TRI_CopyFile(std::string const& src, std::string const& dst, std::string& error);
////////////////////////////////////////////////////////////////////////////////
/// @brief copies the file Attributes from source to dest.
////////////////////////////////////////////////////////////////////////////////
bool TRI_CopyAttributes(std::string const& srcItem, std::string const& dstItem,
std::string& error);
////////////////////////////////////////////////////////////////////////////////
/// @brief copies the symlink from source to dest; will do nothing in Windows?
////////////////////////////////////////////////////////////////////////////////
bool TRI_CopySymlink(std::string const& srcItem, std::string const& dstItem,
std::string& error);
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a symbolic link
////////////////////////////////////////////////////////////////////////////////
bool TRI_CreateSymbolicLink(std::string const& target, std::string const& linkpath,
std::string& error);
////////////////////////////////////////////////////////////////////////////////
/// @brief copies the symlink from source to dest; will do nothing in Windows?
////////////////////////////////////////////////////////////////////////////////
bool TRI_CreateHardlink(std::string const& existingFile, std::string const& newFile,
std::string& error);
////////////////////////////////////////////////////////////////////////////////
/// @brief locate the installation directory
////////////////////////////////////////////////////////////////////////////////
std::string TRI_LocateInstallDirectory(char const* argv0, const char* binaryPath);
////////////////////////////////////////////////////////////////////////////////
/// @brief locate the configuration directory
////////////////////////////////////////////////////////////////////////////////
std::string TRI_LocateConfigDirectory(char const* binaryPath);
////////////////////////////////////////////////////////////////////////////////
/// @brief get the address of the null buffer
////////////////////////////////////////////////////////////////////////////////
char* TRI_GetNullBufferFiles();
////////////////////////////////////////////////////////////////////////////////
/// @brief get the size of the null buffer
////////////////////////////////////////////////////////////////////////////////
size_t TRI_GetNullBufferSizeFiles();
/// @brief creates a new datafile
/// returns the file descriptor or -1 if the file cannot be created
int TRI_CreateDatafile(std::string const& filename, size_t maximalSize);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks whether path is full qualified or relative
////////////////////////////////////////////////////////////////////////////////
bool TRI_PathIsAbsolute(std::string const& path);
////////////////////////////////////////////////////////////////////////////////
/// @brief initialize the files subsystem
////////////////////////////////////////////////////////////////////////////////
void TRI_InitializeFiles();
////////////////////////////////////////////////////////////////////////////////
/// @brief shutdown the files subsystem
////////////////////////////////////////////////////////////////////////////////
void TRI_ShutdownFiles();
////////////////////////////////////////////////////////////////////////////////
/// @brief if which is found, value is overwriten, true returned.
////////////////////////////////////////////////////////////////////////////////
bool TRI_GETENV(char const* which, std::string& value);
////////////////////////////////////////////////////////////////////////////////
/// @brief functor for generating a SHA256. Use with TRI_ProcessFiles.
/// you need to wrap your TRI_SHA256Functor object within std::ref().
////////////////////////////////////////////////////////////////////////////////
struct TRI_SHA256Functor {
SHA256_CTX _context;
unsigned char _digest[SHA256_DIGEST_LENGTH];
TRI_SHA256Functor() {
int ret_val = SHA256_Init(&_context);
if (1 != ret_val) {
TRI_ASSERT(false);
} // if
}
bool operator()(char const* data, size_t size) {
int ret_val = SHA256_Update(&_context, static_cast<void const*>(data), size);
return 1 == ret_val;
}
std::string final() {
int ret_val = SHA256_Final(_digest, &_context);
if (1 != ret_val) {
TRI_ASSERT(false);
} // if
return arangodb::basics::StringUtils::encodeHex((char const *)_digest, SHA256_DIGEST_LENGTH);
}
};// struct TRI_SHA256Functor
#endif