From 499cdaf05204a40d86e0e1b4dd32709b3ab67e20 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 15 Jul 2024 12:59:18 -0700 Subject: MyriadFs improvements and new helper tool. I think the interface could be a lot better...but it does work and we can use it examine and work with MyriadFs files. --- .gitignore | 2 + default.bld | 8 +- src/extra/mount.myriadfs.cpp | 334 +++++++++++++++++++++++++++++++++++++++++++ src/extra/myriadfs.cpp | 334 ------------------------------------------- src/tests/myriadfs.cpp | 14 ++ src/tools/myriadfs.cpp | 251 ++++++++++++++++++++++++++++++++ src/unstable/myriadfs.cpp | 9 +- 7 files changed, 612 insertions(+), 340 deletions(-) create mode 100644 src/extra/mount.myriadfs.cpp delete mode 100644 src/extra/myriadfs.cpp create mode 100644 src/tools/myriadfs.cpp diff --git a/.gitignore b/.gitignore index 9009abe..532bcbf 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ /myriad.exe /jsontool.exe /rununits.exe +/myriadfs.exe /autoconfig /bin2cpp /mkunit @@ -14,6 +15,7 @@ /viewcsv /jsontool /rununits +/myriadfs .*.swp .*.un~ /src/autoconfig.h diff --git a/default.bld b/default.bld index aed9dee..07b562c 100644 --- a/default.bld +++ b/default.bld @@ -54,9 +54,9 @@ action "unit" build: targets("unit tests"); } -action "myriadfs" +action "mount.myriadfs" { - build: "myriadfs"; + build: "mount.myriadfs"; } target ["src/autoconfig.h", "src/version.h"] @@ -181,12 +181,12 @@ target files("src/extra/*.cpp").replace("src/extra/","").replace(".cpp","") // I'm honestly not 100% sure what the policy should be yet, but this seems like // I shouldn't have to do it this way. // -target "src/extra/myriadfs.o" +target "src/extra/mount.myriadfs.o" { CXXFLAGS += "-D_FILE_OFFSET_BITS=64"; } -target "myriadfs" +target "mount.myriadfs" { LDFLAGS += "-lfuse -lpthread"; } diff --git a/src/extra/mount.myriadfs.cpp b/src/extra/mount.myriadfs.cpp new file mode 100644 index 0000000..ff2df3d --- /dev/null +++ b/src/extra/mount.myriadfs.cpp @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2007-2023 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#define _FILE_OFFSET_BITS 64 +#define FUSE_USE_VERSION 26 + +#include + +#include +#include + +#include +#include +#include +#include + +Bu::File *pF = NULL; +Bu::MyriadFs *pFs = NULL; + +typedef Bu::Hash FileHash; +FileHash hOpenFiles; +int64_t iNextFileId = 0; + +#define TRACE + +extern "C" { + static int myriadfs_getattr( const char *sPath, struct stat *stbuf ) + { +#ifdef TRACE + printf("myriadfs_getattr(\"%s\", ... );\n", sPath ); +#endif + try + { + Bu::MyriadFs::Stat st; + pFs->stat( sPath, st ); + stbuf->st_ino = st.iNode; + stbuf->st_mode = st.uPerms; + stbuf->st_nlink = st.iLinks; + stbuf->st_uid = st.iUser; + stbuf->st_gid = st.iGroup; + stbuf->st_rdev = Bu::MyriadFs::devToSys( st.uDev ); + stbuf->st_size = st.iSize; + stbuf->st_blocks = 8; + stbuf->st_atime = st.iATime; + stbuf->st_mtime = st.iMTime; + stbuf->st_ctime = st.iCTime; + return 0; + } + catch(...) + { + return -ENOENT; + } + } + + static int myriadfs_readdir( const char *sPath, void *buf, + fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi ) + { +#ifdef TRACE + printf("myriadfs_readdir(\"%s\", ... );\n", sPath ); +#endif + Bu::MyriadFs::Dir lDir = pFs->readDir( sPath ); + filler( buf, ".", NULL, 0 ); + filler( buf, "..", NULL, 0 ); + for( Bu::MyriadFs::Dir::iterator i = lDir.begin(); i; i++ ) + { + filler( buf, (*i).sName.getStr(), NULL, 0 ); + } + + return 0; + } + + static int myriadfs_mkdir( const char *sPath, mode_t uMode ) + { +#ifdef TRACE + printf("myriadfs_mkdir(\"%s\", 0%o );\n", sPath, uMode ); +#endif + pFs->mkDir( sPath, uMode ); + return 0; + } + + static int myriadfs_open( const char *sPath, struct fuse_file_info *fi ) + { +#ifdef TRACE + printf("myriadfs_open(\"%s\", ... );\n", sPath ); +#endif + try + { + Bu::MyriadStream ms = pFs->open( sPath, 0 ); + fi->fh = iNextFileId; + hOpenFiles.insert( iNextFileId++, ms ); +// printf("File '%s' opened, %d files open now.\n", +// sPath, hOpenFiles.getSize() ); + return 0; + } + catch(...) + { + return -EACCES; + } + } + + static int myriadfs_read( const char *sPath, char *buf, size_t iSize, + off_t iOffset, struct fuse_file_info *fi ) + { +#ifdef TRACE + printf("myriadfs_read(\"%s\", ..., %d, %d, ... );\n", sPath, iSize, + iOffset ); +#endif + Bu::MyriadStream &ms = hOpenFiles.get( fi->fh ); + ms.setPos( iOffset ); + return ms.read( buf, iSize ); + } + + static int myriadfs_write( const char *sPath, const char *buf, size_t iSize, + off_t iOffset, struct fuse_file_info *fi ) + { +#ifdef TRACE + printf("myriadfs_write(\"%s\", ..., %d, %d, ... );\n", sPath, iSize, + iOffset ); +#endif + Bu::MyriadStream &ms = hOpenFiles.get( fi->fh ); + ms.setPos( iOffset ); + return ms.write( buf, iSize ); + } + + static int myriadfs_create( const char *sPath, mode_t uPerms, + struct fuse_file_info *fi ) + { +#ifdef TRACE + printf("myriadfs_create(\"%s\", 0%o, ... );\n", sPath, uPerms ); +#endif + try + { + Bu::MyriadStream ms = pFs->open( sPath, 0, uPerms ); + fi->fh = iNextFileId; + hOpenFiles.insert( iNextFileId++, ms ); +// printf("File '%s' created, %d files open now.\n", +// sPath, hOpenFiles.getSize() ); + return 0; + } + catch(...) + { + return -EACCES; + } + } + + static int myriadfs_mknod( const char *sPath, mode_t uPerms, dev_t Dev ) + { +#ifdef TRACE + printf("myriadfs_mknod(\"%s\", 0%o, %x );\n", sPath, uPerms, Dev ); +#endif + try + { + pFs->create( sPath, uPerms, Bu::MyriadFs::sysToDev( Dev ) ); + return 0; + } + catch(...) + { + return -EACCES; + } + } + + static int myriadfs_release( const char *sPath, struct fuse_file_info *fi ) + { +#ifdef TRACE + printf("myriadfs_release(\"%s\", ... );\n", sPath ); +#endif + hOpenFiles.erase( fi->fh ); +// printf("File '%s' released, %d files open now.\n", +// sPath, hOpenFiles.getSize() ); + + return 0; + } + + static int myriadfs_utimens( const char *sPath, + const struct timespec tv[2] ) + { +#ifdef TRACE + printf("myriadfs_utimens(\"%s\", ... );\n", sPath ); +#endif + try + { + pFs->setTimes( sPath, tv[0].tv_sec, tv[1].tv_sec ); + } + catch(...) + { + return -EACCES; + } + return 0; + } + + static int myriadfs_unlink( const char *sPath ) + { +#ifdef TRACE + printf("myriadfs_unlink(\"%s\");\n", sPath ); +#endif + try + { + pFs->unlink( sPath ); + } + catch( Bu::MyriadFsException &e ) + { + printf("MyriadFsException: %s\n", e.what() ); + return -EACCES; + } + return 0; + } + + static int myriadfs_symlink( const char *sTarget, const char *sPath ) + { +#ifdef TRACE + printf("myriadfs_symlink(\"%s\", \"%s\");\n", sTarget, sPath ); +#endif + try + { + pFs->mkSymLink( sTarget, sPath ); + } + catch( Bu::MyriadFsException &e ) + { + printf("MyriadFsException: %s\n", e.what() ); + return -EACCES; + } + return 0; + } + + static int myriadfs_readlink( const char *sPath, char *sOut, size_t s ) + { +#ifdef TRACE + printf("myriadfs_readlink(\"%s\", ... );\n", sPath ); +#endif + try + { + Bu::String sTrg = pFs->readSymLink( sPath ); + size_t iLen = (s-1>sTrg.getSize())?(sTrg.getSize()):(s-1); + memcpy( sOut, sTrg.getStr(), iLen ); + sOut[iLen] = '\0'; + } + catch( Bu::MyriadFsException &e ) + { + printf("MyriadFsException: %s\n", e.what() ); + return -EACCES; + } + return 0; + } + + static int myriadfs_truncate( const char *sPath, off_t iSize ) + { +#ifdef TRACE + printf("myriadfs_truncate(\"%s\", %d );\n", sPath, iSize ); +#endif + + try + { + pFs->setFileSize( sPath, iSize ); + } + catch( Bu::MyriadFsException &e ) + { + printf("MyriadFsException: %s\n", e.what() ); + return -ENOENT; + } + return 0; + } + + static int myriadfs_link( const char *sTarget, const char *sPath ) + { +#ifdef TRACE + printf("myriadfs_link(\"%s\", \"%s\");\n", sTarget, sPath ); +#endif + + try + { + pFs->mkHardLink( sTarget, sPath ); + } + catch( Bu::MyriadFsException &e ) + { + printf("MyriadFsException: %s\n", e.what() ); + return -EACCES; + } + return 0; + } + + static int myriadfs_rename( const char *sFrom, const char *sTo ) + { +#ifdef TRACE + printf("myriadfs_rename(\"%s\", \"%s\");\n", sFrom, sTo ); +#endif + + try + { + pFs->rename( sFrom, sTo ); + } + catch( Bu::MyriadFsException &e ) + { + printf("MyriadFsException: %s\n", e.what() ); + return -EACCES; + } + return 0; + } + + static struct fuse_operations myriadfs_oper; + + int main( int argc, char *argv[] ) + { + pF = new Bu::File("store.myr", Bu::File::Read|Bu::File::Write|Bu::File::Create ); + pFs = new Bu::MyriadFs( *pF, 512 ); + memset( &myriadfs_oper, sizeof(myriadfs_oper), 0 ); + myriadfs_oper.getattr = myriadfs_getattr; + myriadfs_oper.readdir = myriadfs_readdir; + myriadfs_oper.mkdir = myriadfs_mkdir; + myriadfs_oper.open = myriadfs_open; + myriadfs_oper.read = myriadfs_read; + myriadfs_oper.write = myriadfs_write; + myriadfs_oper.create = myriadfs_create; + myriadfs_oper.mknod = myriadfs_mknod; + myriadfs_oper.release = myriadfs_release; + myriadfs_oper.utimens = myriadfs_utimens; + myriadfs_oper.unlink = myriadfs_unlink; + myriadfs_oper.rmdir = myriadfs_unlink; + myriadfs_oper.symlink = myriadfs_symlink; + myriadfs_oper.readlink = myriadfs_readlink; + myriadfs_oper.truncate = myriadfs_truncate; + myriadfs_oper.link = myriadfs_link; + myriadfs_oper.rename = myriadfs_rename; + printf("Starting fuse_main.\n"); + int iRet = fuse_main( argc, argv, &myriadfs_oper, NULL ); + printf("Done with fuse_main.\n"); + delete pFs; + delete pF; + return iRet; + } +} diff --git a/src/extra/myriadfs.cpp b/src/extra/myriadfs.cpp deleted file mode 100644 index ff2df3d..0000000 --- a/src/extra/myriadfs.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (C) 2007-2023 Xagasoft, All rights reserved. - * - * This file is part of the libbu++ library and is released under the - * terms of the license contained in the file LICENSE. - */ - -#define _FILE_OFFSET_BITS 64 -#define FUSE_USE_VERSION 26 - -#include - -#include -#include - -#include -#include -#include -#include - -Bu::File *pF = NULL; -Bu::MyriadFs *pFs = NULL; - -typedef Bu::Hash FileHash; -FileHash hOpenFiles; -int64_t iNextFileId = 0; - -#define TRACE - -extern "C" { - static int myriadfs_getattr( const char *sPath, struct stat *stbuf ) - { -#ifdef TRACE - printf("myriadfs_getattr(\"%s\", ... );\n", sPath ); -#endif - try - { - Bu::MyriadFs::Stat st; - pFs->stat( sPath, st ); - stbuf->st_ino = st.iNode; - stbuf->st_mode = st.uPerms; - stbuf->st_nlink = st.iLinks; - stbuf->st_uid = st.iUser; - stbuf->st_gid = st.iGroup; - stbuf->st_rdev = Bu::MyriadFs::devToSys( st.uDev ); - stbuf->st_size = st.iSize; - stbuf->st_blocks = 8; - stbuf->st_atime = st.iATime; - stbuf->st_mtime = st.iMTime; - stbuf->st_ctime = st.iCTime; - return 0; - } - catch(...) - { - return -ENOENT; - } - } - - static int myriadfs_readdir( const char *sPath, void *buf, - fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi ) - { -#ifdef TRACE - printf("myriadfs_readdir(\"%s\", ... );\n", sPath ); -#endif - Bu::MyriadFs::Dir lDir = pFs->readDir( sPath ); - filler( buf, ".", NULL, 0 ); - filler( buf, "..", NULL, 0 ); - for( Bu::MyriadFs::Dir::iterator i = lDir.begin(); i; i++ ) - { - filler( buf, (*i).sName.getStr(), NULL, 0 ); - } - - return 0; - } - - static int myriadfs_mkdir( const char *sPath, mode_t uMode ) - { -#ifdef TRACE - printf("myriadfs_mkdir(\"%s\", 0%o );\n", sPath, uMode ); -#endif - pFs->mkDir( sPath, uMode ); - return 0; - } - - static int myriadfs_open( const char *sPath, struct fuse_file_info *fi ) - { -#ifdef TRACE - printf("myriadfs_open(\"%s\", ... );\n", sPath ); -#endif - try - { - Bu::MyriadStream ms = pFs->open( sPath, 0 ); - fi->fh = iNextFileId; - hOpenFiles.insert( iNextFileId++, ms ); -// printf("File '%s' opened, %d files open now.\n", -// sPath, hOpenFiles.getSize() ); - return 0; - } - catch(...) - { - return -EACCES; - } - } - - static int myriadfs_read( const char *sPath, char *buf, size_t iSize, - off_t iOffset, struct fuse_file_info *fi ) - { -#ifdef TRACE - printf("myriadfs_read(\"%s\", ..., %d, %d, ... );\n", sPath, iSize, - iOffset ); -#endif - Bu::MyriadStream &ms = hOpenFiles.get( fi->fh ); - ms.setPos( iOffset ); - return ms.read( buf, iSize ); - } - - static int myriadfs_write( const char *sPath, const char *buf, size_t iSize, - off_t iOffset, struct fuse_file_info *fi ) - { -#ifdef TRACE - printf("myriadfs_write(\"%s\", ..., %d, %d, ... );\n", sPath, iSize, - iOffset ); -#endif - Bu::MyriadStream &ms = hOpenFiles.get( fi->fh ); - ms.setPos( iOffset ); - return ms.write( buf, iSize ); - } - - static int myriadfs_create( const char *sPath, mode_t uPerms, - struct fuse_file_info *fi ) - { -#ifdef TRACE - printf("myriadfs_create(\"%s\", 0%o, ... );\n", sPath, uPerms ); -#endif - try - { - Bu::MyriadStream ms = pFs->open( sPath, 0, uPerms ); - fi->fh = iNextFileId; - hOpenFiles.insert( iNextFileId++, ms ); -// printf("File '%s' created, %d files open now.\n", -// sPath, hOpenFiles.getSize() ); - return 0; - } - catch(...) - { - return -EACCES; - } - } - - static int myriadfs_mknod( const char *sPath, mode_t uPerms, dev_t Dev ) - { -#ifdef TRACE - printf("myriadfs_mknod(\"%s\", 0%o, %x );\n", sPath, uPerms, Dev ); -#endif - try - { - pFs->create( sPath, uPerms, Bu::MyriadFs::sysToDev( Dev ) ); - return 0; - } - catch(...) - { - return -EACCES; - } - } - - static int myriadfs_release( const char *sPath, struct fuse_file_info *fi ) - { -#ifdef TRACE - printf("myriadfs_release(\"%s\", ... );\n", sPath ); -#endif - hOpenFiles.erase( fi->fh ); -// printf("File '%s' released, %d files open now.\n", -// sPath, hOpenFiles.getSize() ); - - return 0; - } - - static int myriadfs_utimens( const char *sPath, - const struct timespec tv[2] ) - { -#ifdef TRACE - printf("myriadfs_utimens(\"%s\", ... );\n", sPath ); -#endif - try - { - pFs->setTimes( sPath, tv[0].tv_sec, tv[1].tv_sec ); - } - catch(...) - { - return -EACCES; - } - return 0; - } - - static int myriadfs_unlink( const char *sPath ) - { -#ifdef TRACE - printf("myriadfs_unlink(\"%s\");\n", sPath ); -#endif - try - { - pFs->unlink( sPath ); - } - catch( Bu::MyriadFsException &e ) - { - printf("MyriadFsException: %s\n", e.what() ); - return -EACCES; - } - return 0; - } - - static int myriadfs_symlink( const char *sTarget, const char *sPath ) - { -#ifdef TRACE - printf("myriadfs_symlink(\"%s\", \"%s\");\n", sTarget, sPath ); -#endif - try - { - pFs->mkSymLink( sTarget, sPath ); - } - catch( Bu::MyriadFsException &e ) - { - printf("MyriadFsException: %s\n", e.what() ); - return -EACCES; - } - return 0; - } - - static int myriadfs_readlink( const char *sPath, char *sOut, size_t s ) - { -#ifdef TRACE - printf("myriadfs_readlink(\"%s\", ... );\n", sPath ); -#endif - try - { - Bu::String sTrg = pFs->readSymLink( sPath ); - size_t iLen = (s-1>sTrg.getSize())?(sTrg.getSize()):(s-1); - memcpy( sOut, sTrg.getStr(), iLen ); - sOut[iLen] = '\0'; - } - catch( Bu::MyriadFsException &e ) - { - printf("MyriadFsException: %s\n", e.what() ); - return -EACCES; - } - return 0; - } - - static int myriadfs_truncate( const char *sPath, off_t iSize ) - { -#ifdef TRACE - printf("myriadfs_truncate(\"%s\", %d );\n", sPath, iSize ); -#endif - - try - { - pFs->setFileSize( sPath, iSize ); - } - catch( Bu::MyriadFsException &e ) - { - printf("MyriadFsException: %s\n", e.what() ); - return -ENOENT; - } - return 0; - } - - static int myriadfs_link( const char *sTarget, const char *sPath ) - { -#ifdef TRACE - printf("myriadfs_link(\"%s\", \"%s\");\n", sTarget, sPath ); -#endif - - try - { - pFs->mkHardLink( sTarget, sPath ); - } - catch( Bu::MyriadFsException &e ) - { - printf("MyriadFsException: %s\n", e.what() ); - return -EACCES; - } - return 0; - } - - static int myriadfs_rename( const char *sFrom, const char *sTo ) - { -#ifdef TRACE - printf("myriadfs_rename(\"%s\", \"%s\");\n", sFrom, sTo ); -#endif - - try - { - pFs->rename( sFrom, sTo ); - } - catch( Bu::MyriadFsException &e ) - { - printf("MyriadFsException: %s\n", e.what() ); - return -EACCES; - } - return 0; - } - - static struct fuse_operations myriadfs_oper; - - int main( int argc, char *argv[] ) - { - pF = new Bu::File("store.myr", Bu::File::Read|Bu::File::Write|Bu::File::Create ); - pFs = new Bu::MyriadFs( *pF, 512 ); - memset( &myriadfs_oper, sizeof(myriadfs_oper), 0 ); - myriadfs_oper.getattr = myriadfs_getattr; - myriadfs_oper.readdir = myriadfs_readdir; - myriadfs_oper.mkdir = myriadfs_mkdir; - myriadfs_oper.open = myriadfs_open; - myriadfs_oper.read = myriadfs_read; - myriadfs_oper.write = myriadfs_write; - myriadfs_oper.create = myriadfs_create; - myriadfs_oper.mknod = myriadfs_mknod; - myriadfs_oper.release = myriadfs_release; - myriadfs_oper.utimens = myriadfs_utimens; - myriadfs_oper.unlink = myriadfs_unlink; - myriadfs_oper.rmdir = myriadfs_unlink; - myriadfs_oper.symlink = myriadfs_symlink; - myriadfs_oper.readlink = myriadfs_readlink; - myriadfs_oper.truncate = myriadfs_truncate; - myriadfs_oper.link = myriadfs_link; - myriadfs_oper.rename = myriadfs_rename; - printf("Starting fuse_main.\n"); - int iRet = fuse_main( argc, argv, &myriadfs_oper, NULL ); - printf("Done with fuse_main.\n"); - delete pFs; - delete pF; - return iRet; - } -} diff --git a/src/tests/myriadfs.cpp b/src/tests/myriadfs.cpp index cb6c6c3..1266e4b 100644 --- a/src/tests/myriadfs.cpp +++ b/src/tests/myriadfs.cpp @@ -30,6 +30,14 @@ int main() Bu::MyriadStream ms = mfs.open("/etc/hello", Bu::MyriadFs::Read ); ms.write("world, again!"); } + { + Bu::MyriadStream ms = mfs.open("/etc/trunc", Bu::MyriadFs::Write ); + ms.write("[longer text shouldn't be seen]"); + } + { + Bu::MyriadStream ms = mfs.open("/etc/trunc", Bu::MyriadFs::Write|Bu::MyriadFs::Create|Bu::MyriadFs::Truncate ); + ms.write("[short text]"); + } sio << "Reading files..." << sio.nl; { @@ -44,5 +52,11 @@ int main() buf[ms.read( buf, 512 )] = '\0'; sio << "read: '" << buf << "'" << sio.nl; } + { + Bu::MyriadStream ms = mfs.open("/etc/trunc", Bu::MyriadFs::Read ); + char buf[512]; + buf[ms.read( buf, 512 )] = '\0'; + sio << "read: '" << buf << "'" << sio.nl; + } } diff --git a/src/tools/myriadfs.cpp b/src/tools/myriadfs.cpp new file mode 100644 index 0000000..9051779 --- /dev/null +++ b/src/tools/myriadfs.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2007-2023 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#include "bu/sio.h" +#include "bu/streamstack.h" +#include "bu/file.h" +#include "bu/myriadfs.h" +#include "bu/myriadstream.h" +#include "bu/optparser.h" + +enum Mode +{ + modeList, + modeCat, + modeCopyIn, + modeCopyOut, + modeMkdir, + modeInitialize, + + modeNone +}; + +Bu::Formatter &operator>>( Bu::Formatter &f, Mode & /*e*/ ) +{ + Bu::sio << "Uh oh, the formatter was called..." << Bu::sio.nl; + return f; +} + +class Options : public Bu::OptParser +{ +public: + Options( int argc, char *argv[] ) : + eMode( modeNone ), + iBlockSize( 64 ) + { + addHelpBanner("Options:"); + addOption( sFile, 'f', "file", "Myriadfs file"); + addOption( iBlockSize, 'b', "block-size", + "Specify the block size when initializing a new MyriadFs"); + + setNonOption( Bu::slot( this, &Options::nonOption ) ); + + addHelpOption(); + + parse( argc, argv ); + } + + int nonOption( Bu::Array aParams ) + { + if( eMode == modeNone ) + { + //Bu::println("Checking mode"); + // First param, must be the mode + if( aParams[0] == "ls" ) + eMode = modeList; + else if( aParams[0] == "cat" ) + eMode = modeCat; + else if( aParams[0] == "cp-in" ) + eMode = modeCopyIn; + else if( aParams[0] == "cp-out" ) + eMode = modeCopyOut; + else if( aParams[0] == "mkdir" ) + eMode = modeMkdir; + else if( aParams[0] == "initialize" ) + eMode = modeInitialize; + else + Bu::println("Unknown command, try --help"); + return 0; + } else { + lParams.append( aParams[0] ); + } + //Bu::println("Got option: \"%1\"").arg( aParams[0] ); + return 0; + } + + Mode eMode; + Bu::String sFile; + Bu::StringList lParams; + int iBlockSize; +}; + +int main( int argc, char *argv[] ) +{ + Options opt( argc, argv ); + + if( opt.sFile.isEmpty() ) + { + Bu::println("You must specify a MyriadFs stream (see -f).\n"); + return 1; + } + + if( opt.eMode == modeNone ) + { + Bu::println("Specify an operation to perfrom.\n"); + return 1; + } + + int iFlags = Bu::File::ReadWrite; + + if( opt.eMode == modeInitialize ) + { + iFlags |= Bu::File::Create|Bu::File::Truncate; + } + + Bu::File fFs( opt.sFile, iFlags ); + Bu::MyriadFs mFs( fFs, opt.iBlockSize ); + + switch( opt.eMode ) + { + case modeList: + { + Bu::String sPath = "/"; + if( opt.lParams.getSize() > 0 ) + { + sPath = opt.lParams.first(); + } + Bu::MyriadFs::Dir lEnt = mFs.readDir( sPath ); + for( Bu::MyriadFs::Dir::iterator i = lEnt.begin(); i; i++ ) + { + Bu::String sPerm; + sPerm += ((*i).uPerms&Bu::MyriadFs::typeDir)?"d": + ((*i).uPerms&Bu::MyriadFs::typeChrDev)?"c": + ((*i).uPerms&Bu::MyriadFs::typeBlkDev)?"b": + ((*i).uPerms&Bu::MyriadFs::typeSymLink)?"l": + ((*i).uPerms&Bu::MyriadFs::typeSocket)?"s":"-"; + sPerm += ((*i).uPerms&Bu::MyriadFs::permUsrR)?"r":"-"; + sPerm += ((*i).uPerms&Bu::MyriadFs::permUsrW)?"w":"-"; + sPerm += ((*i).uPerms&Bu::MyriadFs::permUsrX)?"x":"-"; + sPerm += ((*i).uPerms&Bu::MyriadFs::permGrpR)?"r":"-"; + sPerm += ((*i).uPerms&Bu::MyriadFs::permGrpW)?"w":"-"; + sPerm += ((*i).uPerms&Bu::MyriadFs::permGrpX)?"x":"-"; + sPerm += ((*i).uPerms&Bu::MyriadFs::permOthR)?"r":"-"; + sPerm += ((*i).uPerms&Bu::MyriadFs::permOthW)?"w":"-"; + sPerm += ((*i).uPerms&Bu::MyriadFs::permOthX)?"x":"-"; + Bu::println("%1 %2 %3:%4 %5 %6") + .arg( sPerm ) + .arg( (*i).iNode ) + .arg( (*i).iUser ) + .arg( (*i).iGroup ) + .arg( (*i).iSize ) + .arg( (*i).sName ); + } + } + break; + + case modeCat: + { + if( opt.lParams.isEmpty() ) + { + Bu::println("Specify at least one file."); + return 1; + } + int iBlockSize = 1024*1024; + char *pBuf = new char[iBlockSize]; + for( Bu::StringList::iterator i = opt.lParams.begin(); i; i++ ) + { + Bu::MyriadStream ms = mFs.open( *i, Bu::MyriadFs::Read ); + int iRead = 0; + do + { + iRead = ms.read( pBuf, iBlockSize ); + if( iRead > 0 ) + { + Bu::sioRaw.write( pBuf, iRead ); + } + } while( iRead == iBlockSize ); + } + delete[] pBuf; + } + break; + + case modeCopyIn: + { + if( opt.lParams.getSize() != 2 ) + { + Bu::println("Specify a source file and destination file."); + return 1; + } + int iBlockSize = 1024*1024; + char *pBuf = new char[iBlockSize]; + Bu::File fs = Bu::File( + opt.lParams.first(), Bu::File::Read ); + Bu::MyriadStream ms = mFs.open( + opt.lParams.last(), Bu::MyriadFs::WriteNew ); + int iRead = 0; + do + { + iRead = fs.read( pBuf, iBlockSize ); + if( iRead > 0 ) + { + ms.write( pBuf, iRead ); + } + } while( iRead == iBlockSize ); + delete[] pBuf; + } + break; + + case modeCopyOut: + { + if( opt.lParams.getSize() != 2 ) + { + Bu::println("Specify a source file and destination file."); + return 1; + } + int iBlockSize = 1024*1024; + char *pBuf = new char[iBlockSize]; + Bu::MyriadStream ms = mFs.open( + opt.lParams.first(), Bu::MyriadFs::Read ); + Bu::File fs = Bu::File( + opt.lParams.last(), Bu::File::WriteNew ); + int iRead = 0; + do + { + iRead = ms.read( pBuf, iBlockSize ); + if( iRead > 0 ) + { + fs.write( pBuf, iRead ); + } + } while( iRead == iBlockSize ); + delete[] pBuf; + } + break; + + case modeMkdir: + { + if( opt.lParams.isEmpty() ) + { + Bu::println("Specify at least one directory."); + return 1; + } + for( Bu::StringList::iterator i = opt.lParams.begin(); i; i++ ) + { + mFs.mkDir( *i, 0777 ); + } + } + break; + + case modeInitialize: + Bu::println("MyriadFs initialized.\n"); + break; + + case modeNone: + break; + } + + return 0; +} diff --git a/src/unstable/myriadfs.cpp b/src/unstable/myriadfs.cpp index 919f8b9..e02620d 100644 --- a/src/unstable/myriadfs.cpp +++ b/src/unstable/myriadfs.cpp @@ -113,7 +113,7 @@ void Bu::MyriadFs::stat( const Bu::String &sPath, Bu::MyriadFs::Stat &rBuf ) stat( iNode, rBuf, is ); } -Bu::MyriadStream Bu::MyriadFs::open( const Bu::String &sPath, int /*iMode*/, +Bu::MyriadStream Bu::MyriadFs::open( const Bu::String &sPath, int iMode, uint16_t uPerms ) { int32_t iParent = -1; @@ -123,7 +123,12 @@ Bu::MyriadStream Bu::MyriadFs::open( const Bu::String &sPath, int /*iMode*/, iNode = lookupInode( sPath, iParent ); // sio << "File found." << sio.nl; // The file was found - return openByInode( iNode ); + Bu::MyriadStream ms = openByInode( iNode ); + if( (iMode&Truncate) ) + { + ms.setSize( 0 ); + } + return ms; } catch( Bu::MyriadFsException &e ) { -- cgit v1.2.3