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
17namespace 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
26fssh_mode_t
27from_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
88mode_t
89to_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
150void
151from_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
169void
170to_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
188int
189to_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