14 #include <lib/php/pathinfo.h>
15 #include <drv/disk/dpm.h>
16 #include "lib/string.h"
19 bool tarfs_debug =
false;
21 int oct2bin(
char *str,
int size) {
32 size_t fs_tarfs_read(
const char Disk,
const char* Path,
size_t Offset,
size_t Size,
void* Buffer){
34 qemu_log(
"[FSM] [TARFS] [READ] D:%d | N: %s | O:%d | S:%d",Disk,Path,Offset,Size);
36 TarFS_ROOT* initrd = (TarFS_ROOT*) dpm_metadata_read(Disk);
38 for (
int i = 1; i < initrd->Count; i++){
39 if (!
strcmpn(initrd->Files[i].Name,Path))
42 return dpm_read(Disk,0,initrd->Files[i].Addr+Offset, Size, Buffer);
46 qemu_log(
"[FSM] [TARFS] [READ] NO FOUND!!");
50 size_t fs_tarfs_write(
const char Disk,
const char* Path,
size_t Offset,
size_t Size,
void* Buffer){
54 int fs_tarfs_create(
const char Disk,
const char* Path,
int Mode){
58 int fs_tarfs_delete(
const char Disk,
const char* Path,
int Mode){
62 FSM_FILE fs_tarfs_info(
const char Disk,
const char* Path){
63 if (tarfs_debug) qemu_log(
"[FSM] [TarFS] [Info]");
67 TarFS_ROOT* initrd = (TarFS_ROOT*) dpm_metadata_read(Disk);
69 for (
int i = 1; i < initrd->Count; i++) {
71 if (!
strcmpn(initrd->Files[i].Name,Path))
continue;
74 char* zpath = pathinfo(initrd->Files[i].Name, PATHINFO_DIRNAME);
84 memcpy(file.Name,initrd->Files[i].Name,
strlen(initrd->Files[i].Name));
85 file.CHMOD = (initrd->Files[i].Type == 48?FSM_CHMOD_READ | FSM_CHMOD_EXEC:FSM_CHMOD_READ);
87 file.Size = initrd->Files[i].Size;
88 file.Type = initrd->Files[i].Type - 48;
99 void fs_tarfs_label(
const char Disk,
char* Label){
103 int fs_tarfs_detect(
const char Disk){
104 char* Buffer = kmalloc(5);
108 bool isTarFS = ((Buffer[0] != 0x75 || Buffer[1] != 0x73 || Buffer[2] != 0x74 || Buffer[3] != 0x61 || Buffer[4] != 0x72)?
false:
true);
109 if (tarfs_debug) qemu_log(
"[0] = %x",Buffer[0]);
110 if (tarfs_debug) qemu_log(
"[1] = %x",Buffer[1]);
111 if (tarfs_debug) qemu_log(
"[2] = %x",Buffer[2]);
112 if (tarfs_debug) qemu_log(
"[3] = %x",Buffer[3]);
113 if (tarfs_debug) qemu_log(
"[4] = %x",Buffer[4]);
114 if (tarfs_debug) qemu_log(
"[TarFS] is: %d",isTarFS);
120 FSM_DIR* fs_tarfs_dir(
const char Disk,
const char* Path){
121 if (tarfs_debug) qemu_log(
"[FSM] [TarFS] [Info] Disk:%d | Path:%s",Disk,Path);
122 FSM_DIR *Dir = kcalloc(
sizeof(FSM_DIR), 1);
123 TarFS_ROOT* initrd = dpm_metadata_read(Disk);
124 FSM_FILE *Files = kcalloc(
sizeof(FSM_FILE), initrd->Count);
126 size_t CA = 0, CF = 0, CD = 0, CO = 0;
127 for (
int i = 1; i < initrd->Count; i++){
135 bool isPassed = fsm_isPathToFile(Path, initrd->Files[i].Name) == 1;
140 char* zpath = pathinfo(initrd->Files[i].Name, PATHINFO_DIRNAME);
142 fsm_convertUnix(
atoi(initrd->Files[i].LastTime), &Files[CA].LastTime);
143 Files[CA].CHMOD = FSM_CHMOD_READ;
144 Files[CA].Mode =
'r';
145 Files[CA].Size = initrd->Files[i].Size;
146 Files[CA].Type = initrd->Files[i].Type - 48;
152 initrd->Files[i].Name,
154 strlen(initrd->Files[i].Name) - (Files[CA].Type == 5?1:0) -
strlen(Path)
159 if (Files[CA].Type == 0) {
162 }
else if (Files[CA].Type == 5){
173 Dir->CountFiles = CF;
175 Dir->CountOther = CO;
181 size_t fs_tarfs_countFiles(
const uint32_t in){
183 uint8_t* ptr = (uint8_t*)in;
186 TarFS_Elem* elem = (TarFS_Elem*)ptr;
188 while (
memcmp(elem->Signature,
"ustar", 5) == 0) {
189 int filesize = oct2bin(elem->Size, 11);
193 pos = ALIGN(pos +
sizeof(TarFS_Elem) +
filesize, 512);
194 elem = (TarFS_Elem*)(ptr + pos);
200 TarFS_ROOT* fs_tarfs_init(uint32_t in, uint32_t size,
int Mode){
201 uint8_t *ptr = (uint8_t*)in;
206 || ptr[261] != 0x72) {
207 return kcalloc(
sizeof(TarFS_ROOT), 1);
210 size_t count = fs_tarfs_countFiles(in);
212 if (tarfs_debug) qemu_log(
"Found %d entries.", count);
214 size_t currentInx = 0;
215 ssize_t sizeDir = -1;
217 TarFS_File* tffs = kcalloc(count + 1,
sizeof(TarFS_File));
218 TarFS_ROOT* root = kcalloc(
sizeof(TarFS_ROOT), 1);
222 TarFS_Elem *file = (TarFS_Elem*) ptr;
224 while (
memcmp(file->Signature,
"ustar", 5) == 0) {
225 int filesize = oct2bin(file->Size, 11);
227 if (sizeDir == -1 && Mode == 1){
228 qemu_log(
"Mode:1 | s:%d | m:%d",sizeDir,Mode);
229 sizeDir =
strlen(file->Name) - 1;
230 }
else if (sizeDir == -1) {
235 tffs[currentInx].Ready = (currentInx==0?0:1);
237 tffs[currentInx].Type = (int)file->Type;
238 tffs[currentInx].Real = (uint32_t)(ptr + pos) +
sizeof(TarFS_Elem);
239 tffs[currentInx].Addr = tffs[currentInx].Real - in;
242 memcpy(tffs[currentInx].Mode,file->Mode, 8);
243 memcpy(tffs[currentInx].LastTime,file->LastTime,12);
244 substr(tffs[currentInx].Name,file->Name,sizeDir,100-sizeDir);
245 qemu_log(
"[%d] fix name:%s",
strlen(tffs[currentInx].Name),tffs[currentInx].Name);
248 if (tarfs_debug) qemu_log(
"[%x] Name: %s; Size: %d", file, file->Name,
filesize);
250 pos = ALIGN(pos +
sizeof(TarFS_Elem) +
filesize, 512);
251 file = (TarFS_Elem*)(ptr + pos);
264 TarFS_File tarfs_infoFile(TarFS_ROOT* r,
const char* name){
265 for (
int i = 1;i < r->Count;i++){
266 if (!
strcmpn(r->Files[i].Name,name))
continue;
272 char* tarfs_readFile(TarFS_ROOT* r,
const char* name){
273 for (
int i = 1; i < r->Count; i++) {
274 if (!
strcmpn(r->Files[i].Name,name))
277 char* buffer = kmalloc(r->Files[i].Size);
279 memcpy(buffer, (
char*)r->Files[i].Real, r->Files[i].Size);
size_t dpm_read(char Letter, uint64_t high_offset, uint64_t low_offset, size_t Size, void *Buffer)
[DPM] Считывание данных с диска
size_t filesize(const char *Path)
[FileIO] Возвращает размер указанного файла
size_t strlen(const char *str)
Возращает длину строки
uint32_t atoi(const char s[])
Превращает строку в число
bool strcmpn(const char *str1, const char *str2)
Сравнение строк
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
void substr(char *restrict dest, const char *restrict source, int from, int length)
Вырезает и возвращает подстроку из строки
int32_t memcmp(const char *s1, const char *s2, size_t n)
Сравнение массивов