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 
size_t dpm_read(char Letter, uint64_t high_offset, uint64_t low_offset, size_t Size, void *Buffer)
[DPM] Считывание данных с диска
Definition: dpm.c:82
size_t filesize(const char *Path)
[FileIO] Возвращает размер указанного файла
Definition: fileio.c:67
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
uint32_t atoi(const char s[])
Превращает строку в число
Definition: string.c:565
bool strcmpn(const char *str1, const char *str2)
Сравнение строк
Definition: string.c:270
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173
void substr(char *restrict dest, const char *restrict source, int from, int length)
Вырезает и возвращает подстроку из строки
Definition: string.c:492
int32_t memcmp(const char *s1, const char *s2, size_t n)
Сравнение массивов
Definition: string.c:305