summaryrefslogtreecommitdiffstats
path: root/lib/libUPnP/Neptune/Source/System/Posix/NptPosixFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libUPnP/Neptune/Source/System/Posix/NptPosixFile.cpp')
-rw-r--r--lib/libUPnP/Neptune/Source/System/Posix/NptPosixFile.cpp268
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;
+}