2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
6 #include "compatibility.h"
8 #include "partition_support.h"
15 #include "fssh_errno.h"
16 #include "fssh_stat.h"
17 #include "fssh_unistd.h"
18 #include "stat_priv.h"
21 using namespace FSShell
;
27 struct FileRestriction
{
28 FileRestriction(fssh_dev_t device
, fssh_ino_t node
, fssh_off_t startOffset
,
33 startOffset(startOffset
),
40 fssh_off_t startOffset
;
45 typedef std::list
<FileRestriction
*> FileRestrictionList
;
47 static FileRestrictionList sFileRestrictions
;
50 static FileRestriction
*
51 find_file_restriction(fssh_dev_t device
, fssh_ino_t node
)
53 for (FileRestrictionList::iterator it
= sFileRestrictions
.begin();
54 it
!= sFileRestrictions
.end(); ++it
) {
55 FileRestriction
* restriction
= *it
;
56 if (restriction
->device
== device
&& restriction
->node
== node
)
64 static FileRestriction
*
65 find_file_restriction(int fd
)
68 if (unrestricted_fstat(fd
, &st
) < 0)
71 return find_file_restriction(st
.fssh_st_dev
, st
.fssh_st_ino
);
76 add_file_restriction(const char* fileName
, fssh_off_t startOffset
,
80 if (unrestricted_stat(fileName
, &st
) < 0)
83 fssh_dev_t device
= st
.fssh_st_dev
;
84 fssh_ino_t node
= st
.fssh_st_ino
;
86 FileRestriction
* restriction
= find_file_restriction(device
, node
);
91 endOffset
= st
.fssh_st_size
;
93 restriction
= new FileRestriction(device
, node
, startOffset
, endOffset
);
94 sFileRestrictions
.push_back(restriction
);
99 restricted_file_opened(int fd
)
101 FileRestriction
* restriction
= find_file_restriction(fd
);
105 lseek(fd
, restriction
->startOffset
, SEEK_SET
);
110 restricted_file_duped(int oldFD
, int newFD
)
116 restricted_file_closed(int fd
)
122 restricted_file_restrict_io(int fd
, fssh_off_t
& pos
, fssh_off_t size
)
124 FileRestriction
* restriction
= find_file_restriction(fd
);
129 pos
= lseek(fd
, 0, SEEK_CUR
);
133 pos
+= restriction
->startOffset
;
135 if (pos
< restriction
->startOffset
|| pos
> restriction
->endOffset
) {
136 fssh_set_errno(B_BAD_VALUE
);
140 fssh_off_t maxSize
= restriction
->endOffset
- pos
;
149 restricted_file_restrict_stat(struct fssh_stat
* st
)
151 FileRestriction
* restriction
= find_file_restriction(st
->fssh_st_dev
,
156 st
->fssh_st_size
= restriction
->endOffset
- restriction
->startOffset
;
161 to_platform_seek_mode(int fsshWhence
)
163 switch (fsshWhence
) {
175 } // namespace FSShell
179 fssh_lseek(int fd
, fssh_off_t offset
, int whence
)
181 FileRestriction
* restriction
= find_file_restriction(fd
);
183 return lseek(fd
, offset
, to_platform_seek_mode(whence
));
190 pos
= lseek(fd
, 0, SEEK_CUR
);
197 pos
= restriction
->endOffset
+ offset
;
201 pos
= restriction
->startOffset
+ offset
;
205 if (pos
< restriction
->startOffset
) {
206 fssh_set_errno(B_BAD_VALUE
);
210 pos
= lseek(fd
, pos
, SEEK_SET
);
212 pos
-= restriction
->startOffset
;