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	extern "C" status_t _kern_read_stat(int fd, const char *path,
27		bool traverseLink, struct stat *st, size_t statSize);
28#endif
29
30
31int
32FSShell::unrestricted_stat(const char *path, struct fssh_stat *fsshStat)
33{
34	struct stat st;
35
36	// Use the _kern_read_stat() defined in libroot on BeOS incompatible
37	// systems. Required for support for opening symlinks.
38#if (defined(__BEOS__) || defined(__HAIKU__))
39	if (::stat(path, &st) < 0)
40		return -1;
41#else
42	status_t error = _kern_read_stat(-1, path, true, &st, sizeof(st));
43	if (error < 0) {
44		fssh_set_errno(error);
45		return -1;
46	}
47#endif
48
49	from_platform_stat(&st, fsshStat);
50
51	return 0;
52}
53
54
55int
56FSShell::unrestricted_fstat(int fd, struct fssh_stat *fsshStat)
57{
58	struct stat st;
59
60	// Use the _kern_read_stat() defined in libroot on BeOS incompatible
61	// systems. Required for support for opening symlinks.
62#if (defined(__BEOS__) || defined(__HAIKU__))
63	if (fstat(fd, &st) < 0)
64		return -1;
65#else
66	status_t error = _kern_read_stat(fd, NULL, false, &st, sizeof(st));
67	if (error < 0) {
68		fssh_set_errno(error);
69		return -1;
70	}
71#endif
72
73	from_platform_stat(&st, fsshStat);
74
75	return 0;
76}
77
78
79int
80FSShell::unrestricted_lstat(const char *path, struct fssh_stat *fsshStat)
81{
82	struct stat st;
83
84	// Use the _kern_read_stat() defined in libroot on BeOS incompatible
85	// systems. Required for support for opening symlinks.
86#if (defined(__BEOS__) || defined(__HAIKU__))
87	if (lstat(path, &st) < 0)
88		return -1;
89#else
90	status_t error = _kern_read_stat(-1, path, false, &st, sizeof(st));
91	if (error < 0) {
92		fssh_set_errno(error);
93		return -1;
94	}
95#endif
96
97	from_platform_stat(&st, fsshStat);
98
99	return 0;
100}
101
102// #pragma mark -
103
104int
105fssh_mkdir(const char *path, fssh_mode_t mode)
106{
107	return mkdir(path, to_platform_mode(mode));
108}
109
110
111int
112fssh_stat(const char *path, struct fssh_stat *fsshStat)
113{
114	if (FSShell::unrestricted_stat(path, fsshStat) < 0)
115		return -1;
116
117	FSShell::restricted_file_restrict_stat(fsshStat);
118
119	return 0;
120}
121
122
123int
124fssh_fstat(int fd, struct fssh_stat *fsshStat)
125{
126	if (FSShell::unrestricted_fstat(fd, fsshStat) < 0)
127		return -1;
128
129	FSShell::restricted_file_restrict_stat(fsshStat);
130
131	return 0;
132}
133
134
135int
136fssh_lstat(const char *path, struct fssh_stat *fsshStat)
137{
138	if (FSShell::unrestricted_lstat(path, fsshStat) < 0)
139		return -1;
140
141	FSShell::restricted_file_restrict_stat(fsshStat);
142
143	return 0;
144}
145