· 8 years ago · Aug 26, 2018, 02:50 AM
1#include <stdio.h>
2#include <stdlib.h>
3#include <fcntl.h>
4#include <string.h>
5#include <unistd.h>
6#include <signal.h>
7#include <unistd.h>
8
9#define LCD_SSIZE 512
10#define LONG_DIRECTORY 0x0F
11#define SUB_DIRECTORY 0x10
12
13#define LOG printf("[LOG]%s:%d\n",__FILE__,__LINE__);
14
15
16const char *fsinfo_cmd = "fsinfo";
17const char *open_cmd = "open ";
18const char *close_cmd = "close ";
19const char *create_cmd = "create ";
20const char *read_cmd = "read ";
21const char *write_cmd = "write ";
22const char *rm_cmd = "rm ";
23const char *cd_cmd = "cd ";
24const char *ls_cmd = "ls ";
25const char *mkdir_cmd = "mkdir ";
26const char *rmdir_cmd = "rmdir ";
27const char *size_cmd = "size ";
28const char *srm_cmd = "srm ";
29
30struct disk_info {
31 int dest, len, did, sizeFAT, rootLoc, rootCluster, firstDataSector, i;
32 unsigned short bytesPerSector, reservedSectorCount, sectorsPerTrack;
33 unsigned int totalSectors;
34 char psector[LCD_SSIZE];
35 char name[8];
36 char filename[11];
37 char sectorsPerCluster, numFATs, attrLongName;
38};
39
40struct disk_info diskInfo;
41
42void strip_line(char* cmd){
43 cmd[strlen(cmd) - 1] = '\0';
44}
45
46char * whoami(){
47 char *u = getenv("USER");
48 return u;
49}
50
51void update_disk_struct(int);
52
53char **split_string(const char* str, char *sep, int *size){
54 char *path = strdup(str);
55 // in the case of a really long string
56 // this may waste space, but wont cause leaks
57 char **split_args = malloc(strlen(path)*sizeof(char*));
58
59 char *save;
60 //char *path_start_addr = path;
61 char *save_start_addr = save;
62
63 int x = 0;
64 char *token;
65 for(token = strtok_r(path, sep, &save); token != NULL;
66 token = strtok_r(NULL, sep, &save)){
67 split_args[x] = strdup(token);
68 x++;
69 }
70
71 *size = x;
72
73 free(path);
74 return split_args;
75}
76
77void free_splits(char **split_array, int count){
78 int i;
79 for (i = 0; i < count; i++) {
80 free(split_array[i]);
81 }
82
83 free(split_array);
84}
85
86void prompt(char *img){
87 printf("%s(%s)> ", whoami(), img);
88 fflush(stdout);
89 return;
90}
91
92void open_disk(char* disk){
93
94}
95
96void get_input(char cmd[]) {
97 char str[80];
98 fgets(str, 80, stdin);
99 strip_line(str);
100 strcpy(cmd, str);
101 return;
102}
103
104// TODO:
105// - Fail:
106// if filename cannot be found
107// if filename is already open
108// if filename is not a file (directory)
109void open_file(const char *cmd){
110 int size = 0;
111 char **local = split_string(cmd, " ", &size);
112
113 if(size != 3){
114 printf("You must enter a mode and a filename\n");
115 free_splits(local, size);
116 return;
117 }
118
119 char *mode = local[1];
120
121 if( strcmp(mode, "r") != 0 && strcmp(mode, "w") != 0 && strcmp(mode, "rw") != 0 && strcmp(mode, "wr") != 0 )
122 printf("Invalid mode.\n");
123
124 char *file = local[2];
125 printf("[DEBUG] mode: %s\n", mode);
126 printf("[DEBUG] file: %s\n", file);
127 free_splits(local, size);
128}
129
130// TODO:
131// - Fail:
132// if filename cannot be found in the open file table
133void close_file(const char *cmd){
134 int size = 0;
135 char **local = split_string(cmd, " ", &size);
136 if(size != 2){
137 printf("You need to provide a filename\n");
138 free_splits(local, size);
139 return;
140 }
141
142 char *file = local[1];
143
144 free_splits(local, size);
145
146}
147
148// TODO:
149// - Fail:
150// if file already exists
151void create_file(const char *cmd){
152 int size = 0;
153 char **local = split_string(cmd, " ", &size);
154
155 if(size != 2){
156 printf("You need to provide a filename\n");
157 free_splits(local, size);
158 return;
159 }
160
161 char *file = local[1];
162
163 free_splits(local, size);
164}
165
166// TODO:
167// - Fail:
168// if filename is not int he open filetable
169// if startpos is greater than the size of the file
170// if filename is not open for reading
171// if filename is not a file (directory)
172void read_file(const char *cmd){
173 int size = 0;
174 char **local = split_string(cmd, " ", &size);
175
176 if(size != 2){
177 printf("You need to provide a filename\n");
178 free_splits(local, size);
179 return;
180 }
181
182
183 free_splits(local, size);
184}
185
186// TODO:
187// - Fail:
188// if filename is not in the open file table
189// if filename is not open for writing
190// if filename is not a file (directory)
191void write_file(const char *cmd){
192 int size = 0;
193 char **local = split_string(cmd, " ", &size);
194
195 if(size != 2){
196 printf("You need to provide a filename\n");
197 free_splits(local, size);
198 return;
199 }
200
201 free_splits(local, size);
202}
203
204// TODO:
205// - Fail:
206// if filename is not found in the pwd
207// if filename is not a file (directory)
208void rm_file(const char *cmd){
209 int size = 0;
210 char **local = split_string(cmd, " ", &size);
211
212 if(size != 2){
213 printf("You need to provide a filename\n");
214 free_splits(local, size);
215 return;
216 }
217
218 free_splits(local, size);
219}
220
221void cd(const char *cmd){
222 int size = 0;
223 char **local = split_string(cmd, " ", &size);
224
225 if(size != 2){
226 printf("You need to provide a filename\n");
227 free_splits(local, size);
228 return;
229 }
230
231 free_splits(local, size);
232}
233
234void ls(const char *cmd, int did){
235 char psector[LCD_SSIZE];
236 char filename[11];
237 char attrLongName;
238 int i;
239
240 int size = 0;
241 char **local = split_string(cmd, " ", &size);
242
243 if(size != 2){
244 printf("You need to provide a filename\n");
245 free_splits(local, size);
246 return;
247 }
248
249 //seek to boot sector
250 lseek(did, 0, SEEK_SET);
251 //read in boot sector bytes
252 read(did, psector, LCD_SSIZE);
253
254 //seek to the root directory
255 diskInfo.dest = lseek(did, diskInfo.rootLoc*512, SEEK_SET);
256 //read in the root directory
257 read(did, psector, LCD_SSIZE);
258
259 for(i = 1; i < 64; ++i){
260 memcpy(&filename, &psector[32*i], 11); //grab filename for each directory entry
261 memcpy(&attrLongName, &psector[11 + 32*i], 1); //grab attribute for long directory comparison
262 if(filename[0] == 0x00) //break if last valid directory entry was reached
263 break;
264 if(filename[0] != 0xE5 && attrLongName != LONG_DIRECTORY){ //ignore long directory entries
265 if(attrLongName == SUB_DIRECTORY)
266 printf("Directory is %s %X %X\n", filename, filename, &filename);
267 else
268 printf("Filename is %s\n", filename);
269 }
270 }
271
272 free_splits(local, size);
273}
274
275void mk_dir(const char *cmd){
276 int size = 0;
277 char **local = split_string(cmd, " ", &size);
278
279 if(size != 2){
280 printf("You need to provide a filename\n");
281 free_splits(local, size);
282 return;
283 }
284
285 free_splits(local, size);
286}
287
288void rm_dir(const char *cmd){
289 int size = 0;
290 char **local = split_string(cmd, " ", &size);
291
292 if(size != 2){
293 printf("You need to provide a filename\n");
294 free_splits(local, size);
295 return;
296 }
297
298 free_splits(local, size);
299}
300
301
302void size_file(const char *cmd){
303 int size = 0;
304 char **local = split_string(cmd, " ", &size);
305
306 if(size != 2){
307 printf("You need to provide a filename\n");
308 free_splits(local, size);
309 return;
310 }
311
312 free_splits(local, size);
313}
314
315void srm_file(const char *cmd){
316 int size = 0;
317 char **local = split_string(cmd, " ", &size);
318
319 if(size != 2){
320 printf("You need to provide a filename\n");
321 free_splits(local, size);
322 return;
323 }
324
325 free_splits(local, size);
326}
327
328
329int main(int argc, char *argv[]){
330 char cmd[80];
331
332 int disk_id;
333 prompt(argv[1]);
334 get_input(cmd);
335 disk_id = open(argv[1], O_RDWR);
336 update_disk_struct(disk_id);
337
338 while(1){
339 // needs to be open and closed after each command or wierd stuff happens
340 if(strncmp(cmd, fsinfo_cmd, 5) == 0){
341 fsinfo(disk_id);
342 }else if(strncmp(cmd, open_cmd, 5) == 0){
343 open_file(cmd);
344 }else if(strncmp(cmd, close_cmd, 6) == 0){
345 close_file(cmd);
346 }else if(strncmp(cmd, create_cmd, 7) == 0){
347 create_file(cmd);
348 }else if(strncmp(cmd, read_cmd, 5) == 0){
349 read_file(cmd);
350 }else if(strncmp(cmd, write_cmd, 6) == 0){
351 write_file(cmd);
352 }else if(strncmp(cmd, rm_cmd, 3) == 0){
353 rm_file(cmd);
354 }else if(strncmp(cmd, cd_cmd, 3) == 0){
355 cd(cmd);
356 }else if(strncmp(cmd, ls_cmd, 3) == 0){
357 ls(cmd, disk_id);
358 }else if(strncmp(cmd, mkdir_cmd, 6) == 0){
359 mk_dir(cmd);
360 }else if(strncmp(cmd, rmdir_cmd, 6) == 0){
361 rm_dir(cmd);
362 }else if(strncmp(cmd, size_cmd, 5) == 0){
363 size_file(cmd);
364 }else if(strncmp(cmd, srm_cmd, 4) == 0){
365 srm_file(cmd);
366 }else if(strncmp(cmd, "exit", 4) == 0){
367 close(disk_id);
368 exit(0);
369 }
370
371 update_disk_struct(disk_id);
372 prompt(argv[1]);
373 get_input(cmd);
374
375 }
376
377 return 0;
378}
379
380
381void fsinfo(int disk_id){
382 int dest, len, did, sizeFAT, rootLoc, rootCluster, firstDataSector, i;
383 unsigned short bytesPerSector, reservedSectorCount, sectorsPerTrack;
384 unsigned int totalSectors;
385 char psector[LCD_SSIZE];
386 char name[8];
387 char filename[11];
388 char sectorsPerCluster, numFATs, attrLongName;
389
390 //seek to boot sector
391 lseek(disk_id, 0, SEEK_SET);
392 //read in boot sector bytes
393 read(disk_id, psector, LCD_SSIZE);
394
395 //copy over information from the appropriate offsets
396 memcpy(name,&psector[3],8);
397 memcpy(&bytesPerSector, &psector[11], 2);
398 memcpy(§orsPerCluster, &psector[13], 1);
399 memcpy(&reservedSectorCount, &psector[14], 2);
400 memcpy(&numFATs, &psector[16], 1);
401 memcpy(§orsPerTrack, &psector[24], 2);
402 memcpy(&totalSectors, &psector[32], 4);
403 memcpy(&sizeFAT, &psector[36], 4);
404 memcpy(&rootCluster, &psector[44], 4);
405
406 //calculate the location of the root directory
407 firstDataSector = reservedSectorCount + ((int)numFATs * sizeFAT);
408 rootLoc = ((rootCluster - 2) * (int)sectorsPerCluster) + firstDataSector;
409
410 // bytes per sector
411 // sectors per cluster
412 // total sectors
413 // number of FATs
414 // sectors per FAT
415 // number of free sectors
416
417 printf("Bytes Per Sector: %hd\n", bytesPerSector);
418 printf("Sectors Per Cluster: %d\n", sectorsPerCluster);
419 printf("Total sectors: %d\n", totalSectors);
420 printf("Number of FATs: %d\n", numFATs);
421 printf("Sectors per FAT: %d\n", sectorsPerTrack);
422 printf("Number of free sectors: NEEDED\n");
423
424 //printf("Size of FATs: %d\n", sizeFAT);
425 //printf("Root Cluster: %d\n", rootCluster);
426 //printf("Root Location: %d\n", rootLoc);
427
428
429 return;
430}
431
432void update_disk_struct(int disk_id){
433 int dest, len, did, sizeFAT, rootLoc, rootCluster, firstDataSector, i;
434 unsigned short bytesPerSector, reservedSectorCount;
435 char psector[LCD_SSIZE];
436 char name[8];
437 char filename[11];
438 char sectorsPerCluster, numFATs, attrLongName;
439
440 //open file
441 did = disk_id;
442
443 //seek to boot sector
444 lseek(did, 0, SEEK_SET);
445 //read in boot sector bytes
446 read(did, psector, LCD_SSIZE);
447
448 //copy over information from the appropriate offsets
449 memcpy(diskInfo.name,&psector[3],8);
450 memcpy(&diskInfo.bytesPerSector, &psector[11], 2);
451 memcpy(&diskInfo.sectorsPerCluster, &psector[13], 1);
452 memcpy(&diskInfo.reservedSectorCount, &psector[14], 2);
453 memcpy(&diskInfo.numFATs, &psector[16], 1);
454 memcpy(&diskInfo.sizeFAT, &psector[36], 4);
455 memcpy(&diskInfo.rootCluster, &psector[44], 4);
456
457 //calculate the location of the root directory
458 diskInfo.firstDataSector = diskInfo.reservedSectorCount + ((int)diskInfo.numFATs * diskInfo.sizeFAT);
459 diskInfo.rootLoc = ((diskInfo.rootCluster - 2) * (int)diskInfo.sectorsPerCluster) + diskInfo.firstDataSector;
460
461 //seek to the root directory
462 diskInfo.dest = lseek(did, diskInfo.rootLoc*512, SEEK_SET);
463 //read in the root directory
464 read(did, psector, LCD_SSIZE);
465
466 return;
467}