mirror of
https://github.com/falk-werner/webfuse-provider
synced 2024-10-27 20:44:10 +00:00
basic implementation of read added
This commit is contained in:
parent
318b9afdf9
commit
59caed8600
@ -4,7 +4,25 @@ function startup()
|
|||||||
this.root = root;
|
this.root = root;
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystem.BAD_NO_ENTRY = -1;
|
FileSystem.GOOD = 0;
|
||||||
|
FileSystem.BAD = 1;
|
||||||
|
|
||||||
|
FileSystem.BAD_NOTIMPLEMENTED = 2;
|
||||||
|
FileSystem.BAD_TIMEOUT = 3;
|
||||||
|
FileSystem.BAD_FORMAT = 4;
|
||||||
|
|
||||||
|
FileSystem.BAD_NOENTRY = 101;
|
||||||
|
FileSystem.BAD_NOACCESS = 102;
|
||||||
|
|
||||||
|
FileSystem.O_ACCMODE = 00003;
|
||||||
|
FileSystem.O_RDONLY = 00000;
|
||||||
|
FileSystem.O_WRONLY = 00001;
|
||||||
|
FileSystem.O_RDWR = 00002;
|
||||||
|
FileSystem.O_CREAT = 00100;
|
||||||
|
FileSystem.O_EXCL = 00200;
|
||||||
|
FileSystem.O_TRUNK = 01000;
|
||||||
|
FileSystem.O_APPEND = 02000;
|
||||||
|
|
||||||
|
|
||||||
FileSystem.prototype.getEntry = function(path) {
|
FileSystem.prototype.getEntry = function(path) {
|
||||||
var items = path.split('/');
|
var items = path.split('/');
|
||||||
@ -28,14 +46,14 @@ function startup()
|
|||||||
return {
|
return {
|
||||||
mode: entry.mode || 0755,
|
mode: entry.mode || 0755,
|
||||||
type: entry.type || 'file',
|
type: entry.type || 'file',
|
||||||
size: entry.size || 0,
|
size: entry.size || (entry.contents && entry.contents.length) || 0,
|
||||||
atime: entry.atime || 0,
|
atime: entry.atime || 0,
|
||||||
mtime: entry.mtime || 0,
|
mtime: entry.mtime || 0,
|
||||||
ctime: entry.ctime || 0
|
ctime: entry.ctime || 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return FileSystem.BAD_NO_ENTRY;
|
return FileSystem.BAD_NOENTRY;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -52,17 +70,45 @@ function startup()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = FileSystem.BAD_NO_ENTRY;
|
result = FileSystem.BAD_NOENTRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FileSystem.prototype.open = function(path, mode) {
|
||||||
|
var result = FileSystem.BAD_NOENTRY;
|
||||||
|
var entry = this.getEntry(path);
|
||||||
|
|
||||||
|
if (entry.type == "file") {
|
||||||
|
result = ((mode & FileSystem.O_ACCMODE) == FileSystem.O_RDONLY) ? true : FileSystem.BAD_NOACCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
FileSystem.prototype.read = function(path, offset, length) {
|
||||||
|
var result = FileSystem.BAD_NOENTRY;
|
||||||
|
var entry = this.getEntry(path);
|
||||||
|
|
||||||
|
if (entry.type == "file") {
|
||||||
|
var end = Math.min(offset + length, entry.contents.length);
|
||||||
|
var data = (offset < entry.contents.length) ? entry.contents.substring(offset, end) : "";
|
||||||
|
result = {
|
||||||
|
data: data,
|
||||||
|
format: "identity",
|
||||||
|
count: data.length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
var fs = new FileSystem({
|
var fs = new FileSystem({
|
||||||
mode: 0755,
|
mode: 0755,
|
||||||
type: "dir",
|
type: "dir",
|
||||||
entries: {
|
entries: {
|
||||||
"hello": { mode: 0755, type: "file", size: 10, contents: "Hello, World!"}
|
"hello": { mode: 0755, type: "file", /* size: 10 , */contents: "Hello, World!"}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -74,13 +120,13 @@ function startup()
|
|||||||
console.log('close');
|
console.log('close');
|
||||||
};
|
};
|
||||||
ws.onmessage = function(message) {
|
ws.onmessage = function(message) {
|
||||||
console.log(message);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var request = JSON.parse(message.data);
|
var request = JSON.parse(message.data);
|
||||||
var result = -42;
|
var result = -42;
|
||||||
var response;
|
var response;
|
||||||
|
|
||||||
|
console.log(request);
|
||||||
if (("string" === typeof(request.method)) &&
|
if (("string" === typeof(request.method)) &&
|
||||||
("number" === typeof(request.id)) &&
|
("number" === typeof(request.id)) &&
|
||||||
(request.params)) {
|
(request.params)) {
|
||||||
@ -92,6 +138,12 @@ function startup()
|
|||||||
case "readdir":
|
case "readdir":
|
||||||
result = fs.readdir(request.params[0]);
|
result = fs.readdir(request.params[0]);
|
||||||
break;
|
break;
|
||||||
|
case "open":
|
||||||
|
result = fs.open(request.params[0], request.params[1]);
|
||||||
|
break;
|
||||||
|
case "read":
|
||||||
|
result = fs.read(request.params[0], request.params[1], request.params[2]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -106,7 +158,7 @@ function startup()
|
|||||||
ws.send(JSON.stringify(response));
|
ws.send(JSON.stringify(response));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ex) { console.log(ex); }
|
catch (ex) { console.log(ex, message); }
|
||||||
};
|
};
|
||||||
|
|
||||||
var sendButton = document.getElementById('sendButton');
|
var sendButton = document.getElementById('sendButton');
|
||||||
|
@ -69,13 +69,14 @@ wsfs_status wsfs_filesystem_getattr(
|
|||||||
result->st_mode |= S_IFDIR;
|
result->st_mode |= S_IFDIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result->st_size = wsfs_json_get_int(data, "size", 0);
|
||||||
result->st_atime = wsfs_json_get_int(data, "atime", 0);
|
result->st_atime = wsfs_json_get_int(data, "atime", 0);
|
||||||
result->st_mtime = wsfs_json_get_int(data, "mtime", 0);
|
result->st_mtime = wsfs_json_get_int(data, "mtime", 0);
|
||||||
result->st_ctime = wsfs_json_get_int(data, "ctime", 0);
|
result->st_ctime = wsfs_json_get_int(data, "ctime", 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
status = WSFS_BAD_PARSEERROR;
|
status = WSFS_BAD_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -115,3 +116,90 @@ wsfs_status wsfs_filesystem_readdir(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wsfs_status wsfs_filesystem_open(
|
||||||
|
struct wsfs_filesystem * filesystem,
|
||||||
|
char const * path,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
json_t * result = NULL;
|
||||||
|
wsfs_status const status = wsfs_jsonrpc_invoke(filesystem->rpc, &result, "open", "si", path, flags);
|
||||||
|
if (NULL != result)
|
||||||
|
{
|
||||||
|
// unused
|
||||||
|
json_decref(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WSFS_MAX_READ_LENGTH 4096
|
||||||
|
|
||||||
|
static wsfs_status wsfs_fill_buffer(
|
||||||
|
char * buffer,
|
||||||
|
size_t buffer_size,
|
||||||
|
char const * format,
|
||||||
|
char const * data,
|
||||||
|
size_t count)
|
||||||
|
{
|
||||||
|
wsfs_status status = WSFS_GOOD;
|
||||||
|
|
||||||
|
size_t const copy_count = (buffer_size < count) ? buffer_size : count;
|
||||||
|
if (0 < copy_count)
|
||||||
|
{
|
||||||
|
if (0 == strcmp("identity", format))
|
||||||
|
{
|
||||||
|
memcpy(buffer, data, copy_count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = WSFS_BAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
wsfs_status wsfs_filesystem_read(
|
||||||
|
struct wsfs_filesystem * filesystem,
|
||||||
|
char const * path,
|
||||||
|
char * buffer,
|
||||||
|
size_t buffer_size,
|
||||||
|
size_t offset,
|
||||||
|
size_t * read_count)
|
||||||
|
{
|
||||||
|
int const length = (buffer_size <= WSFS_MAX_READ_LENGTH) ? (int) buffer_size : WSFS_MAX_READ_LENGTH;
|
||||||
|
*read_count = 0;
|
||||||
|
|
||||||
|
json_t * result = NULL;
|
||||||
|
wsfs_status status = wsfs_jsonrpc_invoke(filesystem->rpc, &result, "read", "sii", path, (int) offset, length);
|
||||||
|
if (NULL != result)
|
||||||
|
{
|
||||||
|
json_t * data_holder = json_object_get(result, "data");
|
||||||
|
json_t * format_holder = json_object_get(result, "format");
|
||||||
|
json_t * count_holder = json_object_get(result, "count");
|
||||||
|
|
||||||
|
if ((NULL != data_holder) && (json_is_string(data_holder)) &&
|
||||||
|
(NULL != format_holder) && (json_is_string(format_holder)) &&
|
||||||
|
(NULL != count_holder) && (json_is_integer(count_holder)))
|
||||||
|
{
|
||||||
|
char const * const data = json_string_value(data_holder);
|
||||||
|
char const * const format = json_string_value(format_holder);
|
||||||
|
size_t const count = (size_t) json_integer_value(count_holder);
|
||||||
|
|
||||||
|
status = wsfs_fill_buffer(buffer, buffer_size, format, data, count);
|
||||||
|
if (WSFS_GOOD == status)
|
||||||
|
{
|
||||||
|
*read_count = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = WSFS_BAD_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_decref(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,18 @@ extern wsfs_status wsfs_filesystem_readdir(
|
|||||||
void * buffer,
|
void * buffer,
|
||||||
wsfs_add_entry_fn * add_entry);
|
wsfs_add_entry_fn * add_entry);
|
||||||
|
|
||||||
|
extern wsfs_status wsfs_filesystem_open(
|
||||||
|
struct wsfs_filesystem * filesystem,
|
||||||
|
char const * path,
|
||||||
|
int flags);
|
||||||
|
|
||||||
|
extern wsfs_status wsfs_filesystem_read(
|
||||||
|
struct wsfs_filesystem * filesystem,
|
||||||
|
char const * path,
|
||||||
|
char * buffer,
|
||||||
|
size_t buffer_size,
|
||||||
|
size_t offset,
|
||||||
|
size_t * read_count);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ static int wsfs_result_from_status(wsfs_status status)
|
|||||||
{
|
{
|
||||||
case WSFS_GOOD: return 0;
|
case WSFS_GOOD: return 0;
|
||||||
case WSFS_BAD_NOENTRY: return -ENOENT;
|
case WSFS_BAD_NOENTRY: return -ENOENT;
|
||||||
|
case WSFS_BAD_NOACCESS: return -EACCES;
|
||||||
default: return -ENOENT;
|
default: return -ENOENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,6 +94,38 @@ static int wsfs_operation_readdir(
|
|||||||
return wsfs_result_from_status(status);
|
return wsfs_result_from_status(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wsfs_operation_open(
|
||||||
|
char const *path,
|
||||||
|
struct fuse_file_info * file_info)
|
||||||
|
{
|
||||||
|
struct wsfs_filesystem * filesystem = wsfs_get_filesystem();
|
||||||
|
wsfs_status const status = wsfs_filesystem_open(filesystem, path, file_info->flags);
|
||||||
|
|
||||||
|
return wsfs_result_from_status(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wsfs_operation_read(
|
||||||
|
const char * path,
|
||||||
|
char * buffer,
|
||||||
|
size_t buffer_size,
|
||||||
|
off_t offset,
|
||||||
|
struct fuse_file_info * WSFS_UNUSED_PARAM(file_info))
|
||||||
|
{
|
||||||
|
struct wsfs_filesystem * filesystem = wsfs_get_filesystem();
|
||||||
|
|
||||||
|
size_t count;
|
||||||
|
wsfs_status const status = wsfs_filesystem_read(filesystem, path, buffer, buffer_size, offset, &count);
|
||||||
|
if (WSFS_GOOD == status)
|
||||||
|
{
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return wsfs_result_from_status(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void wsfs_operations_init(
|
void wsfs_operations_init(
|
||||||
struct fuse_operations * operations)
|
struct fuse_operations * operations)
|
||||||
{
|
{
|
||||||
@ -101,5 +134,7 @@ void wsfs_operations_init(
|
|||||||
operations->destroy = &wsfs_operation_destroy;
|
operations->destroy = &wsfs_operation_destroy;
|
||||||
operations->getattr = &wsfs_operation_getattr;
|
operations->getattr = &wsfs_operation_getattr;
|
||||||
operations->readdir = &wsfs_operation_readdir;
|
operations->readdir = &wsfs_operation_readdir;
|
||||||
|
operations->open = &wsfs_operation_open;
|
||||||
|
operations->read = &wsfs_operation_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,14 +12,14 @@ void wsfs_response_parse(
|
|||||||
json_t * response = json_loadb(buffer, length, 0, NULL);
|
json_t * response = json_loadb(buffer, length, 0, NULL);
|
||||||
if (NULL == response)
|
if (NULL == response)
|
||||||
{
|
{
|
||||||
result->status = WSFS_BAD_PARSEERROR;
|
result->status = WSFS_BAD_FORMAT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
json_t * id_holder = json_object_get(response, "id");
|
json_t * id_holder = json_object_get(response, "id");
|
||||||
if ((NULL == id_holder) || (!json_is_integer(id_holder)))
|
if ((NULL == id_holder) || (!json_is_integer(id_holder)))
|
||||||
{
|
{
|
||||||
result->status = WSFS_BAD_INVALIDID;
|
result->status = WSFS_BAD_FORMAT;
|
||||||
json_decref(response);
|
json_decref(response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ void wsfs_response_parse(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result->status = WSFS_BAD_NODATA;
|
result->status = WSFS_BAD_FORMAT;
|
||||||
|
|
||||||
json_t * error = json_object_get(response, "error");
|
json_t * error = json_object_get(response, "error");
|
||||||
if (NULL != error)
|
if (NULL != error)
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
#define _WSFS_STATUS_H
|
#define _WSFS_STATUS_H
|
||||||
|
|
||||||
#define WSFS_GOOD 0
|
#define WSFS_GOOD 0
|
||||||
#define WSFS_BAD 1
|
#define WSFS_BAD 1
|
||||||
|
|
||||||
|
#define WSFS_BAD_NOTIMPLEMENTED 2
|
||||||
|
#define WSFS_BAD_TIMEOUT 3
|
||||||
|
#define WSFS_BAD_FORMAT 4
|
||||||
|
|
||||||
#define WSFS_BAD_NOENTRY 101
|
#define WSFS_BAD_NOENTRY 101
|
||||||
#define WSFS_BAD_TIMEOUT 102
|
#define WSFS_BAD_NOACCESS 102
|
||||||
|
|
||||||
#define WSFS_BAD_PARSEERROR 200
|
|
||||||
#define WSFS_BAD_INVALIDID 201
|
|
||||||
#define WSFS_BAD_NODATA 202
|
|
||||||
|
|
||||||
typedef int wsfs_status;
|
typedef int wsfs_status;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user