mirror of
https://github.com/UzixLS/ehs5fs.git
synced 2025-07-18 23:01:29 +03:00
initial
This commit is contained in:
216
fuse.c
Normal file
216
fuse.c
Normal file
@ -0,0 +1,216 @@
|
||||
#include <fuse.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "main.h"
|
||||
#include "fuse.h"
|
||||
#include "modem.h"
|
||||
|
||||
|
||||
static int fs_getattr( const char *path, struct stat *st )
|
||||
{
|
||||
int ret;
|
||||
printf( "fs_getattr %s\n", path );
|
||||
|
||||
if( 0 == strcmp(path, "/") ) {
|
||||
st->st_mode = S_IFDIR | 0777;
|
||||
st->st_nlink = 2;
|
||||
} else {
|
||||
st->st_nlink = 1;
|
||||
ret = m_stat( &M, path, st );
|
||||
if( ret == ENOENT ) return -ret;
|
||||
if( ret < 0 ) {
|
||||
printf( "fs_getattr: tc_stat err ret=%d'\n", ret );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int fs_readdir(
|
||||
const char *path,
|
||||
void *buf,
|
||||
fuse_fill_dir_t filler,
|
||||
off_t offset,
|
||||
struct fuse_file_info *fi )
|
||||
{
|
||||
printf( "fs_readdir %s\n", path );
|
||||
filler(buf, ".", NULL, 0);
|
||||
filler(buf, "..", NULL, 0);
|
||||
m_ls( &M, path, buf, filler );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int fs_read(
|
||||
const char *path,
|
||||
char *buf,
|
||||
size_t size,
|
||||
off_t offset,
|
||||
struct fuse_file_info *fi )
|
||||
{
|
||||
int ret = 0;
|
||||
int readchunk = min(MAX_SIZE, (int)size);
|
||||
int readed = 0;
|
||||
int left = 0;
|
||||
struct stat st;
|
||||
|
||||
printf( "fs_read %s (%u+%lld)\n", path, size, offset);
|
||||
int fh = m_open( &M, path, 0 );
|
||||
if( fh < 0 ) return -1;
|
||||
if( m_seek( &M, fh, (int)offset, 0) < 0 ) { ret = -EIO; goto fs_read_exit; }
|
||||
if( m_stat( &M, path, &st ) < 0 ) { ret = -EIO; goto fs_read_exit; }
|
||||
left = min( (int)size, (int)st.st_size - (int)offset );
|
||||
|
||||
while( left > 0 ) {
|
||||
int bytes = min( (int)size, left );
|
||||
if( bytes > readchunk ) bytes = readchunk;
|
||||
if( m_read( &M, fh, (unsigned)bytes, buf + readed ) < 0 ) {
|
||||
ret = -1; goto fs_read_exit;
|
||||
}
|
||||
readed += bytes;
|
||||
left -= bytes;
|
||||
printf( "fs_read readed %d bytes from %d (%d left)\n", readed, size, left );
|
||||
usleep( 350 );
|
||||
|
||||
}
|
||||
ret = readed;
|
||||
|
||||
fs_read_exit:
|
||||
m_close( &M, fh );
|
||||
printf( "fs_read ret=%d\n", ret );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int fs_write(
|
||||
const char *path,
|
||||
const char *buf,
|
||||
size_t size,
|
||||
off_t offset,
|
||||
struct fuse_file_info *fi )
|
||||
{
|
||||
int ret = 0;
|
||||
int left = (int)size;
|
||||
int written = 0;
|
||||
|
||||
printf( "fs_write %s (%u+%lld)\n", path, size, offset );
|
||||
int fh = m_open( &M, path, FLAG_APPEND );
|
||||
if( fh < 0 ) return -1;
|
||||
if( m_seek( &M, fh, (int)offset, 0) < 0 ) { ret = -EIO; goto fs_write_exit; }
|
||||
|
||||
while( left > 0 ) {
|
||||
int bytes = min( MAX_SIZE, left );
|
||||
if( m_write( &M, fh, (unsigned)bytes, buf + written ) < 0 ) {
|
||||
ret = -EIO; goto fs_write_exit;
|
||||
}
|
||||
written += bytes;
|
||||
left -= bytes;
|
||||
printf( "fs_write writed %d bytes from %d (%d left)\n", written, size, left );
|
||||
}
|
||||
ret = written;
|
||||
|
||||
fs_write_exit:
|
||||
m_close( &M, fh );
|
||||
printf( "fs_write ret=%d\n", ret );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int fs_mknod(
|
||||
const char *path,
|
||||
mode_t mode,
|
||||
dev_t dev )
|
||||
{
|
||||
int fh = m_open( &M, path, FLAG_CREATE );
|
||||
if( fh < 0 ) return -EIO;
|
||||
m_close( &M, fh );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int fs_mkdir( const char *path, mode_t mode )
|
||||
{
|
||||
if( m_mkdir( &M, path ) < 0 )
|
||||
return -EIO;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fs_rmdir( const char *path )
|
||||
{
|
||||
if( m_rmdir( &M, path ) < 0 )
|
||||
return -EIO;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int fs_unlink( const char *path )
|
||||
{
|
||||
if( m_remove( &M, path ) < 0 )
|
||||
return -EIO;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int fs_truncate( const char *path, off_t offset )
|
||||
{
|
||||
if( offset != 0 ) return -EFAULT;
|
||||
int fh = m_open( &M, path, FLAG_TRUNCATE );
|
||||
if( fh < 0 ) return -EIO;
|
||||
m_close( &M, fh );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int fs_rename( const char *oldpath, const char *newpath )
|
||||
{
|
||||
int saferename = 1;
|
||||
char *ptr_oldpath, *ptr_newpath;
|
||||
|
||||
ptr_oldpath = strrchr( oldpath, '/' );
|
||||
ptr_newpath = strrchr( newpath, '/' );
|
||||
if( strncmp( oldpath, newpath, (unsigned)(max( ptr_oldpath - oldpath, ptr_newpath - newpath ))
|
||||
) != 0 )
|
||||
saferename = 1;
|
||||
|
||||
if( ptr_oldpath[1] == '.' || ptr_newpath[1] == '.' )
|
||||
saferename = 1;
|
||||
|
||||
if( saferename == 0 ) {
|
||||
if( m_rename( &M, oldpath+1, newpath+1 ) < 0 ) return -EIO;
|
||||
} else {
|
||||
if( m_copy( &M, oldpath, newpath ) < 0 ) return -EIO;
|
||||
if( m_remove( &M, oldpath ) < 0 ) return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int fs_statfs( const char *path, struct statvfs *st )
|
||||
{
|
||||
if( m_gstat( &M, st ) < 0 )
|
||||
return -EIO;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct fuse_operations fuse_ops = {
|
||||
.getattr = fs_getattr,
|
||||
.readdir = fs_readdir,
|
||||
.read = fs_read,
|
||||
.write = fs_write,
|
||||
.mknod = fs_mknod,
|
||||
.mkdir = fs_mkdir,
|
||||
.rmdir = fs_rmdir,
|
||||
.unlink = fs_unlink,
|
||||
.truncate = fs_truncate,
|
||||
.rename = fs_rename,
|
||||
.statfs = fs_statfs,
|
||||
};
|
Reference in New Issue
Block a user