-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbackupwormfs.c
219 lines (190 loc) · 4.96 KB
/
backupwormfs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#define FUSE_USE_VERSION 26
#define _FILE_OFFSET_BITS 64
#include <fuse.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <fcntl.h>
#include <errno.h>
#include <syslog.h>
#include <unistd.h>
int device;
struct dirent{
uint8_t deleted;
uint8_t entType;
uint16_t reserved1;
uint32_t firstBlock;
uint32_t fileLength;
uint32_t reserved2;
uint32_t parentNumber;
uint32_t selfNumber;
uint32_t reserved3;
uint32_t reserved4;
char fileName[16];
}currentEntry;
static void readNextEntry(){
read(device,¤tEntry.deleted,1);
read(device,¤tEntry.entType,1);
read(device,¤tEntry.reserved1,2);
read(device,¤tEntry.firstBlock,4);
read(device,¤tEntry.fileLength,4);
read(device,¤tEntry.reserved2,4);
read(device,¤tEntry.parentNumber,4);
read(device,¤tEntry.selfNumber,4);
read(device,¤tEntry.reserved3,4);
read(device,¤tEntry.reserved4,4);
read(device,¤tEntry.fileName,16);
}
static int findEntry(char *path,struct dirent** entry){
char* token;
int found;
int currentDir=0;
struct dirent* fileToOpen=malloc(sizeof(struct dirent));
lseek(device,2048,SEEK_SET);
printf("Path: %s\n",path);
token=strtok(path,"/");
//token=strtok(path,"/");
//syslog(LOG_ERR, "Error %d reading dir id from ROM\n", errno);
printf("firstfileName: %s\n",token);
readNextEntry();
int numEntries=currentEntry.fileLength/48;//Dirent length
while(token!=NULL){
lseek(device,2096,SEEK_SET);
printf("token: %s currentDir: %i\n",token,currentDir);
found=0;
for(int i=1;i<numEntries;i++){
readNextEntry();
if(strcmp(currentEntry.fileName,token)==0&¤tEntry.parentNumber==currentDir){
printf("currentToken: %s\ncurrent number : %i\n currentDir: %i parent: %i\n",token,currentEntry.selfNumber,currentDir,currentEntry.parentNumber);
currentDir=currentEntry.selfNumber;
found=1;
printf("Found\n");
break;
}
/*if(found==1){
break;
}*/
}
if(found==0){
printf("NotFound\n");
break;
}else{
printf("Found2\n");
}
token=strtok(NULL,"/");
printf("endToken: %s\n",token);
}
if(found==1){
memcpy(fileToOpen,¤tEntry,sizeof(struct dirent));
*entry=fileToOpen;
printf("fileLength: %i\n",(*entry)->fileLength);
return 0;
}else{
printf("ENOENT");
return -ENOENT;
}
}
static int testfs_getattr(const char *path, struct stat *stbuf) {
struct dirent* fileToOpen;
int ret=0;
if(strcmp(path,"/")==0){
stbuf->st_mode=S_IFDIR|0755;
stbuf->st_nlink=2;
}else{
ret=findEntry(path,&fileToOpen);
printf("fileLengthAttr: %i\n",fileToOpen->fileLength);
if(ret==0){
switch(fileToOpen->entType){
case 1:
stbuf->st_mode=S_IFREG|0444;
stbuf->st_nlink=1;
stbuf->st_size=fileToOpen->fileLength;
break;
case 0:
stbuf->st_mode=S_IFDIR|0755;
stbuf->st_nlink=2;
break;
default:
printf("Error: type not known");
}
}
}
return ret;
}
static int testfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) {
struct dirent* fileToOpen;
int ret=0;
int dirNum;
lseek(device,2048,SEEK_SET);
filler(buf,".",NULL,0);
filler(buf,"..",NULL,0);
readNextEntry();
//filler(buf,currentEntry.fileName,NULL,0);
int numEntries=currentEntry.fileLength/48;//Dirent length
if(strcmp(path,"/")==0){
dirNum=0;
}else{
ret=findEntry(path,&fileToOpen);
dirNum=fileToOpen->selfNumber;
}
for(int i=1;i<numEntries;i++){
readNextEntry();
if(currentEntry.parentNumber==dirNum){
filler(buf,currentEntry.fileName,NULL,0);
}
}
return 0;
}
static int testfs_open(const char *path, struct fuse_file_info *fi) {
/*char* token;
int found;
struct dirent* fileToOpen=malloc(sizeof(struct dirent));
fseek(device,2048,SEEK_SET);
token=strtok(path,"/");
token=strtok(path,"/");
readNextEntry();
int numEntries=currentEntry.fileLength/48;//Dirent length
for(int i=0;i<numEntries;i++){
readNextEntry();
if(strcmp(currentEntry.fileName,token)==0){
found=1;
break;
}
}
if(found==1){
memcpy(fileToOpen,currentEntry,sizeof(struct dirent));
fi->fh=fileToOpen;
return 0;
}else{
return -ENOENT;
}*/
struct dirent* fileToOpen;
int ret=findEntry(path,&fileToOpen);
if(ret==0){
fi->fh=(uint64_t)(size_t)fileToOpen;
}
return ret;
}
static int testfs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) {
struct dirent* fileToOpen=(struct dirent*)(size_t)fi->fh;
//lseek(device,(2048*fileToOpen->firstBlock)+offset,SEEK_SET);
pread(device,buf,size,(2048*fileToOpen->firstBlock)+offset);
}
static struct fuse_operations testfs_oper = {
.getattr = testfs_getattr,
.readdir = testfs_readdir,
.open = testfs_open,
.read = testfs_read,
};
int main(int argc, char** argv){
if(argc<3){
printf("Usage: testfs <dev/file> <mountpoint> <options>\nError: Too few args\n");
return 1;
}
device=open(argv[1],O_RDONLY);
//printf("%s\n",argv[1]);
argv[1]=argv[0];
fuse_main(argc-1, &argv[1], &testfs_oper, NULL);
return 0;
}