Created
November 14, 2012 00:29
-
-
Save Lull3rSkat3r/4069370 to your computer and use it in GitHub Desktop.
A file system I made for an operating systems class.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Jeremy Ploumis | |
// 974335459 | |
// jep5190@psu.edu | |
// Corey Stubbs | |
// 902041575 | |
// cas5542@psu.edu | |
// Chase Roman | |
// 908235085 | |
// cer197@psu.edu | |
// Michael Gutierrez | |
// 956623934 | |
// mjg5219@psu.edu | |
// CMPSC 473 | |
// Project 4 | |
// 12/8/2011 | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <time.h> | |
#include <sys/mman.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <regex.h> | |
#include <errno.h> | |
#include <string.h> | |
#ifndef MAX_DIR_FILES | |
#define MAX_DIR_FILES 50 | |
#endif | |
#ifndef MAX_PARTITION_FILES | |
#define MAX_PARTITION_FILES 10000 | |
#endif | |
#ifndef MAX_PARTITION_DIR | |
#define MAX_PARTITION_DIR 5000 | |
#endif | |
#define MAXARGS 128 | |
#define MAXLINE 128 | |
typedef struct fileControlBlock fcb_t; | |
typedef struct infoBlock ib_t; | |
typedef struct directoryControlBlock dcb_t; | |
typedef struct partitionControlBlock pcb_t; | |
typedef struct partition p_t; | |
p_t part; | |
dcb_t *currDcb; | |
void printAll(dcb_t* dir, char* prev); | |
void printDirs(dcb_t* dir); | |
void printFiles(dcb_t* dcb); | |
void printPartitionVals(p_t* partMap); | |
void printPartitionAddress(p_t* partMap); | |
void printDCBVals(dcb_t* dir); | |
void printDCBAddresses(dcb_t* dir); | |
void printFCBVals(fcb_t* fcb); | |
void printFCBAddresses(fcb_t* fcb); | |
void createPartition(p_t* partMap); | |
void createPartitionControlBlock(p_t* partMap, char* name); | |
void addFile(char* name, pcb_t* pcb,dcb_t* parent, int readOnly, int hidden, int fileSize); | |
void addFileInfo(pcb_t* pcb, dcb_t* parent, ib_t oldInfo, int fileSize); | |
void addDir(char* name, pcb_t* pcb, dcb_t* parent, int readOnly, int hidden); | |
void deletePartition(p_t* partMap); | |
dcb_t* getDir(char* name, dcb_t* currDir); | |
fcb_t* getFile(char* name, dcb_t* currDir); | |
/* | |
* A basic block of information for files and directories | |
*/ | |
struct infoBlock{ | |
char* name; | |
time_t createDate; | |
time_t modDate; | |
time_t accessDate; | |
int readOnly; | |
int hidden; | |
int index; | |
}; | |
/* | |
* The abstraction of a physical file | |
*/ | |
struct fileControlBlock { | |
ib_t info; | |
dcb_t* parentDir; | |
int fileSize; | |
}; | |
/* | |
* The abstraction of a directory on disk | |
*/ | |
struct directoryControlBlock { | |
ib_t info; | |
dcb_t* parentDir; // add | |
int fileCount; | |
int dirCount; | |
fcb_t* files[MAX_DIR_FILES]; | |
dcb_t* dirs[MAX_DIR_FILES]; | |
}; | |
/* | |
* An abstract disk partition descriptor block | |
*/ | |
struct partitionControlBlock{ | |
fcb_t* usedListStart; | |
fcb_t* usedListEnd; | |
fcb_t* endOfPartition; | |
fcb_t* lastAddedFile; | |
dcb_t* lastAddedDir; | |
dcb_t* rootDir; | |
int usedSpace; | |
int freeSpace; | |
int partitionSize; | |
char* name; | |
}; | |
/* | |
* An abstract representation of a disk partition | |
*/ | |
struct partition{ | |
pcb_t controlBlock; | |
dcb_t dirs[MAX_PARTITION_DIR]; | |
fcb_t files[MAX_PARTITION_FILES]; | |
}; | |
/* | |
* A function to print the files and directories that are within the given directory control program. | |
*/ | |
void printAll(dcb_t* dir, char* prev){ | |
ib_t* info = &dir->info; | |
char newPrev[1000]; | |
sprintf(newPrev,"%s/%s",prev,info->name); | |
int i; | |
printf("%s\n",newPrev); | |
printDirs(dir); | |
printFiles(dir); | |
printf("\n"); | |
for(i = 0; i < (dir->dirCount); i++){ | |
dcb_t* currDir = dir->dirs[i]; | |
ib_t* info = &currDir->info; | |
if(info->hidden == 0 && currDir != dir) | |
printAll(currDir,newPrev); | |
} | |
} | |
void printLS(dcb_t* dcb){ | |
int i; | |
int j; | |
for(i = 0; i < dcb->dirCount; i++){ | |
dcb_t* currDir = dcb->dirs[i]; | |
ib_t* info = &currDir->info; | |
if(info->hidden == 0) | |
printf(" %s ",info->name); | |
if(i>0 && i%7 == 0) | |
printf("\n"); | |
} | |
for(j=0; j < dcb->fileCount; j++) | |
{ | |
fcb_t* i = dcb->files[j]; | |
ib_t* info = &i->info; | |
if(info->hidden == 0) | |
printf(" %s ",info->name); | |
if(j>0 && j%7 == 0) | |
printf("\n"); | |
} | |
printf("\n"); | |
} | |
/* | |
* Prints the directories within the particular directory control block | |
*/ | |
void printDirs(dcb_t* dir){ | |
int i; | |
for(i = 0; i < dir->dirCount; i++){ | |
dcb_t* currDir = dir->dirs[i]; | |
ib_t* info = &currDir->info; | |
if(info->hidden == 0){ | |
printf("\t%s\n\t\t\tHidden File\tNo\n\t\t\t",info->name); | |
if(info->readOnly == 0){ | |
printf("Read Only\tNo\n\t\t\t%s\t\t\t%s\t\t\t%s",ctime(&info->createDate),ctime(&info->modDate),ctime(&info->accessDate)); | |
} | |
else if(info->readOnly == 1){ | |
printf("Read Only\tYes\n\t\t\t%s\t\t\t%s\t\t\t%s",ctime(&info->createDate),ctime(&info->modDate),ctime(&info->accessDate)); | |
} | |
} | |
} | |
} | |
/* | |
* Prints the hidden files and directories within the particular directory control block | |
*/ | |
void printHidden(dcb_t* dir){ | |
int i; | |
int j; | |
for(i = 0; i < dir->dirCount; i++){ | |
dcb_t* currDir = dir->dirs[i]; | |
ib_t* info = &currDir->info; | |
if(info->hidden == 1){ | |
printf("\t%s\n\t\t\tHidden File\tYes\n\t\t\t",info->name); | |
if(info->readOnly == 0){ | |
printf("Read Only\tNo\n\t\t\t%s\t\t\t%s\t\t\t%s",ctime(&info->createDate),ctime(&info->modDate),ctime(&info->accessDate)); | |
} | |
else if(info->readOnly == 1){ | |
printf("Read Only\tYes\n\t\t\t%s\t\t\t%s\t\t\t%s",ctime(&info->createDate),ctime(&info->modDate),ctime(&info->accessDate)); | |
} | |
} | |
} | |
for(j=0; j < dir->fileCount; j++) | |
{ | |
fcb_t* i = dir->files[j]; | |
ib_t* info = &i->info; | |
if(info->hidden == 1){ | |
printf("\t%s\n\t\t\tHidden File\tYes\n\t\t\t",info->name); | |
if(info->readOnly == 0){ | |
printf("Read Only\tNo\n\t\t\t%s\t\t\t%s\t\t\t%s",ctime(&info->createDate),ctime(&info->modDate),ctime(&info->accessDate)); | |
} | |
else{ | |
printf("Read Only\tYes\n\t\t\t%s\t\t\t%s\t\t\t%s",ctime(&info->createDate),ctime(&info->modDate),ctime(&info->accessDate)); | |
} | |
} | |
} | |
} | |
/* | |
* Prints the files within the particular directory control block | |
*/ | |
void printFiles(dcb_t* dcb){ | |
int j; | |
for(j=0; j < dcb->fileCount; j++) | |
{ | |
fcb_t* i = dcb->files[j]; | |
ib_t* info = &i->info; | |
if(info->hidden == 0){ | |
printf("\t%s\n\t\t\tHidden File\tNo\n\t\t\t",info->name); | |
if(info->readOnly == 0){ | |
printf("Read Only\tNo\n\t\t\t%s\t\t\t%s\t\t\t%s",ctime(&info->createDate),ctime(&info->modDate),ctime(&info->accessDate)); | |
} | |
else{ | |
printf("Read Only\tYes\n\t\t\t%s\t\t\t%s\t\t\t%s",ctime(&info->createDate),ctime(&info->modDate),ctime(&info->accessDate)); | |
} | |
} | |
} | |
} | |
/* | |
* A function to print information about the partition control block | |
*/ | |
void printPartitionControlBlock(pcb_t* controlBlock){ | |
printf("Partition information for: %s\n", ((controlBlock->name))); | |
printf("\tUsed partition space is:\t\t %d bytes\n", ((controlBlock->usedSpace))); | |
printf("\tFree partition space is:\t\t %d bytes\n", ((controlBlock->freeSpace))); | |
printf("\tBeginning of free space address:\t %p\n", ((controlBlock->usedListEnd))); | |
printf("\tLast free space address:\t\t %p\n", ((controlBlock->endOfPartition))); | |
printf("\tRoot directory is:\t\t\t %s\n", ((controlBlock->rootDir->info.name))); | |
} | |
/* | |
* A helper function used for debugging | |
*/ | |
void printPartitionVals(p_t* partMap){ | |
printf("Value of partMap->controlBlock.usedListStart is: %p\n", ((partMap->controlBlock.usedListStart))); | |
printf("Value of partMap->controlBlock.usedListEnd is: %p\n", ((partMap->controlBlock.usedListEnd))); | |
printf("Value of partMap->controlBlock.endOfPartition is: %p\n", ((partMap->controlBlock.endOfPartition))); | |
printf("Value of partMap->controlBlock.rootDir.info.name is: %s\n", ((partMap->controlBlock.rootDir->info.name))); | |
printf("Value of partMap->controlBlock.usedSpace is: %d\n", ((partMap->controlBlock.usedSpace))); | |
printf("Value of partMap->controlBlock.freeSpace is: %d\n", ((partMap->controlBlock.freeSpace))); | |
printf("Value of partMap->controlBlock.name is: %s\n",(partMap->controlBlock).name); | |
} | |
/* | |
* A helper function used for debugging | |
*/ | |
void printPartitionAddress(p_t* partMap){ | |
printf("Address of partMap is: %p\n", partMap); | |
printf("Address of partMap->controlBlock is: %p\n",&(partMap->controlBlock)); | |
printf("Address of partMap->controlBlock.usedListStart is: %p\n", &((partMap->controlBlock.usedListStart))); | |
printf("Address of partMap->controlBlock.usedListEnd is: %p\n", &((partMap->controlBlock.usedListEnd))); | |
printf("Address of partMap->controlBlock.endOfPartition is: %p\n", &((partMap->controlBlock.endOfPartition))); | |
printf("Address of partMap->controlBlock.rootDir is: %p\n", &((partMap->controlBlock.rootDir))); | |
printf("Address of partMap->controlBlock.usedSpace is: %p\n", &((partMap->controlBlock.usedSpace))); | |
printf("Address of partMap->controlBlock.freeSpace is: %p\n", &((partMap->controlBlock.freeSpace))); | |
printf("Address of partMap->controlBlock is: %p\n",&(partMap->controlBlock).name); | |
} | |
/* | |
* A helper function used for debugging | |
*/ | |
void printDCBVals(dcb_t* dir){ | |
printf("Value of dir->info.name is: %s\n", dir->info.name); | |
printf("Value of dir->info.creationDate is: %s\n", ctime(&(dir->info.createDate))); | |
printf("Value of dir->info.modDate is: %s\n", ctime(&(dir->info.modDate))); | |
printf("Value of dir->info.accessDate is: %s\n", ctime(&(dir->info.accessDate))); | |
printf("Value of dir->info.readOnly is: %d\n", dir->info.readOnly); | |
printf("Value of dir->info.hidden is: %d\n", dir->info.hidden); | |
printf("Value of dir->files is: %p\n", dir->files); | |
printf("Value of dir->dirs is: %p\n", dir->dirs); | |
} | |
/* | |
* A helper function used for debugging | |
*/ | |
void printDCBAddresses(dcb_t* dir){ | |
printf("Address of dir is: %p\n", dir); | |
printf("Address of dir->info.name is: %p\n", &(dir->info.name)); | |
printf("Address of dir->info.creationDate is: %p\n", &(dir->info.createDate)); | |
printf("Address of dir->info.modDate is: %p\n", &(dir->info.modDate)); | |
printf("Address of dir->info.accessDate is: %p\n",&(dir->info.accessDate)); | |
printf("Address of dir->info.readOnly is: %p\n", &(dir->info.readOnly)); | |
printf("Address of dir->info.hidden is: %p\n", &(dir->info.hidden)); | |
printf("Address of dir->files is: %p\n", &(dir->dirs)); | |
printf("Address of dir->dirs is: %p\n", &(dir->files)); | |
} | |
/* | |
* A helper function used for debugging | |
*/ | |
void printFCBVals(fcb_t* fcb){ | |
printf("Value of fcb->parentDir: %p\n", ((fcb->parentDir))); | |
printf("Value of fcbpcb->lastAddedFile = fileAdd;->fileSize: %d\n", ((fcb->fileSize))); | |
printf("Value of fcb->info.name: %p\n", ((fcb->info.name))); | |
printf("Value of fcb->info.createDate: %s\n", ((ctime(&fcb->info.createDate)))); | |
printf("Value of fcb->info.modDate: %s\n", ((ctime(&fcb->info.modDate)))); | |
printf("Value of fcb->info.accessDate: %s\n", ((ctime(&fcb->info.accessDate)))); | |
printf("Value of fcb->info.readOnly: %d\n", ((fcb->info.readOnly))); | |
printf("Value of fcb->info.hidden: %d\n", ((fcb->info.hidden))); | |
printf("Value of fcb->info.index: %d\n", ((fcb->info.index))); | |
} | |
/* | |
* A helper function used for debugging | |
*/ | |
void printFCBAddresses(fcb_t* fcb){ | |
printf("Address of fcb->parentDir: %p\n", &((fcb->parentDir))); | |
printf("Address of fcb->fileSize: %p\n", &((fcb->fileSize))); | |
printf("Address of fcb->info.name: %p\n", &((fcb->info.name))); | |
printf("Address of fcb->info.createDate: %p\n", ((&fcb->info.createDate))); | |
printf("Address of fcb->info.modDate: %p\n", ((&fcb->info.modDate))); | |
printf("Address of fcb->info.accessDate: %p\n", &((fcb->info.accessDate))); | |
printf("Address of fcb->info.readOnly: %p\n", &((fcb->info.readOnly))); | |
printf("Address of fcb->info.hidden: %p\n", &((fcb->info.hidden))); | |
printf("Address of fcb->info.index: %p\n", &((fcb->info.index))); | |
} | |
/* | |
* Uses mmap to create the partition | |
*/ | |
void createPartition(p_t* partMap){ | |
int fd = open("/tmp/partition", O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600); | |
partMap = mmap(0, sizeof(p_t) , PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | |
if (partMap == MAP_FAILED) { | |
close(fd); | |
perror("Error mmapping the file"); | |
exit(EXIT_FAILURE); | |
} | |
close(fd); | |
} | |
/* | |
* Deletes the partition when we are done. | |
*/ | |
void deletePartition(p_t* partMap ){ | |
int fd = open("/tmp/partition", O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600); | |
if (munmap(partMap, sizeof(p_t)) == -1) { | |
perror("Error un-mmapping the file"); | |
} | |
close(fd); | |
} | |
/* | |
* Populates the control block for the partition. | |
*/ | |
void createPartitionControlBlock(p_t* partMap, char* name){ | |
partMap->controlBlock.usedListStart = (fcb_t*)&(partMap->controlBlock)+sizeof(pcb_t); | |
partMap->controlBlock.usedListEnd = (fcb_t*)&(partMap->controlBlock)+sizeof(pcb_t); | |
partMap->controlBlock.endOfPartition = (fcb_t*)&(partMap)+sizeof(p_t); | |
partMap->controlBlock.rootDir = (dcb_t*)partMap->controlBlock.usedListStart; | |
addDir("root",&(partMap->controlBlock), (partMap->controlBlock.rootDir), 0,0); | |
partMap->controlBlock.usedSpace = sizeof(pcb_t); | |
partMap->controlBlock.freeSpace =sizeof(p_t) - sizeof(pcb_t); | |
partMap->controlBlock.name = name; | |
} | |
/* | |
* Adds a file to the parent directory control block. The fileSize will take up that many amount of bytes on the partition. | |
*/ | |
void addFile(char* name, pcb_t* pcb, dcb_t* parent, int readOnly, int hidden, int fileSize){ | |
if(parent->fileCount < MAX_DIR_FILES){ | |
fcb_t* fileAdd = pcb->usedListEnd; | |
ib_t* info = &fileAdd->info; | |
fileAdd->parentDir = parent; | |
fileAdd->fileSize = fileSize; | |
info->name = strdup(name); | |
info->readOnly = readOnly; | |
info->hidden = hidden; | |
info->createDate = time(NULL); | |
info->modDate = time(NULL); | |
info->accessDate = time(NULL); | |
info->index = parent->fileCount; | |
pcb->usedListEnd += sizeof(fcb_t)+fileSize; | |
pcb->usedSpace += (sizeof(fcb_t) + fileSize); | |
pcb->freeSpace -= (sizeof(fcb_t) + fileSize); | |
pcb->lastAddedFile = fileAdd; | |
parent->files[parent->fileCount] = fileAdd; | |
parent->fileCount++; | |
} else{ | |
printf("Too many files in directory %s.\n",parent->info.name); | |
} | |
} | |
void addFileInfo(pcb_t* pcb, dcb_t* parent, ib_t oldInfo, int fileSize){ | |
if(parent->fileCount < MAX_DIR_FILES){ | |
fcb_t* fileAdd = pcb->usedListEnd; | |
fileAdd->info = oldInfo; | |
fileAdd->parentDir = parent; | |
fileAdd->fileSize = fileSize; | |
fileAdd->info.index = parent->fileCount; | |
pcb->usedListEnd += sizeof(fcb_t)+fileSize; | |
pcb->usedSpace += (sizeof(fcb_t) + fileSize); | |
pcb->freeSpace -= (sizeof(fcb_t) + fileSize); | |
pcb->lastAddedFile = fileAdd; | |
parent->files[parent->fileCount] = fileAdd; | |
parent->fileCount++; | |
} else{ | |
printf("Too many files in directory %s.\n",parent->info.name); | |
} | |
} | |
/* | |
* Adds a directory to the parent directory specified | |
*/ | |
void addDir(char* name, pcb_t* pcb, dcb_t* parent, int readOnly, int hidden){ | |
if(parent->dirCount < MAX_DIR_FILES){ | |
dcb_t* dir = (dcb_t*)pcb->usedListEnd; | |
dir->parentDir = parent; | |
dir->fileCount = 0; | |
dir->dirCount = 0; | |
ib_t* info = &dir->info; | |
info->name = strdup(name); | |
info->readOnly = readOnly; | |
info->hidden = hidden; | |
info->createDate = time(NULL); | |
info->modDate = time(NULL); | |
info->accessDate = time(NULL); | |
info->index = parent->dirCount; | |
pcb->usedListEnd += sizeof(dcb_t); | |
pcb->usedSpace += sizeof(dcb_t); | |
pcb->freeSpace -= sizeof(dcb_t); | |
pcb->lastAddedDir = dir; | |
parent->dirs[parent->dirCount] = dir; | |
parent->dirCount++; | |
} else{ | |
printf("Too many files in directory %s.\n",parent->info.name); | |
} | |
} | |
dcb_t* addDirInfo(pcb_t* pcb, dcb_t* parent, ib_t oldInfo){ | |
dcb_t* dirAdd = (dcb_t*)pcb->usedListEnd; | |
if(parent->fileCount < MAX_DIR_FILES){ | |
dirAdd->info = oldInfo; | |
dirAdd->parentDir = parent; | |
dirAdd->info.index = parent->fileCount; | |
pcb->usedListEnd += sizeof(dcb_t); | |
pcb->usedSpace += (sizeof(dcb_t)); | |
pcb->freeSpace -= (sizeof(dcb_t)); | |
pcb->lastAddedDir = dirAdd; | |
parent->dirs[parent->fileCount] = dirAdd; | |
parent->dirCount++; | |
} else{ | |
dirAdd = NULL; | |
printf("Too many files in directory %s.\n",parent->info.name); | |
} | |
return dirAdd; | |
} | |
/* | |
* Deletes a file from the parent directory control block. | |
*/ | |
void deleteFile(pcb_t* pcb, fcb_t* file) | |
{ | |
dcb_t* parent = file->parentDir; | |
int index = file->info.index; | |
parent->files[index] = parent->files[parent->fileCount-1]; | |
parent->files[index]->info.index = index; | |
parent->fileCount--; | |
pcb->usedSpace -= (sizeof(fcb_t) + file->fileSize); | |
pcb->freeSpace += (sizeof(fcb_t) + file->fileSize); | |
} | |
/* | |
* Deletes a directory from the parent directory specified | |
*/ | |
void deleteDir(pcb_t* pcb, dcb_t* dir) | |
{ | |
if(pcb->rootDir == dir){ | |
printf("Cannot remove root directory.\n"); | |
} else{ | |
dcb_t* parent = dir->parentDir; | |
int index = dir->info.index; | |
parent->dirs[index] = parent->dirs[parent->dirCount-1]; | |
parent->dirs[index]->info.index = index; | |
dcb_t* newDir = parent->dirs[index]; | |
int j; | |
for(j=0; j < newDir->fileCount; j++) | |
{ | |
fcb_t* i = newDir->files[j]; | |
ib_t* info = &i->info; | |
info->index = index; | |
} | |
int i; | |
for(i = 0; i < newDir->dirCount; i++){ | |
dcb_t* currDir = newDir->dirs[i]; | |
ib_t* info = &currDir->info; | |
info->index = index; | |
} | |
parent->dirCount--; | |
pcb->usedSpace -= sizeof(dcb_t); | |
pcb->freeSpace += sizeof(dcb_t); | |
} | |
} | |
/* | |
* Copies a file to the parent directory control block. | |
*/ | |
void copyFile(fcb_t* file, dcb_t* dir, pcb_t* pcb) | |
{ | |
addFileInfo(pcb, dir, file->info, file->fileSize); | |
} | |
/* | |
* Copies a directory to the parent directory specified | |
*/ | |
void copyDir(dcb_t* dir, dcb_t* parent, pcb_t* pcb) | |
{ | |
if(dir == pcb->rootDir){ | |
printf("Cannot copy root directory\n"); | |
return; | |
} | |
if(parent == pcb->rootDir){ | |
printf("Cannot copy to root directory. Scheduled for service pack 1 release.\n"); | |
return; | |
} | |
dcb_t* newDir = addDirInfo(pcb, parent, dir->info); | |
if(newDir != NULL){ | |
for(int i = 0; i < dir->dirCount; i++){ | |
copyDir(dir->dirs[i],newDir, pcb); | |
} | |
for(int i = 0; i < dir->fileCount; i++){ | |
copyFile(dir->files[i],newDir, pcb); | |
} | |
} | |
} | |
/* | |
* Moves a file to the parent directory control block. | |
*/ | |
void moveFile(fcb_t* file, dcb_t* dir, pcb_t* pcb) | |
{ | |
copyFile(file, dir, pcb); | |
deleteFile(pcb, file); | |
} | |
/* | |
* Moves a directory to the parent directory specified | |
*/ | |
void moveDir(dcb_t* dir, dcb_t* parent, pcb_t* pcb ) | |
{ | |
copyDir(dir, parent, pcb); | |
deleteDir(pcb, dir); | |
} | |
int builtin(char* argv[]) | |
{ | |
if(strcmp(argv[0], "mkdir") == 0) | |
{ | |
if(argv[1] != NULL) | |
{ | |
addDir(argv[1], &part.controlBlock, currDcb, 0, 0); | |
} | |
else | |
printf("No directory specified to create\n"); | |
return 1; | |
} | |
if(strcmp(argv[0], "mkfile") == 0) | |
{ | |
if(argv[1] != NULL) | |
{ | |
addFile(argv[1], &part.controlBlock, currDcb, 0, 0, 20); | |
} | |
else | |
printf("No file specified to create\n"); | |
return 1; | |
} | |
if(strcmp(argv[0], "rm") == 0) | |
{ | |
if(argv[1] != NULL) | |
{ | |
dcb_t* delDir = getDir(argv[1], currDcb); | |
fcb_t* file = getFile(argv[1], currDcb); | |
if(file != NULL){ | |
deleteFile(&part.controlBlock, file); | |
return 1; | |
} | |
else if (delDir != NULL){ | |
deleteDir(&part.controlBlock, delDir); | |
return 1; | |
}else | |
printf("rm: No such file or directory\n"); | |
} | |
else | |
printf("rm: missing operand\n"); | |
return 1; | |
} | |
if(strcmp(argv[0], "mv") == 0) | |
{ | |
if(argv[1] != NULL && argv[2] != NULL) | |
{ | |
dcb_t* movDir = getDir(argv[1], currDcb); | |
dcb_t* destDir = getDir(argv[2], currDcb); | |
fcb_t* file = getFile(argv[1], currDcb); | |
if(file != NULL && destDir != NULL){ | |
moveFile(file, destDir, &part.controlBlock); | |
return 1; | |
} | |
else if (movDir != NULL && destDir != NULL){ | |
moveDir(movDir, destDir, &part.controlBlock); | |
return 1; | |
} | |
else if(strcmp(argv[2], "..") ==0){ | |
if(file != NULL) | |
moveFile(file, currDcb->parentDir, &part.controlBlock); | |
return 1; | |
}else | |
printf("mv: No such file or directory\n"); | |
} | |
else | |
printf("mv: missing operand\n"); | |
return 1; | |
} | |
if(strcmp(argv[0], "cp") == 0) | |
{ | |
if(argv[1] != NULL && argv[2] != NULL) | |
{ | |
dcb_t* copDir = getDir(argv[1], currDcb); | |
dcb_t* destDir = getDir(argv[2], currDcb); | |
fcb_t* file = getFile(argv[1], currDcb); | |
if(file != NULL && destDir != NULL){ | |
copyFile(file, destDir, &part.controlBlock); | |
return 1; | |
} | |
else if (copDir != NULL && destDir != NULL){ | |
copyDir(copDir, destDir, &part.controlBlock); | |
return 1; | |
} | |
else if(strcmp(argv[2], "..") ==0){ | |
if(file != NULL) | |
copyFile(file, currDcb->parentDir, &part.controlBlock); | |
return 1; | |
} | |
else | |
printf("cp: No such file or directory\n"); | |
} | |
else | |
printf("cp: missing operand\n"); | |
return 1; | |
} | |
if(strcmp(argv[0], "cd") == 0) | |
{ | |
if(argv[1] != NULL) | |
{ | |
dcb_t* dir = getDir(argv[1], currDcb); | |
fcb_t* file = getFile(argv[1], currDcb); | |
if(file != NULL){ | |
printf("cd: %s is a file not a directory", argv[1]); | |
} | |
else if (dir != NULL){ | |
currDcb = dir; | |
return 1; | |
} | |
else if(strcmp(argv[1], "..") ==0) | |
currDcb = currDcb->parentDir; | |
else if(strcmp(argv[1], ".") ==0) | |
currDcb = currDcb; | |
else | |
printf("cd: No such file or directory\n"); | |
} | |
else | |
currDcb = part.controlBlock.rootDir; | |
return 1; | |
} | |
if(strcmp(argv[0], "ls") == 0) | |
{ | |
if(argv[1] != NULL){ | |
if(strcmp(argv[1], "-R") ==0){ | |
printAll(currDcb, ""); | |
} | |
else if(strcmp(argv[1], "-a") ==0){ | |
printFiles(currDcb); | |
printDirs(currDcb); | |
printHidden(currDcb); | |
} | |
else if(strcmp(argv[1], "-l") ==0){ | |
printFiles(currDcb); | |
printDirs(currDcb); | |
} | |
} | |
else{ | |
printLS(currDcb); | |
} | |
return 1; | |
} | |
if(strcmp(argv[0], "sudo") == 0) | |
{ | |
if(strcmp(argv[1], "pcb") == 0) | |
{ | |
printPartitionControlBlock(&part.controlBlock); | |
} | |
if(strcmp(argv[1], "dcb") == 0) | |
{ | |
dcb_t* dcb = currDcb; | |
if(argv[3] != NULL) | |
dcb = getDir(argv[3], currDcb) ; | |
if(dcb == NULL){ | |
printf("sudo:dcb: missing operand\n"); | |
return 1; | |
} | |
if(strcmp(argv[2], "val") == 0) | |
printDCBVals(dcb); | |
else if(strcmp(argv[2], "mem") == 0) | |
printDCBAddresses(dcb); | |
} | |
if(strcmp(argv[1], "fcb") == 0) | |
{ | |
fcb_t* fcb; | |
if(argv[3] != NULL) | |
fcb = getFile(argv[3], currDcb) ; | |
if(fcb == NULL){ | |
printf("sudo:fcb: missing operand\n"); | |
return 1; | |
} | |
if(strcmp(argv[2], "val") == 0) | |
printFCBVals(fcb); | |
else if(strcmp(argv[2], "mem") == 0) | |
printFCBAddresses(fcb); | |
} | |
return 1; | |
} | |
if(strcmp(argv[0], "quit") == 0) | |
{ | |
exit(0); | |
return 1; | |
} | |
else | |
{ | |
printf("%s: Command not found\n", argv[0]); | |
} | |
return 0; | |
} | |
int parse(char*buf, char*argv[]) | |
{ | |
char*delim; /* points to first whitespace delimiter*/ | |
int argc = 0; /* number of args*/ | |
char whsp[] = " \t\n\v\f\r/"; /* whitespace characters*/ | |
/* Note - the trailing '\n' in buf is whitespace, and we need it as a delimiter.*/ | |
while (1) /* build the argv list*/ | |
{ | |
buf += strspn(buf, whsp); /* skip leading whitespace*/ | |
delim = strpbrk(buf, whsp); /* next whitespace char or NULL*/ | |
if (delim == NULL) //Check for the NULL pointer /* end of line*/ | |
{ break; } | |
argv[argc++] = buf; /* start argv[i]*/ | |
*delim = '\0'; /* terminate argv[i]*/ | |
buf = delim + 1; /* start argv[i+1]?*/ | |
} | |
if(argc == 0) | |
argv[argc] =buf; | |
else | |
argv[argc] =NULL; | |
return argc; | |
} | |
fcb_t* getFile(char* name, dcb_t* currDir){ | |
char*argv[MAXARGS]; | |
parse(name,argv); | |
int j; | |
for(j=0; j < currDir->fileCount; j++) | |
{ | |
fcb_t* i = currDir->files[j]; | |
ib_t* info = &i->info; | |
if(strcmp(argv[0], info->name) == 0) | |
{ | |
return currDir->files[j]; | |
} | |
} | |
return NULL; | |
} | |
dcb_t* getDir(char* name, dcb_t* currDir){ | |
char*argv[MAXARGS]; | |
parse(name,argv); | |
int i; | |
for(i = 0; i < currDir->dirCount; i++){ | |
dcb_t* childDir = currDir->dirs[i]; | |
ib_t* info = &childDir->info; | |
if(strcmp(argv[0], info->name) == 0) | |
{ | |
return currDir->dirs[i]; | |
} | |
} | |
return NULL; | |
} | |
int eval_line(char*cmdline) | |
{ | |
char*argv[MAXARGS]; /* argv array */ | |
char buf[MAXLINE]; /* holds modified command line*/ | |
int ret = EXIT_SUCCESS; | |
strcpy(buf, cmdline); /* buf[] will be modified by parse()*/ | |
parse(buf, argv); | |
if (argv[0] == NULL) //Check for the NULL pointer /* ignore empty lines*/ | |
{ return ret; } | |
if(builtin(argv) == 1) | |
{ return ret; } | |
return ret; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
char* name = "TestPartition2"; | |
createPartition(&part); | |
createPartitionControlBlock(&part, name ); | |
currDcb = part.controlBlock.rootDir; | |
addFile("fooFile", &part.controlBlock, (part.controlBlock.rootDir), 0,0,20); | |
addFile("fooFile2",&part.controlBlock,(part.controlBlock.rootDir), 0,0,20); | |
addFile("foofooFile",&part.controlBlock, (part.controlBlock.rootDir), 0,0,20); | |
addDir("fooDir", &part.controlBlock, (part.controlBlock.rootDir), 0,0); | |
addDir("fooDirHidden", &part.controlBlock, (part.controlBlock.rootDir),0 ,1); | |
addDir("fooDir2",&part.controlBlock,(part.controlBlock.rootDir), 0,0); | |
addDir("fooDir3",&part.controlBlock,(part.controlBlock.rootDir), 0,0); | |
addDir("fooDir21",&part.controlBlock,(part.controlBlock.rootDir->dirs[1]), 1,0); | |
char cmdline[MAXLINE]; | |
int ret = EXIT_SUCCESS; | |
while ( ret == EXIT_SUCCESS ) | |
{ | |
if(fgets(cmdline, MAXLINE, stdin) != NULL) | |
{ | |
if (feof(stdin)) // end of file | |
{ break; } | |
ret = eval_line(cmdline); | |
} | |
else if(errno != EINTR) | |
{ | |
printf("error encountered with error number %d and error message %s\n",errno, strerror(errno)); | |
break; | |
} | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# CMPSC 473, Project 4 | |
# Corey Stubbs, 90201575, cas5542@psu.edu | |
# Jeremy Ploumis, 974335459, jep5190@psu.edu | |
SRC = pr4.c | |
#LIB = | |
#INC = | |
#$(LIB) $(INC) | |
pr3: $(SRC) | |
gcc -std=c99 -Wall -Wextra -o pr4 $(SRC) | |
noWarn: $(SRC) | |
gcc -std=c99 -w -o pr4 $(SRC) | |
clean: | |
rm -f pr4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment