mirror of
				https://github.com/falk-werner/webfuse
				synced 2025-06-13 12:54:15 +00:00 
			
		
		
		
	added implementation for access, getattr and readdir
This commit is contained in:
		
							parent
							
								
									7924fa1191
								
							
						
					
					
						commit
						0a513322b7
					
				@ -23,7 +23,8 @@ add_library(webfuse_static STATIC
 | 
				
			|||||||
    src/webfuse/filesystem/empty_filesystem.cpp
 | 
					    src/webfuse/filesystem/empty_filesystem.cpp
 | 
				
			||||||
    src/webfuse/ws/config.cpp
 | 
					    src/webfuse/ws/config.cpp
 | 
				
			||||||
    src/webfuse/ws/server.cpp
 | 
					    src/webfuse/ws/server.cpp
 | 
				
			||||||
    src/webfuse/ws/message.cpp
 | 
					    src/webfuse/ws/messagewriter.cpp
 | 
				
			||||||
 | 
					    src/webfuse/ws/messagereader.cpp
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_include_directories(webfuse_static PUBLIC src)
 | 
					target_include_directories(webfuse_static PUBLIC src)
 | 
				
			||||||
 | 
				
			|||||||
@ -98,11 +98,24 @@ class MessageWriter:
 | 
				
			|||||||
        self.buffer.append(value)
 | 
					        self.buffer.append(value)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    def write_u32(self, value):
 | 
					    def write_u32(self, value):
 | 
				
			||||||
        a = (value >> 24) & 0xff
 | 
					        self.buffer.extend([
 | 
				
			||||||
        b = (value >> 16) & 0xff
 | 
					            (value >> 24) & 0xff,
 | 
				
			||||||
        c = (value >>  8) & 0xff
 | 
					            (value >> 16) & 0xff,
 | 
				
			||||||
        d = value         & 0xff
 | 
					            (value >>  8) & 0xff,
 | 
				
			||||||
        self.buffer.extend([a, b, c, d])
 | 
					             value        & 0xff
 | 
				
			||||||
 | 
					        ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def write_u64(self, value):
 | 
				
			||||||
 | 
					        self.buffer.extend([
 | 
				
			||||||
 | 
					            (value >> 56) & 0xff,
 | 
				
			||||||
 | 
					            (value >> 48) & 0xff,
 | 
				
			||||||
 | 
					            (value >> 40) & 0xff,
 | 
				
			||||||
 | 
					            (value >> 32) & 0xff,
 | 
				
			||||||
 | 
					            (value >> 24) & 0xff,
 | 
				
			||||||
 | 
					            (value >> 16) & 0xff,
 | 
				
			||||||
 | 
					            (value >>  8) & 0xff,
 | 
				
			||||||
 | 
					             value        & 0xff
 | 
				
			||||||
 | 
					        ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def write_i32(self, value):
 | 
					    def write_i32(self, value):
 | 
				
			||||||
        self.write_u32(value & 0xffffffff)
 | 
					        self.write_u32(value & 0xffffffff)
 | 
				
			||||||
@ -113,7 +126,23 @@ class MessageWriter:
 | 
				
			|||||||
                value = ERRNO[value]
 | 
					                value = ERRNO[value]
 | 
				
			||||||
        self.write_i32(value)
 | 
					        self.write_i32(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def write_str(self, value):
 | 
				
			||||||
 | 
					        data = value.encode('utf-8')
 | 
				
			||||||
 | 
					        self.write_bytes(data)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def write_bytes(self, value):
 | 
				
			||||||
 | 
					        size = len(value)
 | 
				
			||||||
 | 
					        self.write_u32(size)
 | 
				
			||||||
 | 
					        self.buffer.extend(value)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def write_strings(self, values):
 | 
				
			||||||
 | 
					        count = len(values)
 | 
				
			||||||
 | 
					        self.write_u32(count)
 | 
				
			||||||
 | 
					        for value in values:
 | 
				
			||||||
 | 
					            self.write_str(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_bytes(self):
 | 
					    def get_bytes(self):
 | 
				
			||||||
 | 
					        print(self.buffer)
 | 
				
			||||||
        return bytearray(self.buffer)
 | 
					        return bytearray(self.buffer)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -122,7 +151,9 @@ class FilesystemProvider:
 | 
				
			|||||||
        self.root = os.path.abspath(path)
 | 
					        self.root = os.path.abspath(path)
 | 
				
			||||||
        self.url = url
 | 
					        self.url = url
 | 
				
			||||||
        self.commands = {
 | 
					        self.commands = {
 | 
				
			||||||
            0x01: FilesystemProvider.access
 | 
					            0x01: FilesystemProvider.access,
 | 
				
			||||||
 | 
					            0x02: FilesystemProvider.getattr,
 | 
				
			||||||
 | 
					            0x13: FilesystemProvider.readdir
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    async def run(self):
 | 
					    async def run(self):
 | 
				
			||||||
@ -132,6 +163,7 @@ class FilesystemProvider:
 | 
				
			|||||||
                reader = MessageReader(request)
 | 
					                reader = MessageReader(request)
 | 
				
			||||||
                message_id = reader.read_u32()
 | 
					                message_id = reader.read_u32()
 | 
				
			||||||
                message_type = reader.read_u8()
 | 
					                message_type = reader.read_u8()
 | 
				
			||||||
 | 
					                print("received message: id=%d, type=%d" % (message_id, message_type))
 | 
				
			||||||
                writer = MessageWriter(message_id, RESPONSE + message_type)
 | 
					                writer = MessageWriter(message_id, RESPONSE + message_type)
 | 
				
			||||||
                if message_type in self.commands:
 | 
					                if message_type in self.commands:
 | 
				
			||||||
                    method = self.commands[message_type]
 | 
					                    method = self.commands[message_type]
 | 
				
			||||||
@ -152,6 +184,43 @@ class FilesystemProvider:
 | 
				
			|||||||
            result = -ex.errno
 | 
					            result = -ex.errno
 | 
				
			||||||
        writer.write_result(result)
 | 
					        writer.write_result(result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def getattr(self, reader, writer):
 | 
				
			||||||
 | 
					        path = reader.read_path(self.root)
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            attr = os.lstat(path)
 | 
				
			||||||
 | 
					        except OSError as ex:
 | 
				
			||||||
 | 
					            writer.write_result(-ex.errno)
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        writer.write_result(0)
 | 
				
			||||||
 | 
					        writer.write_u64(attr.st_ino)
 | 
				
			||||||
 | 
					        writer.write_u64(attr.st_nlink)
 | 
				
			||||||
 | 
					        writer.write_u32(attr.st_mode)
 | 
				
			||||||
 | 
					        writer.write_i32(attr.st_uid)
 | 
				
			||||||
 | 
					        writer.write_i32(attr.st_gid)
 | 
				
			||||||
 | 
					        writer.write_u64(attr.st_dev)
 | 
				
			||||||
 | 
					        writer.write_u64(attr.st_size)
 | 
				
			||||||
 | 
					        writer.write_u64(attr.st_blocks)
 | 
				
			||||||
 | 
					        writer.write_u64(int(attr.st_atime))
 | 
				
			||||||
 | 
					        writer.write_u32(attr.st_atime_ns)
 | 
				
			||||||
 | 
					        writer.write_u64(int(attr.st_mtime))
 | 
				
			||||||
 | 
					        writer.write_u32(attr.st_mtime_ns)
 | 
				
			||||||
 | 
					        writer.write_u64(int(attr.st_ctime))
 | 
				
			||||||
 | 
					        writer.write_u32(attr.st_ctime_ns)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def readdir(self, reader, writer):
 | 
				
			||||||
 | 
					        path = reader.read_path(self.root)
 | 
				
			||||||
 | 
					        names = []
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            with os.scandir(path) as it:
 | 
				
			||||||
 | 
					                for entry in it:
 | 
				
			||||||
 | 
					                    names.append(entry.name)
 | 
				
			||||||
 | 
					        except OSError as ex:
 | 
				
			||||||
 | 
					            writer.write_result(-ex.errno)
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        writer.write_result(0)
 | 
				
			||||||
 | 
					        writer.write_strings(names)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
    provider = FilesystemProvider('.', 'ws://localhost:8081')
 | 
					    provider = FilesystemProvider('.', 'ws://localhost:8081')
 | 
				
			||||||
    asyncio.run(provider.run())
 | 
					    asyncio.run(provider.run())
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
#include "webfuse/filesystem.hpp"
 | 
					#include "webfuse/filesystem.hpp"
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace webfuse
 | 
					namespace webfuse
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -14,15 +15,15 @@ filesystem::~filesystem()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::access(std::string const & path, access_mode mode)
 | 
					int filesystem::access(std::string const & path, int mode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::access_req);
 | 
					        messagewriter req(message_type::access_req);
 | 
				
			||||||
        req.add_str(path);
 | 
					        req.write_str(path);
 | 
				
			||||||
        req.add_i8(mode);
 | 
					        req.write_access_mode(mode);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        auto reader = proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return reader.read_result();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -30,27 +31,34 @@ status filesystem::access(std::string const & path, access_mode mode)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::getattr(std::string const & path, file_attributes & attr)
 | 
					int filesystem::getattr(std::string const & path, struct stat * attr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::getattr_req);
 | 
					        messagewriter req(message_type::getattr_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        req.write_str(path);
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        auto reader = proxy.perform(std::move(req));
 | 
				
			||||||
 | 
					        int const result = reader.read_result();
 | 
				
			||||||
 | 
					        if (0 == result)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            reader.read_attr(attr);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        puts("getattr: failed");
 | 
				
			||||||
        return fallback.getattr(path, attr);
 | 
					        return fallback.getattr(path, attr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::readlink(std::string const & path, std::string & out)
 | 
					int filesystem::readlink(std::string const & path, std::string & out)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::readlink_req);
 | 
					        messagewriter req(message_type::readlink_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -58,13 +66,13 @@ status filesystem::readlink(std::string const & path, std::string & out)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::symlink(std::string const & target, std::string const & linkpath)
 | 
					int filesystem::symlink(std::string const & target, std::string const & linkpath)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::symlink_req);
 | 
					        messagewriter req(message_type::symlink_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -72,13 +80,13 @@ status filesystem::symlink(std::string const & target, std::string const & linkp
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::link(std::string const & old_path, std::string const & new_path)
 | 
					int filesystem::link(std::string const & old_path, std::string const & new_path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::link_req);
 | 
					        messagewriter req(message_type::link_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -86,27 +94,27 @@ status filesystem::link(std::string const & old_path, std::string const & new_pa
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::rename(std::string const & old_path, std::string const & new_path)
 | 
					int filesystem::rename(std::string const & old_path, std::string const & new_path, int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::rename_req);
 | 
					        messagewriter req(message_type::rename_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return fallback.rename(old_path, new_path);
 | 
					        return fallback.rename(old_path, new_path, flags);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::chmod(std::string const & path, filemode mode)
 | 
					int filesystem::chmod(std::string const & path, mode_t mode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::chmod_req);
 | 
					        messagewriter req(message_type::chmod_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -114,13 +122,13 @@ status filesystem::chmod(std::string const & path, filemode mode)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::chown(std::string const & path, user_id uid, group_id gid)
 | 
					int filesystem::chown(std::string const & path, uid_t uid, gid_t gid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::chown_req);
 | 
					        messagewriter req(message_type::chown_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -128,27 +136,27 @@ status filesystem::chown(std::string const & path, user_id uid, group_id gid)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::truncate(std::string const & path, uint64_t offset, filehandle handle)
 | 
					int filesystem::truncate(std::string const & path, uint64_t size, uint64_t handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::truncate_req);
 | 
					        messagewriter req(message_type::truncate_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return fallback.truncate(path, offset, handle);
 | 
					        return fallback.truncate(path, size, handle);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::fsync(std::string const & path, bool is_datasync, filehandle handle)
 | 
					int filesystem::fsync(std::string const & path, bool is_datasync, uint64_t handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::fsync_req);
 | 
					        messagewriter req(message_type::fsync_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -156,13 +164,13 @@ status filesystem::fsync(std::string const & path, bool is_datasync, filehandle
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::open(std::string const & path, openflags flags, filehandle & handle)
 | 
					int filesystem::open(std::string const & path, int flags, uint64_t & handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::open_req);
 | 
					        messagewriter req(message_type::open_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -170,13 +178,13 @@ status filesystem::open(std::string const & path, openflags flags, filehandle &
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::mknod(std::string const & path, filemode mode, uint64_t rdev)
 | 
					int filesystem::mknod(std::string const & path, mode_t mode, dev_t rdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::mknod_req);
 | 
					        messagewriter req(message_type::mknod_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -184,13 +192,13 @@ status filesystem::mknod(std::string const & path, filemode mode, uint64_t rdev)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::create(std::string const & path, filemode mode, filehandle & handle)
 | 
					int filesystem::create(std::string const & path, mode_t mode, uint64_t & handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::create_req);
 | 
					        messagewriter req(message_type::create_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -198,13 +206,13 @@ status filesystem::create(std::string const & path, filemode mode, filehandle &
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::release(std::string const & path, filehandle handle)
 | 
					int filesystem::release(std::string const & path, uint64_t handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::release_req);
 | 
					        messagewriter req(message_type::release_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -212,13 +220,13 @@ status filesystem::release(std::string const & path, filehandle handle)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::unlink(std::string const & path)
 | 
					int filesystem::unlink(std::string const & path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::unlink_req);
 | 
					        messagewriter req(message_type::unlink_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -226,13 +234,13 @@ status filesystem::unlink(std::string const & path)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::read(std::string const & path, char * buffer, size_t buffer_size, uint64_t offset, filehandle handle)
 | 
					int filesystem::read(std::string const & path, char * buffer, size_t buffer_size, uint64_t offset, uint64_t handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::read_req);
 | 
					        messagewriter req(message_type::read_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -240,13 +248,13 @@ status filesystem::read(std::string const & path, char * buffer, size_t buffer_s
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::write(std::string const & path, char const * buffer, size_t buffer_size, uint64_t offset, filehandle handle)
 | 
					int filesystem::write(std::string const & path, char const * buffer, size_t buffer_size, uint64_t offset, uint64_t handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::write_req);
 | 
					        messagewriter req(message_type::write_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -254,13 +262,13 @@ status filesystem::write(std::string const & path, char const * buffer, size_t b
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::mkdir(std::string const & path, filemode mode)
 | 
					int filesystem::mkdir(std::string const & path, mode_t mode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::mkdir_req);
 | 
					        messagewriter req(message_type::mkdir_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -268,13 +276,19 @@ status filesystem::mkdir(std::string const & path, filemode mode)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::readdir(std::string const & path, std::vector<std::string> & entries, filehandle handle)
 | 
					int filesystem::readdir(std::string const & path, std::vector<std::string> & entries, uint64_t handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::readdir_req);
 | 
					        messagewriter req(message_type::readdir_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        req.write_str(path);        
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        auto resp = proxy.perform(std::move(req));
 | 
				
			||||||
 | 
					        int result = resp.read_result();
 | 
				
			||||||
 | 
					        if (0 == result)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            resp.read_strings(entries);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -282,13 +296,13 @@ status filesystem::readdir(std::string const & path, std::vector<std::string> &
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::rmdir(std::string const & path)
 | 
					int filesystem::rmdir(std::string const & path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::rmdir_req);
 | 
					        messagewriter req(message_type::rmdir_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -296,13 +310,13 @@ status filesystem::rmdir(std::string const & path)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status filesystem::statfs(std::string const & path, filesystem_statistics & statistics)
 | 
					int filesystem::statfs(std::string const & path, struct statvfs * statistics)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        message req(message_type::statfs_req);
 | 
					        messagewriter req(message_type::statfs_req);
 | 
				
			||||||
        proxy.perform(std::move(req));
 | 
					        proxy.perform(std::move(req));
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(...)
 | 
					    catch(...)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
@ -18,33 +18,33 @@ public:
 | 
				
			|||||||
    explicit filesystem(ws_server& server);
 | 
					    explicit filesystem(ws_server& server);
 | 
				
			||||||
    ~filesystem() override;
 | 
					    ~filesystem() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    status access(std::string const & path, access_mode mode) override;
 | 
					    int access(std::string const & path, int mode) override;
 | 
				
			||||||
    status getattr(std::string const & path, file_attributes & attr) override;
 | 
					    int getattr(std::string const & path, struct stat * attr) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    status readlink(std::string const & path, std::string & out) override;
 | 
					    int readlink(std::string const & path, std::string & out) override;
 | 
				
			||||||
    status symlink(std::string const & target, std::string const & linkpath) override;
 | 
					    int symlink(std::string const & target, std::string const & linkpath) override;
 | 
				
			||||||
    status link(std::string const & old_path, std::string const & new_path) override;
 | 
					    int link(std::string const & old_path, std::string const & new_path) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    status rename(std::string const & old_path, std::string const & new_path) override;
 | 
					    int rename(std::string const & old_path, std::string const & new_path, int flags) override;
 | 
				
			||||||
    status chmod(std::string const & path, filemode mode) override;
 | 
					    int chmod(std::string const & path, mode_t mode) override;
 | 
				
			||||||
    status chown(std::string const & path, user_id uid, group_id gid) override;
 | 
					    int chown(std::string const & path, uid_t uid, gid_t gid) override;
 | 
				
			||||||
    status truncate(std::string const & path, uint64_t offset, filehandle handle) override;
 | 
					    int truncate(std::string const & path, uint64_t size, uint64_t handle) override;
 | 
				
			||||||
    status fsync(std::string const & path, bool is_datasync, filehandle handle) override;
 | 
					    int fsync(std::string const & path, bool is_datasync, uint64_t handle) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    status open(std::string const & path, openflags flags, filehandle & handle) override;
 | 
					    int open(std::string const & path, int flags, uint64_t & handle) override;
 | 
				
			||||||
    status mknod(std::string const & path, filemode mode, uint64_t rdev) override;
 | 
					    int mknod(std::string const & path, mode_t mode, dev_t rdev) override;
 | 
				
			||||||
    status create(std::string const & path, filemode mode, filehandle & handle) override;
 | 
					    int create(std::string const & path, mode_t mode, uint64_t & handle) override;
 | 
				
			||||||
    status release(std::string const & path, filehandle handle) override;
 | 
					    int release(std::string const & path, uint64_t handle) override;
 | 
				
			||||||
    status unlink(std::string const & path) override;
 | 
					    int unlink(std::string const & path) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    status read(std::string const & path, char * buffer, size_t buffer_size, uint64_t offset, filehandle handle) override;
 | 
					    int read(std::string const & path, char * buffer, size_t buffer_size, uint64_t offset, uint64_t handle) override;
 | 
				
			||||||
    status write(std::string const & path, char const * buffer, size_t buffer_size, uint64_t offset, filehandle handle) override;
 | 
					    int write(std::string const & path, char const * buffer, size_t buffer_size, uint64_t offset, uint64_t handle) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    status mkdir(std::string const & path, filemode mode) override;
 | 
					    int mkdir(std::string const & path, mode_t mode) override;
 | 
				
			||||||
    status readdir(std::string const & path, std::vector<std::string> & entries, filehandle handle) override;
 | 
					    int readdir(std::string const & path, std::vector<std::string> & entries, uint64_t handle) override;
 | 
				
			||||||
    status rmdir(std::string const & path) override;
 | 
					    int rmdir(std::string const & path) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    status statfs(std::string const & path, filesystem_statistics & statistics) override;
 | 
					    int statfs(std::string const & path, struct statvfs * statistics) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
				
			|||||||
@ -1,134 +1,135 @@
 | 
				
			|||||||
#include "webfuse/filesystem/empty_filesystem.hpp"
 | 
					#include "webfuse/filesystem/empty_filesystem.hpp"
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace webfuse
 | 
					namespace webfuse
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::access(std::string const & path, access_mode mode)
 | 
					int empty_filesystem::access(std::string const & path, int mode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (path == "/")
 | 
					    if (path == "/")
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return status::good;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::getattr(std::string const & path, file_attributes & attr)
 | 
					int empty_filesystem::getattr(std::string const & path, struct stat * attr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (path == "/")
 | 
					    if (path == "/")
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        attr.inode = 1;
 | 
					        attr->st_ino = 1;
 | 
				
			||||||
        attr.nlink = 1;
 | 
					        attr->st_nlink = 1;
 | 
				
			||||||
        attr.mode = filemode(filemode::dir | 0x444);
 | 
					        attr->st_mode = S_IFDIR | 0x444;
 | 
				
			||||||
        return status::good;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::readlink(std::string const & path, std::string & out)
 | 
					int empty_filesystem::readlink(std::string const & path, std::string & out)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_enoent;
 | 
					    return -ENOENT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::symlink(std::string const & target, std::string const & linkpath)
 | 
					int empty_filesystem::symlink(std::string const & target, std::string const & linkpath)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_enoent;
 | 
					    return -ENOENT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::link(std::string const & old_path, std::string const & new_path)
 | 
					int empty_filesystem::link(std::string const & old_path, std::string const & new_path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_enoent;
 | 
					    return -ENOENT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::rename(std::string const & old_path, std::string const & new_path)
 | 
					int empty_filesystem::rename(std::string const & old_path, std::string const & new_path, int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_enoent;
 | 
					    return -ENOENT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::chmod(std::string const & path, filemode mode)
 | 
					int empty_filesystem::chmod(std::string const & path, mode_t mode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_eperm;
 | 
					    return -EPERM;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::chown(std::string const & path, user_id uid, group_id gid)
 | 
					int empty_filesystem::chown(std::string const & path, uid_t uid, gid_t gid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_eperm;
 | 
					    return -EPERM;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::truncate(std::string const & path, uint64_t offset, filehandle handle)
 | 
					int empty_filesystem::truncate(std::string const & path, uint64_t size, uint64_t handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_eperm;
 | 
					    return -EPERM;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::fsync(std::string const & path, bool is_datasync, filehandle handle)
 | 
					int empty_filesystem::fsync(std::string const & path, bool is_datasync, uint64_t handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::good;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::open(std::string const & path, openflags flags, filehandle & handle)
 | 
					int empty_filesystem::open(std::string const & path, int flags, uint64_t & handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_enoent;
 | 
					    return -ENOENT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::mknod(std::string const & path, filemode mode, uint64_t rdev)
 | 
					int empty_filesystem::mknod(std::string const & path, mode_t mode, dev_t rdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_eperm;
 | 
					    return -EPERM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
status empty_filesystem::create(std::string const & path, filemode mode, filehandle & handle)
 | 
					int empty_filesystem::create(std::string const & path, mode_t mode, uint64_t & handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_eperm;
 | 
					    return -EPERM;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::release(std::string const & path, filehandle handle)
 | 
					int empty_filesystem::release(std::string const & path, uint64_t handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::good;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::unlink(std::string const & path)
 | 
					int empty_filesystem::unlink(std::string const & path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_eperm;
 | 
					    return -EPERM;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::read(std::string const & path, char * buffer, size_t buffer_size, uint64_t offset, filehandle handle)
 | 
					int empty_filesystem::read(std::string const & path, char * buffer, size_t buffer_size, uint64_t offset, uint64_t handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_ebadf;
 | 
					    return -EBADF;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
status empty_filesystem::write(std::string const & path, char const * buffer, size_t buffer_size, uint64_t offset, filehandle handle)
 | 
					int empty_filesystem::write(std::string const & path, char const * buffer, size_t buffer_size, uint64_t offset, uint64_t handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_ebadf;
 | 
					    return -EBADF;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::mkdir(std::string const & path, filemode mode)
 | 
					int empty_filesystem::mkdir(std::string const & path, mode_t mode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_eperm;
 | 
					    return -EPERM;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::readdir(std::string const & path, std::vector<std::string> & entries, filehandle handle)
 | 
					int empty_filesystem::readdir(std::string const & path, std::vector<std::string> & entries, uint64_t handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (path == "/")
 | 
					    if (path == "/")
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return status::good;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return status::bad_enoent;
 | 
					        return -ENOENT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::rmdir(std::string const & path)
 | 
					int empty_filesystem::rmdir(std::string const & path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_eperm;
 | 
					    return -EPERM;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
status empty_filesystem::statfs(std::string const & path, filesystem_statistics & statistics)
 | 
					int empty_filesystem::statfs(std::string const & path, struct statvfs * statistics)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return status::bad_enosys;
 | 
					    return -ENOSYS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -11,33 +11,33 @@ class empty_filesystem: public filesystem_i
 | 
				
			|||||||
public:
 | 
					public:
 | 
				
			||||||
    ~empty_filesystem() override = default;
 | 
					    ~empty_filesystem() override = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    status access(std::string const & path, access_mode mode) override;
 | 
					    int access(std::string const & path, int mode) override;
 | 
				
			||||||
    status getattr(std::string const & path, file_attributes & attr) override;
 | 
					    int getattr(std::string const & path, struct stat * attr) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    status readlink(std::string const & path, std::string & out) override;
 | 
					    int readlink(std::string const & path, std::string & out) override;
 | 
				
			||||||
    status symlink(std::string const & target, std::string const & linkpath) override;
 | 
					    int symlink(std::string const & target, std::string const & linkpath) override;
 | 
				
			||||||
    status link(std::string const & old_path, std::string const & new_path) override;
 | 
					    int link(std::string const & old_path, std::string const & new_path) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    status rename(std::string const & old_path, std::string const & new_path) override;
 | 
					    int rename(std::string const & old_path, std::string const & new_path, int flags) override;
 | 
				
			||||||
    status chmod(std::string const & path, filemode mode) override;
 | 
					    int chmod(std::string const & path, mode_t mode) override;
 | 
				
			||||||
    status chown(std::string const & path, user_id uid, group_id gid) override;
 | 
					    int chown(std::string const & path, uid_t uid, gid_t gid) override;
 | 
				
			||||||
    status truncate(std::string const & path, uint64_t offset, filehandle handle) override;
 | 
					    int truncate(std::string const & path, uint64_t size, uint64_t handle) override;
 | 
				
			||||||
    status fsync(std::string const & path, bool is_datasync, filehandle handle) override;
 | 
					    int fsync(std::string const & path, bool is_datasync, uint64_t handle) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    status open(std::string const & path, openflags flags, filehandle & handle) override;
 | 
					    int open(std::string const & path, int flags, uint64_t & handle) override;
 | 
				
			||||||
    status mknod(std::string const & path, filemode mode, uint64_t rdev) override;
 | 
					    int mknod(std::string const & path, mode_t mode, dev_t rdev) override;
 | 
				
			||||||
    status create(std::string const & path, filemode mode, filehandle & handle) override;
 | 
					    int create(std::string const & path, mode_t mode, uint64_t & handle) override;
 | 
				
			||||||
    status release(std::string const & path, filehandle handle) override;
 | 
					    int release(std::string const & path, uint64_t handle) override;
 | 
				
			||||||
    status unlink(std::string const & path) override;
 | 
					    int unlink(std::string const & path) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    status read(std::string const & path, char * buffer, size_t buffer_size, uint64_t offset, filehandle handle) override;
 | 
					    int read(std::string const & path, char * buffer, size_t buffer_size, uint64_t offset, uint64_t handle) override;
 | 
				
			||||||
    status write(std::string const & path, char const * buffer, size_t buffer_size, uint64_t offset, filehandle handle) override;
 | 
					    int write(std::string const & path, char const * buffer, size_t buffer_size, uint64_t offset, uint64_t handle) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    status mkdir(std::string const & path, filemode mode) override;
 | 
					    int mkdir(std::string const & path, mode_t mode) override;
 | 
				
			||||||
    status readdir(std::string const & path, std::vector<std::string> & entries, filehandle handle) override;
 | 
					    int readdir(std::string const & path, std::vector<std::string> & entries, uint64_t handle) override;
 | 
				
			||||||
    status rmdir(std::string const & path) override;
 | 
					    int rmdir(std::string const & path) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    status statfs(std::string const & path, filesystem_statistics & statistics) override;
 | 
					    int statfs(std::string const & path, struct statvfs * statistivs) override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,15 +1,10 @@
 | 
				
			|||||||
#ifndef WEBFUSE_FILESYSTEM_I_HPP
 | 
					#ifndef WEBFUSE_FILESYSTEM_I_HPP
 | 
				
			||||||
#define WEBFUSE_FILESYSTEM_I_HPP
 | 
					#define WEBFUSE_FILESYSTEM_I_HPP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "webfuse/filesystem/filehandle.hpp"
 | 
					#include <sys/types.h>
 | 
				
			||||||
#include "webfuse/filesystem/accessmode.hpp"
 | 
					#include <sys/stat.h>
 | 
				
			||||||
#include "webfuse/filesystem/filemode.hpp"
 | 
					#include <sys/statvfs.h>
 | 
				
			||||||
#include "webfuse/filesystem/fileattributes.hpp"
 | 
					#include <unistd.h>
 | 
				
			||||||
#include "webfuse/filesystem/openflags.hpp"
 | 
					 | 
				
			||||||
#include "webfuse/filesystem/userid.hpp"
 | 
					 | 
				
			||||||
#include "webfuse/filesystem/groupid.hpp"
 | 
					 | 
				
			||||||
#include "webfuse/filesystem/status.hpp"
 | 
					 | 
				
			||||||
#include "webfuse/filesystem/filesystem_statistics.hpp"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <cinttypes>
 | 
					#include <cinttypes>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
@ -23,33 +18,33 @@ class filesystem_i
 | 
				
			|||||||
public:
 | 
					public:
 | 
				
			||||||
    virtual ~filesystem_i() = default;
 | 
					    virtual ~filesystem_i() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual status access(std::string const & path, access_mode mode) = 0;
 | 
					    virtual int access(std::string const & path, int mode) = 0;
 | 
				
			||||||
    virtual status getattr(std::string const & path, file_attributes & attr) = 0;
 | 
					    virtual int getattr(std::string const & path, struct stat * attr) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual status readlink(std::string const & path, std::string & out) = 0;
 | 
					    virtual int readlink(std::string const & path, std::string & out) = 0;
 | 
				
			||||||
    virtual status symlink(std::string const & target, std::string const & linkpath) = 0;
 | 
					    virtual int symlink(std::string const & target, std::string const & linkpath) = 0;
 | 
				
			||||||
    virtual status link(std::string const & old_path, std::string const & new_path) = 0;
 | 
					    virtual int link(std::string const & old_path, std::string const & new_path) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual status rename(std::string const & old_path, std::string const & new_path) = 0;
 | 
					    virtual int rename(std::string const & old_path, std::string const & new_path, int flags) = 0;
 | 
				
			||||||
    virtual status chmod(std::string const & path, filemode mode) = 0;
 | 
					    virtual int chmod(std::string const & path, mode_t mode) = 0;
 | 
				
			||||||
    virtual status chown(std::string const & path, user_id uid, group_id gid) = 0;
 | 
					    virtual int chown(std::string const & path, uid_t uid, gid_t gid) = 0;
 | 
				
			||||||
    virtual status truncate(std::string const & path, uint64_t offset, filehandle handle) = 0;
 | 
					    virtual int truncate(std::string const & path, uint64_t size, uint64_t handle) = 0;
 | 
				
			||||||
    virtual status fsync(std::string const & path, bool is_datasync, filehandle handle) = 0;
 | 
					    virtual int fsync(std::string const & path, bool is_datasync, uint64_t handle) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual status open(std::string const & path, openflags flags, filehandle & handle) = 0;
 | 
					    virtual int open(std::string const & path, int flags, uint64_t & handle) = 0;
 | 
				
			||||||
    virtual status mknod(std::string const & path, filemode mode, uint64_t rdev) = 0;
 | 
					    virtual int mknod(std::string const & path, mode_t mode, dev_t rdev) = 0;
 | 
				
			||||||
    virtual status create(std::string const & path, filemode mode, filehandle & handle) = 0;
 | 
					    virtual int create(std::string const & path, mode_t mode, uint64_t & handle) = 0;
 | 
				
			||||||
    virtual status release(std::string const & path, filehandle handle) = 0;
 | 
					    virtual int release(std::string const & path, uint64_t handle) = 0;
 | 
				
			||||||
    virtual status unlink(std::string const & path) = 0;
 | 
					    virtual int unlink(std::string const & path) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual status read(std::string const & path, char * buffer, size_t buffer_size, uint64_t offset, filehandle handle) = 0;
 | 
					    virtual int read(std::string const & path, char * buffer, size_t buffer_size, uint64_t offset, uint64_t handle) = 0;
 | 
				
			||||||
    virtual status write(std::string const & path, char const * buffer, size_t buffer_size, uint64_t offset, filehandle handle) = 0;
 | 
					    virtual int write(std::string const & path, char const * buffer, size_t buffer_size, uint64_t offset, uint64_t handle) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual status mkdir(std::string const & path, filemode mode) = 0;
 | 
					    virtual int mkdir(std::string const & path, mode_t mode) = 0;
 | 
				
			||||||
    virtual status readdir(std::string const & path, std::vector<std::string> & entries, filehandle handle) = 0;
 | 
					    virtual int readdir(std::string const & path, std::vector<std::string> & entries, uint64_t handle) = 0;
 | 
				
			||||||
    virtual status rmdir(std::string const & path) = 0;
 | 
					    virtual int rmdir(std::string const & path) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual status statfs(std::string const & path, filesystem_statistics & statistics) = 0;
 | 
					    virtual int statfs(std::string const & path, struct statvfs * statistics) = 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -15,9 +15,9 @@ static webfuse::filesystem_i * fs_get_filesystem()
 | 
				
			|||||||
    return reinterpret_cast<webfuse::filesystem_i*>(private_data);
 | 
					    return reinterpret_cast<webfuse::filesystem_i*>(private_data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static webfuse::filehandle fs_get_handle(fuse_file_info * info)
 | 
					static uint64_t fs_get_handle(fuse_file_info * info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return (nullptr != info) ? info->fh : webfuse::invalid_handle;
 | 
					    return (nullptr != info) ? info->fh : ((uint64_t) -1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void * fs_init(fuse_conn_info * connection, fuse_config * config)
 | 
					static void * fs_init(fuse_conn_info * connection, fuse_config * config)
 | 
				
			||||||
@ -33,24 +33,18 @@ static void * fs_init(fuse_conn_info * connection, fuse_config * config)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_access(char const * path, int raw_mode)
 | 
					static int fs_access(char const * path, int mode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    auto const mode = webfuse::access_mode::from_int(raw_mode);
 | 
					    return fs->access(path, mode);
 | 
				
			||||||
    auto const result = fs->access(path, mode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_getattr(char const * path, struct stat * buffer, fuse_file_info * info)
 | 
					static int fs_getattr(char const * path, struct stat * buffer, fuse_file_info * info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    (void) info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    webfuse::file_attributes attributes(*buffer);
 | 
					    return fs->getattr(path, buffer);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    auto const result = fs->getattr(path, attributes);
 | 
					 | 
				
			||||||
    attributes.to_stat(*buffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_readlink(char const * path, char * buffer, size_t buffer_size)
 | 
					static int fs_readlink(char const * path, char * buffer, size_t buffer_size)
 | 
				
			||||||
@ -59,63 +53,55 @@ static int fs_readlink(char const * path, char * buffer, size_t buffer_size)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    std::string out;
 | 
					    std::string out;
 | 
				
			||||||
    auto result = fs->readlink(path, out);
 | 
					    auto result = fs->readlink(path, out);
 | 
				
			||||||
    if (webfuse::status::good == result)
 | 
					    if (0 == result)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        snprintf(buffer, buffer_size, "%s", out.c_str());
 | 
					        snprintf(buffer, buffer_size, "%s", out.c_str());
 | 
				
			||||||
        result = strlen(buffer);
 | 
					        result = strlen(buffer);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					    return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_symlink(char const * target, char const * linkpath)
 | 
					static int fs_symlink(char const * target, char const * linkpath)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    auto const result = fs->symlink(target, linkpath);
 | 
					    return fs->symlink(target, linkpath);
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_link(char const * old_path, char const * new_path)
 | 
					static int fs_link(char const * old_path, char const * new_path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    auto const result = fs->link(old_path, new_path);
 | 
					    return fs->link(old_path, new_path);
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_rename(char const * from, char const * to, unsigned int flags)
 | 
					static int fs_rename(char const * from, char const * to, unsigned int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // ToDo: provide flags 
 | 
					 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    auto const result = fs->rename(from, to);
 | 
					    return fs->rename(from, to, flags);
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_chmod(char const * path, mode_t raw_mode, fuse_file_info * info)
 | 
					static int fs_chmod(char const * path, mode_t mode, fuse_file_info * info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    (void) info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    auto const mode = webfuse::filemode::from_mode(raw_mode);
 | 
					    return fs->chmod(path, mode);
 | 
				
			||||||
    auto const result = fs->chmod(path, mode);
 | 
					 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_chown(char const * path, uid_t raw_uid, 
 | 
					static int fs_chown(char const * path, uid_t uid, gid_t gid, fuse_file_info * info)
 | 
				
			||||||
    gid_t raw_gid, fuse_file_info * info)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    (void) info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    auto const uid = webfuse::user_id::from_uid(raw_uid);
 | 
					    return fs->chown(path, uid, gid);
 | 
				
			||||||
    auto const gid = webfuse::group_id::from_gid(raw_gid);
 | 
					 | 
				
			||||||
    auto const result = fs->chown(path, uid, gid);
 | 
					 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_truncate(char const * path, off_t raw_size, fuse_file_info * info)
 | 
					static int fs_truncate(char const * path, off_t size, fuse_file_info * info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    auto const size = static_cast<uint64_t>(raw_size);
 | 
					 | 
				
			||||||
    auto const handle = fs_get_handle(info);
 | 
					    auto const handle = fs_get_handle(info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto const result = fs->truncate(path, size, handle);
 | 
					    return fs->truncate(path, size, handle);
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_fsync(char const * path, int isdatasync, fuse_file_info * info)
 | 
					static int fs_fsync(char const * path, int isdatasync, fuse_file_info * info)
 | 
				
			||||||
@ -124,36 +110,30 @@ static int fs_fsync(char const * path, int isdatasync, fuse_file_info * info)
 | 
				
			|||||||
    bool const is_datasync = (is_datasync != 0);
 | 
					    bool const is_datasync = (is_datasync != 0);
 | 
				
			||||||
    auto const handle = fs_get_handle(info);
 | 
					    auto const handle = fs_get_handle(info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto const result = fs->fsync(path, is_datasync, handle);
 | 
					    return fs->fsync(path, is_datasync, handle);
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_open(char const * path, fuse_file_info * info)
 | 
					static int fs_open(char const * path, fuse_file_info * info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    auto const flags = webfuse::openflags::from_int(info->flags);
 | 
					    auto const flags = info->flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto const result = fs->open(path, flags, info->fh);
 | 
					    return fs->open(path, flags, info->fh);
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_mknod(char const * path, mode_t raw_mode, dev_t raw_rdev)
 | 
					static int fs_mknod(char const * path, mode_t mode, dev_t raw_rdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    auto const mode = webfuse::filemode::from_mode(raw_mode);
 | 
					 | 
				
			||||||
    auto const rdev = static_cast<uint64_t>(raw_rdev);
 | 
					    auto const rdev = static_cast<uint64_t>(raw_rdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto const result = fs->mknod(path, mode, rdev);
 | 
					    return fs->mknod(path, mode, rdev);
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_create(char const * path, mode_t raw_mode, fuse_file_info * info)
 | 
					static int fs_create(char const * path, mode_t mode, fuse_file_info * info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    auto const mode = webfuse::filemode::from_mode(raw_mode);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto const result = fs->create(path, mode, info->fh);
 | 
					    return fs->create(path, mode, info->fh);
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_release(char const * path, fuse_file_info * info)
 | 
					static int fs_release(char const * path, fuse_file_info * info)
 | 
				
			||||||
@ -161,15 +141,13 @@ static int fs_release(char const * path, fuse_file_info * info)
 | 
				
			|||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    auto const handle = fs_get_handle(info);
 | 
					    auto const handle = fs_get_handle(info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto const result = fs->release(path, handle);
 | 
					    return fs->release(path, handle);
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_unlink(char const * path)
 | 
					static int fs_unlink(char const * path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    auto const result = fs->unlink(path);
 | 
					    return fs->unlink(path);
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_read(char const * path, char * buffer,
 | 
					static int fs_read(char const * path, char * buffer,
 | 
				
			||||||
@ -180,8 +158,7 @@ static int fs_read(char const * path, char * buffer,
 | 
				
			|||||||
    auto const offset = static_cast<uint64_t>(raw_offset);
 | 
					    auto const offset = static_cast<uint64_t>(raw_offset);
 | 
				
			||||||
    auto const handle = fs_get_handle(info);
 | 
					    auto const handle = fs_get_handle(info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto const result = fs->read(path, buffer, buffer_size, offset, handle);
 | 
					    return fs->read(path, buffer, buffer_size, offset, handle);
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_write(char const * path, char const * buffer,
 | 
					static int fs_write(char const * path, char const * buffer,
 | 
				
			||||||
@ -192,17 +169,13 @@ static int fs_write(char const * path, char const * buffer,
 | 
				
			|||||||
    auto const offset = static_cast<uint64_t>(raw_offset);
 | 
					    auto const offset = static_cast<uint64_t>(raw_offset);
 | 
				
			||||||
    auto const handle = fs_get_handle(info);
 | 
					    auto const handle = fs_get_handle(info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto const result = fs->write(path, buffer, buffer_size, offset, handle);
 | 
					    return fs->write(path, buffer, buffer_size, offset, handle);
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_mkdir(char const * path, mode_t raw_mode)
 | 
					static int fs_mkdir(char const * path, mode_t mode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    auto const mode = webfuse::filemode::from_mode(raw_mode);
 | 
					    return fs->mkdir(path, mode);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    auto const result = fs->mkdir(path, mode);
 | 
					 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_readdir(char const * path, void * buffer, 
 | 
					static int fs_readdir(char const * path, void * buffer, 
 | 
				
			||||||
@ -213,7 +186,7 @@ static int fs_readdir(char const * path, void * buffer,
 | 
				
			|||||||
    auto handle = fs_get_handle(info);
 | 
					    auto handle = fs_get_handle(info);
 | 
				
			||||||
    std::vector<std::string> names;
 | 
					    std::vector<std::string> names;
 | 
				
			||||||
    auto const result = fs->readdir(path, names, handle);
 | 
					    auto const result = fs->readdir(path, names, handle);
 | 
				
			||||||
    if (result.is_good())
 | 
					    if (0 == result)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        filler(buffer, ".", nullptr, 0, static_cast<fuse_fill_dir_flags>(0));
 | 
					        filler(buffer, ".", nullptr, 0, static_cast<fuse_fill_dir_flags>(0));
 | 
				
			||||||
        filler(buffer, "..", nullptr, 0, static_cast<fuse_fill_dir_flags>(0));
 | 
					        filler(buffer, "..", nullptr, 0, static_cast<fuse_fill_dir_flags>(0));
 | 
				
			||||||
@ -223,26 +196,19 @@ static int fs_readdir(char const * path, void * buffer,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					    return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_rmdir(char const * path)
 | 
					static int fs_rmdir(char const * path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    auto const result = fs->rmdir(path);
 | 
					    return fs->rmdir(path);
 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fs_statfs(char const * path, struct statvfs * buffer)
 | 
					static int fs_statfs(char const * path, struct statvfs * buffer)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto * const fs = fs_get_filesystem();
 | 
					    auto * const fs = fs_get_filesystem();
 | 
				
			||||||
    webfuse::filesystem_statistics statistics(*buffer);
 | 
					    return fs->statfs(path, buffer);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    auto const result = fs->statfs(path, statistics);
 | 
					 | 
				
			||||||
    statistics.copy_to(*buffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return result.to_fusestatus();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,45 +0,0 @@
 | 
				
			|||||||
#ifndef WEBFUSE_MESSAGEBUILDER_HPP
 | 
					 | 
				
			||||||
#define WEBFUSE_MESSAGEBUILDER_HPP
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "webfuse/message_type.hpp"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <cinttypes>
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
#include <vector>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace webfuse
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class message
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    message(message const &) = delete;
 | 
					 | 
				
			||||||
    message& operator=(message const &) = delete;
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
    explicit message(message_type msg_type);
 | 
					 | 
				
			||||||
    ~message() = default;
 | 
					 | 
				
			||||||
    message(message && other);
 | 
					 | 
				
			||||||
    message& operator=(message && other);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void set_id(uint32_t value);
 | 
					 | 
				
			||||||
    uint32_t get_id() const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void add_bool(bool value);
 | 
					 | 
				
			||||||
    void add_u8(uint8_t value);
 | 
					 | 
				
			||||||
    void add_i8(int8_t value);
 | 
					 | 
				
			||||||
    void add_i32(int32_t value);
 | 
					 | 
				
			||||||
    void add_u32(uint32_t value);
 | 
					 | 
				
			||||||
    void add_u64(uint64_t value);
 | 
					 | 
				
			||||||
    void add_str(std::string const &value);
 | 
					 | 
				
			||||||
    void add_data(char const * buffer, size_t size);
 | 
					 | 
				
			||||||
    void add_strings(std::vector<std::string> const & list);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    unsigned char * get_data(size_t &size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
    uint32_t id;
 | 
					 | 
				
			||||||
    std::vector<uint8_t> data;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
							
								
								
									
										158
									
								
								src/webfuse/ws/messagereader.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								src/webfuse/ws/messagereader.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,158 @@
 | 
				
			|||||||
 | 
					#include "webfuse/ws/messagereader.hpp"
 | 
				
			||||||
 | 
					#include "webfuse/filesystem/status.hpp"
 | 
				
			||||||
 | 
					#include "webfuse/filesystem/fileattributes.hpp"
 | 
				
			||||||
 | 
					#include "webfuse/filesystem/filemode.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdexcept>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace webfuse
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					messagereader::messagereader(std::string & value)
 | 
				
			||||||
 | 
					: data(std::move(value))
 | 
				
			||||||
 | 
					, pos(0)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					messagereader::messagereader(messagereader && other)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    this->data = std::move(other.data);
 | 
				
			||||||
 | 
					    this->pos = other.pos;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					messagereader& messagereader::operator=(messagereader && other)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (this != &other)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        this->data = std::move(other.data);
 | 
				
			||||||
 | 
					        this->pos = other.pos;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int messagereader::read_result()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    status value(read_i32());
 | 
				
			||||||
 | 
					    return value.to_fusestatus();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void messagereader::read_attr(struct stat * attr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    attr->st_ino = static_cast<ino_t>(read_u64());
 | 
				
			||||||
 | 
					    attr->st_nlink = static_cast<nlink_t>(read_u64());
 | 
				
			||||||
 | 
					    attr->st_mode = read_mode();
 | 
				
			||||||
 | 
					    attr->st_uid = static_cast<uid_t>(read_u32());
 | 
				
			||||||
 | 
					    attr->st_gid = static_cast<gid_t>(read_u32());
 | 
				
			||||||
 | 
					    attr->st_rdev = static_cast<dev_t>(read_u64());
 | 
				
			||||||
 | 
					    attr->st_size = static_cast<off_t>(read_u64());
 | 
				
			||||||
 | 
					    attr->st_blocks = static_cast<blkcnt64_t>(read_u64());
 | 
				
			||||||
 | 
					    attr->st_atim.tv_sec = static_cast<time_t>(read_u64());
 | 
				
			||||||
 | 
					    attr->st_atim.tv_nsec = static_cast<long>(read_u32());
 | 
				
			||||||
 | 
					    attr->st_mtim.tv_sec = static_cast<time_t>(read_u64());
 | 
				
			||||||
 | 
					    attr->st_mtim.tv_nsec = static_cast<long>(read_u32());
 | 
				
			||||||
 | 
					    attr->st_ctim.tv_sec = static_cast<time_t>(read_u64());
 | 
				
			||||||
 | 
					    attr->st_ctim.tv_nsec = static_cast<long>(read_u32());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mode_t messagereader::read_mode()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    filemode mode(read_u32());
 | 
				
			||||||
 | 
					    return mode.to_mode();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t messagereader::read_u8()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (pos < data.size())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        uint8_t value = static_cast<uint8_t>(data[pos]);
 | 
				
			||||||
 | 
					        pos++;
 | 
				
			||||||
 | 
					        return value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        throw std::runtime_error("out of bounds");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t messagereader::read_u32()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if ((pos + 3) < data.size())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        uint32_t value = 
 | 
				
			||||||
 | 
					            ((static_cast<uint32_t>(data[pos    ]) & 0xff) << 24) |
 | 
				
			||||||
 | 
					            ((static_cast<uint32_t>(data[pos + 1]) & 0xff) << 16) |
 | 
				
			||||||
 | 
					            ((static_cast<uint32_t>(data[pos + 2]) & 0xff) <<  8) |
 | 
				
			||||||
 | 
					            ((static_cast<uint32_t>(data[pos + 3]) & 0xff)      );
 | 
				
			||||||
 | 
					        pos += 4;
 | 
				
			||||||
 | 
					        return value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        throw std::runtime_error("out of bounds");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint64_t messagereader::read_u64()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if ((pos + 7) < data.size())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        uint32_t value = 
 | 
				
			||||||
 | 
					            (static_cast<uint64_t>(data[pos    ] & 0xff) << 56) |
 | 
				
			||||||
 | 
					            (static_cast<uint64_t>(data[pos + 1] & 0xff) << 48) |
 | 
				
			||||||
 | 
					            (static_cast<uint64_t>(data[pos + 2] & 0xff) << 40) |
 | 
				
			||||||
 | 
					            (static_cast<uint64_t>(data[pos + 3] & 0xff) << 32) |
 | 
				
			||||||
 | 
					            (static_cast<uint64_t>(data[pos + 4] & 0xff) << 24) |
 | 
				
			||||||
 | 
					            (static_cast<uint64_t>(data[pos + 5] & 0xff) << 16) |
 | 
				
			||||||
 | 
					            (static_cast<uint64_t>(data[pos + 6] & 0xff) <<  8) |
 | 
				
			||||||
 | 
					            (static_cast<uint64_t>(data[pos + 7] & 0xff)      );
 | 
				
			||||||
 | 
					        pos += 8;
 | 
				
			||||||
 | 
					        return value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        throw std::runtime_error("out of bounds");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t messagereader::read_i32()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t value = read_u32();
 | 
				
			||||||
 | 
					    return static_cast<int32_t>(value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string messagereader::read_str()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return std::move(read_bytes());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string messagereader::read_bytes()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t size = read_u32();
 | 
				
			||||||
 | 
					    if ((pos + size) <= data.size())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::string const value(&data[pos], size);
 | 
				
			||||||
 | 
					        pos += size;
 | 
				
			||||||
 | 
					        return std::move(value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        throw std::runtime_error("out of bounds");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void messagereader::read_strings(std::vector<std::string> &entries)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t const count = read_u32();
 | 
				
			||||||
 | 
					    for(uint32_t i = 0; i < count; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::string entry = read_str();
 | 
				
			||||||
 | 
					        entries.push_back(entry);
 | 
				
			||||||
 | 
					    } 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,17 +1,43 @@
 | 
				
			|||||||
#ifndef WEBFUSE_MESSAGEREADER_HPP
 | 
					#ifndef WEBFUSE_MESSAGEREADER_HPP
 | 
				
			||||||
#define WEBFUSE_MESSAGEREADER_HPP
 | 
					#define WEBFUSE_MESSAGEREADER_HPP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cinttypes>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace webfuse
 | 
					namespace webfuse
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class messagereader
 | 
					class messagereader
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    messagereader(messagereader const &) = delete;
 | 
				
			||||||
 | 
					    messagereader& operator=(messagereader const &) = delete;
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    explicit messagereader(std::string && value);
 | 
					    explicit messagereader(std::string & value);
 | 
				
			||||||
    ~messagereader() = default;
 | 
					    ~messagereader() = default;
 | 
				
			||||||
 | 
					    messagereader(messagereader && other);
 | 
				
			||||||
 | 
					    messagereader& operator=(messagereader && other);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int read_result();
 | 
				
			||||||
 | 
					    void read_attr(struct stat * attr);
 | 
				
			||||||
 | 
					    mode_t read_mode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t read_u8();
 | 
				
			||||||
 | 
					    uint32_t read_u32();
 | 
				
			||||||
 | 
					    uint64_t read_u64();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int32_t read_i32();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string read_str();
 | 
				
			||||||
 | 
					    std::string read_bytes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void read_strings(std::vector<std::string> &entries);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    std::string data;
 | 
					    std::string data;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,24 +1,26 @@
 | 
				
			|||||||
#include "message.hpp"
 | 
					#include "webfuse/ws/messagewriter.hpp"
 | 
				
			||||||
 | 
					#include "webfuse/filesystem/accessmode.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <libwebsockets.h>
 | 
					#include <libwebsockets.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace webfuse
 | 
					namespace webfuse
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
message::message(message_type msg_type)
 | 
					messagewriter::messagewriter(message_type msg_type)
 | 
				
			||||||
: id(0)
 | 
					: id(0)
 | 
				
			||||||
, data(LWS_PRE)
 | 
					, data(LWS_PRE)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    add_u32(0);
 | 
					    write_u32(0);
 | 
				
			||||||
    add_u8(static_cast<uint8_t>(msg_type));
 | 
					    write_u8(static_cast<uint8_t>(msg_type));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
message::message(message && other)
 | 
					messagewriter::messagewriter(messagewriter && other)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    this->id = other.id;
 | 
					    this->id = other.id;
 | 
				
			||||||
    this->data = std::move(other.data);
 | 
					    this->data = std::move(other.data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
message& message::operator=(message && other)
 | 
					messagewriter& messagewriter::operator=(messagewriter && other)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (this != &other)
 | 
					    if (this != &other)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -29,41 +31,41 @@ message& message::operator=(message && other)
 | 
				
			|||||||
    return *this;
 | 
					    return *this;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void message::set_id(uint32_t value)
 | 
					void messagewriter::set_id(uint32_t value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    id = id;
 | 
					    id = value;
 | 
				
			||||||
    data[LWS_PRE    ] = (id >> 24) & 0xff;
 | 
					    data[LWS_PRE    ] = (id >> 24) & 0xff;
 | 
				
			||||||
    data[LWS_PRE + 1] = (id >> 16) & 0xff;
 | 
					    data[LWS_PRE + 1] = (id >> 16) & 0xff;
 | 
				
			||||||
    data[LWS_PRE + 2] = (id >>  8) & 0xff;
 | 
					    data[LWS_PRE + 2] = (id >>  8) & 0xff;
 | 
				
			||||||
    data[LWS_PRE + 3] =  id        & 0xff;
 | 
					    data[LWS_PRE + 3] =  id        & 0xff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint32_t message::get_id() const
 | 
					uint32_t messagewriter::get_id() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return id;
 | 
					    return id;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void message::add_bool(bool value)
 | 
					void messagewriter::write_bool(bool value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    data.push_back(value ? 0x01 : 0x00);
 | 
					    data.push_back(value ? 0x01 : 0x00);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void message::add_u8(uint8_t value)
 | 
					void messagewriter::write_u8(uint8_t value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    data.push_back(value);
 | 
					    data.push_back(value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void message::add_i8(int8_t value)
 | 
					void messagewriter::write_i8(int8_t value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    data.push_back(static_cast<uint8_t>(value));
 | 
					    data.push_back(static_cast<uint8_t>(value));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void message::add_i32(int32_t value)
 | 
					void messagewriter::write_i32(int32_t value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    add_u32((static_cast<uint32_t>(value)));
 | 
					    write_u32((static_cast<uint32_t>(value)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void message::add_u32(uint32_t value)
 | 
					void messagewriter::write_u32(uint32_t value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto const offset = data.size(); 
 | 
					    auto const offset = data.size(); 
 | 
				
			||||||
    data.resize(offset + 4);
 | 
					    data.resize(offset + 4);
 | 
				
			||||||
@ -73,7 +75,7 @@ void message::add_u32(uint32_t value)
 | 
				
			|||||||
    data[offset + 3] =  value        & 0xff;
 | 
					    data[offset + 3] =  value        & 0xff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void message::add_u64(uint64_t value)
 | 
					void messagewriter::write_u64(uint64_t value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto const offset = data.size(); 
 | 
					    auto const offset = data.size(); 
 | 
				
			||||||
    data.resize(offset + 8);
 | 
					    data.resize(offset + 8);
 | 
				
			||||||
@ -87,15 +89,15 @@ void message::add_u64(uint64_t value)
 | 
				
			|||||||
    data[offset + 7] =  value        & 0xff;
 | 
					    data[offset + 7] =  value        & 0xff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void message::add_str(std::string const &value)
 | 
					void messagewriter::write_str(std::string const &value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    add_data(value.data(), value.size());
 | 
					    write_data(value.data(), value.size());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void message::add_data(char const * buffer, size_t size)
 | 
					void messagewriter::write_data(char const * buffer, size_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t const effective_size = size & 0xffffffff;
 | 
					    uint32_t const effective_size = size & 0xffffffff;
 | 
				
			||||||
    add_u32(effective_size);
 | 
					    write_u32(effective_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (size > 0)
 | 
					    if (size > 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -107,17 +109,24 @@ void message::add_data(char const * buffer, size_t size)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void message::add_strings(std::vector<std::string> const & list)
 | 
					void messagewriter::write_strings(std::vector<std::string> const & list)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t const count = list.size() & 0xffffffff;
 | 
					    uint32_t const count = list.size() & 0xffffffff;
 | 
				
			||||||
    add_u32(count);
 | 
					    write_u32(count);
 | 
				
			||||||
    for (auto const & item: list)
 | 
					    for (auto const & item: list)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        add_str(item);
 | 
					        write_str(item);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned char * message::get_data(size_t &size)
 | 
					void messagewriter::write_access_mode(int value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    access_mode mode = access_mode::from_int(value);
 | 
				
			||||||
 | 
					    write_i8(mode);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned char * messagewriter::get_data(size_t &size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    size = data.size() - LWS_PRE;
 | 
					    size = data.size() - LWS_PRE;
 | 
				
			||||||
    void * result = reinterpret_cast<void *>(&data.data()[LWS_PRE]);
 | 
					    void * result = reinterpret_cast<void *>(&data.data()[LWS_PRE]);
 | 
				
			||||||
							
								
								
									
										47
									
								
								src/webfuse/ws/messagewriter.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/webfuse/ws/messagewriter.hpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					#ifndef WEBFUSE_MESSAGEWRITER_HPP
 | 
				
			||||||
 | 
					#define WEBFUSE_MESSAGEWRITER_HPP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "webfuse/message_type.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cinttypes>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace webfuse
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class messagewriter
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    messagewriter(messagewriter const &) = delete;
 | 
				
			||||||
 | 
					    messagewriter& operator=(messagewriter const &) = delete;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit messagewriter(message_type msg_type);
 | 
				
			||||||
 | 
					    ~messagewriter() = default;
 | 
				
			||||||
 | 
					    messagewriter(messagewriter && other);
 | 
				
			||||||
 | 
					    messagewriter& operator=(messagewriter && other);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void set_id(uint32_t value);
 | 
				
			||||||
 | 
					    uint32_t get_id() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void write_bool(bool value);
 | 
				
			||||||
 | 
					    void write_u8(uint8_t value);
 | 
				
			||||||
 | 
					    void write_i8(int8_t value);
 | 
				
			||||||
 | 
					    void write_i32(int32_t value);
 | 
				
			||||||
 | 
					    void write_u32(uint32_t value);
 | 
				
			||||||
 | 
					    void write_u64(uint64_t value);
 | 
				
			||||||
 | 
					    void write_str(std::string const &value);
 | 
				
			||||||
 | 
					    void write_data(char const * buffer, size_t size);
 | 
				
			||||||
 | 
					    void write_strings(std::vector<std::string> const & list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void write_access_mode(int value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsigned char * get_data(size_t &size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    uint32_t id;
 | 
				
			||||||
 | 
					    std::vector<uint8_t> data;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@ -1,5 +1,4 @@
 | 
				
			|||||||
#include "webfuse/ws/server.hpp"
 | 
					#include "webfuse/ws/server.hpp"
 | 
				
			||||||
#include "webfuse/ws/message.hpp"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <libwebsockets.h>
 | 
					#include <libwebsockets.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -25,10 +24,12 @@ namespace
 | 
				
			|||||||
struct user_data
 | 
					struct user_data
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct lws * connection = nullptr;
 | 
					    struct lws * connection = nullptr;
 | 
				
			||||||
 | 
					    std::string current_message;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::mutex mut;
 | 
					    std::mutex mut;
 | 
				
			||||||
    std::queue<webfuse::message> requests;
 | 
					    uint32_t id = 0;
 | 
				
			||||||
    std::unordered_map<uint32_t, std::promise<std::string>> pending_responses;
 | 
					    std::queue<webfuse::messagewriter> requests;
 | 
				
			||||||
 | 
					    std::unordered_map<uint32_t, std::promise<webfuse::messagereader>> pending_responses;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -68,11 +69,49 @@ static int ws_server_callback(struct lws *wsi, enum lws_callback_reasons reason,
 | 
				
			|||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case LWS_CALLBACK_RECEIVE:
 | 
					        case LWS_CALLBACK_RECEIVE:
 | 
				
			||||||
            std::cout << "lws: receive "<< std::endl;
 | 
					            std::cout << "lws: receive "<< std::endl;
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                auto * fragment = reinterpret_cast<char*>(in);
 | 
				
			||||||
 | 
					                data->current_message.append(fragment, len);
 | 
				
			||||||
 | 
					                if (lws_is_final_fragment(wsi))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    try
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        webfuse::messagereader reader(data->current_message);
 | 
				
			||||||
 | 
					                        uint32_t id = reader.read_u32();
 | 
				
			||||||
 | 
					                        uint8_t message_type = reader.read_u8();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        std::lock_guard lock(data->mut);
 | 
				
			||||||
 | 
					                        auto it = data->pending_responses.find(id);
 | 
				
			||||||
 | 
					                        if (it != data->pending_responses.end())
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            std::cout << "propagate message" << std::endl;
 | 
				
			||||||
 | 
					                            it->second.set_value(std::move(reader));
 | 
				
			||||||
 | 
					                            data->pending_responses.erase(it);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        else
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            // ToDo: log request not found
 | 
				
			||||||
 | 
					                            std::cout << "warning: request not found: id=" << id << std::endl;
 | 
				
			||||||
 | 
					                            for(auto const & entry: data->pending_responses)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                std::cout << "\t" << entry.first << std::endl;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    catch(...)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        // ToDo: log invalid message
 | 
				
			||||||
 | 
					                        std::cout << "warning: invalid message" << std::endl;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case LWS_CALLBACK_SERVER_WRITEABLE:
 | 
					        case LWS_CALLBACK_SERVER_WRITEABLE:
 | 
				
			||||||
            std::cout << "lws: server writable "<< std::endl;
 | 
					            std::cout << "lws: server writable "<< std::endl;
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                webfuse::message msg(webfuse::message_type::access_req);
 | 
					                webfuse::messagewriter writer(webfuse::message_type::access_req);
 | 
				
			||||||
                bool has_msg = false;
 | 
					                bool has_msg = false;
 | 
				
			||||||
                bool has_more = false;
 | 
					                bool has_more = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -82,7 +121,7 @@ static int ws_server_callback(struct lws *wsi, enum lws_callback_reasons reason,
 | 
				
			|||||||
                    if (has_msg)
 | 
					                    if (has_msg)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        has_msg = true;
 | 
					                        has_msg = true;
 | 
				
			||||||
                        msg = std::move(data->requests.front());
 | 
					                        writer = std::move(data->requests.front());
 | 
				
			||||||
                        data->requests.pop();
 | 
					                        data->requests.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        has_more = !(data->requests.empty());
 | 
					                        has_more = !(data->requests.empty());
 | 
				
			||||||
@ -92,7 +131,7 @@ static int ws_server_callback(struct lws *wsi, enum lws_callback_reasons reason,
 | 
				
			|||||||
                if (has_msg)
 | 
					                if (has_msg)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    size_t size;
 | 
					                    size_t size;
 | 
				
			||||||
                    unsigned char * raw_data = msg.get_data(size);
 | 
					                    unsigned char * raw_data = writer.get_data(size);
 | 
				
			||||||
                    int const rc = lws_write(data->connection, raw_data, size, LWS_WRITE_BINARY);
 | 
					                    int const rc = lws_write(data->connection, raw_data, size, LWS_WRITE_BINARY);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -148,11 +187,12 @@ public:
 | 
				
			|||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if (nullptr != data.connection)
 | 
					                        if (nullptr != data.connection)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
 | 
					                            std::cout << "request write" << std::endl;
 | 
				
			||||||
                            lws_callback_on_writable(data.connection);
 | 
					                            lws_callback_on_writable(data.connection);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        else
 | 
					                        else
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            data.requests = std::move(std::queue<webfuse::message>());
 | 
					                            data.requests = std::move(std::queue<webfuse::messagewriter>());
 | 
				
			||||||
                            data.pending_responses.clear();
 | 
					                            data.pending_responses.clear();
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@ -172,6 +212,16 @@ public:
 | 
				
			|||||||
        lws_context_destroy(context);
 | 
					        lws_context_destroy(context);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint32_t next_id()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        data.id++;
 | 
				
			||||||
 | 
					        if (0 == data.id)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            data.id = 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return data.id;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::thread thread;
 | 
					    std::thread thread;
 | 
				
			||||||
    std::atomic<bool> shutdown_requested;
 | 
					    std::atomic<bool> shutdown_requested;
 | 
				
			||||||
    lws_protocols protocols[2];
 | 
					    lws_protocols protocols[2];
 | 
				
			||||||
@ -209,26 +259,27 @@ ws_server& ws_server::operator=(ws_server && other)
 | 
				
			|||||||
    return *this;
 | 
					    return *this;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ws_server::perform(message msg)
 | 
					messagereader ws_server::perform(messagewriter writer)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    std::future<std::string> f;
 | 
					    std::future<messagereader> f;
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::promise<std::string> p;
 | 
					        std::promise<messagereader> p;
 | 
				
			||||||
        f = p.get_future();
 | 
					        f = p.get_future();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::lock_guard lock(d->data.mut);
 | 
					        std::lock_guard lock(d->data.mut);
 | 
				
			||||||
        d->data.requests.emplace(std::move(msg));
 | 
					        uint32_t id = d->next_id();
 | 
				
			||||||
        d->data.pending_responses.emplace(42, std::move(p));
 | 
					        writer.set_id(id);
 | 
				
			||||||
 | 
					        d->data.requests.emplace(std::move(writer));
 | 
				
			||||||
 | 
					        d->data.pending_responses.emplace(id, std::move(p));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    lws_cancel_service(d->context);
 | 
					    lws_cancel_service(d->context);
 | 
				
			||||||
    if(std::future_status::timeout == f.wait_for(std::chrono::seconds(1)))
 | 
					    if(std::future_status::timeout == f.wait_for(std::chrono::seconds(10)))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        throw std::runtime_error("timeout");
 | 
					        throw std::runtime_error("timeout");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    std::string resp = f.get();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    throw std::runtime_error("not implemented");
 | 
					    return std::move(f.get());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,8 @@
 | 
				
			|||||||
#define WEBFUSE_WSSERVER_HPP
 | 
					#define WEBFUSE_WSSERVER_HPP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "webfuse/ws/config.hpp"
 | 
					#include "webfuse/ws/config.hpp"
 | 
				
			||||||
#include "webfuse/ws/message.hpp"
 | 
					#include "webfuse/ws/messagewriter.hpp"
 | 
				
			||||||
 | 
					#include "webfuse/ws/messagereader.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
@ -21,7 +22,7 @@ public:
 | 
				
			|||||||
    ws_server(ws_server && other);
 | 
					    ws_server(ws_server && other);
 | 
				
			||||||
    ws_server& operator=(ws_server && other);
 | 
					    ws_server& operator=(ws_server && other);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    void perform(message msg);
 | 
					    messagereader perform(messagewriter writer);
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    class detail;
 | 
					    class detail;
 | 
				
			||||||
    detail * d;
 | 
					    detail * d;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user