├── LICENSE ├── README.md └── simulatedFileSystem.c /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Yash Jain 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simulation of File System! 2 | 3 | This repo is a simulation of File System in C Language. 4 | 5 | - Following basic operations can be performed : 6 | 7 | |COMMAND |ACTION | 8 | |----------------|------------------------------- 9 | |`root` |initialize root directory 10 | |`print` |print current working directory and all descendants 11 | |`chdir`|change current working directory (.. refers to parent directory) 12 | |`mkdir` |sub-directory create 13 | |`rmdir` |delete a directory 14 | |`mvdir` |move a directory 15 | |`mkfil` | file create 16 | |`rmfil`| file delete 17 | |`mvfil` | file rename 18 | |`szfil` | file resize 19 | |`exit`| quit the program 20 | 21 | - To run the file system, run in the terminal the following commands: 22 | > **`gcc -o fs simulatedFileSystem.c && ./fs `** 23 | -------------------------------------------------------------------------------- /simulatedFileSystem.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /* command action 8 | * ------- ------ 9 | * root initialize root directory 10 | * print print current working directory and all descendants 11 | * chdir change current working directory (.. refers to parent directory) 12 | * mkdir sub-directory create 13 | * rmdir delete 14 | * mvdir rename 15 | * mkfil file create 16 | * rmfil delete 17 | * mvfil rename 18 | * szfil resize 19 | * exit quit the program 20 | */ 21 | 22 | int debug = 1; // extra output; 1 = on, 0 = off 23 | 24 | int do_root (char *name, char *size); 25 | int do_print(char *name, char *size); 26 | int do_chdir(char *name, char *size); 27 | int do_mkdir(char *name, char *size); 28 | int do_rmdir(char *name, char *size); 29 | int do_mvdir(char *name, char *size); 30 | int do_mkfil(char *name, char *size); 31 | int do_rmfil(char *name, char *size); 32 | int do_mvfil(char *name, char *size); 33 | int do_szfil(char *name, char *size); 34 | int do_exit (char *name, char *size); 35 | /* 36 | returns 0 (success) or -1 (failure) 37 | */ 38 | 39 | struct action { 40 | char *cmd; // pointer to string 41 | int (*action)(char *name, char *size); // pointer to function 42 | } table[] = { 43 | { "root" , do_root }, 44 | { "print", do_print }, 45 | { "chdir", do_chdir }, 46 | { "mkdir", do_mkdir }, 47 | { "rmdir", do_rmdir }, 48 | { "mvdir", do_mvdir }, 49 | { "mkfil", do_mkfil }, 50 | { "rmfil", do_rmfil }, 51 | { "mvfil", do_mvfil }, 52 | { "szfil", do_szfil }, 53 | { "exit" , do_exit }, 54 | { NULL, NULL } // end mark, do not remove ,gives wierd errors! :( 55 | }; 56 | 57 | /*--------------------------------------------------------------------------------*/ 58 | void printing(char *name); 59 | void print_descriptor ( ); 60 | void parse(char *buf, int *argc, char *argv[]); 61 | int allocate_block (char *name, bool directory ) ; 62 | void unallocate_block ( int offset ); 63 | int find_block ( char* name, bool directory ); 64 | 65 | int add_descriptor ( char * name ); 66 | int edit_descriptor ( int free_index, bool free, int name_index, char * name ); 67 | int edit_descriptor_name (int index, char* new_name); 68 | int add_directory( char * name ); 69 | int remove_directory( char * name ); 70 | int rename_directory( char *name, char *new_name ); 71 | int edit_directory ( char * name, char*subitem_name, char *new_name, bool name_change, bool directory ); 72 | int add_file( char * name, int size ); 73 | int edit_file ( char * name, int size, char *new_name ); 74 | int remove_file (char* name); 75 | int edit_directory_subitem (char* name, char* sub_name, char* new_sub_name); 76 | 77 | void print_directory ( char *name); 78 | char * get_directory_name ( char*name ); 79 | char * get_directory_top_level ( char*name); 80 | char * get_directory_subitem ( char*name, int subitem_index, char * subitem ); 81 | int get_directory_subitem_count ( char*name); 82 | 83 | char * get_file_name ( char*name ); 84 | char * get_file_top_level ( char*name); 85 | int get_file_size( char*name); 86 | void print_file ( char *name); 87 | 88 | /************************** Defining Constants for fs *******************/ 89 | #define LINESIZE 128 90 | #define DISK_PARTITION 4000000 91 | #define BLOCK_SIZE 5000 92 | #define BLOCKS 4000000/5000 93 | #define MAX_STRING_LENGTH 20 94 | #define MAX_FILE_DATA_BLOCKS (BLOCK_SIZE-64*59) //Hard-coded as of now 95 | #define MAX_SUBDIRECTORIES (BLOCK_SIZE - 136)/MAX_STRING_LENGTH 96 | 97 | typedef struct { 98 | char directory[MAX_STRING_LENGTH]; 99 | int directory_index; 100 | char parent[MAX_STRING_LENGTH]; 101 | int parent_index; 102 | } working_directory; 103 | 104 | 105 | typedef struct dir_type { 106 | char name[MAX_STRING_LENGTH]; //Name of file or dir 107 | char top_level[MAX_STRING_LENGTH]; //Name of directory one level up(immediate parent) 108 | char (*subitem)[MAX_STRING_LENGTH]; 109 | bool subitem_type[MAX_SUBDIRECTORIES]; //true if directory, false if file 110 | int subitem_count; 111 | struct dir_type *next; 112 | } dir_type; 113 | 114 | 115 | typedef struct file_type { 116 | char name[MAX_STRING_LENGTH]; //Name of file or dir 117 | char top_level[MAX_STRING_LENGTH]; //Name of directory one level up 118 | int data_block_index[MAX_FILE_DATA_BLOCKS]; 119 | int data_block_count; 120 | int size; 121 | struct file_type *next; 122 | } file_type; 123 | 124 | typedef struct { 125 | bool free[BLOCKS]; 126 | bool directory[BLOCKS]; 127 | char (*name)[MAX_STRING_LENGTH]; 128 | } descriptor_block; 129 | 130 | char *disk; 131 | working_directory current; 132 | bool disk_allocated = false; // makes sure that do_root is first thing being called and only called once 133 | 134 | /*--------------------------------------------------------------------------------*/ 135 | 136 | int main(int argc, char *argv[]) 137 | { 138 | (void)argc; 139 | (void)*argv; 140 | char in[LINESIZE]; 141 | char *cmd, *fnm, *fsz; 142 | char dummy[] = ""; 143 | 144 | //printf("sizeof file_type = %d\nsizeof dir_type = %d\nsize of descriptor_block = %d\nMAX_FILE_SIZE %d\n", sizeof(file_type), sizeof(dir_type), sizeof(descriptor_block), MAX_FILE_DATA_BLOCKS ); 145 | 146 | printf("Welcome to your file system\n"); 147 | int n; 148 | char *a[LINESIZE]; 149 | 150 | while (fgets(in, LINESIZE, stdin) != NULL) 151 | { 152 | // commands are all of form "cmd filename filesize\n" with whitespace as a delimiter 153 | 154 | // parse input 155 | parse(in, &n, a); 156 | 157 | cmd = (n > 0) ? a[0] : dummy; 158 | fnm = (n > 1) ? a[1] : dummy; 159 | fsz = (n > 2) ? a[2] : dummy; 160 | 161 | if (debug) printf(":%s:%s:%s:\n", cmd, fnm, fsz); 162 | 163 | if (n == 0) continue; // blank line 164 | 165 | int found = 0; 166 | 167 | for (struct action *ptr = table; ptr->cmd != NULL; ptr++){ 168 | if (strcmp(ptr->cmd, cmd) == 0) 169 | { 170 | found = 1; 171 | 172 | int ret = (ptr->action)(fnm, fsz); 173 | //every function returns -1 on failure 174 | if (ret == -1) 175 | { printf(" %s %s %s: failed\n", cmd, fnm, fsz); } 176 | break; 177 | } 178 | } 179 | if (!found) { printf("command not found: %s\n", cmd);} 180 | } 181 | 182 | return 0; 183 | } 184 | 185 | 186 | /*--------------------------------------------------------------------------------*/ 187 | 188 | void parse(char *buf, int *argc, char *argv[]) 189 | { 190 | char *delim; // points to first space delimiter 191 | int count = 0; // number of args 192 | 193 | char whsp[] = " \t\n\v\f\r"; // whitespace characters 194 | 195 | while (1) // build the argv list 196 | { 197 | buf += strspn(buf, whsp); // skip leading whitespace 198 | delim = strpbrk(buf, whsp); // next whitespace char or NULL 199 | if (delim == NULL) // end of line, input parsed 200 | { break; } 201 | argv[count++] = buf; 202 | *delim = '\0'; 203 | buf = delim + 1; 204 | } 205 | argv[count] = NULL; 206 | 207 | *argc = count; 208 | 209 | return; 210 | } 211 | 212 | /*--------------------------------------------------------------------------------*/ 213 | 214 | //This function initializes the disk, descriptor within the disk, as well as the root directory. 215 | int do_root(char *name, char *size) 216 | { 217 | (void)*name; 218 | (void)*size; 219 | if ( disk_allocated == true ) 220 | return 0; 221 | 222 | //Initialize disk 223 | disk = (char*)malloc ( DISK_PARTITION ); 224 | if ( debug ) printf("\t[%s] Allocating [%d] Bytes of memory to the disk\n", __func__, DISK_PARTITION ); 225 | 226 | //Add descriptor and root directory to disk 227 | add_descriptor("descriptor"); 228 | if ( debug ) printf("\t[%s] Creating Descriptor Block\n", __func__ ); 229 | add_directory("root"); 230 | if ( debug ) printf("\t[%s] Creating Root Directory\n", __func__ ); 231 | 232 | //Set up the working_directory structure 233 | strcpy(current.directory, "root"); 234 | current.directory_index = 3; 235 | strcpy(current.parent, "" ); 236 | current.parent_index = -1; 237 | if ( debug ) printf("\t[%s] Set Current Directory to [%s], with Parent Directory [%s]\n", __func__, "root", "" ); 238 | 239 | if ( debug ) printf("\t[%s] Disk Successfully Allocated\n", __func__ ); 240 | disk_allocated = true; 241 | 242 | return 0; 243 | } 244 | 245 | /*--------------------------------------------------------------------------------*/ 246 | 247 | int do_print(char *name, char *size) 248 | { 249 | (void)*name; 250 | (void)*size; 251 | if ( disk_allocated == false ) { 252 | printf("Error: Disk not allocated\n"); 253 | return 0; 254 | } 255 | //Start with the root directory, which is directory type (true) 256 | printing("root"); 257 | 258 | if (debug) if ( debug ) printf("\n\t[%s] Finished printing\n", __func__); 259 | return 0; 260 | } 261 | 262 | /*--------------------------------------------------------------------------------*/ 263 | 264 | int do_chdir(char *name, char *size) 265 | { 266 | (void)*size; 267 | if ( disk_allocated == false ) { 268 | printf("Error: Disk not allocated\n"); 269 | return 0; 270 | } 271 | 272 | //Case if ".." is the argument to "chdir" 273 | if ( strcmp(name, ".." ) == 0 ) { 274 | 275 | //If we are in root directory then we can't go back 276 | if ( strcmp(current.directory, "root") == 0 ) 277 | return 0; 278 | 279 | //Adjust the working_directory struct 280 | strcpy ( current.directory, current.parent ); 281 | strcpy (current.parent, get_directory_top_level( current.parent) ); 282 | if ( debug ) printf ("\t[%s] Current Directory is now [%s], Parent Directory is [%s]\n", __func__, current.directory, current.parent); 283 | return 0; 284 | } 285 | else 286 | { 287 | char tmp[20]; 288 | 289 | //Check to make sure it is a subdirectory that is to be changed 290 | //If name is not in the current directory then returns -1, else return 0 291 | if ( (strcmp(get_directory_subitem(current.directory, -1, name), "-1") == 0) && strcmp( current.parent, name ) != 0 ) { 292 | if ( debug ) printf( "\t\t\t[%s] Cannot Change to Directory [%s]\n", __func__, name ); 293 | if (!debug ) printf( "%s: %s: No such file or directory\n", "chdir", name ); 294 | return 0; 295 | } 296 | 297 | strcpy( tmp, get_directory_name(name)); 298 | if ( strcmp(tmp, "") == 0 ) 299 | return 0; 300 | 301 | if ( strcmp( tmp, name ) == 0 ) { 302 | //Adjust the working_directory struct 303 | strcpy ( current.directory, tmp); 304 | 305 | 306 | strcpy(current.parent, get_directory_top_level(name) ); 307 | if ( debug ) printf ("\t[%s] Current Directory is now [%s], Parent Directory is [%s]\n", __func__, current.directory, current.parent); 308 | return 1; 309 | } 310 | return -1; 311 | } 312 | return 0; 313 | } 314 | 315 | /*--------------------------------------------------------------------------------*/ 316 | 317 | int do_mkdir(char *name, char *size) 318 | { 319 | (void)*size; 320 | if ( disk_allocated == false ) { 321 | printf("Error: Disk not allocated\n"); 322 | return 0; 323 | } 324 | 325 | //If it returns 0, there is a subitem with that name already 326 | if ( get_directory_subitem(current.directory, -1, name) == 0 ) { 327 | if ( debug ) printf( "\t\t\t[%s] Cannot Make Directory [%s]\n", __func__, name ); 328 | if (!debug ) printf( "%s: cannot create directory '%s': Folder exists\n", "mkdir", name ); 329 | return 0; 330 | } 331 | 332 | //Call add directory 333 | if ( debug ) printf("\t[%s] Creating Directory: [%s]\n", __func__, name ); 334 | if ( add_directory( name ) != 0 ) { 335 | if (!debug ) printf("%s: missing operand\n", "mkdir"); 336 | return 0; 337 | } 338 | 339 | //Edit the current directory to add our new directory to the current directory's "subdirectory" member. 340 | //NULL ==> for just editing the subdirectory 341 | edit_directory( current.directory, name, NULL, false, true ); 342 | if ( debug ) printf("\t[%s] Updating Parents Subitem content\n", __func__ ); 343 | 344 | if ( debug ) printf("\t[%s] Directory Created Successfully\n", __func__ ); 345 | if( debug ) print_directory(name); 346 | 347 | return 0; 348 | } 349 | 350 | /*--------------------------------------------------------------------------------*/ 351 | 352 | int do_rmdir(char *name, char *size) 353 | { 354 | (void)*size; 355 | if ( disk_allocated == false ) { 356 | printf("Error: Disk not allocated\n"); 357 | return 0; 358 | } 359 | 360 | if ( strcmp(name,"") == 0 ) { 361 | if ( debug ) printf("\t[%s] Invalid Command\n", __func__ ); 362 | if (!debug ) printf("%s: missing operand\n", "rmdir"); 363 | return 0; 364 | } 365 | 366 | if( (strcmp(name, ".") == 0) || (strcmp(name, "..") == 0) ) { 367 | if ( debug ) printf("\t[%s] Invalid command [%s] Will not remove directory\n", __func__, name); 368 | if (!debug ) printf( "%s: %s: No such file or directory\n", "rmdir", name ); 369 | return 0; 370 | } 371 | 372 | //Check to make sure it is a subdirectory that is to be changed 373 | //If name is not in the current directory then returns -1, else return 0 374 | if ( strcmp(get_directory_subitem(current.directory, -1, name), "-1") == 0 ) { 375 | if ( debug ) printf( "\t[%s] Cannot Remove Directory [%s]\n", __func__, name ); 376 | if (!debug ) printf( "%s: %s: No such file or directory\n", "rmdir", name ); 377 | return 0; 378 | } 379 | 380 | //Remove directory from the parent's subitems. 381 | dir_type *folder = malloc ( BLOCK_SIZE ); 382 | int block_index = find_block(name, true); 383 | memcpy( folder, disk + block_index*BLOCK_SIZE, BLOCK_SIZE ); 384 | 385 | dir_type *top_folder = malloc ( BLOCK_SIZE ); 386 | 387 | //The top_level is created based off the folder 388 | int top_block_index = find_block(folder->top_level, true); 389 | memcpy( disk + block_index*BLOCK_SIZE, folder, BLOCK_SIZE ); 390 | memcpy( top_folder, disk + top_block_index*BLOCK_SIZE, BLOCK_SIZE ); 391 | 392 | char subitem_name[MAX_STRING_LENGTH]; // holds the current subitem in the parent directory array 393 | const int subcnt = top_folder->subitem_count; // no. of subitems 394 | int j; 395 | int k=0; 396 | 397 | //iterate through the subitem count 398 | for(j = 0; jsubitem[j]); 400 | if (strcmp(subitem_name, name) != 0) 401 | { 402 | strcpy(top_folder->subitem[k],subitem_name); 403 | //printf("------ Subitem [%s] copied ------\n", subitem_name); 404 | k++; 405 | } 406 | } 407 | 408 | //Remove the directory subitem from the parent 409 | strcpy(top_folder->subitem[k], ""); 410 | 411 | top_folder->subitem_count--; 412 | memcpy( disk + top_block_index*BLOCK_SIZE, top_folder, BLOCK_SIZE ); 413 | free(top_folder); 414 | 415 | //Remove the directory with its contents 416 | if ( debug ) printf("\t[%s] Removing Directory: [%s]\n", __func__, name ); 417 | if( remove_directory( name ) == -1 ) { 418 | return 0; 419 | } 420 | 421 | if (debug) printf("\t[%s] Directory Removed Successfully\n", __func__); 422 | return 0; 423 | } 424 | 425 | /*--------------------------------------------------------------------------------*/ 426 | 427 | int do_mvdir(char *name, char *size) //"size" is actually the new name 428 | { 429 | if ( disk_allocated == false ) { 430 | printf("Error: Disk not allocated\n"); 431 | return 0; 432 | } 433 | 434 | //Rename the directory 435 | if ( debug ) printf("\t[%s] Renaming Directory: [%s]\n", __func__, name ); 436 | //if the directory "name" is not found, return -1 437 | if( edit_directory( name, "", size, true, true ) == -1 ) { 438 | if (!debug ) printf( "%s: cannot rename file or directory '%s'\n", "mvdir", name ); 439 | return 0; 440 | } 441 | 442 | //else the directory is renamed 443 | if (debug) printf( "\t[%s] Directory Renamed Successfully: [%s]\n", __func__, size ); 444 | if (debug) print_directory(size); 445 | return 0; 446 | } 447 | 448 | /*--------------------------------------------------------------------------------*/ 449 | 450 | int do_mkfil(char *name, char *size) 451 | { 452 | if ( disk_allocated == false ) { 453 | printf("Error: Disk not allocated\n"); 454 | return 0; 455 | } 456 | 457 | if ( debug ) printf("\t[%s] Creating File: [%s], with Size: [%s]\n", __func__, name, size ); 458 | 459 | //If it returns 0, there is a subitem with that name already 460 | if ( get_directory_subitem(current.directory, -1, name) == 0 ) { 461 | if ( debug ) printf( "\t\t\t[%s] Cannot make file [%s], a file or directory [%s] already exists\n", __func__, name, name ); 462 | if (!debug ) printf( "%s: cannot create file '%s': File exists\n", "mkfil", name ); 463 | return 0; 464 | } 465 | 466 | if ( add_file ( name, atoi(size)) != 0 ) 467 | return 0; 468 | 469 | //Edit the current directory to add our new file to the current directory's "subdirectory" member. 470 | edit_directory( current.directory, name, NULL, false, false); 471 | if ( debug ) printf("\t[%s] Updating Parents Subitem content\n", __func__ ); 472 | 473 | if ( debug ) print_file(name); 474 | return 0; 475 | } 476 | 477 | /*--------------------------------------------------------------------------------*/ 478 | 479 | // Remove a file 480 | int do_rmfil(char *name, char *size) 481 | { 482 | if ( disk_allocated == false ) { 483 | printf("Error: Disk not allocated\n"); 484 | return 0; 485 | } 486 | 487 | (void)*size; 488 | if ( debug ) printf("\t[%s] Removing File: [%s]\n", __func__, name); 489 | 490 | //If the file to be removed actually exists in current directory, remove it 491 | if ( get_directory_subitem(current.directory, -1, name) == 0 ) { 492 | remove_file(name); 493 | return 0; 494 | } 495 | else{ // If it doesn't exist, print error and return 0 496 | if ( debug ) printf( "\t\t\t[%s] Cannot remove file [%s], it does not exist in this directory\n", __func__, name ); 497 | if (!debug ) printf( "%s: %s: No such file or directory\n", "rmfil", name ); 498 | return 0; 499 | } 500 | } 501 | 502 | /*--------------------------------------------------------------------------------*/ 503 | 504 | // Rename a file 505 | int do_mvfil(char *name, char *size) 506 | { 507 | if ( disk_allocated == false ) { 508 | printf("Error: Disk not allocated\n"); 509 | return 0; 510 | } 511 | 512 | if ( debug ) printf("\t[%s] Renaming File: [%s], to: [%s]\n", __func__, name, size ); 513 | 514 | //If it returns 0, there is a subitem with that name already 515 | if ( get_directory_subitem(current.directory, -1, size) == 0 ) { 516 | if ( debug ) printf( "\t\t\t[%s] Cannot rename file [%s], a file or directory [%s] already exists\n", __func__, name, size ); 517 | if (!debug ) printf( "%s: cannot rename file or directory '%s'\n", "mvfil", name ); 518 | return 0; 519 | } 520 | 521 | int er = edit_file( name, 0, size); 522 | 523 | if (er == -1) return -1; 524 | if (debug) print_file(size); 525 | 526 | return 0; 527 | } 528 | 529 | /*--------------------------------------------------------------------------------*/ 530 | 531 | // Resize a file -- addon to be implemented 532 | int do_szfil(char *name, char *size) 533 | { 534 | if ( disk_allocated == false ) { 535 | printf("Error: Disk not allocated\n"); 536 | return 0; 537 | } 538 | 539 | if ( debug ) printf("\t[%s] Resizing File: [%s], to: [%s]\n", __func__, name, size ); 540 | //remove file; make new file with updated size 541 | if (remove_file(name) != -1) do_mkfil(name, size); 542 | 543 | else { 544 | if ( debug ) printf("\t[%s] File: [%s] does not exist. Cannot resize.\n", __func__, name); 545 | if (!debug ) printf( "%s: cannot resize '%s': No such file or directory\n", "szfil", name ); 546 | } 547 | 548 | return 0; 549 | } 550 | 551 | /*--------------------------------------------------------------------------------*/ 552 | 553 | int do_exit(char *name, char *size) 554 | { 555 | (void)*name; 556 | (void)*size; 557 | if (debug) printf("\t[%s] Exiting\n", __func__); 558 | exit(0); 559 | return 0; 560 | } 561 | 562 | /*--------------------------------------------------------------------------------*/ 563 | 564 | 565 | /******************************* Helper Functions Start *****************************/ 566 | 567 | //Prints the information of directories and files starting at the root 568 | void printing(char *name) { 569 | //Allocate memory to a dir_type so that we can copy the folder from memory into this variable. 570 | dir_type *folder = malloc (BLOCK_SIZE); 571 | int block_index = find_block(name, true); 572 | 573 | memcpy( folder, disk + block_index*BLOCK_SIZE, BLOCK_SIZE); 574 | 575 | printf("%s:\n", folder->name); 576 | for( int i = 0; i < folder->subitem_count; i++ ) { 577 | printf("\t%s\n", folder->subitem[i]); 578 | } 579 | 580 | //Go through again if there is a subdirectory 581 | for( int i = 0; i < folder->subitem_count; i++ ) { 582 | if( folder->subitem_type[i] == true ) { 583 | //Recursively call the function! can be improved further ;) 584 | printing(folder->subitem[i]); 585 | } 586 | } 587 | } 588 | 589 | /*--------------------------------------------------------------------------------*/ 590 | 591 | //Displays the content of the descriptor block and free block table. 592 | void print_descriptor ( ) { 593 | descriptor_block *descriptor = malloc( BLOCK_SIZE*2 ); 594 | 595 | memcpy ( descriptor, disk, BLOCK_SIZE*2 ); 596 | 597 | printf("Disk Descriptor Free Table:\n"); 598 | 599 | for ( int i = 0; i < BLOCKS ; i++ ) { 600 | printf("\tIndex %d : %d\n", i, descriptor->free[i]); 601 | } 602 | 603 | free(descriptor); 604 | } 605 | 606 | /*--------------------------------------------------------------------------------*/ 607 | 608 | //finds the first free block on the disk; the free block index is returned 609 | int allocate_block ( char *name, bool directory ) { 610 | 611 | descriptor_block *descriptor = malloc( BLOCK_SIZE*2); 612 | 613 | memcpy ( descriptor, disk, BLOCK_SIZE*2 ); 614 | 615 | //Goes through every block until free one is found 616 | if ( debug ) printf("\t\t\t[%s] Finding Free Memory Block in the Descriptor\n", __func__ ); 617 | for ( int i = 0; i < BLOCKS; i++ ) { 618 | if ( descriptor->free[i] ) { 619 | //Once free block is found, update descriptor information 620 | descriptor->free[i] = false; 621 | descriptor->directory[i] = directory; 622 | strcpy(descriptor->name[i], name); 623 | 624 | //update descriptor back to the beginning of the disk 625 | memcpy(disk, descriptor, BLOCK_SIZE*2); 626 | if ( debug ) printf("\t\t\t[%s] Allocated [%s] at Memory Block [%d]\n", __func__, name, i ); 627 | 628 | free(descriptor); 629 | return i; 630 | } 631 | } 632 | free(descriptor); 633 | if ( debug ) printf("\t\t\t[%s] No Free Space Found: Returning -1\n", __func__); 634 | return -1; 635 | } 636 | 637 | /*--------------------------------------------------------------------------------*/ 638 | 639 | //updates the descriptor block on disk to reflect that the block is no longer in use. 640 | void unallocate_block ( int offset ) { 641 | descriptor_block *descriptor = malloc( BLOCK_SIZE*2 ); 642 | 643 | memcpy ( descriptor, disk, BLOCK_SIZE*2 ); 644 | 645 | //TODO: check if the block holds a file, and then unallocate all its sub-block 646 | if ( debug ) printf("\t\t\t[%s] Unallocating Memory Block [%d]\n", __func__, offset ); 647 | descriptor->free[offset] = true; 648 | strcpy( descriptor->name[offset], "" ); 649 | 650 | memcpy ( disk, descriptor, BLOCK_SIZE*2 ); 651 | 652 | free(descriptor); 653 | } 654 | 655 | /*--------------------------------------------------------------------------------*/ 656 | 657 | //Takes in a name, and searches through descriptor block to find the block that contains the item 658 | int find_block ( char *name, bool directory ) { 659 | 660 | descriptor_block *descriptor = malloc( BLOCK_SIZE*2 ); 661 | 662 | memcpy ( descriptor, disk, BLOCK_SIZE*2 ); 663 | 664 | if ( debug ) printf("\t\t\t[%s] Searching Descriptor for [%s], which is a [%s]\n", __func__, name, directory == true ? "Folder": "File" ); 665 | for ( int i = 0; i < BLOCKS; i++ ) { 666 | if ( strcmp(descriptor->name[i], name) ==0 ){ 667 | //Make sure it is of the type that we are searching for 668 | if ( descriptor->directory[i] == directory ) { 669 | if ( debug ) printf("\t\t\t[%s] Found [%s] at Memory Block [%d]\n", __func__, name, i ); 670 | free(descriptor); 671 | //Return the block index where the item resides in memory 672 | return i; 673 | } 674 | } 675 | } 676 | 677 | free(descriptor); 678 | if ( debug ) printf("\t\t\t[%s] Block Not Found: Returning -1\n", __func__); 679 | return -1; 680 | } 681 | 682 | /*--------------------------------------------------------------------------------*/ 683 | 684 | int add_descriptor ( char * name ) { 685 | //Allocate memory to a descriptor_block type so that we start assigning values to its members. 686 | descriptor_block *descriptor = malloc( BLOCK_SIZE*2); 687 | if ( debug ) printf("\t\t[%s] Allocating Space for Descriptor Block\n", __func__); 688 | 689 | //Allocate memory to the array of strings within the descriptor block, which holds the name of each block 690 | descriptor->name = malloc ( sizeof*name*BLOCKS ); 691 | if ( debug ) printf("\t\t[%s] Allocating Space for Descriptor's Name Member\n", __func__); 692 | 693 | //initialize each block ==> that it is free 694 | if ( debug ) printf("\t\t[%s] Initializing Descriptor to Have All of Memory Available\n", __func__); 695 | for (int i = 0; i < BLOCKS; i++ ) { 696 | descriptor->free[i] = true; 697 | descriptor->directory[i] = false; 698 | } 699 | 700 | //descriptor occupied space on the disk 701 | int limit = (int)(sizeof(descriptor_block)/BLOCK_SIZE) + 1; 702 | 703 | if ( debug ) printf("\t\t[%s] Updating Descriptor to Show that first [%d] Memory Blocks Are Taken\n", __func__, limit+1); 704 | for ( int i = 0; i < limit; i ++ ) { 705 | descriptor->free[i]= false; //marking space occupied by descriptor as used 706 | } 707 | 708 | strcpy(descriptor->name[0], "descriptor"); 709 | 710 | //writing new updated descriptor to the beginning of the disk 711 | //may encounter error here, to be fixed 712 | memcpy ( disk, descriptor, (BLOCK_SIZE*(limit+1))); 713 | 714 | return 0; 715 | } 716 | 717 | /*--------------------------------------------------------------------------------*/ 718 | 719 | //Allows us to directly update values in the descriptor block. 720 | int edit_descriptor ( int free_index, bool free, int name_index, char * name ) { 721 | 722 | descriptor_block *descriptor = malloc( BLOCK_SIZE*2 ); 723 | 724 | //Copy descriptor on disk to our descriptor_block type, 725 | memcpy ( descriptor, disk, BLOCK_SIZE*2 ); 726 | 727 | //Each array in the descriptor block will be updated 728 | if ( free_index > 0 ) { 729 | descriptor->free[free_index] = free; 730 | if ( debug ) printf("\t\t[%s] Descriptor Free Member now shows Memory Block [%d] is [%s]\n", __func__, free_index, free == true ? "Free": "Used"); 731 | } 732 | if ( name_index > 0 ) { 733 | strcpy(descriptor->name[name_index], name ); 734 | if ( debug ) printf("\t\t[%s] Descriptor Name Member now shows Memory Block [%d] has Name [%s]\n", __func__, name_index, name); 735 | } 736 | 737 | // write the new updated descriptor back to the beginning of the disk 738 | memcpy(disk, descriptor, BLOCK_SIZE*2); 739 | 740 | return 0; 741 | } 742 | 743 | /*--------------------------------------------------------------------------------*/ 744 | 745 | // This changes the name of a file in the descriptor; used for moving files; 746 | int edit_descriptor_name (int index, char* new_name) 747 | { 748 | descriptor_block *descriptor = malloc( BLOCK_SIZE*2 ); 749 | 750 | memcpy ( descriptor, disk, BLOCK_SIZE*2 ); 751 | 752 | // Change the name of the file at index to the new_name 753 | strcpy(descriptor->name[index], new_name); 754 | 755 | memcpy(disk, descriptor, BLOCK_SIZE*2); 756 | 757 | free(descriptor); 758 | return 0; 759 | } 760 | 761 | /*--------------------------------------------------------------------------------*/ 762 | 763 | //Allows us to add a folder to the disk. 764 | int add_directory( char * name ) { 765 | 766 | if ( strcmp(name,"") == 0 ) { 767 | if ( debug ) printf("\t\t[%s] Invalid Command\n", __func__ ); 768 | return -1; 769 | } 770 | 771 | //Allocating memory for new folder 772 | dir_type *folder = malloc ( BLOCK_SIZE); 773 | if ( debug ) printf("\t\t[%s] Allocating Space for New Folder\n", __func__); 774 | 775 | //Initialize our new folder 776 | strcpy(folder->name, name); 777 | strcpy(folder->top_level, current.directory); 778 | folder->subitem = malloc ( sizeof*(folder->subitem)*MAX_SUBDIRECTORIES); 779 | folder->subitem_count = 0; // Imp : Initialize subitem array to have 0 elements 780 | 781 | 782 | //Find free block in disk to store our folder; true => mark the block as directory 783 | int index = allocate_block(name, true); 784 | if ( debug ) printf("\t\t[%s] Assigning New Folder to Memory Block [%d]\n", __func__, index); 785 | 786 | //Copy our folder to the disk 787 | memcpy( disk + index*BLOCK_SIZE, folder, BLOCK_SIZE); 788 | 789 | if ( debug ) printf("\t\t[%s] Folder [%s] Successfully Added\n", __func__, name); 790 | free(folder); 791 | return 0; 792 | } 793 | 794 | /*--------------------------------------------------------------------------------*/ 795 | 796 | //Allows to remove a directory folder from the disk. 797 | int remove_directory( char * name ) { 798 | 799 | dir_type *folder = malloc (BLOCK_SIZE); 800 | int block_index = find_block(name, true); 801 | 802 | //If there was no subdirectory found, then return -1 803 | if( block_index == -1 ) { 804 | if ( debug ) printf("\t\t[%s] Directory [%s] does not exist in the current folder [%s]\n", __func__, name, current.directory); 805 | return -1; 806 | } 807 | 808 | memcpy( folder, disk + block_index*BLOCK_SIZE, BLOCK_SIZE ); 809 | 810 | //Go through again if there is a subdirectory ==> as implemented in Unix 811 | for( int i = 0; i < folder->subitem_count; i++ ) { 812 | if( folder->subitem_type[i] == true ) { 813 | //Recursively call the function to remove the subitem 814 | remove_directory(folder->subitem[i]); 815 | } 816 | else { 817 | //Remove the subitem that is a file 818 | remove_file(folder->subitem[i]); 819 | } 820 | } 821 | unallocate_block(block_index); 822 | free(folder); 823 | 824 | return 0; 825 | } 826 | 827 | /*--------------------------------------------------------------------------------*/ 828 | 829 | //Allows you to directly add items to a folders subitem array, or change the folder's name 830 | int edit_directory (char * name, char*subitem_name, char *new_name, bool name_change, bool directory ) { 831 | 832 | if( strcmp(name,"") == 0 ) { 833 | if( debug ) printf("\t\t[%s] Invalid Command\n", __func__ ); 834 | return -1; 835 | } 836 | 837 | dir_type *folder = malloc ( BLOCK_SIZE); 838 | 839 | //Find where the folder is on disk 840 | int block_index = find_block(name, true); 841 | //If the directory is not found, should return 842 | if( block_index == -1 ) { 843 | if ( debug ) printf("\t\t[%s] Directory [%s] does not exist\n", __func__, name); 844 | return -1; 845 | } 846 | if ( debug ) printf("\t\t[%s] Folder [%s] Found At Memory Block [%d]\n", __func__, name, block_index); 847 | 848 | memcpy( folder, disk + block_index*BLOCK_SIZE, BLOCK_SIZE); 849 | 850 | if ( strcmp(subitem_name, "") != 0 ) { //Case that we are adding subitem to the descriptor block 851 | 852 | if ( !name_change ) { //Case adding subitem 853 | if ( debug ) printf("\t\t[%s] Added Subitem [%s] at Subitem index [%d] to directory [%s]\n", __func__, subitem_name, folder->subitem_count, folder->name ); 854 | strcpy (folder->subitem[folder->subitem_count], subitem_name ); 855 | folder->subitem_type[folder->subitem_count] = directory; 856 | folder->subitem_count++; 857 | if ( debug ) printf("\t\t[%s] Folder [%s] Now Has [%d] Subitems\n", __func__, name, folder->subitem_count); 858 | 859 | //update the disk too! 860 | memcpy( disk + block_index*BLOCK_SIZE, folder, BLOCK_SIZE); 861 | 862 | free(folder); 863 | return 0; 864 | } 865 | else { //Case editing a subitem's name 866 | for ( int i =0; i < folder->subitem_count; i++ ) { 867 | if ( strcmp(folder->subitem[i], subitem_name) == 0 ) { 868 | strcpy( folder->subitem[i], new_name); 869 | if ( debug ) printf("\t\t[%s] Edited Subitem [%s] to [%s] at Subitem index [%d] for directory [%s]\n", __func__, subitem_name, new_name, i, folder->name ); 870 | 871 | memcpy( disk + block_index*BLOCK_SIZE, folder, BLOCK_SIZE); 872 | free(folder); 873 | return 0; 874 | } 875 | } 876 | 877 | if ( debug ) printf("\t\t[%s] Subitem Does Not Exist in Directory [%s]\n", __func__, folder->name ); 878 | free(folder); 879 | return -1; 880 | } 881 | } 882 | else { //Case we are changing the folders name 883 | //if directory with given name already exists, don't allow 884 | int block_index2 = find_block(new_name, true); 885 | 886 | //If the directory for the new name already exists, should return -1 887 | if( block_index2 != -1 ) { 888 | if ( debug ) printf("\t\t[%s] Directory [%s] already exists. Choose a different name\n", __func__, new_name); 889 | return -1; 890 | } 891 | 892 | strcpy(folder->name, new_name ); 893 | if ( debug ) printf("\t\t[%s] Folder [%s] Now Has Name [%s]\n", __func__, name, folder->name); 894 | 895 | memcpy( disk + block_index*BLOCK_SIZE, folder, BLOCK_SIZE); 896 | 897 | //edit descriptors 898 | edit_descriptor(-1, false, block_index, new_name ); 899 | if ( debug ) printf("\t\t[%s] Updated Descriptor's Name Member\n", __func__); 900 | if ( debug ) print_directory(folder->name); 901 | 902 | //changing parents name 903 | edit_directory(folder->top_level, name, new_name, true, true ); 904 | if ( debug ) printf("\t\t[%s] Updated Parents Subitem Name\n", __func__); 905 | 906 | int child_index; 907 | 908 | //Iterates through to change the subitems' top_level name 909 | for ( int i = 0; i < folder->subitem_count; i++) { 910 | file_type *child_file = malloc ( BLOCK_SIZE); 911 | dir_type *child_folder = malloc ( BLOCK_SIZE); 912 | 913 | child_index = find_block ( folder->subitem[i], folder->subitem_type); 914 | if ( folder->subitem_type[i] ) { 915 | //if type == folder 916 | memcpy( child_folder, disk + child_index*BLOCK_SIZE, BLOCK_SIZE); 917 | strcpy( child_folder->top_level, new_name ); 918 | 919 | memcpy( disk + child_index*BLOCK_SIZE, child_folder, BLOCK_SIZE); 920 | free ( child_folder ); 921 | free ( child_file ); 922 | } 923 | else { 924 | //if type == file 925 | memcpy( child_file, disk + child_index*BLOCK_SIZE, BLOCK_SIZE); 926 | strcpy( child_file->top_level, new_name ); 927 | 928 | memcpy( disk + child_index*BLOCK_SIZE, child_file, BLOCK_SIZE); 929 | free ( child_folder ); 930 | free ( child_file ); 931 | } 932 | } 933 | 934 | free(folder); 935 | return 0; 936 | } 937 | 938 | free ( folder ); 939 | } 940 | 941 | /*--------------------------------------------------------------------------------*/ 942 | 943 | //Allows us to add a file to our disk; This function will allocate this file descriptor block (holds file info), as well as data blocks 944 | int add_file( char * name, int size ) { 945 | char subname[20]; 946 | 947 | if ( size < 0 || strcmp(name,"") == 0 ) { 948 | if ( debug ) printf("\t\t[%s] Invalid command\n", __func__); 949 | if (!debug ) printf("%s: missing operand\n", "mkfil"); 950 | return 1; 951 | } 952 | 953 | 954 | //Allocate memory to a file_type 955 | file_type *file = malloc ( BLOCK_SIZE ); 956 | if ( debug ) printf("\t\t[%s] Allocating Space for New File\n", __func__); 957 | 958 | //Initialize all the members of our new file 959 | strcpy( file->name, name); 960 | strcpy ( file->top_level, current.directory ); 961 | file->size = size; 962 | file->data_block_count = 0; 963 | if ( debug ) printf("\t\t[%s] Initializing File Members\n", __func__); 964 | 965 | //Find free block to put this file descriptor block in memory, false ==> indicates a file 966 | int index = allocate_block(name, false); 967 | 968 | //Find free blocks to put the file data into 969 | if ( debug ) printf("\t\t[%s] Allocating [%d] Data Blocks in Memory for File Data\n", __func__, (int)size/BLOCK_SIZE); 970 | for ( int i = 0; i < size/BLOCK_SIZE + 1; i++ ) { 971 | sprintf(subname, "%s->%d", name, i); 972 | file->data_block_index[i] = allocate_block(subname, false); 973 | file->data_block_count++; 974 | } 975 | //data blocks in memory not copied to disk 976 | memcpy( disk + index*BLOCK_SIZE, file, BLOCK_SIZE); 977 | 978 | if ( debug ) printf("\t\t[%s] File [%s] Successfully Added\n", __func__, name); 979 | 980 | free(file); 981 | return 0; 982 | } 983 | 984 | /*--------------------------------------------------------------------------------*/ 985 | 986 | int remove_file (char* name) 987 | { 988 | if (strcmp(name,"") == 0 ) { 989 | if ( debug ) printf("\t\t[%s] Invalid command\n", __func__); 990 | if (!debug ) printf("%s: missing operand\n", "rmfil"); 991 | return 1; 992 | } 993 | 994 | file_type *file = malloc ( BLOCK_SIZE); 995 | dir_type *folder = malloc ( BLOCK_SIZE); 996 | 997 | int file_index = find_block(name, false); 998 | 999 | // If the file is not found, error, return -1 1000 | if ( file_index == -1 ) { 1001 | if ( debug ) printf("\t\t\t[%s] File [%s] not found\n", __func__, name); 1002 | return -1; 1003 | } 1004 | 1005 | if ( debug ) printf("\t\t[%s] File [%s] Found At Memory Block [%d]\n", __func__, name, file_index); 1006 | 1007 | memcpy( file, disk + file_index*BLOCK_SIZE, BLOCK_SIZE); 1008 | 1009 | //Find the top_level folder on disk 1010 | int folder_index = find_block(file->top_level, true); 1011 | 1012 | if ( debug ) printf("\t\t[%s] Folder [%s] Found At Memory Block [%d]\n", __func__, name, folder_index); 1013 | memcpy( folder, disk + folder_index*BLOCK_SIZE, BLOCK_SIZE); 1014 | 1015 | 1016 | // Go through the parent directory's subitem array and remove our file 1017 | char subitem_name[MAX_STRING_LENGTH]; 1018 | const int subcnt = folder->subitem_count; // no of subitems 1019 | int j; 1020 | int k=0; 1021 | for(j = 0; jsubitem[j]); 1024 | if (strcmp(subitem_name, name) != 0) 1025 | // if this element is not the one we are removing, copy back 1026 | { 1027 | strcpy(folder->subitem[k],subitem_name); 1028 | k++; 1029 | } 1030 | } 1031 | strcpy(folder->subitem[k], ""); 1032 | folder->subitem_count--; 1033 | 1034 | memcpy(disk + folder_index*BLOCK_SIZE, folder, BLOCK_SIZE); // Update the folder in memory 1035 | 1036 | 1037 | //Imp : Unallocate all of the data blocks from the file that we are deleting 1038 | int i = 0; 1039 | while(file->data_block_count != 0) 1040 | { 1041 | unallocate_block(file->data_block_index[i]); 1042 | file->data_block_count--; 1043 | i++; 1044 | } 1045 | 1046 | unallocate_block(file_index); // Deallocate the file control block 1047 | 1048 | free(folder); 1049 | free(file); 1050 | return 0; 1051 | } 1052 | 1053 | /*--------------------------------------------------------------------------------*/ 1054 | 1055 | //Allows you to directly edit a file and change its size or its name 1056 | int edit_file ( char * name, int size, char *new_name ) { 1057 | file_type *file = malloc ( BLOCK_SIZE); 1058 | 1059 | //Find the block in memory where this file is written 1060 | int block_index = find_block(name, false); 1061 | if ( block_index == -1 ) { 1062 | if ( debug ) printf("\t\t\t[%s] File [%s] not found\n", __func__, name); 1063 | return -1; 1064 | } 1065 | if ( debug ) printf("\t\t[%s] File [%s] Found At Memory Block [%d]\n", __func__, name, block_index); 1066 | 1067 | memcpy( file, disk + block_index*BLOCK_SIZE, BLOCK_SIZE); 1068 | 1069 | if ( size > 0 ) { 1070 | //If size is greater than zero, then the files size will be updated 1071 | file->size = size; 1072 | if ( debug ) printf("\t\t[%s] File [%s] Now Has Size [%d]\n", __func__, name, size); 1073 | free(file); 1074 | return 0; 1075 | } 1076 | else { 1077 | //Otherwise, the file's name will be updated 1078 | char top_level[MAX_STRING_LENGTH]; 1079 | strcpy(top_level, get_file_top_level(name)); 1080 | 1081 | // Change the name of the directory's subitem 1082 | edit_directory_subitem(top_level, name, new_name); 1083 | 1084 | // Change the name of the actual file descriptor 1085 | edit_descriptor_name(block_index, new_name); 1086 | 1087 | strcpy(file->name, new_name ); 1088 | memcpy( disk + block_index*BLOCK_SIZE, file, BLOCK_SIZE); 1089 | 1090 | if ( debug ) printf("\t\t\t[%s] File [%s] Now Has Name [%s]\n", __func__, name, file->name); 1091 | 1092 | free(file); 1093 | return 0; 1094 | } 1095 | } 1096 | 1097 | /*--------------------------------------------------------------------------------*/ 1098 | 1099 | /************************** Getter functions ************************************/ 1100 | char * get_directory_name ( char*name ) { 1101 | dir_type *folder = malloc ( BLOCK_SIZE); 1102 | char *tmp = malloc(sizeof(char)*MAX_STRING_LENGTH); 1103 | 1104 | //True arguement tells the find function that we are looking 1105 | //for a directory not a file 1106 | int block_index = find_block(name, true); 1107 | if ( block_index == -1 ) { 1108 | if ( debug ) printf("\t\t\t[%s] Folder [%s] not found\n", __func__, name); 1109 | strcpy ( tmp, ""); 1110 | return tmp; 1111 | } 1112 | 1113 | memcpy( folder, disk + block_index*BLOCK_SIZE, BLOCK_SIZE); 1114 | 1115 | strcpy( tmp, folder->name); 1116 | if ( debug ) printf("\t\t\t[%s] Name [%s] found for [%s] folder\n", __func__, tmp, name ); 1117 | 1118 | free ( folder ); 1119 | return tmp; 1120 | } 1121 | 1122 | /*--------------------------------------------------------------------------------*/ 1123 | 1124 | char * get_directory_top_level ( char*name) { 1125 | dir_type *folder = malloc ( BLOCK_SIZE); 1126 | char *tmp = malloc(sizeof(char)*MAX_STRING_LENGTH); 1127 | 1128 | //true ==> indicates a folder and not a file 1129 | int block_index = find_block(name, true); 1130 | if ( block_index == -1 ) { 1131 | if ( debug ) printf("\t\t\t[%s] Folder [%s] not found\n", __func__,name); 1132 | strcpy ( tmp, ""); 1133 | return tmp; 1134 | } 1135 | 1136 | memcpy( folder, disk + block_index*BLOCK_SIZE, BLOCK_SIZE); 1137 | 1138 | strcpy( tmp, folder->top_level); 1139 | if ( debug ) printf("\t\t\t[%s] top_level [%s] found for [%s] folder\n", __func__, tmp, name ); 1140 | 1141 | free ( folder ); 1142 | return tmp; 1143 | } 1144 | 1145 | /*--------------------------------------------------------------------------------*/ 1146 | 1147 | char * get_directory_subitem ( char*name, int subitem_index, char*subitem_name ) { 1148 | dir_type *folder = malloc ( BLOCK_SIZE); 1149 | char *tmp = malloc(sizeof(char)*MAX_STRING_LENGTH); 1150 | 1151 | int block_index = find_block(name, true); 1152 | if ( block_index == -1 ) { 1153 | if ( debug ) printf("\t\t\t[%s] Folder [%s] not found\n", __func__, name); 1154 | strcpy ( tmp, ""); 1155 | return tmp; 1156 | } 1157 | 1158 | memcpy( folder, disk + block_index*BLOCK_SIZE, BLOCK_SIZE); 1159 | 1160 | if ( subitem_index >= 0 ) { 1161 | //Case we are changing the name of a subitem 1162 | strcpy( tmp, folder->subitem[subitem_index]); 1163 | if ( debug ) printf("\t\t\t[%s] subitem[%d] = [%s] for [%s] folder\n", __func__, subitem_index, tmp, name ); 1164 | free(folder); 1165 | return tmp; 1166 | } 1167 | else { 1168 | //Case that we Are Searching for a Sub Item 1169 | for ( int i =0; i < folder->subitem_count; i ++ ) { 1170 | if ( strcmp( folder->subitem[i], subitem_name ) == 0 ) { 1171 | if ( debug ) printf( "\t\t\t[%s] Found [%s] as a Subitem of Directory [%s]\n", __func__, subitem_name, name ); 1172 | return "0"; 1173 | } 1174 | } 1175 | if ( debug ) printf( "\t\t\t[%s] Did Not Find [%s] as a Subitem of Directory [%s]\n", __func__, subitem_name, name ); 1176 | free ( folder ); 1177 | return "-1"; 1178 | } 1179 | free ( folder ); 1180 | return tmp; 1181 | } 1182 | 1183 | /*--------------------------------------------------------------------------------*/ 1184 | 1185 | int edit_directory_subitem (char* name, char* sub_name, char* new_sub_name) 1186 | { 1187 | dir_type *folder = malloc ( BLOCK_SIZE); 1188 | 1189 | //True argument tells the find function that we are looking 1190 | //for a directory not a file 1191 | int block_index = find_block(name, true); 1192 | if ( block_index == -1 ) { 1193 | if ( debug ) printf("\t\t\t[%s] Folder [%s] not found\n", __func__, name); 1194 | } 1195 | 1196 | memcpy( folder, disk + block_index*BLOCK_SIZE, BLOCK_SIZE); 1197 | 1198 | const int cnt = folder->subitem_count; 1199 | int i; 1200 | for (i=0; i < cnt; i++) 1201 | { 1202 | if (strcmp(folder->subitem[i], sub_name) == 0) 1203 | { 1204 | strcpy(folder->subitem[i], new_sub_name); 1205 | if (debug) printf("\t\t\t[%s] Edited subitem in %s from %s to %s\n", __func__, folder->name, sub_name, folder->subitem[i]); 1206 | 1207 | memcpy(disk + block_index*BLOCK_SIZE ,folder, BLOCK_SIZE); 1208 | free(folder); 1209 | return i; 1210 | } 1211 | } 1212 | 1213 | free(folder); 1214 | return -1; 1215 | } 1216 | 1217 | /*--------------------------------------------------------------------------------*/ 1218 | 1219 | int get_directory_subitem_count( char*name) { 1220 | 1221 | dir_type *folder = malloc ( BLOCK_SIZE); 1222 | int tmp; 1223 | 1224 | int block_index = find_block(name, true); 1225 | if ( block_index == -1 ) { 1226 | if ( debug ) printf("\t\t\t[%s] Folder [%s] not found\n", __func__, name); 1227 | return -1; 1228 | } 1229 | 1230 | memcpy( folder, disk + block_index*BLOCK_SIZE, BLOCK_SIZE); 1231 | 1232 | tmp = folder->subitem_count; 1233 | if ( debug ) printf("\t\t\t[%s] subitem_count [%d] found for [%s] folder\n", __func__, folder->subitem_count, name ); 1234 | 1235 | free ( folder ); 1236 | return tmp; 1237 | } 1238 | 1239 | /*--------------------------------------------------------------------------------*/ 1240 | 1241 | char * get_file_name ( char*name ) { 1242 | file_type *file = malloc ( BLOCK_SIZE); 1243 | char *tmp = malloc(sizeof(char)*MAX_STRING_LENGTH); 1244 | 1245 | //false ==> indicates a file and not a folder 1246 | int block_index = find_block(name, false); 1247 | if ( block_index == -1 ) { 1248 | if ( debug ) printf("\t\t\t[%s] File [%s] not found\n", __func__, name); 1249 | strcpy ( tmp, ""); 1250 | return tmp; 1251 | } 1252 | 1253 | memcpy( file, disk + block_index*BLOCK_SIZE, BLOCK_SIZE); 1254 | 1255 | strcpy( tmp, file->name); 1256 | if ( debug ) printf("\t\t\t[%s] Name [%s] found for [%s] file\n", __func__, tmp, name ); 1257 | 1258 | free ( file ); 1259 | return tmp; 1260 | } 1261 | 1262 | /*--------------------------------------------------------------------------------*/ 1263 | 1264 | char * get_file_top_level ( char*name) { 1265 | file_type *file = malloc ( BLOCK_SIZE); 1266 | char *tmp = malloc(sizeof(char)*MAX_STRING_LENGTH); 1267 | 1268 | int block_index = find_block(name, false); 1269 | if ( block_index == -1 ) { 1270 | if ( debug ) printf("\t\t\t[%s] File [%s] not found\n", __func__, name); 1271 | strcpy ( tmp, ""); 1272 | return tmp; 1273 | } 1274 | 1275 | memcpy( file, disk + block_index*BLOCK_SIZE, BLOCK_SIZE); 1276 | 1277 | strcpy( tmp, file->top_level); 1278 | if ( debug ) printf("\t\t\t[%s] top_level [%s] found for [%s] file\n", __func__, tmp, name ); 1279 | 1280 | free ( file ); 1281 | return tmp; 1282 | } 1283 | 1284 | /*--------------------------------------------------------------------------------*/ 1285 | 1286 | int get_file_size( char*name) { 1287 | 1288 | file_type *file = malloc ( BLOCK_SIZE); 1289 | int tmp; 1290 | 1291 | int block_index = find_block(name, false); 1292 | if ( block_index == -1 ) { 1293 | if ( debug ) printf("\t\t\t[%s] File [%s] not found\n", __func__, name); 1294 | return -1; 1295 | } 1296 | 1297 | memcpy( file, disk + block_index*BLOCK_SIZE, BLOCK_SIZE); 1298 | 1299 | tmp = file->size; 1300 | if ( debug ) printf("\t\t\t[%s] size of [%d] found for [%s] file\n", __func__, tmp, name ); 1301 | 1302 | free ( file ); 1303 | return tmp; 1304 | } 1305 | 1306 | /*--------------------------------------------------------------------------------*/ 1307 | 1308 | /********************************* Print Functions ********************************/ 1309 | void print_directory ( char *name) { 1310 | dir_type *folder = malloc( BLOCK_SIZE); 1311 | int block_index = find_block(name, true); 1312 | memcpy( folder, disk + block_index*BLOCK_SIZE, BLOCK_SIZE); 1313 | 1314 | printf(" -----------------------------\n"); 1315 | printf(" New Folder Attributes:\n\n\tname = %s\n\ttop_level = %s\n\tsubitems = ", folder->name, folder->top_level); 1316 | for (int i = 0; i < folder->subitem_count; i++) { 1317 | printf( "%s ", folder->subitem[i]); 1318 | } 1319 | printf("\n\tsubitem_count = %d\n", folder->subitem_count); 1320 | printf(" -----------------------------\n"); 1321 | 1322 | free(folder); 1323 | } 1324 | 1325 | void print_file ( char *name) { 1326 | file_type *file = malloc( BLOCK_SIZE); 1327 | int block_index = find_block(name, false); 1328 | memcpy( file, disk + block_index*BLOCK_SIZE, BLOCK_SIZE); 1329 | 1330 | printf(" -----------------------------\n"); 1331 | printf(" New File Attributes:\n\n\tname = %s\n\ttop_level = %s\n\tfile size = %d\n\tblock count = %d\n", file->name, file->top_level, file->size, file->data_block_count); 1332 | printf(" -----------------------------\n"); 1333 | 1334 | free(file); 1335 | } 1336 | 1337 | /*--------------------------------------------------------------------------------*/ --------------------------------------------------------------------------------