1 /* 2 * Copyright 2005-2007, Ingo Weinhold, bonefish@users.sf.net. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include "compatibility.h" 7 8 #include "stat_util.h" 9 10 #include <fcntl.h> 11 #include <sys/stat.h> 12 13 #include "fssh_fcntl.h" 14 #include "fssh_stat.h" 15 16 17 namespace FSShell { 18 19 // Haiku only mode_t flags 20 #ifndef HAIKU_HOST_PLATFORM_HAIKU 21 # define S_LINK_SELF_HEALING 0 22 # define S_LINK_AUTO_DELETE 0 23 #endif 24 25 26 fssh_mode_t 27 from_platform_mode(mode_t mode) 28 { 29 #define SET_ST_MODE_BIT(flag, fsshFlag) \ 30 if (mode & flag) \ 31 fsshMode |= fsshFlag; 32 33 fssh_mode_t fsshMode = 0; 34 35 // BeOS/Haiku only 36 #if (defined(__BEOS__) || defined(__HAIKU__)) 37 SET_ST_MODE_BIT(FSSH_S_ATTR_DIR, S_ATTR_DIR); 38 SET_ST_MODE_BIT(FSSH_S_ATTR, S_ATTR); 39 SET_ST_MODE_BIT(FSSH_S_INDEX_DIR, S_INDEX_DIR); 40 SET_ST_MODE_BIT(FSSH_S_INT_INDEX, S_INT_INDEX); 41 SET_ST_MODE_BIT(FSSH_S_UINT_INDEX, S_UINT_INDEX); 42 SET_ST_MODE_BIT(FSSH_S_LONG_LONG_INDEX, S_LONG_LONG_INDEX); 43 SET_ST_MODE_BIT(FSSH_S_ULONG_LONG_INDEX, S_ULONG_LONG_INDEX); 44 SET_ST_MODE_BIT(FSSH_S_FLOAT_INDEX, S_FLOAT_INDEX); 45 SET_ST_MODE_BIT(FSSH_S_DOUBLE_INDEX, S_DOUBLE_INDEX); 46 SET_ST_MODE_BIT(FSSH_S_ALLOW_DUPS, S_ALLOW_DUPS); 47 SET_ST_MODE_BIT(FSSH_S_LINK_SELF_HEALING, S_LINK_SELF_HEALING); 48 SET_ST_MODE_BIT(FSSH_S_LINK_AUTO_DELETE, S_LINK_AUTO_DELETE); 49 #endif 50 51 switch (mode & S_IFMT) { 52 case S_IFLNK: 53 fsshMode |= FSSH_S_IFLNK; 54 break; 55 case S_IFREG: 56 fsshMode |= FSSH_S_IFREG; 57 break; 58 case S_IFBLK: 59 fsshMode |= FSSH_S_IFBLK; 60 break; 61 case S_IFDIR: 62 fsshMode |= FSSH_S_IFDIR; 63 break; 64 case S_IFIFO: 65 fsshMode |= FSSH_S_IFIFO; 66 break; 67 } 68 69 SET_ST_MODE_BIT(FSSH_S_ISUID, S_ISUID); 70 SET_ST_MODE_BIT(FSSH_S_ISGID, S_ISGID); 71 SET_ST_MODE_BIT(FSSH_S_ISVTX, S_ISVTX); 72 SET_ST_MODE_BIT(FSSH_S_IRUSR, S_IRUSR); 73 SET_ST_MODE_BIT(FSSH_S_IWUSR, S_IWUSR); 74 SET_ST_MODE_BIT(FSSH_S_IXUSR, S_IXUSR); 75 SET_ST_MODE_BIT(FSSH_S_IRGRP, S_IRGRP); 76 SET_ST_MODE_BIT(FSSH_S_IWGRP, S_IWGRP); 77 SET_ST_MODE_BIT(FSSH_S_IXGRP, S_IXGRP); 78 SET_ST_MODE_BIT(FSSH_S_IROTH, S_IROTH); 79 SET_ST_MODE_BIT(FSSH_S_IWOTH, S_IWOTH); 80 SET_ST_MODE_BIT(FSSH_S_IXOTH, S_IXOTH); 81 82 #undef SET_ST_MODE_BIT 83 84 return fsshMode; 85 } 86 87 88 mode_t 89 to_platform_mode(fssh_mode_t fsshMode) 90 { 91 #define SET_ST_MODE_BIT(flag, fsshFlag) \ 92 if (fsshMode & fsshFlag) \ 93 mode |= flag; 94 95 mode_t mode = 0; 96 97 // BeOS/Haiku only 98 #if (defined(__BEOS__) || defined(__HAIKU__)) 99 SET_ST_MODE_BIT(FSSH_S_ATTR_DIR, S_ATTR_DIR); 100 SET_ST_MODE_BIT(FSSH_S_ATTR, S_ATTR); 101 SET_ST_MODE_BIT(FSSH_S_INDEX_DIR, S_INDEX_DIR); 102 SET_ST_MODE_BIT(FSSH_S_INT_INDEX, S_INT_INDEX); 103 SET_ST_MODE_BIT(FSSH_S_UINT_INDEX, S_UINT_INDEX); 104 SET_ST_MODE_BIT(FSSH_S_LONG_LONG_INDEX, S_LONG_LONG_INDEX); 105 SET_ST_MODE_BIT(FSSH_S_ULONG_LONG_INDEX, S_ULONG_LONG_INDEX); 106 SET_ST_MODE_BIT(FSSH_S_FLOAT_INDEX, S_FLOAT_INDEX); 107 SET_ST_MODE_BIT(FSSH_S_DOUBLE_INDEX, S_DOUBLE_INDEX); 108 SET_ST_MODE_BIT(FSSH_S_ALLOW_DUPS, S_ALLOW_DUPS); 109 SET_ST_MODE_BIT(FSSH_S_LINK_SELF_HEALING, S_LINK_SELF_HEALING); 110 SET_ST_MODE_BIT(FSSH_S_LINK_AUTO_DELETE, S_LINK_AUTO_DELETE); 111 #endif 112 113 switch (fsshMode & FSSH_S_IFMT) { 114 case FSSH_S_IFLNK: 115 mode |= S_IFLNK; 116 break; 117 case FSSH_S_IFREG: 118 mode |= S_IFREG; 119 break; 120 case FSSH_S_IFBLK: 121 mode |= S_IFBLK; 122 break; 123 case FSSH_S_IFDIR: 124 mode |= S_IFDIR; 125 break; 126 case FSSH_S_IFIFO: 127 mode |= S_IFIFO; 128 break; 129 } 130 131 SET_ST_MODE_BIT(FSSH_S_ISUID, S_ISUID); 132 SET_ST_MODE_BIT(FSSH_S_ISGID, S_ISGID); 133 SET_ST_MODE_BIT(FSSH_S_ISVTX, S_ISVTX); 134 SET_ST_MODE_BIT(FSSH_S_IRUSR, S_IRUSR); 135 SET_ST_MODE_BIT(FSSH_S_IWUSR, S_IWUSR); 136 SET_ST_MODE_BIT(FSSH_S_IXUSR, S_IXUSR); 137 SET_ST_MODE_BIT(FSSH_S_IRGRP, S_IRGRP); 138 SET_ST_MODE_BIT(FSSH_S_IWGRP, S_IWGRP); 139 SET_ST_MODE_BIT(FSSH_S_IXGRP, S_IXGRP); 140 SET_ST_MODE_BIT(FSSH_S_IROTH, S_IROTH); 141 SET_ST_MODE_BIT(FSSH_S_IWOTH, S_IWOTH); 142 SET_ST_MODE_BIT(FSSH_S_IXOTH, S_IXOTH); 143 144 #undef SET_ST_MODE_BIT 145 146 return mode; 147 } 148 149 150 void 151 from_platform_stat(const struct stat *st, struct fssh_stat *fsshStat) 152 { 153 fsshStat->fssh_st_dev = st->st_dev; 154 fsshStat->fssh_st_ino = st->st_ino; 155 fsshStat->fssh_st_mode = from_platform_mode(st->st_mode); 156 fsshStat->fssh_st_nlink = st->st_nlink; 157 fsshStat->fssh_st_uid = st->st_uid; 158 fsshStat->fssh_st_gid = st->st_gid; 159 fsshStat->fssh_st_size = st->st_size; 160 fsshStat->fssh_st_blksize = st->st_blksize; 161 fsshStat->fssh_st_atime = st->st_atime; 162 fsshStat->fssh_st_mtime = st->st_mtime; 163 fsshStat->fssh_st_ctime = st->st_ctime; 164 fsshStat->fssh_st_crtime = st->st_ctime; 165 fsshStat->fssh_st_type = 0; 166 } 167 168 169 void 170 to_platform_stat(const struct fssh_stat *fsshStat, struct stat *st) 171 { 172 st->st_dev = fsshStat->fssh_st_dev; 173 st->st_ino = fsshStat->fssh_st_ino; 174 st->st_mode = to_platform_mode(fsshStat->fssh_st_mode); 175 st->st_nlink = fsshStat->fssh_st_nlink; 176 st->st_uid = fsshStat->fssh_st_uid; 177 st->st_gid = fsshStat->fssh_st_gid; 178 st->st_size = fsshStat->fssh_st_size; 179 st->st_blksize = fsshStat->fssh_st_blksize; 180 st->st_atime = fsshStat->fssh_st_atime; 181 st->st_mtime = fsshStat->fssh_st_mtime; 182 st->st_ctime = fsshStat->fssh_st_ctime; 183 // st->st_crtime = fsshStat->fssh_st_crtime; 184 // st->st_type = fsshStat->fssh_st_type; 185 } 186 187 188 int 189 to_platform_open_mode(int fsshMode) 190 { 191 #define SET_OPEN_MODE_FLAG(flag, fsshFlag) \ 192 if (fsshMode & fsshFlag) \ 193 mode |= flag; 194 195 int mode = 0; 196 197 // the r/w mode 198 switch (fsshMode & FSSH_O_RWMASK) { 199 case FSSH_O_RDONLY: 200 mode |= O_RDONLY; 201 break; 202 case FSSH_O_WRONLY: 203 mode |= O_WRONLY; 204 break; 205 case FSSH_O_RDWR: 206 mode |= O_RDWR; 207 break; 208 } 209 210 // the flags 211 //SET_OPEN_MODE_FLAG(O_CLOEXEC, FSSH_O_CLOEXEC) 212 SET_OPEN_MODE_FLAG(O_NONBLOCK, FSSH_O_NONBLOCK) 213 SET_OPEN_MODE_FLAG(O_EXCL, FSSH_O_EXCL) 214 SET_OPEN_MODE_FLAG(O_CREAT, FSSH_O_CREAT) 215 SET_OPEN_MODE_FLAG(O_TRUNC, FSSH_O_TRUNC) 216 SET_OPEN_MODE_FLAG(O_APPEND, FSSH_O_APPEND) 217 SET_OPEN_MODE_FLAG(O_NOCTTY, FSSH_O_NOCTTY) 218 SET_OPEN_MODE_FLAG(O_NOTRAVERSE, FSSH_O_NOTRAVERSE) 219 //SET_OPEN_MODE_FLAG(O_TEXT, FSSH_O_TEXT) 220 //SET_OPEN_MODE_FLAG(O_BINARY, FSSH_O_BINARY) 221 222 #undef SET_OPEN_MODE_FLAG 223 224 return mode; 225 } 226 227 } // namespace FSShell 228