-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfuse.c
More file actions
161 lines (125 loc) · 3.51 KB
/
fuse.c
File metadata and controls
161 lines (125 loc) · 3.51 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
/*
* DARFS: browse files inside a DAR archive (http://dar.linux.free.fr/)
* Copyright (C) 2010 Guido De Rosa <guido.derosa@vemarsas.it>
*
* based on: FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
*
* This program can be distributed under the terms of the GNU GPL.
*/
#define FUSE_USE_VERSION 26
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <fuse.h>
#include <fuse_opt.h>
const char * cplusplus_hello_str();
int darfs_exists(const char * path);
mode_t darfs_mode(const char * path);
off_t darfs_size(const char * path);
int open_dar_archive(const char * archive_);
void darfs_dir_listing_flush();
void get_files_in_dir(const char * path, char *** files_in_dir, unsigned long * n_files);
static char * archive = NULL;
static int darfs_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs);
#define hello_str cplusplus_hello_str()
static const char *hello_path = "/hello";
/** options for fuse_opt.h */
/* struct options {
int readonly;
}options;
*/
/** macro to define options */
/* #define HELLOFS_OPT_KEY(t, p, v) { t, offsetof(struct options, p), v } */
static int hello_getattr(const char *path, struct stat *stbuf)
{
int res = 0;
memset(stbuf, 0, sizeof(struct stat));
if (strcmp(path, "/") == 0) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
} else if (strcmp(path, hello_path) == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen(hello_str);
} else if (darfs_exists(path)) {
stbuf->st_mode = darfs_mode(path);
stbuf->st_nlink = 1; /* TODO: darfs_nlink()? */
stbuf->st_size = darfs_size(path);
} else
res = -ENOENT;
return res;
}
static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
{
(void) offset;
(void) fi;
if (strcmp(path, "/") != 0)
return -ENOENT;
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
filler(buf, hello_path + 1, NULL, 0);
unsigned long n_files = 0;
char ** files = NULL;
darfs_dir_listing_flush();
get_files_in_dir("", &files, &n_files);
unsigned int i;
for (i=0; i<n_files; i++)
{
filler(buf, files[i], NULL, 0);
printf("fuse.c: %s\n", files[i]);
}
return 0;
}
static int hello_open(const char *path, struct fuse_file_info *fi)
{
if (strcmp(path, hello_path) != 0)
return -ENOENT;
if ((fi->flags & 3) != O_RDONLY)
return -EACCES;
return 0;
}
static int hello_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
{
size_t len;
(void) fi;
if(strcmp(path, hello_path) != 0)
return -ENOENT;
len = strlen(hello_str);
if (offset < len) {
if (offset + size > len)
size = len - offset;
memcpy(buf, hello_str + offset, size);
} else
size = 0;
return size;
}
static struct fuse_operations hello_oper = {
.getattr = hello_getattr,
.readdir = hello_readdir,
.open = hello_open,
.read = hello_read,
};
static int darfs_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs)
{
if (key == FUSE_OPT_KEY_NONOPT && archive == NULL) {
archive = strdup(arg);
open_dar_archive(archive);
return 0;
}
return 1;
}
int main(int argc, char *argv[])
{
int ret;
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
fuse_opt_parse(&args, NULL, NULL, darfs_opt_proc);
ret = fuse_main(args.argc, args.argv, &hello_oper, NULL);
/** free arguments */
fuse_opt_free_args(&args);
return ret;
}