* Copyright 2005-2007, Ingo Weinhold, bonefish@users.sf.net.
* Distributed under the terms of the MIT License.
*/
#include "compatibility.h"
#include "stat_util.h"
#include <fcntl.h>
#include <sys/stat.h>
#include "fssh_fcntl.h"
#include "fssh_stat.h"
namespace FSShell {
#ifndef HAIKU_HOST_PLATFORM_HAIKU
# define S_LINK_SELF_HEALING 0
# define S_LINK_AUTO_DELETE 0
#endif
fssh_mode_t
from_platform_mode(mode_t mode)
{
#define SET_ST_MODE_BIT(flag, fsshFlag) \
if (mode & flag) \
fsshMode |= fsshFlag;
fssh_mode_t fsshMode = 0;
#if (defined(__BEOS__) || defined(__HAIKU__))
SET_ST_MODE_BIT(FSSH_S_ATTR_DIR, S_ATTR_DIR);
SET_ST_MODE_BIT(FSSH_S_ATTR, S_ATTR);
SET_ST_MODE_BIT(FSSH_S_INDEX_DIR, S_INDEX_DIR);
SET_ST_MODE_BIT(FSSH_S_INT_INDEX, S_INT_INDEX);
SET_ST_MODE_BIT(FSSH_S_UINT_INDEX, S_UINT_INDEX);
SET_ST_MODE_BIT(FSSH_S_LONG_LONG_INDEX, S_LONG_LONG_INDEX);
SET_ST_MODE_BIT(FSSH_S_ULONG_LONG_INDEX, S_ULONG_LONG_INDEX);
SET_ST_MODE_BIT(FSSH_S_FLOAT_INDEX, S_FLOAT_INDEX);
SET_ST_MODE_BIT(FSSH_S_DOUBLE_INDEX, S_DOUBLE_INDEX);
SET_ST_MODE_BIT(FSSH_S_ALLOW_DUPS, S_ALLOW_DUPS);
SET_ST_MODE_BIT(FSSH_S_LINK_SELF_HEALING, S_LINK_SELF_HEALING);
SET_ST_MODE_BIT(FSSH_S_LINK_AUTO_DELETE, S_LINK_AUTO_DELETE);
#endif
switch (mode & S_IFMT) {
case S_IFLNK:
fsshMode |= FSSH_S_IFLNK;
break;
case S_IFREG:
fsshMode |= FSSH_S_IFREG;
break;
case S_IFBLK:
fsshMode |= FSSH_S_IFBLK;
break;
case S_IFDIR:
fsshMode |= FSSH_S_IFDIR;
break;
case S_IFIFO:
fsshMode |= FSSH_S_IFIFO;
break;
}
SET_ST_MODE_BIT(FSSH_S_ISUID, S_ISUID);
SET_ST_MODE_BIT(FSSH_S_ISGID, S_ISGID);
SET_ST_MODE_BIT(FSSH_S_ISVTX, S_ISVTX);
SET_ST_MODE_BIT(FSSH_S_IRUSR, S_IRUSR);
SET_ST_MODE_BIT(FSSH_S_IWUSR, S_IWUSR);
SET_ST_MODE_BIT(FSSH_S_IXUSR, S_IXUSR);
SET_ST_MODE_BIT(FSSH_S_IRGRP, S_IRGRP);
SET_ST_MODE_BIT(FSSH_S_IWGRP, S_IWGRP);
SET_ST_MODE_BIT(FSSH_S_IXGRP, S_IXGRP);
SET_ST_MODE_BIT(FSSH_S_IROTH, S_IROTH);
SET_ST_MODE_BIT(FSSH_S_IWOTH, S_IWOTH);
SET_ST_MODE_BIT(FSSH_S_IXOTH, S_IXOTH);
#undef SET_ST_MODE_BIT
return fsshMode;
}
mode_t
to_platform_mode(fssh_mode_t fsshMode)
{
#define SET_ST_MODE_BIT(flag, fsshFlag) \
if (fsshMode & fsshFlag) \
mode |= flag;
mode_t mode = 0;
#if (defined(__BEOS__) || defined(__HAIKU__))
SET_ST_MODE_BIT(FSSH_S_ATTR_DIR, S_ATTR_DIR);
SET_ST_MODE_BIT(FSSH_S_ATTR, S_ATTR);
SET_ST_MODE_BIT(FSSH_S_INDEX_DIR, S_INDEX_DIR);
SET_ST_MODE_BIT(FSSH_S_INT_INDEX, S_INT_INDEX);
SET_ST_MODE_BIT(FSSH_S_UINT_INDEX, S_UINT_INDEX);
SET_ST_MODE_BIT(FSSH_S_LONG_LONG_INDEX, S_LONG_LONG_INDEX);
SET_ST_MODE_BIT(FSSH_S_ULONG_LONG_INDEX, S_ULONG_LONG_INDEX);
SET_ST_MODE_BIT(FSSH_S_FLOAT_INDEX, S_FLOAT_INDEX);
SET_ST_MODE_BIT(FSSH_S_DOUBLE_INDEX, S_DOUBLE_INDEX);
SET_ST_MODE_BIT(FSSH_S_ALLOW_DUPS, S_ALLOW_DUPS);
SET_ST_MODE_BIT(FSSH_S_LINK_SELF_HEALING, S_LINK_SELF_HEALING);
SET_ST_MODE_BIT(FSSH_S_LINK_AUTO_DELETE, S_LINK_AUTO_DELETE);
#endif
switch (fsshMode & FSSH_S_IFMT) {
case FSSH_S_IFLNK:
mode |= S_IFLNK;
break;
case FSSH_S_IFREG:
mode |= S_IFREG;
break;
case FSSH_S_IFBLK:
mode |= S_IFBLK;
break;
case FSSH_S_IFDIR:
mode |= S_IFDIR;
break;
case FSSH_S_IFIFO:
mode |= S_IFIFO;
break;
}
SET_ST_MODE_BIT(FSSH_S_ISUID, S_ISUID);
SET_ST_MODE_BIT(FSSH_S_ISGID, S_ISGID);
SET_ST_MODE_BIT(FSSH_S_ISVTX, S_ISVTX);
SET_ST_MODE_BIT(FSSH_S_IRUSR, S_IRUSR);
SET_ST_MODE_BIT(FSSH_S_IWUSR, S_IWUSR);
SET_ST_MODE_BIT(FSSH_S_IXUSR, S_IXUSR);
SET_ST_MODE_BIT(FSSH_S_IRGRP, S_IRGRP);
SET_ST_MODE_BIT(FSSH_S_IWGRP, S_IWGRP);
SET_ST_MODE_BIT(FSSH_S_IXGRP, S_IXGRP);
SET_ST_MODE_BIT(FSSH_S_IROTH, S_IROTH);
SET_ST_MODE_BIT(FSSH_S_IWOTH, S_IWOTH);
SET_ST_MODE_BIT(FSSH_S_IXOTH, S_IXOTH);
#undef SET_ST_MODE_BIT
return mode;
}
void
from_platform_stat(const struct stat *st, struct fssh_stat *fsshStat)
{
fsshStat->fssh_st_dev = st->st_dev;
fsshStat->fssh_st_ino = st->st_ino;
fsshStat->fssh_st_mode = from_platform_mode(st->st_mode);
fsshStat->fssh_st_nlink = st->st_nlink;
fsshStat->fssh_st_uid = st->st_uid;
fsshStat->fssh_st_gid = st->st_gid;
fsshStat->fssh_st_size = st->st_size;
fsshStat->fssh_st_blksize = st->st_blksize;
fsshStat->fssh_st_atime = st->st_atime;
fsshStat->fssh_st_mtime = st->st_mtime;
fsshStat->fssh_st_ctime = st->st_ctime;
fsshStat->fssh_st_crtime = st->st_ctime;
fsshStat->fssh_st_type = 0;
}
void
to_platform_stat(const struct fssh_stat *fsshStat, struct stat *st)
{
st->st_dev = fsshStat->fssh_st_dev;
st->st_ino = fsshStat->fssh_st_ino;
st->st_mode = to_platform_mode(fsshStat->fssh_st_mode);
st->st_nlink = fsshStat->fssh_st_nlink;
st->st_uid = fsshStat->fssh_st_uid;
st->st_gid = fsshStat->fssh_st_gid;
st->st_size = fsshStat->fssh_st_size;
st->st_blksize = fsshStat->fssh_st_blksize;
st->st_atime = fsshStat->fssh_st_atime;
st->st_mtime = fsshStat->fssh_st_mtime;
st->st_ctime = fsshStat->fssh_st_ctime;
}
int
to_platform_open_mode(int fsshMode)
{
#define SET_OPEN_MODE_FLAG(flag, fsshFlag) \
if (fsshMode & fsshFlag) \
mode |= flag;
int mode = 0;
switch (fsshMode & FSSH_O_RWMASK) {
case FSSH_O_RDONLY:
mode |= O_RDONLY;
break;
case FSSH_O_WRONLY:
mode |= O_WRONLY;
break;
case FSSH_O_RDWR:
mode |= O_RDWR;
break;
}
SET_OPEN_MODE_FLAG(O_NONBLOCK, FSSH_O_NONBLOCK)
SET_OPEN_MODE_FLAG(O_EXCL, FSSH_O_EXCL)
SET_OPEN_MODE_FLAG(O_CREAT, FSSH_O_CREAT)
SET_OPEN_MODE_FLAG(O_TRUNC, FSSH_O_TRUNC)
SET_OPEN_MODE_FLAG(O_APPEND, FSSH_O_APPEND)
SET_OPEN_MODE_FLAG(O_NOCTTY, FSSH_O_NOCTTY)
SET_OPEN_MODE_FLAG(O_NOTRAVERSE, FSSH_O_NOTRAVERSE)
#undef SET_OPEN_MODE_FLAG
return mode;
}
}