int checkout_commit(const char* commit_id) { /* COMPLETE THE REST */ // Going through the index of the current index file, // delete all those files (in the current directory; // i.e., the directory where we ran beargit). //sprintf(current_index_file, ".beargit/.index/%s", commit_id); // fs_rm(".beargit/.index"); if (strcmp(commit_id, init_id) != 0) { FILE* findex = fopen(".beargit/.index", "r"); FILE *findex_w = fopen(".beargit/.index", "w"); char line[FILENAME_SIZE]; while(fgets(line, sizeof(line), findex)) { strtok(line, "\n"); /* Split string to files */ fs_rm(line); } fclose(findex); // Copy the index from the commit that is being // checked out to the .beargit directory, and use // it to copy all that commit's tracked files from // the commit's directory into the current directory. char newindex_dir[FILENAME_SIZE]; strcpy(newindex_dir, ".beargit/"); // .beargit/ strcat(newindex_dir, commit_id); // .beargit/<new_ID> strcat(newindex_dir, "/.index"); // .beargit/<new_ID>/.index FILE *fnewindex = fopen(newindex_dir, "r"); char rec_file[FILENAME_SIZE]; char direc[FILENAME_SIZE+15]; fs_cp(newindex_dir, ".beargit/.index"); while(fgets(rec_file, sizeof(rec_file), fnewindex)) { strtok(rec_file, "\n"); /* Split string to files */ sprintf(direc, ".beargit/%s/%s", commit_id, rec_file); fs_cp(direc, rec_file); } fclose(fnewindex); fclose(findex_w); } else { FILE* findex = fopen(".beargit/.index", "r"); FILE *findex_w = fopen(".beargit/.index", "w"); char line[FILENAME_SIZE]; while(fgets(line, sizeof(line), findex)) { strtok(line, "\n"); /* Split string to files */ fs_rm(line); } fclose(findex); fclose(findex_w); } // Write the ID of the commit that is being checked // out into .prev. write_string_to_file(".beargit/.prev", commit_id); return 0; }
int beargit_add(const char* filename) { FILE* findex = fopen(".beargit/.index", "r"); FILE *fnewindex = fopen(".beargit/.newindex", "w"); char line[FILENAME_SIZE]; while(fgets(line, sizeof(line), findex)) { strtok(line, "\n"); if (strcmp(line, filename) == 0) { fprintf(stderr, "ERROR: File %s has already been added.\n", filename); fclose(findex); fclose(fnewindex); fs_rm(".beargit/.newindex"); return 3; } fprintf(fnewindex, "%s\n", line); } fprintf(fnewindex, "%s\n", filename); fclose(findex); fclose(fnewindex); fs_mv(".beargit/.newindex", ".beargit/.index"); return 0; }
int beargit_rm(const char* filename) { /* COMPLETE THE REST */ FILE *findex = fopen(".beargit/.index", "r"); FILE *fnewindex = fopen(".beargit/.newindex", "w"); int exist = 0; char line[FILENAME_SIZE]; while (fgets(line, sizeof(line),findex)) { strtok(line, "\n"); if(strcmp(line, filename) == 0){ exist = 1; continue; } fprintf(fnewindex, "%s\n", line); } if (exist == 0) { fprintf(stdout, "ERROR: File %s not tracked.\n", filename); fclose(findex); fclose(fnewindex); fs_rm(".beargit/.newindex"); return 1; } fclose(findex); fclose(fnewindex); fs_mv(".beargit/.newindex", ".beargit/.index"); return 0; }
int checkout_commit(const char* commit_id) { if (strcmp(commit_id, d) == 0) { FILE* findex = fopen(".beargit/.index", "r"); char line[FILENAME_SIZE]; while(fgets(line, sizeof(line), findex)){ strtok(line, "\n"); char gg[FILENAME_SIZE]; sprintf(gg, "%s", line); fs_rm(gg); } fclose(findex); FILE* troll = fopen(".beargit/.index", "w"); fclose(troll); } else { FILE* findex = fopen(".beargit/.index", "r"); char line[FILENAME_SIZE]; while(fgets(line, sizeof(line), findex)){ strtok(line, "\n"); char gg[FILENAME_SIZE]; sprintf(gg, "%s", line); fs_rm(gg); } fclose(findex); char dir[FILENAME_SIZE]; sprintf(dir, ".beargit/%s/.index", commit_id); fs_cp(dir, ".beargit/.index"); // commit id change FILE* cIndex = fopen(dir , "r"); char cline[FILENAME_SIZE]; while (fgets(cline,sizeof(cline),cIndex)) { strtok(cline, "\n"); char fName[FILENAME_SIZE]; sprintf(fName, ".beargit/%s/%s", commit_id, cline); fs_cp(fName, cline); // needs to be fixed, it's not copying } fclose(cIndex); } write_string_to_file(".beargit/.prev", commit_id); return 0; }
static void clay_unsandbox(void) { if (_clay_path[0] == '\0') return; #ifdef _WIN32 chdir(".."); #endif fs_rm(_clay_path); }
void delete_tracked_files() { FILE *index = fopen(".beargit/.index", "r"); char tracked_file[FILENAME_SIZE]; while (fgets(tracked_file, FILENAME_SIZE, index)) { strtok(tracked_file, "\n"); if (access(tracked_file, F_OK) != -1) { fs_rm(tracked_file); } } fclose(index); }
//This suite tests merging multiple files. It first tests for error cases, then //it tests for non-conflicting files then test for conflicted files. void merge_test(void) { struct commit* commit_list = NULL; int retval; retval = beargit_init(); CU_ASSERT(0==retval); write_string_to_file("wug.txt", "Dis a wug"); write_string_to_file("wug1.txt", "Dis a wug 1.5"); write_string_to_file("wug2.txt", "Der two wugz"); write_string_to_file("wug3.txt", "Dis not a wug"); retval = beargit_add("wug.txt"); CU_ASSERT(0==retval); retval = beargit_add("wug1.txt"); CU_ASSERT(0==retval); run_commit(&commit_list, "THIS IS BEAR TERRITORY!1"); //save commit1's ID char commit1_id[512] = ""; read_string_from_file(".beargit/.prev", commit1_id, 512); retval = beargit_add("wug2.txt"); CU_ASSERT(0==retval); run_commit(&commit_list, "THIS IS BEAR TERRITORY!2"); //remove wug, wug1 and wug2 fs_rm("wug.txt"); retval = beargit_rm("wug.txt"); CU_ASSERT(0==retval); fs_rm("wug1.txt"); retval = beargit_rm("wug1.txt"); CU_ASSERT(0==retval); fs_rm("wug2.txt"); retval = beargit_rm("wug2.txt"); CU_ASSERT(0==retval); //add wug3 & commit retval = beargit_add("wug3.txt"); CU_ASSERT(0==retval); run_commit(&commit_list, "THIS IS BEAR TERRITORY!3"); //Check for err msg when merging non existent commit ID / brench retval = beargit_merge("alskdfjlaskfj"); CU_ASSERT(1==retval); //first line of stderr: "ERROR: No branch or commit alskdfjlaskfj exists." //test merging non-conflicted files retval = beargit_merge(commit1_id); CU_ASSERT(0==retval); //first line of stdout: "wug.txt added\nwug1.txt added\n" //check files actually moved FILE* fstdout_wug = fopen("wug.txt", "r"); CU_ASSERT_PTR_NOT_NULL(fstdout_wug); FILE* fstdout_wug1 = fopen("wug1.txt", "r"); CU_ASSERT_PTR_NOT_NULL(fstdout_wug1); fclose(fstdout_wug); fclose(fstdout_wug1); //test merging conflicted files retval = beargit_merge(commit1_id); CU_ASSERT(0==retval); //first line of stdout: "wug.txt conflicted copy created \nwug1.txt conflicted copy created\n" //check conflicted files created char wugc[512] = "wug.txt."; strcat(wugc, commit1_id); char wugc1[512] = "wug1.txt."; strcat(wugc1, commit1_id); FILE* fstdout_wugc = fopen(wugc, "r"); CU_ASSERT_PTR_NOT_NULL(fstdout_wugc); FILE* fstdout_wugc1 = fopen(wugc1, "r"); CU_ASSERT_PTR_NOT_NULL(fstdout_wugc1); fclose(fstdout_wugc); fclose(fstdout_wugc1); //Read stderr file char PostToBe4Err[512] = "ERROR: No branch or commit alskdfjlaskfj exists.\n"; char ActualErr[512] =""; read_string_from_file("TEST_STDERR", ActualErr, 512); CU_ASSERT(strcmp(PostToBe4Err, ActualErr) == 0); // read stdout char PostToBe[512] = "wug.txt added\nwug1.txt added\nwug.txt conflicted copy created\nwug1.txt conflicted copy created\n"; char Actual[512] =""; read_string_from_file("TEST_STDOUT", Actual, 512); CU_ASSERT(strcmp(PostToBe, Actual) == 0); free_commit_list(&commit_list); }
//this test tests reset. It checks for the two erroring cases //It checks if reset replaces the version of the file in the //working directory with the specified file for reset. //it also tests if index is update and file is sucessfully //reset if the file is not in the working directory. void reset_test(void) { struct commit* commit_list = NULL; int retval; retval = beargit_init(); CU_ASSERT(0==retval); write_string_to_file("wug.txt", "Dis a wug"); write_string_to_file("wug2.txt", "Der two wugz"); write_string_to_file("wug3.txt", "Dis not a wug"); retval = beargit_add("wug.txt"); CU_ASSERT(0==retval); run_commit(&commit_list, "THIS IS BEAR TERRITORY!1"); retval = beargit_add("wug2.txt"); CU_ASSERT(0==retval); run_commit(&commit_list, "THIS IS BEAR TERRITORY!2"); retval = beargit_add("wug3.txt"); CU_ASSERT(0==retval); run_commit(&commit_list, "THIS IS BEAR TERRITORY!3"); char commit_id[512] = ""; read_string_from_file(".beargit/.prev", commit_id, 512); //Check for error if commit doens't exit retval = beargit_reset("alskdfjlaskfj", "wug.txt"); CU_ASSERT(1==retval); //first line of stderr: "ERROR: Commit alskdfjlaskfj does not exist.\n" //Check for error if file not in commit retval = beargit_reset(commit_id, "wug6.txt"); CU_ASSERT(1==retval); //second line of stderr: "ERROR: wug6.txt is not in the index of commit [insert commit_id].\n" //modifies wug.txt in working directory write_string_to_file("wug.txt", "JK dis not a wug"); //Resets wug.txt from commit 3 retval = beargit_reset(commit_id, "wug.txt"); CU_ASSERT(0==retval); char stuffinwug[512] = ""; read_string_from_file("wug.txt", stuffinwug, 512); CU_ASSERT(strcmp(stuffinwug, "Dis a wug") == 0); //remove wug3.txt fs_rm("wug3.txt"); retval = beargit_rm("wug3.txt"); CU_ASSERT(retval == 0); FILE* fstdout_wug = fopen("wug3.txt", "r"); CU_ASSERT_PTR_NULL(fstdout_wug); //try to reset wug3.txt retval = beargit_reset(commit_id, "wug3.txt"); FILE* check_wug_exist = fopen("wug3.txt", "r"); CU_ASSERT_PTR_NOT_NULL(check_wug_exist); char check_index_4wug[512] = ""; read_string_from_file(".beargit/.index", check_index_4wug, 512); char PostToBe[512] = "wug2.txt\nwug.txt\nwug3.txt\n"; CU_ASSERT(strcmp(check_index_4wug, PostToBe) == 0); fclose(check_wug_exist); //Read stderr file char PostToBe4Err[512] = ""; strcat(PostToBe4Err, "ERROR: Commit alskdfjlaskfj does not exist.\nERROR: wug6.txt is not in the index of commit "); strcat(PostToBe4Err, commit_id); strcat(PostToBe4Err, ".\n"); char ActualErr[512] =""; read_string_from_file("TEST_STDERR", ActualErr, 512); CU_ASSERT(strcmp(PostToBe4Err, ActualErr) == 0); free_commit_list(&commit_list); }
// Removes an inode from the filesystem, documented in header unsigned int fs_rm(unsigned int inode, int inside_recursion) { inode_read(inode, &n); if(!(inode > 1)) { return ERR_PERMS; // Permissions check } if(!fs_has_perms(&n, ACTION_WRITE)) { return ERR_PERMS; // If you can't write you can't delete... } if (!inside_recursion) { // I'm not sure about this, but well... at least it's just a security flaw. inode_read(n._dir_inode, &n); if(!fs_has_perms(&n, ACTION_WRITE)) { return ERR_PERMS; // If you can't write on the parent folder you can't delete } inode_read(inode, &n); } int log_block = n.blocks / 2 + 1; // Logical block top int ph_block = 0; // Go from top to bottom to delete everything. while(log_block > 0) { log_block--; make_ph_block(&n, &ph_block, &log_block); if (n.mode & EXT2_S_IFDIR) { // If it's a directory... then... RECURSION! D: block entries; data_read_block(&entries, ph_block); int off = 0; dir_op_offset = 0; dir_entry * old_dot = NULL; dir_entry * dot = iterate_dir_entry(&entries); // Iterates dir entries while (dot != NULL) { if (dot == NULL) { break; } else { if (dot->name_len > 0 && dot->inode != inode && dot->inode != n._dir_inode) { // If we get an error we don't actually make anything :D, but we might delete other files. int _rm = fs_rm(dot->inode, 1); if(_rm < 0) { data_write_block(&entries, ph_block); bitmap_write(bm_blocks, ph_block - 1, 0); return _rm; } off = dir_op_offset; dot->name_len = 0; dir_op_offset = off; inode_read(inode, &n); } } old_dot = dot; dot = iterate_dir_entry(&entries); } data_write_block(&entries, ph_block); } bitmap_write(bm_blocks, ph_block - 1, 0); // This deletes the stuff actually delete_internal_inodes(log_block); // This deletes the EXT2 ugly but wise indirects. } // Delete the directory entry of the file. if (!inside_recursion) { inode_read(inode, &n); unsigned int folder_inode = n._dir_inode; inode_read(folder_inode, &n); folder_rem_direntry(inode, folder_inode); } bitmap_write(bm_inodes, inode - 1, 0); // Persist the directory liberation. fs_bitmaps_write_all(); // Persist in the FS. return 1; }
// Opens a file unsigned int fs_open_file(char * name, unsigned int folder_inode, int mode, int type) { unsigned int inode_id = 0; if(strcmp(name, "/") == 0 && strlen(name) == strlen("/")) { return 1; // root } if(name[0] == 0) { inode_id = current_ttyc()->pwd; } else { inode_id = fs_indir(name, folder_inode); } if (inode_id) { if (mode & O_CREAT) { int _rm_res = fs_rm(inode_id, 0); if(_rm_res < 0) { return _rm_res; } } else if(mode & O_NEW) { inode_read(inode_id, &n); if(n.mode == EXT2_S_IFLNK) { return n.data_blocks[0]; } return inode_id; } else { inode_read(inode_id, &n); int can = 1; if((mode & O_RD) && !fs_has_perms(&n, ACTION_READ)) { can = 0; } if((mode & O_WR) && !fs_has_perms(&n, ACTION_WRITE)) { can = 0; } if(can || !fs_done) { if(n.mode == EXT2_S_IFLNK) { return n.data_blocks[0]; } return inode_id; } else { return ERR_PERMS; } } } else if (!(mode & (O_NEW | O_CREAT))) { return ERR_NO_EXIST; } inode_id = bitmap_first_valued(bm_inodes, FS_INODE_BITMAP_SIZE, 0) + 1; if (!folder_inode) { folder_inode = inode_id; } int log_block; if (folder_inode != inode_id) { inode_read(folder_inode, &n); if(!fs_has_perms(&n, ACTION_WRITE)) { return ERR_PERMS; } log_block = n.blocks / 2; block_clear(&b); dir_op_offset = 0; log_block_read(&n, &log_block); add_dir_entry(&n, EXT2_FT_DIR, inode_id, name, &log_block); log_block_write(&n, &log_block); inode_write(folder_inode, &n); } bitmap_write(bm_inodes, inode_id - 1, 1); inode_clear(&n); if(!fs_done) { n.uid = 0; } else { n.uid = current_ttyc()->uid; } n.mode = type; n.size = 0; n.blocks = 0; // Beware! This represents the SECTORS! n._last_write_offset = 0; n.i_file_acl = 511; n._dir_inode = folder_inode; inode_write(inode_id, &n); inode_clear(&n); if(n.mode == EXT2_S_IFLNK) { return n.data_blocks[0]; } return inode_id; }
// INT 80h Handler, kernel entry. void int_80() { if(krn) { return; } krn++; int systemCall = kernel_buffer[0]; int fd = kernel_buffer[1]; int buffer = kernel_buffer[2]; int count = kernel_buffer[3]; int i, j; Process * current; Process * p; int inode; int _fd; // Yeah, wanna know why we don't access an array directly? ... Because of big bugs we might have. switch(systemCall) { case READY: kernel_buffer[KERNEL_RETURN] = kernel_ready(); break; case WRITE: current = getp(); kernel_buffer[KERNEL_RETURN] = fd_write(current->file_descriptors[fd],(char *)buffer,count); break; case READ: current = getp(); kernel_buffer[KERNEL_RETURN] = fd_read(current->file_descriptors[fd],(char *)buffer,count); break; case MKFIFO: _fd = process_getfreefd(); fd = fd_open(_FD_FIFO, (void *)kernel_buffer[1],kernel_buffer[2]); if(_fd != -1 && fd != -1) { getp()->file_descriptors[_fd] = fd; kernel_buffer[KERNEL_RETURN] = _fd; } else { kernel_buffer[KERNEL_RETURN] = -1; } break; case OPEN: _fd = process_getfreefd(); fd = fd_open(_FD_FILE, (void *) kernel_buffer[1], kernel_buffer[2]); if(_fd != -1 && fd >= 0) { getp()->file_descriptors[_fd] = fd; kernel_buffer[KERNEL_RETURN] = _fd; } else { kernel_buffer[KERNEL_RETURN] = fd; } break; case CLOSE: kernel_buffer[KERNEL_RETURN] = fd_close(getp()->file_descriptors[fd]); break; case PCREATE: kernel_buffer[KERNEL_RETURN] = sched_pcreate(kernel_buffer[1],kernel_buffer[2],kernel_buffer[3]); break; case PRUN: kernel_buffer[KERNEL_RETURN] = sched_prun(kernel_buffer[1]); break; case PDUP2: kernel_buffer[KERNEL_RETURN] = sched_pdup2(kernel_buffer[1],kernel_buffer[2],kernel_buffer[3]); break; case GETPID: kernel_buffer[KERNEL_RETURN] = sched_getpid(); break; case WAITPID: kernel_buffer[KERNEL_RETURN] = sched_waitpid(kernel_buffer[1]); break; case PTICKS: kernel_buffer[KERNEL_RETURN] = (int) storage_index(); break; case PNAME: p = process_getbypid(kernel_buffer[1]); if(p == NULL) { kernel_buffer[KERNEL_RETURN] = (int) NULL; } else { kernel_buffer[KERNEL_RETURN] = (int) p->name; } break; case PSTATUS: p = process_getbypid(kernel_buffer[1]); if(p == NULL) { kernel_buffer[KERNEL_RETURN] = (int) -1; } else { kernel_buffer[KERNEL_RETURN] = (int) p->state; } break; case PPRIORITY: p = process_getbypid(kernel_buffer[1]); if(p == NULL) { kernel_buffer[KERNEL_RETURN] = (int) -1; } else { kernel_buffer[KERNEL_RETURN] = (int) p->priority; } break; case PGID: p = process_getbypid(kernel_buffer[1]); if(p == NULL) { kernel_buffer[KERNEL_RETURN] = (int) -1; } else { kernel_buffer[KERNEL_RETURN] = (int) p->gid; } break; case PGETPID_AT: p = process_getbypindex(kernel_buffer[1]); if (p->state != -1) { kernel_buffer[KERNEL_RETURN] = (int) p->pid; } else { kernel_buffer[KERNEL_RETURN] = -1; } break; case KILL: kernel_buffer[KERNEL_RETURN - 1] = kernel_buffer[1]; kernel_buffer[KERNEL_RETURN - 2] = kernel_buffer[2]; break; case PSETP: p = process_getbypid(kernel_buffer[1]); if(p == NULL) { kernel_buffer[KERNEL_RETURN] = (int) -1; } else { if(kernel_buffer[2] <= 4 && kernel_buffer[2] >= 0) { p->priority = kernel_buffer[2]; } kernel_buffer[KERNEL_RETURN] = (int) p->gid; } break; case SETSCHED: sched_set_mode(kernel_buffer[1]); break; case PWD: kernel_buffer[KERNEL_RETURN] = (int) fs_pwd(); break; case CD: kernel_buffer[KERNEL_RETURN] = (int) fs_cd(kernel_buffer[1]); break; case FINFO: fs_finfo(kernel_buffer[1], kernel_buffer[2]); break; case MOUNT: fs_init(); break; case MKDIR: kernel_buffer[KERNEL_RETURN] = (int) fs_mkdir(kernel_buffer[1],current_ttyc()->pwd); break; case RM: inode = fs_indir(kernel_buffer[1],current_ttyc()->pwd); if (inode) { kernel_buffer[KERNEL_RETURN] = (int) fs_rm(inode,0); } else { kernel_buffer[KERNEL_RETURN] = ERR_NO_EXIST; } break; case GETUID: if(kernel_buffer[1] == 0) { kernel_buffer[KERNEL_RETURN] = (int) current_ttyc()->uid; } else { kernel_buffer[KERNEL_RETURN] = (int) user_exists(kernel_buffer[1]); } break; case GETGID: if(kernel_buffer[1] == 0) { kernel_buffer[KERNEL_RETURN] = (int) user_gid(current_ttyc()->uid); } else { kernel_buffer[KERNEL_RETURN] = (int) user_gid(kernel_buffer[1]); } break; case MAKEUSER: kernel_buffer[KERNEL_RETURN] = user_create(kernel_buffer[1], kernel_buffer[2], user_gid(current_ttyc()->uid)); break; case SETGID: kernel_buffer[KERNEL_RETURN] = user_setgid(kernel_buffer[1], kernel_buffer[2]); break; case UDELETE: kernel_buffer[KERNEL_RETURN] = user_delete(kernel_buffer[1]); break; case UEXISTS: kernel_buffer[KERNEL_RETURN] = user_exists(kernel_buffer[1]); break; case ULOGIN: kernel_buffer[KERNEL_RETURN] = user_login(kernel_buffer[1], kernel_buffer[2]); break; case ULOGOUT: kernel_buffer[KERNEL_RETURN] = user_logout(); break; case CHOWN: kernel_buffer[KERNEL_RETURN] = fs_chown(kernel_buffer[1], kernel_buffer[2]); break; case CHMOD: kernel_buffer[KERNEL_RETURN] = fs_chmod(kernel_buffer[1], kernel_buffer[2]); break; case GETOWN: kernel_buffer[KERNEL_RETURN] = fs_getown(kernel_buffer[1]); break; case GETMOD: kernel_buffer[KERNEL_RETURN] = fs_getmod(kernel_buffer[1]); break; case CP: kernel_buffer[KERNEL_RETURN] = fs_cp(kernel_buffer[1], kernel_buffer[2], current_ttyc()->pwd, current_ttyc()->pwd); break; case MV: kernel_buffer[KERNEL_RETURN] = fs_mv(kernel_buffer[1], kernel_buffer[2], current_ttyc()->pwd); break; case LINK: kernel_buffer[KERNEL_RETURN] = fs_open_link(kernel_buffer[1], kernel_buffer[2], current_ttyc()->pwd); break; case FSSTAT: kernel_buffer[KERNEL_RETURN] = fs_stat(kernel_buffer[1]); break; case SLEEP: kernel_buffer[KERNEL_RETURN] = scheduler_sleep(kernel_buffer[1]); break; default: break; } krn--; }
void cl_fs_cleanup(void) { fs_rm(fixture_path(_clay_path, "*")); }
void cl_fixture_cleanup(const char *fixture_name) { fs_rm(fixture_path(_clay_path, fixture_name)); }