#include <sl.h>
typedef long (* FSLoadFile)(CICell ih, char *filePath);
typedef long (* FSGetDirEntry)(CICell ih, char *dirPath,
long *dirIndex, char **name,
long *flags, long *time);
#define kPartNet (0)
#define kPartHFS (1)
#define kPartUFS (2)
#define kPartExt2 (3)
struct PartInfo {
long partType;
CICell partIH;
FSLoadFile loadFile;
FSGetDirEntry getDirEntry;
char partName[1024];
};
typedef struct PartInfo PartInfo, *PartInfoPtr;
#define kNumPartInfos (16)
static PartInfo gParts[kNumPartInfos];
long LookupPartition(char *devSpec);
long LoadFile(char *fileSpec)
{
char devSpec[256];
char *filePath;
FSLoadFile loadFile;
long ret, length, partIndex;
ret = ConvertFileSpec(fileSpec, devSpec, &filePath);
if ((ret == -1) || (filePath == NULL)) return -1;
partIndex = LookupPartition(devSpec);
if (partIndex == -1) return -1;
loadFile = gParts[partIndex].loadFile;
length = loadFile(gParts[partIndex].partIH, filePath);
return length;
}
long CopyFile(char *fileSpec, char **addr, long *length)
{
long len;
char *file;
len = LoadFile(fileSpec);
if (len == -1) return -1;
file = malloc(len + 2);
if (file == NULL) return -1;
strncpy(file, (char *)kLoadAddr, len);
file[len] = '\0';
file[len + 1] = '\0';
*addr = file;
*length = len;
return 0;
}
long GetFileInfo(char *dirSpec, char *name, long *flags, long *time)
{
long ret, index = 0;
char *curName;
while (1) {
ret = GetDirEntry(dirSpec, &index, &curName, flags, time);
if (ret == -1) break;
if (!strcmp(name, curName)) break;
}
return ret;
}
long GetDirEntry(char *dirSpec, long *dirIndex, char **name,
long *flags, long *time)
{
char devSpec[256];
char *dirPath;
FSGetDirEntry getDirEntry;
long ret, partIndex;
ret = ConvertFileSpec(dirSpec, devSpec, &dirPath);
if ((ret == -1) || (dirPath == NULL)) return -1;
partIndex = LookupPartition(devSpec);
if (partIndex == -1) return -1;
getDirEntry = gParts[partIndex].getDirEntry;
ret = getDirEntry(gParts[partIndex].partIH, dirPath,
dirIndex, name, flags, time);
return ret;
}
long DumpDir(char *dirSpec)
{
long ret, flags, time, index = 0;
char *name;
printf("DumpDir on [%s]\n", dirSpec);
while (1) {
ret = GetDirEntry(dirSpec, &index, &name, &flags, &time);
if (ret == -1) break;
printf("%x %x [%s]\n", flags, time, name);
}
return 0;
}
long LookupPartition(char *devSpec)
{
CICell partIH;
long partIndex, partType;
long deviceType;
for (partIndex = 0; partIndex < kNumPartInfos; partIndex++) {
if (!strcmp(gParts[partIndex].partName, devSpec)) break;
}
if (partIndex == kNumPartInfos) {
for (partIndex = 0; partIndex < kNumPartInfos; partIndex++) {
if (gParts[partIndex].partIH == 0) break;
}
if (partIndex == kNumPartInfos) return -1;
deviceType = GetDeviceType(devSpec);
switch (deviceType) {
case kNetworkDeviceType :
partIH = NetInitPartition(devSpec);
if (partIH == 0) return -1;
partType = kPartNet;
break;
case kBlockDeviceType :
printf("Opening partition [%s]...\n", devSpec);
partIH = Open(devSpec);
if (partIH == 0) {
printf("Failed to open partition [%s].\n", devSpec);
return -1;
}
if (HFSInitPartition(partIH) != -1) partType = kPartHFS;
else if (UFSInitPartition(partIH) != -1) partType = kPartUFS;
else if (Ext2InitPartition(partIH) != -1) partType = kPartExt2;
else return -1;
break;
default :
return -1;
}
gParts[partIndex].partIH = partIH;
gParts[partIndex].partType = partType;
strcpy(gParts[partIndex].partName, devSpec);
switch (partType) {
case kPartNet:
gParts[partIndex].loadFile = NetLoadFile;
gParts[partIndex].getDirEntry = NetGetDirEntry;
break;
case kPartHFS:
gParts[partIndex].loadFile = HFSLoadFile;
gParts[partIndex].getDirEntry = HFSGetDirEntry;
break;
case kPartUFS:
gParts[partIndex].loadFile = UFSLoadFile;
gParts[partIndex].getDirEntry = UFSGetDirEntry;
break;
case kPartExt2:
gParts[partIndex].loadFile = Ext2LoadFile;
gParts[partIndex].getDirEntry = Ext2GetDirEntry;
break;
}
}
return partIndex;
}