forked from MaaSTaaR/LSYSFS
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlsysfs.c
More file actions
185 lines (143 loc) · 4.34 KB
/
Copy pathlsysfs.c
File metadata and controls
185 lines (143 loc) · 4.34 KB
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
/**
* Less Simple, Yet Stupid Filesystem.
*
* Mohammed Q. Hussain - http://www.maastaar.net
*
* This is an example of using FUSE to build a simple filesystem. It is a part of a tutorial in MQH Blog with the title "Writing Less Simple, Yet Stupid Filesystem Using FUSE in C": http://maastaar.net/fuse/linux/filesystem/c/2019/09/28/writing-less-simple-yet-stupid-filesystem-using-FUSE-in-C/
*
* License: GNU GPL
*/
#define FUSE_USE_VERSION 30
#include <fuse.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
// ... //
char dir_list[ 256 ][ 256 ];
int curr_dir_idx = -1;
char files_list[ 256 ][ 256 ];
int curr_file_idx = -1;
char files_content[ 256 ][ 256 ];
int curr_file_content_idx = -1;
void add_dir( const char *dir_name )
{
curr_dir_idx++;
strcpy( dir_list[ curr_dir_idx ], dir_name );
}
int is_dir( const char *path )
{
path++; // Eliminating "/" in the path
for ( int curr_idx = 0; curr_idx <= curr_dir_idx; curr_idx++ )
if ( strcmp( path, dir_list[ curr_idx ] ) == 0 )
return 1;
return 0;
}
void add_file( const char *filename )
{
curr_file_idx++;
strcpy( files_list[ curr_file_idx ], filename );
curr_file_content_idx++;
strcpy( files_content[ curr_file_content_idx ], "" );
}
int is_file( const char *path )
{
path++; // Eliminating "/" in the path
for ( int curr_idx = 0; curr_idx <= curr_file_idx; curr_idx++ )
if ( strcmp( path, files_list[ curr_idx ] ) == 0 )
return 1;
return 0;
}
int get_file_index( const char *path )
{
path++; // Eliminating "/" in the path
for ( int curr_idx = 0; curr_idx <= curr_file_idx; curr_idx++ )
if ( strcmp( path, files_list[ curr_idx ] ) == 0 )
return curr_idx;
return -1;
}
void write_to_file( const char *path, const char *new_content )
{
int file_idx = get_file_index( path );
if ( file_idx == -1 ) // No such file
return;
strcpy( files_content[ file_idx ], new_content );
}
// ... //
static int do_getattr( const char *path, struct stat *st )
{
st->st_uid = getuid(); // The owner of the file/directory is the user who mounted the filesystem
st->st_gid = getgid(); // The group of the file/directory is the same as the group of the user who mounted the filesystem
st->st_atime = time( NULL ); // The last "a"ccess of the file/directory is right now
st->st_mtime = time( NULL ); // The last "m"odification of the file/directory is right now
if ( strcmp( path, "/" ) == 0 || is_dir( path ) == 1 )
{
st->st_mode = S_IFDIR | 0755;
st->st_nlink = 2; // Why "two" hardlinks instead of "one"? The answer is here: http://unix.stackexchange.com/a/101536
}
else if ( is_file( path ) == 1 )
{
st->st_mode = S_IFREG | 0644;
st->st_nlink = 1;
st->st_size = 1024;
}
else
{
return -ENOENT;
}
return 0;
}
static int do_readdir( const char *path, void *buffer, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi )
{
filler( buffer, ".", NULL, 0 ); // Current Directory
filler( buffer, "..", NULL, 0 ); // Parent Directory
if ( strcmp( path, "/" ) == 0 ) // If the user is trying to show the files/directories of the root directory show the following
{
for ( int curr_idx = 0; curr_idx <= curr_dir_idx; curr_idx++ )
filler( buffer, dir_list[ curr_idx ], NULL, 0 );
for ( int curr_idx = 0; curr_idx <= curr_file_idx; curr_idx++ )
filler( buffer, files_list[ curr_idx ], NULL, 0 );
}
return 0;
}
static int do_read( const char *path, char *buffer, size_t size, off_t offset, struct fuse_file_info *fi )
{
int file_idx = get_file_index( path );
if ( file_idx == -1 )
return -1;
char *content = files_content[ file_idx ];
memcpy( buffer, content + offset, size );
return strlen( content ) - offset;
}
static int do_mkdir( const char *path, mode_t mode )
{
path++;
add_dir( path );
return 0;
}
static int do_mknod( const char *path, mode_t mode, dev_t rdev )
{
path++;
add_file( path );
return 0;
}
static int do_write( const char *path, const char *buffer, size_t size, off_t offset, struct fuse_file_info *info )
{
write_to_file( path, buffer );
return size;
}
static struct fuse_operations operations = {
.getattr = do_getattr,
.readdir = do_readdir,
.read = do_read,
.mkdir = do_mkdir,
.mknod = do_mknod,
.write = do_write,
};
int main( int argc, char *argv[] )
{
return fuse_main( argc, argv, &operations, NULL );
}