Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed a.out
Binary file not shown.
56 changes: 31 additions & 25 deletions ext2_cp.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,14 @@
#include "utilities.h"

unsigned char *disk;
struct ext2_inode *inodeTable;

int main(int argc, char **argv) {
int src_fd;
FILE *src_fd;
char parentDirPath[EXT2_NAME_LEN];
char fileName[EXT2_NAME_LEN];
int fileSize;
int parentInodeNum, childInodeNum;
struct ext2_inode parentInode, childInode;
struct ext2_dir_entry_2 *dir_entry = NULL;
int total_rec_len;
struct ext2_inode *inodeTable;
struct ext2_inode *parentInode, *childInode;

if(argc!=4) {
fprintf(stderr, "Usage: ext2_cp <image file name> <native path> <absolute path on the disk>\n");
Expand All @@ -46,51 +43,60 @@ int main(int argc, char **argv) {
// get the parent directory inode
strcpy(parentDirPath, argv[3]);
if (parentDirPath[0]!='/') {
fprintf(stderr, "No such file or directory\n");
fprintf(stderr, "Must be absolute path\n");
return ENOENT;
} else if (parentDirPath[1]=='\0'){
fprintf(stderr, "Destination cannot be root directory\n");
return EEXIST;
} else {
getParentDirPath(parentDirPath);
}
parentInodeNum = getInodeFromPath(getParentDirPath);
parentInodeNum = getInodeFromPath(parentDirPath);
if (parentInodeNum == 0) {
fprintf(stderr, "No such file or directory\n");
return ENOENT;
}
parentInode = inodeTable[parentInodeNum-1];
parentInode = &inodeTable[parentInodeNum-1];

// check file exist
getFileNameFromPath(fileName, argv[3]);
childInodeNum = searchFileInDir(&parentInode, fileName);
if (parentInodeNum != 0) {
childInodeNum = searchFileInDir(parentInode, fileName);
if (childInodeNum != 0) {
fprintf(stderr, "File or directory already exist\n");
return EEXIST;
}

// create file and cp
childInodeNum = initInode('f');
unsigned int *singleIndirect;
childInodeNum = initInode(EXT2_S_IFREG);
childInode = &inodeTable[childInodeNum-1];
unsigned int *singleIndirect = NULL;
int nextBlockNum, byteRead;
int fileSize = 0;
int i = 0;
while (feof(src_fd)) {
nextBlockNum = allocateBlock();
while (!feof(src_fd)) {
nextBlockNum = allocateNewBlock();
if (i<12) {
inodeTable[childInodeNum].i_block[i] = nextBlockNum;
childInode->i_block[i] = nextBlockNum;
} else if (i==12) {
inodeTable[childInodeNum].i_block[i] = nextBlockNum;
singleIndirect = getBlock(nextBlockNum);
nextBlockNum = allocateBlock();
childInode->i_block[i] = nextBlockNum;
singleIndirect = initSingleIndirect(nextBlockNum);
i++;
continue;
} else {
singleIndirect[i-13] = nextBlockNum;
}

byteRead = fread(getBlock(nextBlockNum), 1024, 1, src_fd);
byteRead = fread(getBlock(nextBlockNum), 1, 1024, src_fd);
fileSize += byteRead;
i++;
}
// uptate inode filed
inodeTable[childInodeNum].i_size = fileSize;
inodeTable[childInodeNum].i_blocks = (fileSize+511)/512;

fclose(src_fd);
// update inode fields
childInode->i_size = fileSize;
if (singleIndirect == NULL)
childInode->i_blocks = ((fileSize+1023)/1024)*2;
else
childInode->i_blocks = ((fileSize+1023)/1024+1)*2;
// add dir_entry fot this file into parent dir
allocateNewDirent(&parentInode, childInodeNum, 'f', fileName);
initNewDirent(parentInode, childInodeNum, EXT2_FT_REG_FILE, fileName);
}
126 changes: 125 additions & 1 deletion ext2_ln.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,134 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include "ext2.h"
#include "utilities.h"

unsigned char *disk;
struct ext2_inode *inodeTable;

int main(int argc, char **argv) {

char pathTo[EXT2_NAME_LEN];
char pathFrom[EXT2_NAME_LEN];
char pathToCopy[EXT2_NAME_LEN];
char pathFromCopy[EXT2_NAME_LEN];
char parentOfPathFrom[EXT2_NAME_LEN];
char linkName[EXT2_NAME_LEN];

int flagged = FALSE;
int inodeNum, parentInodeNum, childInodeNum;

struct ext2_inode *targetInode, *parentInode, *childInode;

if(argc!=4 && argc!=5) {
fprintf(stderr, "Usage: ext2_ln <image file name> <optional flag -s> <absolute path> <absolute path>\n");
exit(1);
}

// read disk and get inode table
int fd = open(argv[1], O_RDWR);
disk = mmap(NULL, 128 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if(disk == MAP_FAILED) {
perror("mmap");
exit(1);
}
inodeTable = getInodeTable();

// read other arguments
if(argc == 4) {
strcpy(pathTo, argv[2]);
strcpy(pathFrom, argv[3]);
} else {
if (strcmp(argv[2], "-s") != 0) {
fprintf(stderr, "Invalid Flag\n");
exit(1);
}
flagged = TRUE;
strcpy(pathTo, argv[3]);
strcpy(pathFrom, argv[4]);
}

// get the inode from pathTo
strcpy(pathToCopy, pathTo);
if (pathToCopy[0]!='/') {
perror("Invalid path argument");
fprintf(stderr, "No such file or directory\n");
return ENOENT;
} else {
inodeNum = getInodeFromPath(pathToCopy);
}

if (inodeNum == 0) {
fprintf(stderr, "No such file or directory\n");
return ENOENT;
}
targetInode = &inodeTable[inodeNum-1];
if (targetInode->i_mode & EXT2_S_IFDIR){
fprintf(stderr, "No link to a directory\n");
return EISDIR;
}

// get the upper level inode from pathFrom
strcpy(pathFromCopy, pathFrom);
strcpy(parentOfPathFrom, pathFrom);

if (parentOfPathFrom[0]!='/') {
perror("Invalid parentDirPath");
fprintf(stderr, "No such file or directory\n");
return ENOENT;
} else if (parentOfPathFrom[1]=='\0'){
fprintf(stderr, "No link from a directory\n");
return EISDIR;
} else {
getParentDirPath(parentOfPathFrom);
}

parentInodeNum = getInodeFromPath(parentOfPathFrom);
if (parentInodeNum == 0) {
perror("parentDirPath not exist");
fprintf(stderr, "No such file or directory\n");
return ENOENT;
}
parentInode = &inodeTable[parentInodeNum-1];

// check whether the link has already existed
getFileNameFromPath(linkName, pathFromCopy);
childInodeNum = searchFileInDir(parentInode, linkName);
if (childInodeNum != 0) {
fprintf(stderr, "File or directory already exist\n");
return EEXIST;
}

if (!flagged){

// implementation for the hard link
initNewDirent(parentInode, inodeNum, EXT2_FT_REG_FILE, linkName);
// increment the link count of the target inode
targetInode->i_links_count++;

}else{

// implementation for the symbolic link
childInodeNum = initInode(EXT2_S_IFLNK);
childInode = &inodeTable[childInodeNum-1];
childInode->i_size = strlen(pathFromCopy);
childInode->i_blocks = 0;

initNewDirent(parentInode, childInodeNum, EXT2_FT_SYMLINK, linkName);

if (childInode->i_size <= 60){
strncpy((char *)childInode->i_block, pathTo, 60);
}else{
// append path to the inode block
int block_num = allocateNewBlock();
strcpy((char *)getBlock(block_num), pathTo);
childInode->i_block[0] = block_num;
}

}

return 0;
}
}
50 changes: 18 additions & 32 deletions ext2_ls.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,8 @@ int main(int argc, char **argv) {
char path[EXT2_NAME_LEN];
char pathCopy[EXT2_NAME_LEN];
char fileName[EXT2_NAME_LEN];
int flagged = FALSE;
int flagged = 0;
struct ext2_inode inode;
struct ext2_dir_entry_2 *dir_entry = NULL;
int total_rec_len;
unsigned char *singleIndirect;

if(argc!=3 && argc!=4) {
fprintf(stderr, "Usage: ext2_ls <image file name> <optional flag -a> <absolute path>\n");
Expand All @@ -45,7 +42,7 @@ int main(int argc, char **argv) {
fprintf(stderr, "Invalid Flag\n");
exit(1);
}
flagged = TRUE;
flagged = 1;
strcpy(path, argv[3]);
}

Expand All @@ -57,50 +54,39 @@ int main(int argc, char **argv) {
return ENOENT;
}
inode = inodeTable[inodeNum-1];

// print all file nemes in directory data block
if (inode.i_mode & EXT2_S_IFDIR) {
struct ext2_dir_entry_2 *dir_entry = NULL;
unsigned int *singleIndirect = NULL;
int total_rec_len = 0;

// print file names in direct blocks
for (int i=0; i<12; i++) {
if (inode.i_block[i] == 0){
for (int i=0; i<13+EXT2_BLOCK_SIZE/4; i++) {

if (i<12) {
if (inode.i_block[i] == 0) continue;
dir_entry = (struct ext2_dir_entry_2 *)getBlock(inode.i_block[i]);
} else if (i==12) {
if (inode.i_block[i] == 0) break;
singleIndirect = (unsigned int *)getBlock(inode.i_block[12]);
continue;
} else {
dir_entry = (struct ext2_dir_entry_2 *)getBlock(inode.i_block[i]);
if (singleIndirect[i-13] == 0) continue;
dir_entry = (struct ext2_dir_entry_2 *)getBlock(singleIndirect[i-13]);
}

// for each dir entry in the block
total_rec_len = 0;
while (total_rec_len < EXT2_BLOCK_SIZE) {
if (dir_entry->name[0]!='.' || flagged) {
if ((dir_entry->name[0]!='.' || flagged) && (dir_entry->name_len!=0)) {
printf("%s\n", dir_entry->name);
}
total_rec_len = total_rec_len + dir_entry->rec_len;
dir_entry = (void *) dir_entry + dir_entry->rec_len;
}
}

// print file in single indirect blocks
if (inode.i_block[12] != 0) {
singleIndirect = getBlock(inode.i_block[12]);
for(int i = 0; i<EXT2_BLOCK_SIZE/4;i++) {
if (singleIndirect[i] == 0) {
continue;
} else {
dir_entry = (struct ext2_dir_entry_2 *)getBlock(singleIndirect[i]);
}

total_rec_len = 0;
while (total_rec_len < EXT2_BLOCK_SIZE) {
if (dir_entry->name[0]!='.' || flagged) {
printf("%s\n", dir_entry->name);
}
total_rec_len = total_rec_len + dir_entry->rec_len;
dir_entry = (void *) dir_entry + dir_entry->rec_len;
}
}
}

// print file name
} else if (inode.i_mode&EXT2_S_IFREG || inode.i_mode&EXT2_S_IFLNK) {
getFileNameFromPath(fileName, path);
Expand Down
Loading