-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathumka_fuse.c
177 lines (153 loc) · 4.45 KB
/
umka_fuse.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
/*
SPDX-License-Identifier: GPL-2.0-or-later
UMKa - User-Mode KolibriOS developer tools
umka_fuse - FUSE <-> KolibriOS FS calls converter
Copyright (C) 2017-2023 Ivan Baravy <[email protected]>
*/
#define FUSE_USE_VERSION 31
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "umkaio.h"
#include "vdisk.h"
#define DIRENTS_TO_READ 100
struct umka_fuse_ctx {
struct umka_ctx *umka;
struct umka_io *io;
};
static struct umka_fuse_ctx *
umka_fuse_init(void) {
struct umka_fuse_ctx *ctx = malloc(sizeof(struct umka_fuse_ctx));
ctx->umka = umka_init(UMKA_RUNNING_NEVER);
ctx->io = io_init(&ctx->umka->running);
return ctx;
}
static void
umka_fuse_close(struct umka_fuse_ctx *ctx) {
umka_close(ctx->umka);
io_close(ctx->io);
free(ctx);
}
static void
bdfe_to_stat(bdfe_t *kf, struct stat *st) {
// if (kf->attr & KF_FOLDER) {
if (st) {
st->st_mode = S_IFDIR | 0755;
st->st_nlink = 2;
} else {
st->st_mode = S_IFREG | 0644;
st->st_nlink = 1;
st->st_size = kf->size;
}
st->st_atime = kos_time_to_epoch(&(kf->atime));
st->st_mtime = kos_time_to_epoch(&(kf->mtime));
st->st_ctime = kos_time_to_epoch(&(kf->ctime));
}
static void *
fs_init(struct fuse_conn_info *conn, struct fuse_config *cfg) {
(void) conn;
cfg->kernel_cache = 1;
return NULL;
}
static void
fs_destroy(void *private_data) {
struct umka_fuse_ctx *ctx = private_data;
umka_fuse_close(ctx);
}
static int
fs_getattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi) {
(void) fi;
int res = 0;
bdfe_t file;
f7080s5arg_t fX0 = {.sf = 5,
.flags = 0,
.buf = &file,
.u = {.f80 = {.path_encoding = UTF8,
.path = path
}
}
};
f7080ret_t r;
umka_sys_lfn(&fX0, &r, F80);
bdfe_to_stat(&file, stbuf);
// res = -ENOENT;
return res;
}
static int
fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
struct fuse_file_info *fi, enum fuse_readdir_flags flags) {
(void) offset; // TODO
(void) fi;
(void) flags;
f7080s1info_t *dir = (f7080s1info_t*)malloc(sizeof(f7080s1info_t) +
BDFE_LEN_UNICODE * DIRENTS_TO_READ);
f7080s1arg_t fX0 = {.sf = 1,
.offset = 0,
.encoding = UTF8,
.size = DIRENTS_TO_READ,
.buf = dir,
.u = {.f80 = {.path_encoding = UTF8,
.path = path
}
}
};
f7080ret_t r;
umka_sys_lfn(&fX0, &r, F80);
bdfe_t *bdfe = dir->bdfes;
for (size_t i = 0; i < dir->cnt; i++) {
filler(buf, bdfe->name, NULL, 0, 0);
bdfe = (bdfe_t*)((uintptr_t)bdfe + BDFE_LEN_UNICODE);
}
free(dir);
return 0;
}
static int
fs_open(const char *path, struct fuse_file_info *fi) {
// if (strcmp(path+1, "blah") != 0)
// return -ENOENT;
(void) path;
if ((fi->flags & O_ACCMODE) != O_RDONLY)
return -EACCES;
return 0;
}
static int
fs_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi) {
(void) fi;
f7080s0arg_t fX0 = {.sf = 0, .offset = offset, .count = size, .buf = buf,
.u = {.f80 = {.path_encoding = UTF8, .path = path}}};
f7080ret_t r;
umka_sys_lfn(&fX0, &r, F80);
return size;
}
static struct fuse_operations umka_oper = {
.init = fs_init,
.destroy = fs_destroy,
.getattr = fs_getattr,
.readdir = fs_readdir,
.open = fs_open,
.read = fs_read,
};
int
main(int argc, char *argv[]) {
if (argc != 3) {
printf("usage: umka_fuse dir img\n");
exit(1);
}
struct umka_fuse_ctx *ctx = umka_fuse_init();
umka_boot();
struct vdisk *umka_disk = vdisk_init(argv[2], 1, 0u, ctx->io);
disk_t *disk = disk_add(&umka_disk->diskfunc, "hd0", umka_disk, 0);
disk_media_changed(disk, 1);
return fuse_main(argc-1, argv, &umka_oper, ctx);
}