Skip to content

Commit bd40377

Browse files
committedApr 9, 2021
Final Commit
0 parents  commit bd40377

8 files changed

+902
-0
lines changed
 

‎.gitkeep

Whitespace-only changes.

‎Makefile

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FLAGS= -Wall -Werror -fsanitize=address -g
2+
OBJ = simfs.o initfs.o printfs.o simfs_ops.o
3+
DEPENDENCIES = simfs.h simfstypes.h
4+
5+
all : simfs
6+
7+
simfs : ${OBJ}
8+
gcc ${FLAGS} -o $@ $^
9+
10+
%.o : %.c ${DEPENDENCIES}
11+
gcc ${FLAGS} -c $<
12+
13+
clean :
14+
rm -f *.o simfs

‎initfs.c

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include "simfs.h"
4+
5+
6+
/* Create a simulated file system structure in the file specified by
7+
* filename. This function overwrites whatever was in the file
8+
* filename.
9+
*/
10+
11+
void
12+
initfs(char *filename) {
13+
14+
fentry files[MAXFILES];
15+
fnode fnodes[MAXBLOCKS];
16+
int i;
17+
int bytes_used = sizeof(fentry) * MAXFILES + sizeof(fnode) * MAXBLOCKS;
18+
FILE *fp = openfs(filename, "w");
19+
20+
/* Initialize the metadata structures */
21+
22+
for(i = 0; i < MAXFILES; i++) {
23+
files[i].name[0] = '\0';
24+
files[i].size = 0;
25+
files[i].firstblock = -1;
26+
}
27+
28+
for(i = 0; i < MAXBLOCKS; i++) {
29+
fnodes[i].blockindex = -i;
30+
fnodes[i].nextblock = -1;
31+
}
32+
for (i = 1; i < MAXBLOCKS && i <= (bytes_used - 1) / BLOCKSIZE; i++) {
33+
fnodes[i].blockindex = i;
34+
}
35+
36+
/* Write the metadata to the file. */
37+
38+
if(fwrite(files, sizeof(fentry), MAXFILES, fp) < MAXFILES) {
39+
fprintf(stderr, "Error: write failed on init\n");
40+
closefs(fp);
41+
exit(1);
42+
}
43+
44+
if(fwrite(fnodes, sizeof(fnode), MAXBLOCKS, fp) < MAXBLOCKS) {
45+
fprintf(stderr, "Error: write failed on init\n");
46+
closefs(fp);
47+
exit(1);
48+
}
49+
50+
/* Write buffer bytes to the file to fill the current block. */
51+
int bytes_to_write = (BLOCKSIZE - (bytes_used % BLOCKSIZE)) % BLOCKSIZE;
52+
char zerobuf[BLOCKSIZE] = {0};
53+
if (bytes_to_write != 0 && fwrite(zerobuf, bytes_to_write, 1, fp) < 1) {
54+
fprintf(stderr, "Error: write failed on init\n");
55+
closefs(fp);
56+
exit(1);
57+
}
58+
59+
closefs(fp);
60+
}

‎printfs.c

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include "simfs.h"
4+
5+
6+
/* Print the contents of the file system file in a readable form. */
7+
8+
void
9+
printfs(char *filename) {
10+
fentry files[MAXFILES];
11+
fnode fnodes[MAXBLOCKS];
12+
char block[BLOCKSIZE + 1];
13+
int i;
14+
15+
FILE *fp = openfs(filename, "r");
16+
17+
if ((fread(files, sizeof(fentry), MAXFILES, fp)) == 0) {
18+
fprintf(stderr, "Error: could not read file entries\n");
19+
closefs(fp);
20+
exit(1);
21+
}
22+
if ((fread(fnodes, sizeof(fnode), MAXBLOCKS, fp)) == 0) {
23+
fprintf(stderr, "Error: could not read fnodes\n");
24+
closefs(fp);
25+
exit(1);
26+
}
27+
int bytes_used = sizeof(fentry) * MAXFILES + sizeof(fnode) * MAXBLOCKS;
28+
int bytes_to_read = (BLOCKSIZE - (bytes_used % BLOCKSIZE)) % BLOCKSIZE;
29+
if (bytes_to_read != 0 && fseek(fp, bytes_to_read, SEEK_CUR) != 0) {
30+
fprintf(stderr, "Error: seek failed during print\n");
31+
closefs(fp);
32+
exit(1);
33+
}
34+
35+
printf("File entry structures:\n");
36+
37+
for (i = 0; i < MAXFILES; i++) {
38+
printf("[%d] \"%s\"\t%hu\t%hd\n",
39+
i,
40+
files[i].name,
41+
files[i].size,
42+
files[i].firstblock);
43+
}
44+
45+
printf("\nFile node structures:\n");
46+
for (i = 0; i < MAXBLOCKS; i++) {
47+
printf("[%d] %hd\t%hd\n",
48+
i,
49+
fnodes[i].blockindex,
50+
fnodes[i].nextblock);
51+
}
52+
53+
/* Write the raw file data to standard out */
54+
printf("\nFile blocks:\n");
55+
while (fread(block, 1, BLOCKSIZE, fp) == BLOCKSIZE) {
56+
fwrite(block, BLOCKSIZE, 1, stdout);
57+
}
58+
if (ferror(fp)) {
59+
fprintf(stderr, "Error: could not read data block\n");
60+
closefs(fp);
61+
exit(1);
62+
}
63+
64+
printf("\n");
65+
closefs(fp);
66+
}

‎simfs.c

+144
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/* This program simulates a file system within an actual file. The
2+
* simulated file system has only one directory, and two types of
3+
* metadata structures defined in simfstypes.h.
4+
*/
5+
6+
/* Simfs is run as:
7+
* simfs -f myfs command args
8+
* where the -f option specifies the actual file that the simulated file system
9+
* occupies, the command is the command to be run on the simulated file system,
10+
* and args represents a list of arguments for the command. Note that
11+
* different commands take different numbers of arguments.
12+
*/
13+
14+
#include <stdio.h>
15+
#include <unistd.h>
16+
#include <stdlib.h>
17+
#include <string.h>
18+
#include "simfs.h"
19+
20+
// We use the ops array to match the file system command entered by the user.
21+
#define MAXOPS 6
22+
char *ops[MAXOPS] = {"initfs", "printfs", "createfile", "readfile",
23+
"writefile", "deletefile"};
24+
int find_command(char *);
25+
26+
int
27+
main(int argc, char **argv)
28+
{
29+
int oc; /* option character */
30+
char *cmd; /* command to run on the file system */
31+
char *fsname; /* name of the simulated file system file */
32+
33+
char *usage_string = "Usage: simfs -f file cmd arg1 arg2 ...\n";
34+
35+
/* Get and check the arguments */
36+
if(argc < 4) {
37+
fputs(usage_string, stderr);
38+
exit(1);
39+
}
40+
41+
while((oc = getopt(argc, argv, "f:")) != -1) {
42+
switch(oc) {
43+
case 'f' :
44+
fsname = optarg;
45+
break;
46+
default:
47+
fputs(usage_string, stderr);
48+
exit(1);
49+
}
50+
}
51+
52+
/* Get the command name */
53+
char *end_ptr;
54+
char *end_ptr2;
55+
cmd = argv[optind];
56+
optind++;
57+
switch((find_command(cmd))) {
58+
case 0: /* initfs */
59+
initfs(fsname);
60+
break;
61+
case 1: /* printfs */
62+
printfs(fsname);
63+
break;
64+
case 2: /* createfile */
65+
if (argc == 5){
66+
createFile(argv[optind], fsname);
67+
}
68+
else if (argc > 5){
69+
fprintf(stderr, "Error: Too many arguments provided.\n");
70+
}
71+
72+
//fprintf(stderr, "Error: createfile not yet implemented\n");
73+
break;
74+
case 3: /* readfile */
75+
//check if end_ptr and 2 are empty otherwise return error
76+
if (argc == 7){
77+
int start = strtol(argv[optind+1], &end_ptr,10);
78+
int length = strtol(argv[optind+2], &end_ptr2, 10);
79+
if (strlen(end_ptr) ==0 && strlen(end_ptr2)==0){
80+
readFile(argv[optind], start, length, fsname);
81+
}
82+
else{
83+
fprintf(stderr, "Error: Incorrect parameters.\n");
84+
}
85+
}
86+
else if (argc > 7){
87+
fprintf(stderr, "Error: Too many arguments provided.\n");
88+
}
89+
else if (argc< 7){
90+
fprintf(stderr, "Error: Not enough arguments provided.\n");
91+
}
92+
//fprintf(stderr, "Error: readfile not yet implemented\n");
93+
break;
94+
case 4: /* writefile */
95+
if (argc == 7){
96+
int start = strtol(argv[optind+1], &end_ptr,10);
97+
int length = strtol(argv[optind+2], &end_ptr2, 10);
98+
if (strlen(end_ptr) ==0 && strlen(end_ptr2)==0){
99+
writeFile(argv[optind], start, length, fsname);
100+
}
101+
else{
102+
fprintf(stderr, "Error: Incorrect parameters.\n");
103+
}
104+
}
105+
else if (argc > 7){
106+
fprintf(stderr, "Error: Too many arguments provided.\n");
107+
}
108+
else if (argc< 7){
109+
fprintf(stderr, "Error: Not enough arguments provided.\n");
110+
}
111+
//fprintf(stderr, "Error: writefile not yet implemented\n");
112+
break;
113+
case 5: /* deletefile */
114+
if (argc == 5){
115+
deleteFile(argv[optind], fsname);
116+
}
117+
else if (argc > 5){
118+
fprintf(stderr, "Error: Too many arguments provided.\n");
119+
}
120+
//fprintf(stderr, "Error: deletefile not yet implemented\n");
121+
break;
122+
default:
123+
fprintf(stderr, "Error: Invalid command\n");
124+
exit(1);
125+
}
126+
127+
return 0;
128+
}
129+
130+
/* Returns a integer corresponding to the file system command that
131+
* is to be executed
132+
*/
133+
int
134+
find_command(char *cmd)
135+
{
136+
int i;
137+
for(i = 0; i < MAXOPS; i++) {
138+
if ((strncmp(cmd, ops[i], strlen(ops[i]))) == 0) {
139+
return i;
140+
}
141+
}
142+
fprintf(stderr, "Error: Command %s not found\n", cmd);
143+
return -1;
144+
}

‎simfs.h

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <stdio.h>
2+
#include "simfstypes.h"
3+
4+
/* File system operations */
5+
void printfs(char *);
6+
void initfs(char *);
7+
void createFile(char *filename, char *fsname);
8+
void deleteFile(char *filename, char *fsname);
9+
void readFile(char *filename, int start, int length, char *fsname);
10+
void writeFile(char *filename, int start, int length, char *fsname);
11+
/* Internal functions */
12+
FILE *openfs(char *filename, char *mode);
13+
void closefs(FILE *fp);

‎simfs_ops.c

+590
Large diffs are not rendered by default.

‎simfstypes.h

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
typedef struct file_entry {
2+
char name[12]; // An empty name means the fentry is not in use.
3+
unsigned short size;
4+
short firstblock; // A -1 indicates that no file blocks have been allocated.
5+
} fentry;
6+
7+
typedef struct file_node {
8+
short blockindex; // Negative value means this block is not in use.
9+
short nextblock; // A -1 indicates there is no next block of data.
10+
} fnode;
11+
12+
13+
#define MAXFILES 8
14+
#define MAXBLOCKS 32
15+
#define BLOCKSIZE 128

0 commit comments

Comments
 (0)
Please sign in to comment.