SayoriOS 0.3.3

tarfs.c
1
11 #include <io/ports.h>
12 #include <fs/fsm.h>
13 #include <fs/tarfs.h>
14 #include <lib/php/pathinfo.h>
15 #include <drv/disk/dpm.h>
16 #include "lib/string.h"
17 #include "mem/vmm.h"
18
19 bool tarfs_debug = false;
20
21 int oct2bin(char *str, int size) {
22 int n = 0;
23 char *c = str;
24 while (size-- > 0) {
25 n *= 8;
26 n += *c - '0';
27 c++;
28 }
29 return n;
30 }
31
32 size_t fs_tarfs_read(const char Disk, const char* Path, size_t Offset, size_t Size, void* Buffer){
33 if(tarfs_debug)
34 qemu_log("[FSM] [TARFS] [READ] D:%d | N: %s | O:%d | S:%d",Disk,Path,Offset,Size);
35
36 TarFS_ROOT* initrd = (TarFS_ROOT*) dpm_metadata_read(Disk);
37
38 for (int i = 1; i < initrd->Count; i++){
39 if (!strcmpn(initrd->Files[i].Name,Path))
40 continue;
41
42 return dpm_read(Disk,0,initrd->Files[i].Addr+Offset, Size, Buffer);
43 }
44
45 if (tarfs_debug)
46 qemu_log("[FSM] [TARFS] [READ] NO FOUND!!");
47 return 0;
48 }
49
50 size_t fs_tarfs_write(const char Disk,const char* Path,size_t Offset,size_t Size,void* Buffer){
51 return 0;
52 }
53
54 int fs_tarfs_create(const char Disk,const char* Path,int Mode){
55 return 0;
56 }
57
58 int fs_tarfs_delete(const char Disk,const char* Path,int Mode){
59 return 0;
60 }
61
62 FSM_FILE fs_tarfs_info(const char Disk,const char* Path){
63 if (tarfs_debug) qemu_log("[FSM] [TarFS] [Info]");
64 // FSM_FILE *file = kcalloc(sizeof(FSM_FILE), 1);
65 FSM_FILE file = {};
66
67 TarFS_ROOT* initrd = (TarFS_ROOT*) dpm_metadata_read(Disk);
68
69 for (int i = 1; i < initrd->Count; i++) {
70 //qemu_log("[%d] '%s' != '%s'",strcmp(initrd->Files[i].Name,Path),initrd->Files[i].Name,Path);
71 if (!strcmpn(initrd->Files[i].Name,Path)) continue;
72 // file->Ready = 1;
73 file.Ready = 1;
74 char* zpath = pathinfo(initrd->Files[i].Name, PATHINFO_DIRNAME);
75 //qemu_log("[%d] zpath: %s",strlen(zpath),zpath);
76 // memcpy(file->Path,zpath,strlen(zpath));
77 // memcpy(file->Name,initrd->Files[i].Name,strlen(initrd->Files[i].Name));
78 // file->Mode = 'r';
79 // file->Size = initrd->Files[i].Size;
80 // file->Type = initrd->Files[i].Type - 48;
81
82
83 memcpy(file.Path,zpath,strlen(zpath));
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);
86 file.Mode = 'r';
87 file.Size = initrd->Files[i].Size;
88 file.Type = initrd->Files[i].Type - 48;
89
90 kfree(zpath);
91 //return dpm_read(Disk,initrd->Files[i].Addr+Offset,Size,Buffer);
92 break;
93 }
94
95 // return file[0];
96 return file;
97 }
98
99 void fs_tarfs_label(const char Disk, char* Label){
100 memcpy(Label,"ustar",strlen("ustar"));
101 }
102
103 int fs_tarfs_detect(const char Disk){
104 char* Buffer = kmalloc(5);
105
106 dpm_read(Disk,0,257, 5,Buffer);
107
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);
115
116 kfree(Buffer);
117 return (int)isTarFS;
118 }
119
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); // noalloc
124 FSM_FILE *Files = kcalloc(sizeof(FSM_FILE), initrd->Count);
125
126 size_t CA = 0, CF = 0, CD = 0, CO = 0;
127 for (int i = 1; i < initrd->Count; i++){
131 // char* zpath = pathinfo(initrd->Files[i].Name, PATHINFO_DIRNAME);
132 // qemu_log("[%d] %s",strcmpn(zpath,Path),zpath);
135 bool isPassed = fsm_isPathToFile(Path, initrd->Files[i].Name) == 1;
136
137 if (!isPassed)
138 continue;
139
140 char* zpath = pathinfo(initrd->Files[i].Name, PATHINFO_DIRNAME);
141
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;
147 Files[CA].Ready = 1;
148
149 memcpy(Files[CA].Path, zpath, strlen(zpath));
150
151 substr(Files[CA].Name,
152 initrd->Files[i].Name,
153 strlen(Path),
154 strlen(initrd->Files[i].Name) - (Files[CA].Type == 5?1:0) - strlen(Path)
155 );
156
157 kfree(zpath);
158
159 if (Files[CA].Type == 0) {
161 CF++;
162 } else if (Files[CA].Type == 5){
164 CD++;
165 } else {
167 CO++;
168 }
169 CA++;
170 }
171 Dir->Ready = 1;
172 Dir->Count = CA;
173 Dir->CountFiles = CF;
174 Dir->CountDir = CD;
175 Dir->CountOther = CO;
176 Dir->Files = Files;
177
178 return Dir;
179 }
180
181 size_t fs_tarfs_countFiles(const uint32_t in){
182 size_t count = 0;
183 uint8_t* ptr = (uint8_t*)in;
184
185 size_t pos = 0;
186 TarFS_Elem* elem = (TarFS_Elem*)ptr;
187
188 while (memcmp(elem->Signature, "ustar", 5) == 0) {
189 int filesize = oct2bin(elem->Size, 11);
190
191 count++;
192
193 pos = ALIGN(pos + sizeof(TarFS_Elem) + filesize, 512);
194 elem = (TarFS_Elem*)(ptr + pos);
195 }
196
197 return count;
198 }
199
200 TarFS_ROOT* fs_tarfs_init(uint32_t in, uint32_t size, int Mode){
201 uint8_t *ptr = (uint8_t*)in;
202 if(ptr[257] != 0x75
203 || ptr[258] != 0x73
204 || ptr[259] != 0x74
205 || ptr[260] != 0x61
206 || ptr[261] != 0x72) {
207 return kcalloc(sizeof(TarFS_ROOT), 1);
208 }
209
210 size_t count = fs_tarfs_countFiles(in);
211
212 if (tarfs_debug) qemu_log("Found %d entries.", count);
213
214 size_t currentInx = 0;
215 ssize_t sizeDir = -1;
216
217 TarFS_File* tffs = kcalloc(count + 1, sizeof(TarFS_File));
218 TarFS_ROOT* root = kcalloc(sizeof(TarFS_ROOT), 1);
219
220 size_t pos = 0;
221
222 TarFS_Elem *file = (TarFS_Elem*) ptr;
223
224 while (memcmp(file->Signature, "ustar", 5) == 0) {
225 int filesize = oct2bin(file->Size, 11);
226
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) {
231 qemu_log("Mode:0");
232 sizeDir = 1;
233 }
234
235 tffs[currentInx].Ready = (currentInx==0?0:1);
236 tffs[currentInx].Size = filesize;
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;
240
241
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);
246 currentInx++;
247
248 if (tarfs_debug) qemu_log("[%x] Name: %s; Size: %d", file, file->Name, filesize);
249
250 pos = ALIGN(pos + sizeof(TarFS_Elem) + filesize, 512);
251 file = (TarFS_Elem*)(ptr + pos);
252 // ptr += (((filesize + 511) / 512) + 1) * 512;
253 }
254
255 //while(1);
256
257 root->Ready = 1;
258 root->Count = count;
259 root->Files = tffs;
260
261 return root;
262 }
263
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;
267 return r->Files[i];
268 }
269 return r->Files[0];
270 }
271
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))
275 continue;
276
277 char* buffer = kmalloc(r->Files[i].Size);
278
279 memcpy(buffer, (char*)r->Files[i].Real, r->Files[i].Size);
280
281 return buffer;
282 }
283 return 0;
284 }
285
dpm_read
size_t dpm_read(char Letter, uint64_t high_offset, uint64_t low_offset, size_t Size, void *Buffer)
[DPM] Считывание данных с диска
Definition: dpm.c:82
filesize
size_t filesize(const char *Path)
[FileIO] Возвращает размер указанного файла
Definition: fileio.c:67
strlen
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
atoi
uint32_t atoi(const char s[])
Превращает строку в число
Definition: string.c:565
strcmpn
bool strcmpn(const char *str1, const char *str2)
Сравнение строк
Definition: string.c:270
memcpy
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173
substr
void substr(char *restrict dest, const char *restrict source, int from, int length)
Вырезает и возвращает подстроку из строки
Definition: string.c:492
memcmp
int32_t memcmp(const char *s1, const char *s2, size_t n)
Сравнение массивов
Definition: string.c:305