1/*
2 * Copyright 2007, Ingo Weinhold, bonefish@cs.tu-berlin.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6#include "compatibility.h"
7
8#include "fssh_stat.h"
9
10#include <SupportDefs.h>
11
12#include <sys/stat.h>
13
14#include "fssh_errno.h"
15#include "partition_support.h"
16#include "stat_priv.h"
17#include "stat_util.h"
18
19
20using FSShell::from_platform_stat;
21using FSShell::to_platform_mode;
22
23
24#if (!defined(__BEOS__) && !defined(__HAIKU__))
25	// The _kern_read_stat() defined in libroot_build.so.
26#	define _kern_read_stat	_kernbuild_read_stat
27	extern "C" status_t _kern_read_stat(int fd, const char *path,
28		bool traverseLink, struct stat *st, size_t statSize);
29#endif
30
31
32int
33FSShell::unrestricted_stat(const char *path, struct fssh_stat *fsshStat)
34{
35	struct stat st;
36
37	// Use the _kern_read_stat() defined in libroot on BeOS incompatible
38	// systems. Required for support for opening symlinks.
39#if (defined(__BEOS__) || defined(__HAIKU__))
40	if (::stat(path, &st) < 0)
41		return -1;
42#else
43	status_t error = _kern_read_stat(-1, path, true, &st, sizeof(st));
44	if (error < 0) {
45		fssh_set_errno(error);
46		return -1;
47	}
48#endif
49
50	from_platform_stat(&st, fsshStat);
51
52	return 0;
53}
54
55
56int
57FSShell::unrestricted_fstat(int fd, struct fssh_stat *fsshStat)
58{
59	struct stat st;
60
61	// Use the _kern_read_stat() defined in libroot on BeOS incompatible
62	// systems. Required for support for opening symlinks.
63#if (defined(__BEOS__) || defined(__HAIKU__))
64	if (fstat(fd, &st) < 0)
65		return -1;
66#else
67	status_t error = _kern_read_stat(fd, NULL, false, &st, sizeof(st));
68	if (error < 0) {
69		fssh_set_errno(error);
70		return -1;
71	}
72#endif
73
74	from_platform_stat(&st, fsshStat);
75
76	return 0;
77}
78
79
80int
81FSShell::unrestricted_lstat(const char *path, struct fssh_stat *fsshStat)
82{
83	struct stat st;
84
85	// Use the _kern_read_stat() defined in libroot on BeOS incompatible
86	// systems. Required for support for opening symlinks.
87#if (defined(__BEOS__) || defined(__HAIKU__))
88	if (lstat(path, &st) < 0)
89		return -1;
90#else
91	status_t error = _kern_read_stat(-1, path, false, &st, sizeof(st));
92	if (error < 0) {
93		fssh_set_errno(error);
94		return -1;
95	}
96#endif
97
98	from_platform_stat(&st, fsshStat);
99
100	return 0;
101}
102
103// #pragma mark -
104
105int
106fssh_mkdir(const char *path, fssh_mode_t mode)
107{
108	return mkdir(path, to_platform_mode(mode));
109}
110
111
112int
113fssh_stat(const char *path, struct fssh_stat *fsshStat)
114{
115	if (FSShell::unrestricted_stat(path, fsshStat) < 0)
116		return -1;
117
118	FSShell::restricted_file_restrict_stat(fsshStat);
119
120	return 0;
121}
122
123
124int
125fssh_fstat(int fd, struct fssh_stat *fsshStat)
126{
127	if (FSShell::unrestricted_fstat(fd, fsshStat) < 0)
128		return -1;
129
130	FSShell::restricted_file_restrict_stat(fsshStat);
131
132	return 0;
133}
134
135
136int
137fssh_lstat(const char *path, struct fssh_stat *fsshStat)
138{
139	if (FSShell::unrestricted_lstat(path, fsshStat) < 0)
140		return -1;
141
142	FSShell::restricted_file_restrict_stat(fsshStat);
143
144	return 0;
145}
146