3 /* <project_name> -- <project_description>
5 * Copyright (C) 2006 - 2007
6 * Giuseppe Coviello <cjg@cruxppc.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 int (*load_file
) (void *this, char *filename
, void *buffer
);
29 void (*destroy
) (void *this);
30 struct RdbPartition
*partition
;
31 struct SfsObject
*root
;
32 uint32_t extentbnoderoot
;
36 uint32_t calcchecksum(struct SfsBlockHeader
*block
, uint32_t blocksize
)
38 uint32_t *data
= (uint32_t *) block
;
39 uint32_t checksum
= 1;
43 while (blocksize
> 0) {
51 static int sfs_loadsector(sfs_boot_dev_t
*self
, uint32_t block
, void *buffer
)
53 return loadsector(self
->partition
->info
->start
54 + (block
* (self
->blocksize
/ 512)),
55 self
->partition
->info
->blksz
, self
->blocksize
/ 512,
59 static struct SfsObject
*sfs_nextobject(struct SfsObject
*o
)
64 for (i
= 2; i
> 0; p
++)
67 if ((p
- (uint8_t *) o
) & 0x01)
70 return ((struct SfsObject
*)p
);
73 static struct SfsObject
*sfs_findobject(sfs_boot_dev_t
* self
,
74 struct SfsObject
*cwd
,
75 char *dirname
, uint8_t type
)
81 buffer
= malloc(self
->blocksize
);
82 next
= cwd
->object
.dir
.firstdirblock
;
85 sfs_loadsector(self
, next
, buffer
);
86 if (!calcchecksum(SBH(buffer
), self
->blocksize
)) {
87 printf("Invalid checksum!\n");
90 if (SBH(buffer
)->id
!= SOC_ID
)
92 o
= SOC(buffer
)->object
;
93 while (o
->objectnode
> 0) {
94 if (strcasecmp((char *)o
->name
, dirname
) == 0
95 && (!type
|| o
->bits
& type
))
97 o
= sfs_nextobject(o
);
99 next
= SOC(buffer
)->next
;
105 static struct SfsObject
*sfs_find(sfs_boot_dev_t
* self
, char *filename
)
109 struct SfsObject
*root
;
111 if (*filename
== '/')
114 directory
= malloc(strlen(filename
) + 1);
116 while (root
&& (p
= strchr(filename
, '/')) != NULL
) {
117 memmove(directory
, filename
, strlen(filename
) - strlen(p
));
118 directory
[strlen(filename
) - strlen(p
)] = 0;
119 filename
+= strlen(directory
) + 1;
120 root
= sfs_findobject(self
, root
, directory
, OTYPE_DIR
);
128 return sfs_findobject(self
, root
, filename
, 0);
131 static struct BNode
*get_bnode(sfs_boot_dev_t
* self
, uint32_t key
)
134 struct BNode
*bnode
, *tmp
;
139 buffer
= malloc(self
->blocksize
);
140 next
= self
->extentbnoderoot
;
141 while (sfs_loadsector(self
, next
, buffer
)) {
142 if (!calcchecksum(SBH(buffer
), self
->blocksize
)) {
143 printf("Invalid checksum!\n");
147 for (i
= SBNC(buffer
)->btc
.nodecount
- 1; i
>= 0; i
--) {
148 tmp
= (struct BNode
*)(((uint8_t *) SBNC(buffer
)->btc
.
150 i
* SBNC(buffer
)->btc
.nodesize
);
151 if (tmp
->key
<= key
) {
158 if (SBNC(buffer
)->btc
.isleaf
)
165 static int sfs_loadfile(sfs_boot_dev_t
* self
, char *filename
, void *filebuffer
)
169 uint32_t i
, next
, readed
, size
, tocopy
;
170 struct SfsExtentBNode
*sebn
;
172 if ((o
= sfs_find(self
, filename
)) == NULL
) {
173 printf("%s not found!\n", filename
);
177 buffer
= malloc(self
->blocksize
);
179 next
= o
->object
.file
.data
;
180 size
= o
->object
.file
.size
;
182 while (next
!= 0 && readed
< size
) {
183 sebn
= (struct SfsExtentBNode
*)get_bnode(self
, next
);
184 for (i
= 0; i
< sebn
->blocks
; i
++) {
185 sfs_loadsector(self
, next
+ i
, buffer
);
186 tocopy
= (size
- readed
>= self
->blocksize
187 ? self
->blocksize
: size
- readed
);
188 if (filebuffer
!= NULL
)
189 memmove(filebuffer
+ readed
, buffer
, tocopy
);
198 static int sfs_destroy(sfs_boot_dev_t
* this)
204 boot_dev_t
*sfs_create(struct RdbPartition
*partition
)
206 sfs_boot_dev_t
*boot
;
210 boot
= malloc(sizeof(sfs_boot_dev_t
));
211 boot
->partition
= partition
;
213 buffer
= malloc(64 * 512);
214 loadsector(boot
->partition
->info
->start
, boot
->partition
->info
->blksz
,
216 if (SBH(buffer
)->id
!= SRB_ID
) {
217 printf("** Bad sfs partition or disk - %d:%d **\n",
218 boot
->partition
->disk
, boot
->partition
->partition
);
224 boot
->extentbnoderoot
= SRB(buffer
)->extentbnoderoot
;
225 boot
->blocksize
= SRB(buffer
)->blocksize
;
227 sfs_loadsector(boot
, SRB(buffer
)->rootobjectcontainer
, buffer
);
229 if (SBH(buffer
)->id
!= SOC_ID
) {
230 printf("** Root Object Container not found - %d:%d **\n",
231 boot
->partition
->disk
, boot
->partition
->partition
);
237 printf("Found sfs partition! Name: %s\n",
238 (char *)SOC(buffer
)->object
->name
);
240 boot
->root
= malloc(sizeof(struct SfsObject
));
241 memmove(boot
->root
, SOC(buffer
)->object
, sizeof(struct SfsObject
));
244 boot
->load_file
= (int (*)(void *, char *, void *))sfs_loadfile
;
245 boot
->destroy
= (void (*)(void *))sfs_destroy
;
247 return (boot_dev_t
*) boot
;