2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
12 #include "filehandles3.h"
13 #include "afsblocks.h"
16 #include "baseredef.h"
18 LONG
sameLock(struct AfsHandle
*ah1
, struct AfsHandle
*ah2
) {
20 return (ah1
->header_block
== ah2
->header_block
) ? LOCK_SAME
: LOCK_DIFFERENT
;
23 static const ULONG sizes
[]=
26 offsetof(struct ExAllData
,ed_Type
),
27 offsetof(struct ExAllData
,ed_Size
),
28 offsetof(struct ExAllData
,ed_Prot
),
29 offsetof(struct ExAllData
,ed_Days
),
30 offsetof(struct ExAllData
,ed_Comment
),
31 offsetof(struct ExAllData
,ed_OwnerUID
),
32 sizeof(struct ExAllData
)
37 struct AFSBase
*afsbase
,
38 struct Volume
*volume
,
39 struct ExAllData
*ead
,
40 struct BlockCache
*entryblock
,
48 next
= (STRPTR
)ead
+sizes
[mode
];
49 end
= (STRPTR
)ead
+size
;
51 if (next
> end
) /* > is correct. Not >= */
52 return ERROR_BUFFER_OVERFLOW
;
57 owner
= OS_BE2LONG(entryblock
->buffer
[BLK_OWNER(volume
)]);
58 ead
->ed_OwnerUID
= owner
>>16;
59 ead
->ed_OwnerGID
= owner
& 0xFFFF;
61 if (OS_BE2LONG(entryblock
->buffer
[BLK_SECONDARY_TYPE(volume
)]) != ST_ROOT
)
63 name
= (STRPTR
)((char *)entryblock
->buffer
+(BLK_COMMENT_START(volume
)*4));
64 if ((next
+name
[0]+1) > end
)
65 return ERROR_BUFFER_OVERFLOW
;
66 ead
->ed_Comment
= next
;
67 CopyMem(name
+1, ead
->ed_Comment
, name
[0]);
68 ead
->ed_Comment
[(ULONG
)name
[0]] = 0;
69 next
+= name
[0]+1; /* NULL-Byte */
74 ead
->ed_Days
= OS_BE2LONG(entryblock
->buffer
[BLK_DAYS(volume
)]);
75 ead
->ed_Mins
= OS_BE2LONG(entryblock
->buffer
[BLK_MINS(volume
)]);
76 ead
->ed_Ticks
= OS_BE2LONG(entryblock
->buffer
[BLK_TICKS(volume
)]);
78 ead
->ed_Prot
= OS_BE2LONG(entryblock
->buffer
[BLK_PROTECT(volume
)]);
80 ead
->ed_Size
= OS_BE2LONG(entryblock
->buffer
[BLK_BYTE_SIZE(volume
)]);
82 ead
->ed_Type
= OS_BE2LONG(entryblock
->buffer
[BLK_SECONDARY_TYPE(volume
)]);
84 name
= (STRPTR
)((char *)entryblock
->buffer
+(BLK_FILENAME_START(volume
)*4));
85 if ((next
+name
[0]+1) > end
)
86 return ERROR_BUFFER_OVERFLOW
;
88 CopyMem(name
+1, ead
->ed_Name
, name
[0]);
89 ead
->ed_Name
[(ULONG
)name
[0]] = 0;
90 next
+= name
[0]+1; /* NULL-Byte */
92 ead
->ed_Next
= (struct ExAllData
*)(((IPTR
)next
+ OS_PTRALIGN
- 1) & ~(OS_PTRALIGN
- 1));
99 struct AFSBase
*afsbase
,
100 struct AfsHandle
*ah
,
101 struct ExAllData
*ead
,
107 struct BlockCache
*entryblock
;
109 D(bug("[afs] examine(%ld,ead,%ld,%ld)\n",ah
->header_block
,size
,mode
));
111 return ERROR_BAD_NUMBER
;
112 entryblock
= getBlock(afsbase
, ah
->volume
, ah
->header_block
);
113 if (entryblock
== NULL
)
114 return ERROR_UNKNOWN
;
115 examineEAD(afsbase
, ah
->volume
, ead
, entryblock
, size
, mode
);
116 *dirpos
= ah
->header_block
;
120 ULONG getNextExamineBlock
121 (struct AFSBase
*afsbase
, struct AfsHandle
*ah
, ULONG
*key
, ULONG
*pos
)
123 struct BlockCache
*entryblock
;
127 entryblock
= getBlock(afsbase
, ah
->volume
, *key
);
128 if (entryblock
== NULL
)
129 return ERROR_UNKNOWN
;
130 if (*key
== ah
->header_block
) /* start examining entries in ah */
132 *pos
= BLK_TABLE_START
;
136 if (entryblock
->buffer
[BLK_HASHCHAIN(ah
->volume
)] != 0)
139 *pos
= BLK_HASHCHAIN(ah
->volume
);
143 string
= (char *)entryblock
->buffer
+(BLK_FILENAME_START(ah
->volume
)*4);
144 CopyMem(string
+1, cstr
, string
[0]);
145 cstr
[(ULONG
)string
[0]] = 0;
146 *pos
= BLK_TABLE_START
+getHashKey(cstr
, ah
->volume
->SizeBlock
-56, ah
->volume
->dosflags
)+1;
147 if (*pos
> BLK_TABLE_END(ah
->volume
))
148 return ERROR_NO_MORE_ENTRIES
;
149 entryblock
= getBlock(afsbase
, ah
->volume
, ah
->header_block
);
150 if (entryblock
== NULL
)
151 return ERROR_UNKNOWN
;
154 /* in one case entryblock->buffer[i] points to a block
155 which should be examined next
156 in the other cases it may point to NULL */
157 while (entryblock
->buffer
[*pos
] == 0)
159 if (*pos
== BLK_TABLE_END(ah
->volume
))
160 return ERROR_NO_MORE_ENTRIES
;
163 /* now i is on a valid position */
164 *key
= OS_BE2LONG(entryblock
->buffer
[*pos
]);
171 struct AFSBase
*afsbase
,
172 struct AfsHandle
*ah
,
173 struct ExAllData
*ead
,
174 struct ExAllControl
*eac
,
179 struct BlockCache
*headerblock
;
180 struct BlockCache
*entryblock
;
181 struct ExAllData
*last
;
184 D(bug("[afs] examineAll(%ld,ead,%ld,%ld)\n",ah
->header_block
,size
,mode
));
185 eac
->eac_Entries
= 0;
187 return ERROR_BAD_NUMBER
;
188 headerblock
= getBlock(afsbase
, ah
->volume
, ah
->header_block
);
189 if (headerblock
== NULL
)
190 return ERROR_UNKNOWN
;
192 if ((LONG
)(OS_BE2LONG(headerblock
->buffer
[BLK_SECONDARY_TYPE(ah
->volume
)])) < 0)
194 error
= examineEAD(afsbase
, ah
->volume
, ead
, headerblock
, size
, mode
);
196 eac
->eac_Entries
= 1;
199 error
= getNextExamineBlock(afsbase
, ah
, &ah
->dirpos
, &i
);
200 /* FIXME: if ah->dirpos is an entry stored in a hashchain we return entries twice */
205 the contents of headerblock may have changed
206 by getNextExamineBlock
208 if (headerblock
->blocknum
!= ah
->header_block
)
210 headerblock
= getBlock(afsbase
, ah
->volume
, ah
->header_block
);
211 if (headerblock
== NULL
)
212 return ERROR_UNKNOWN
;
214 headerblock
->flags
|= BCF_USED
;
215 for (; i
<=BLK_TABLE_END(ah
->volume
); i
++)
217 if (headerblock
->buffer
[i
] != 0)
219 block
= OS_BE2LONG(headerblock
->buffer
[i
]);
222 entryblock
= getBlock(afsbase
, ah
->volume
, block
);
223 if (entryblock
== NULL
)
225 headerblock
->flags
&= ~BCF_USED
;
226 return ERROR_UNKNOWN
;
228 error
= examineEAD(afsbase
, ah
->volume
, ead
, entryblock
, size
, mode
);
231 /* stegerg: CHECK CHECK CHECK CHECK CHECK */
232 if (error
== ERROR_BUFFER_OVERFLOW
)
234 ah
->dirpos
= OS_BE2LONG(headerblock
->buffer
[i
]);
237 /* stegerg: END CHECK CHECK CHECK CHECK CHECK */
240 headerblock
->flags
&= ~BCF_USED
;
243 size
-= (ULONG
)((char *)ead
->ed_Next
-(char *)ead
);
246 ah
->dirpos
= OS_BE2LONG(headerblock
->buffer
[i
]);
247 block
= OS_BE2LONG(entryblock
->buffer
[BLK_HASHCHAIN(ah
->volume
)]);
249 } while (block
!= 0);
252 last
->ed_Next
= NULL
;
253 headerblock
->flags
&= ~BCF_USED
;
254 return ERROR_NO_MORE_ENTRIES
;
258 (struct AFSBase
*afsbase
, struct AfsHandle
*ah
, struct FileInfoBlock
*fib
)
260 struct BlockCache
*entryblock
;
262 ULONG filelistentries
,datablocksize
,datablocks
;
265 ULONG dirkey
= fib
->fib_DiskKey
; /* fib_DiskKey is an IPTR, so we need this conversion */
267 D(bug("[afs] examineNext(%ld,fib)\n", ah
->header_block
));
268 D(bug("[afs] examineNext: diskey=%ld\n", dirkey
));
270 error
= getNextExamineBlock(afsbase
, ah
, &dirkey
, &filekey
);
271 fib
->fib_DiskKey
= dirkey
;
274 /* examine the block */
275 entryblock
= getBlock(afsbase
, ah
->volume
, dirkey
);
276 if (entryblock
== NULL
)
277 return ERROR_UNKNOWN
;
278 fib
->fib_DirEntryType
=
279 OS_BE2LONG(entryblock
->buffer
[BLK_SECONDARY_TYPE(ah
->volume
)]);
280 string
= (char *)entryblock
->buffer
+(BLK_FILENAME_START(ah
->volume
)*4);
281 CopyMem(string
, fib
->fib_FileName
, string
[0]+1);
282 fib
->fib_Protection
= OS_BE2LONG(entryblock
->buffer
[BLK_PROTECT(ah
->volume
)]);
283 fib
->fib_EntryType
= fib
->fib_DirEntryType
;
284 fib
->fib_Size
= OS_BE2LONG(entryblock
->buffer
[BLK_BYTE_SIZE(ah
->volume
)]);
285 filelistentries
= ah
->volume
->SizeBlock
-56;
286 datablocksize
= BLOCK_SIZE(ah
->volume
);
287 if (ah
->volume
->dosflags
== 0)
288 datablocksize
= datablocksize
-24;
289 datablocks
= ((fib
->fib_Size
+datablocksize
-1)/datablocksize
);
291 datablocks
+((datablocks
+filelistentries
-1)/filelistentries
);
292 fib
->fib_Date
.ds_Days
= OS_BE2LONG(entryblock
->buffer
[BLK_DAYS(ah
->volume
)]);
293 fib
->fib_Date
.ds_Minute
= OS_BE2LONG(entryblock
->buffer
[BLK_MINS(ah
->volume
)]);
294 fib
->fib_Date
.ds_Tick
= OS_BE2LONG(entryblock
->buffer
[BLK_TICKS(ah
->volume
)]);
295 if (fib
->fib_DirEntryType
!= ST_ROOT
)
297 string
= (char *)entryblock
->buffer
+(BLK_COMMENT_START(ah
->volume
)*4);
298 CopyMem(string
, fib
->fib_Comment
, string
[0] + 1);
300 owner
= OS_BE2LONG(entryblock
->buffer
[BLK_OWNER(ah
->volume
)]);
301 fib
->fib_OwnerUID
= owner
>>16;
302 fib
->fib_OwnerGID
= owner
& 0xFFFF;