diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
commit | c04dcc2e7d834218ef2d4194331e383402495ae1 (patch) | |
tree | 7333e38d10d75386e60f336b80c2443c1166031d /lib/libUPnP/Neptune/Source/System/Posix/NptPosixFile.cpp | |
parent | Initial commit. (diff) | |
download | kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip |
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/libUPnP/Neptune/Source/System/Posix/NptPosixFile.cpp')
-rw-r--r-- | lib/libUPnP/Neptune/Source/System/Posix/NptPosixFile.cpp | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/lib/libUPnP/Neptune/Source/System/Posix/NptPosixFile.cpp b/lib/libUPnP/Neptune/Source/System/Posix/NptPosixFile.cpp new file mode 100644 index 0000000..8cfe210 --- /dev/null +++ b/lib/libUPnP/Neptune/Source/System/Posix/NptPosixFile.cpp @@ -0,0 +1,268 @@ +/***************************************************************** +| +| Neptune - File :: Posix Implementation +| +| (c) 2001-2008 Gilles Boccon-Gibod +| Author: Gilles Boccon-Gibod (bok@bok.net) +| + ****************************************************************/ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#define _LARGEFILE_SOURCE +#define _LARGEFILE_SOURCE64 +#define _LARGEFILE64_SOURCE +#define _FILE_OFFSET_BITS 64 + +#include <sys/stat.h> + +#include <errno.h> + +#if defined(_WIN32) +#include <direct.h> +#include <stdlib.h> +#include <stdio.h> +#else +#include <unistd.h> +#include <dirent.h> +#endif + +#include "NptConfig.h" +#include "NptLogging.h" +#include "NptFile.h" +#include "NptUtils.h" + +/*---------------------------------------------------------------------- +| logging ++---------------------------------------------------------------------*/ +//NPT_SET_LOCAL_LOGGER("neptune.posix.file") + +/*---------------------------------------------------------------------- +| Win32 adaptation ++---------------------------------------------------------------------*/ +#if defined(_WIN32) || defined(_XBOX) +extern int NPT_stat_utf8(const char* path, NPT_stat_struct* info); +extern char* NPT_getcwd_utf8(char* path, unsigned int path_size); +#define getcwd NPT_getcwd_utf8 +#define S_ISDIR(_m) (((_m)&_S_IFMT) == _S_IFDIR) +#define S_ISREG(_m) (((_m)&_S_IFMT) == _S_IFREG) +#define S_IWUSR _S_IWRITE +#endif + +/*---------------------------------------------------------------------- +| MapErrno ++---------------------------------------------------------------------*/ +static NPT_Result +MapErrno(int err) { + switch (err) { + case EACCES: return NPT_ERROR_PERMISSION_DENIED; + case EPERM: return NPT_ERROR_PERMISSION_DENIED; + case ENOENT: return NPT_ERROR_NO_SUCH_FILE; + case ENAMETOOLONG: return NPT_ERROR_INVALID_PARAMETERS; + case EBUSY: return NPT_ERROR_FILE_BUSY; + case EROFS: return NPT_ERROR_FILE_NOT_WRITABLE; + case ENOTDIR: return NPT_ERROR_FILE_NOT_DIRECTORY; + case EEXIST: return NPT_ERROR_FILE_ALREADY_EXISTS; + case ENOSPC: return NPT_ERROR_FILE_NOT_ENOUGH_SPACE; + case ENOTEMPTY: return NPT_ERROR_DIRECTORY_NOT_EMPTY; + default: return NPT_ERROR_ERRNO(err); + } +} + +#if !defined(_WIN32) +/*---------------------------------------------------------------------- +| NPT_FilePath::Separator ++---------------------------------------------------------------------*/ +const char* const NPT_FilePath::Separator = "/"; + +/*---------------------------------------------------------------------- +| NPT_File::GetRoots ++---------------------------------------------------------------------*/ +NPT_Result +NPT_File::GetRoots(NPT_List<NPT_String>& roots) +{ + roots.Clear(); + roots.Add("/"); + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_File::CreateDir ++---------------------------------------------------------------------*/ +NPT_Result +NPT_File::CreateDir(const char* path) +{ + int result; + + result = mkdir(path, 0755); + if (result != 0) { + return MapErrno(errno); + } + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_File::RemoveFile ++---------------------------------------------------------------------*/ +NPT_Result +NPT_File::RemoveFile(const char* path) +{ + int result = unlink(path); + if (result != 0) return MapErrno(errno); + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_File::RemoveDir ++---------------------------------------------------------------------*/ +NPT_Result +NPT_File::RemoveDir(const char* path) +{ + int result = rmdir(path); + if (result != 0) return MapErrno(errno); + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_File::Rename ++---------------------------------------------------------------------*/ +NPT_Result +NPT_File::Rename(const char* from_path, const char* to_path) +{ + int result = rename(from_path, to_path); + if (result != 0) return MapErrno(errno); + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_File::ListDir ++---------------------------------------------------------------------*/ +NPT_Result +NPT_File::ListDir(const char* path, + NPT_List<NPT_String>& entries, + NPT_Ordinal start /* = 0 */, + NPT_Cardinal max /* = 0 */) +{ + // default return value + entries.Clear(); + + // check the arguments + if (path == NULL) return NPT_ERROR_INVALID_PARAMETERS; + + // list the entries + DIR *directory = opendir(path); + if (directory == NULL) return NPT_ERROR_NO_SUCH_ITEM; + + NPT_Cardinal count = 0; + for (;;) { + struct dirent* entry_pointer = NULL; +#if defined(NPT_CONFIG_HAVE_READDIR_R) + struct dirent entry; + int result = readdir_r(directory, &entry, &entry_pointer); + if (result != 0 || entry_pointer == NULL) break; +#else + entry_pointer = readdir(directory); + if (entry_pointer == NULL) break; +#endif + // ignore odd names + if (entry_pointer->d_name[0] == '\0') continue; + + // ignore . and .. + if (entry_pointer->d_name[0] == '.' && + entry_pointer->d_name[1] == '\0') { + continue; + } + if (entry_pointer->d_name[0] == '.' && + entry_pointer->d_name[1] == '.' && + entry_pointer->d_name[2] == '\0') { + continue; + } + + // continue if we still have some items to skip + if (start > 0) { + --start; + continue; + } + entries.Add(NPT_String(entry_pointer->d_name)); + + // stop when we have reached the maximum requested + if (max && ++count == max) break; + } + + closedir(directory); + + return NPT_SUCCESS; +} +#endif + +/*---------------------------------------------------------------------- +| NPT_File::GetWorkingDir ++---------------------------------------------------------------------*/ +NPT_Result +NPT_File::GetWorkingDir(NPT_String& path) +{ + char buffer[1024+1]; + char* dir = getcwd(buffer, 1024+1); + if (dir == NULL) return MapErrno(errno); + path = dir; + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_File::GetInfo ++---------------------------------------------------------------------*/ +NPT_Result +NPT_File::GetInfo(const char* path, NPT_FileInfo* info) +{ + // default value + if (info) NPT_SetMemory(info, 0, sizeof(*info)); + +#if defined(_WIN32) || defined(_XBOX) + // On Windows, stat will fail if a dir ends with a separator + NPT_String _path = path; + _path.TrimRight("\\/"); + // keep a separator at the end for drive names such as C:<backslash> + if (NPT_StringLength(_path) == 2 && _path[1] == ':') { + _path += NPT_FilePath::Separator; + } +#else +#define _path path +#endif + + // get the file info + NPT_stat_struct stat_buffer; + int result = NPT_stat(_path, &stat_buffer); + if (result != 0) return MapErrno(errno); + + // setup the returned fields + if (info) { + info->m_Size = stat_buffer.st_size; + if (S_ISREG(stat_buffer.st_mode)) { + info->m_Type = NPT_FileInfo::FILE_TYPE_REGULAR; + } else if (S_ISDIR(stat_buffer.st_mode)) { + info->m_Type = NPT_FileInfo::FILE_TYPE_DIRECTORY; + } else { + info->m_Type = NPT_FileInfo::FILE_TYPE_OTHER; + } + info->m_AttributesMask &= NPT_FILE_ATTRIBUTE_READ_ONLY; + if ((stat_buffer.st_mode & S_IWUSR) == 0) { + info->m_Attributes &= NPT_FILE_ATTRIBUTE_READ_ONLY; + } +#if defined(NPT_CONFIG_HAVE_STAT_ST_BIRTHTIME) + info->m_CreationTime.SetSeconds(stat_buffer.st_birthtime); +#elif defined(NPT_CONFIG_STAT_ST_CTIME_IS_ST_BIRTHTIME) + info->m_CreationTime.SetSeconds(stat_buffer.st_ctime); +#else + info->m_CreationTime.SetSeconds(0); +#endif + info->m_ModificationTime.SetSeconds(stat_buffer.st_mtime); + } + + return NPT_SUCCESS; +} |