From 2d1b146abfdf05e8aebdc11738c84d2592b5c3dd Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 9 Sep 2017 20:10:07 -0500 Subject: [PATCH] Squashed 'deps/ox/' changes from 56d91c1..4887d55 4887d55 Merge branch 'master' of github.com:wombatant/ox 84533e5 Add walk command. 916d07e Merge branch 'master' of github.com:wombatant/ox into ox_master 31af216 Add operator< for DirectoryListing 218511c Fix mkdir not to overwrite an existing dir 15e05df Remove unused scripts 292caad Add link count to stat in FS 99e459a Add links count field to inodes 3211cc4 Add . and .. directory entries to directores 30c2837 Switch to .liccor.yml 16b6ed3 Add a check to ls to prevent ls-ing of non-directories git-subtree-dir: deps/ox git-subtree-split: 4887d55a984c0d9c53d9faa9747ef5e9b7c1674a --- .liccor | 5 -- .liccor.yml | 9 ++++ scripts/check | 1 - scripts/newcpp | 16 ------- src/ox/fs/filestore.hpp | 76 +++++++++++++++++++++++++++-- src/ox/fs/filesystem.cpp | 2 +- src/ox/fs/filesystem.hpp | 101 +++++++++++++++++++++++++++++++-------- src/ox/fs/oxfstool.cpp | 32 ++++++++++++- src/ox/fs/test/tests.cpp | 8 ++-- 9 files changed, 198 insertions(+), 52 deletions(-) delete mode 100644 .liccor create mode 100644 .liccor.yml delete mode 100755 scripts/check delete mode 100755 scripts/newcpp diff --git a/.liccor b/.liccor deleted file mode 100644 index 7fed3f1e..00000000 --- a/.liccor +++ /dev/null @@ -1,5 +0,0 @@ -Copyright 2015 - 2017 gtalent2@gmail.com - -This Source Code Form is subject to the terms of the Mozilla Public -License, v. 2.0. If a copy of the MPL was not distributed with this -file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/.liccor.yml b/.liccor.yml new file mode 100644 index 00000000..55025146 --- /dev/null +++ b/.liccor.yml @@ -0,0 +1,9 @@ +--- +source: +- src +copyright_notice: |- + Copyright 2015 - 2017 gtalent2@gmail.com + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/scripts/check b/scripts/check deleted file mode 100755 index 74346523..00000000 --- a/scripts/check +++ /dev/null @@ -1 +0,0 @@ -clang-check `find . | grep "\.cpp" | grep -v CMakeFiles | grep -v editormodels\.cpp` diff --git a/scripts/newcpp b/scripts/newcpp deleted file mode 100755 index c9ef12ab..00000000 --- a/scripts/newcpp +++ /dev/null @@ -1,16 +0,0 @@ -#! /usr/bin/env python - -import sys - -if len(sys.argv) < 3: - sys.exit(1) - -pkg = sys.argv[1] -name = sys.argv[2] -ifdef = "WOMBAT_%s_%s_HPP" % (pkg.upper(), name.upper()) -namespace = "namespace wombat {\nnamespace %s {\n\n}\n}" % pkg -hpp = "#ifndef %s\n#define %s\n\n%s\n\n#endif" % (ifdef, ifdef, namespace) -cpp = "#include \"%s.hpp\"\n\n%s" % (name, namespace) - -open("src/%s/%s.hpp" % (pkg, name), "w").write(hpp) -open("src/%s/%s.cpp" % (pkg, name), "w").write(cpp) diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index 20b261a5..cedcf99c 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -17,7 +17,7 @@ struct __attribute__((packed)) FileStoreHeader { public: typedef InodeId InodeId_t; typedef FsT FsSize_t; - const static auto VERSION = 5; + const static auto VERSION = 6; private: uint16_t m_version; @@ -103,6 +103,7 @@ class FileStore { struct StatInfo { InodeId_t inodeId; + InodeId_t links; typename Header::FsSize_t size; uint8_t fileType; }; @@ -116,6 +117,7 @@ class FileStore { typename Header::FsSize_t m_dataLen; InodeId_t m_id; + InodeId_t m_links; uint8_t m_fileType; typename Header::FsSize_t m_left; typename Header::FsSize_t m_right; @@ -135,6 +137,9 @@ class FileStore { void setId(InodeId_t); InodeId_t getId(); + void setLinks(InodeId_t); + InodeId_t getLinks(); + void setFileType(uint8_t); uint8_t getFileType(); @@ -178,6 +183,18 @@ class FileStore { */ int remove(InodeId_t id); + /** + * Increments the links of the inode of the given ID. + * @param id the id of the inode + */ + int incLinks(InodeId_t id); + + /** + * Decrements the links of the inode of the given ID. + * @param id the id of the inode + */ + int decLinks(InodeId_t id); + /** * Removes all inodes of the type. * @param fileType the type of file to remove @@ -251,6 +268,8 @@ class FileStore { */ typename Header::FsSize_t available(); + void walk(int(*cb)(const char*, uint64_t start, uint64_t end)); + uint16_t fsType(); uint16_t version(); @@ -268,7 +287,7 @@ class FileStore { Inode *getInode(Inode *root, InodeId_t id); /** - * Gets the inode at the given id. + * Gets the parent inode at the given id. * @param root the root node to start comparing on * @param id id of the "file" * @param pathLen number of characters in pathLen @@ -405,6 +424,16 @@ typename Header::InodeId_t FileStore
::Inode::getId() { return bigEndianAdapt(m_id); } +template +void FileStore
::Inode::setLinks(InodeId_t links) { + this->m_links = bigEndianAdapt(links); +} + +template +typename Header::InodeId_t FileStore
::Inode::getLinks() { + return bigEndianAdapt(m_links); +} + template void FileStore
::Inode::setFileType(uint8_t fileType) { this->m_fileType = bigEndianAdapt(fileType); @@ -441,7 +470,6 @@ void FileStore
::Inode::setData(void *data, typename Header::FsSize_t siz setDataLen(size); } - template uint8_t *FileStore
::Inode::getData() { return (uint8_t*) (this + 1); @@ -511,6 +539,36 @@ int FileStore
::remove(InodeId_t id) { return remove(ptr(m_header.getRootInode()), id); } +/** + * Increments the links of the inode of the given ID. + * @param id the id of the inode + */ +template +int FileStore
::incLinks(InodeId_t id) { + auto inode = getInode(ptr(m_header.getRootInode()), id); + if (inode) { + inode->setLinks(inode->getLinks() + 1); + return 0; + } else { + return 1; + } +} + +/** + * Decrements the links of the inode of the given ID. + * @param id the id of the inode + */ +template +int FileStore
::decLinks(InodeId_t id) { + auto inode = getInode(ptr(m_header.getRootInode()), id); + if (inode) { + inode->setLinks(inode->getLinks() - 1); + return 0; + } else { + return 1; + } +} + template int FileStore
::remove(Inode *root, InodeId_t id) { auto err = 1; @@ -664,6 +722,7 @@ typename FileStore
::StatInfo FileStore
::stat(InodeId_t id) { if (inode) { stat.size = inode->getDataLen(); stat.fileType = inode->getFileType(); + stat.links = inode->getLinks(); stat.inodeId = id; } else { stat.inodeId = 0; @@ -830,6 +889,17 @@ uint16_t FileStore
::version() { return m_header.getVersion(); }; +template +void FileStore
::walk(int(*cb)(const char*, uint64_t start, uint64_t end)) { + auto err = cb("Header", 0, sizeof(Header)); + auto inode = ptr(firstInode()); + while (!err && inode != (Inode*) begin()) { + inode = ptr(inode->getNext()); + auto start = ptr(inode); + err = cb("Inode", start, start + inode->size()); + } +} + template uint8_t *FileStore
::format(uint8_t *buffer, typename Header::FsSize_t size, uint16_t fsType) { ox_memset(buffer, 0, size); diff --git a/src/ox/fs/filesystem.cpp b/src/ox/fs/filesystem.cpp index ceeaa5fb..b6f9b94f 100644 --- a/src/ox/fs/filesystem.cpp +++ b/src/ox/fs/filesystem.cpp @@ -16,7 +16,7 @@ FileSystem *createFileSystem(uint8_t *buff, size_t buffSize, bool ownsBuff) { FileSystem *fs = nullptr; switch (version) { - case 5: + case 6: switch (type) { case ox::OxFS_16: fs = new FileSystem16(buff, ownsBuff); diff --git a/src/ox/fs/filesystem.hpp b/src/ox/fs/filesystem.hpp index 0854456e..3fc5cee6 100644 --- a/src/ox/fs/filesystem.hpp +++ b/src/ox/fs/filesystem.hpp @@ -26,6 +26,7 @@ enum FileType { struct FileStat { uint64_t inode; + uint64_t links; uint64_t size; uint8_t fileType; }; @@ -42,6 +43,11 @@ struct DirectoryListing { } }; +template +bool operator<(const DirectoryListing &a, const DirectoryListing &b) { + return a.name < b.name; +} + template struct __attribute__((packed)) DirectoryEntry { InodeId_t inode; @@ -81,7 +87,7 @@ struct __attribute__((packed)) Directory { return size ? (DirectoryEntry*) (this + 1) : nullptr; } - uint64_t getFileInode(const char *name, uint64_t buffSize); + uint64_t getFileInode(const char *name); int getChildrenInodes(InodeId_t *inodes, size_t inodesLen); @@ -94,7 +100,7 @@ struct __attribute__((packed)) Directory { }; template -uint64_t Directory::getFileInode(const char *name, uint64_t buffSize) { +uint64_t Directory::getFileInode(const char *name) { uint64_t inode = 0; auto current = files(); if (current) { @@ -120,7 +126,9 @@ int Directory::getChildrenInodes(InodeId_t *inodes, size_t auto current = files(); if (current) { for (uint64_t i = 0; i < this->children; i++) { - inodes[i] = current->inode; + if (ox_strcmp(current->getName(), ".") and ox_strcmp(current->getName(), "..")) { + inodes[i] = current->inode; + } current = (DirectoryEntry*) (((uint8_t*) current) + current->size()); } return 0; @@ -201,6 +209,13 @@ class FileSystem { virtual int mkdir(const char *path) = 0; + /** + * Moves an entry from one directory to another. + * @param src the path to the file + * @param dest the path of the destination directory + */ + virtual int move(const char *src, const char *dest) = 0; + template int ls(const char *path, List *list); @@ -234,17 +249,22 @@ class FileSystem { virtual uint8_t *buff() = 0; + virtual void walk(int(*cb)(const char*, uint64_t, uint64_t)) = 0; + protected: virtual int readDirectory(const char *path, Directory *dirOut) = 0; }; template int FileSystem::ls(const char *path, List *list) { + int err = 0; auto s = stat(path); - uint8_t dirBuff[s.size * 4]; - auto dir = (Directory*) dirBuff; - auto err = readDirectory(path, dir); - err |= dir->ls(list); + if (s.fileType == FileType_Directory) { + uint8_t dirBuff[s.size * 4]; + auto dir = (Directory*) dirBuff; + err = readDirectory(path, dir); + err |= dir->ls(list); + } return err; } @@ -314,18 +334,15 @@ class FileSystemTemplate: public FileSystem { uint8_t *buff() override; - /** - * Moves an entry from one directory to another. - * @param src the path to the file - * @param dest the path of the destination directory - */ - int move(const char *src, const char *dest); + int move(const char *src, const char *dest) override; /** * Removes an entry from a directory. This does not delete the referred to file. */ int rmDirectoryEntry(const char *path); + void walk(int(*cb)(const char*, uint64_t, uint64_t)) override; + static uint8_t *format(uint8_t *buffer, typename FileStore::FsSize_t size, bool useDirectories); protected: @@ -368,8 +385,36 @@ int FileSystemTemplate::stripDirectories() { template int FileSystemTemplate::mkdir(const char *path) { - Directory dir; - return write(path, &dir, sizeof(dir), FileType::FileType_Directory); + if (!stat(path).inode) { + Directory dir; + auto err = write(path, &dir, sizeof(dir), FileType::FileType_Directory); + if (err) { + return err; + } + + // add . entry for self + auto inode = findInodeOf(path); + err = insertDirectoryEntry(path, ".", inode); + if (err) { + remove(inode); + return err; + } + + // add .. entry for parent + size_t pathLen = ox_strlen(path); + char dirPath[pathLen]; + PathIterator pathReader(path, pathLen); + err |= pathReader.dirPath(dirPath, pathLen); + err = insertDirectoryEntry(path, "..", findInodeOf(dirPath)); + if (err) { + remove(inode); + return err; + } + + return err; + } else { + return 1; + } } template @@ -392,6 +437,7 @@ FileStat FileSystemTemplate::stat(uint64_t inode) { auto s = m_store->stat(inode); stat.size = s.size; stat.inode = s.inodeId; + stat.links = s.links; stat.fileType = s.fileType; return stat; } @@ -476,7 +522,7 @@ template int FileSystemTemplate::remove(const char *path, bool recursive) { auto inode = findInodeOf(path); if (inode) { - return remove(inode, recursive) | rmDirectoryEntry(path); + return rmDirectoryEntry(path) | remove(inode, recursive); } else { return 1; } @@ -503,10 +549,13 @@ int FileSystemTemplate::remove(uint64_t inode, bool recursiv } typename FileStore::InodeId_t inodes[dir->children]; + ox_memset(inodes, 0, sizeof(typename FileStore::InodeId_t) * dir->children); dir->getChildrenInodes(inodes, dir->children); for (auto i : inodes) { - err |= remove(i, true); + if (i) { + err |= remove(i, true); + } } if (!err) { @@ -542,7 +591,8 @@ int FileSystemTemplate::write(const char *path, void *buffer // find an inode value for the given path if (!inode) { inode = generateInodeId(); - err = insertDirectoryEntry(dirPath, fileName, inode); + err |= write(inode, buffer, 0, fileType); // ensure file exists before indexing it + err |= insertDirectoryEntry(dirPath, fileName, inode); } if (!err) { @@ -587,7 +637,7 @@ uint64_t FileSystemTemplate::findInodeOf(const char *path) { auto dir = (Directory*) dirBuffer; if (read(inode, dirBuffer, dirStat.size) == 0) { if (dirStat.fileType == FileType::FileType_Directory && it.next(fileName, pathLen) == 0) { - inode = dir->getFileInode(fileName, dirStat.size); + inode = dir->getFileInode(fileName); } else { inode = 0; // null out inode and break break; @@ -693,7 +743,9 @@ int FileSystemTemplate::insertDirectoryEntry(const char *dir auto entry = (DirectoryEntry*) &dirBuff[s.size]; entry->inode = inode; entry->setName(fileName); - return write(s.inode, dirBuff, dirBuffSize, FileType_Directory); + err = write(s.inode, dirBuff, dirBuffSize, FileType_Directory); + err |= m_store->incLinks(inode); + return err; } else { return 1; } @@ -770,7 +822,9 @@ int FileSystemTemplate::rmDirectoryEntry(const char *path) { } auto dir = (Directory*) dirBuff; - err = dir->rmFile(fileName); + auto inode = dir->getFileInode(fileName); + err |= dir->rmFile(fileName); + err |= m_store->decLinks(inode); if (err) { return err; @@ -809,6 +863,11 @@ void FileSystemTemplate::expand(uint64_t newSize) { } } +template +void FileSystemTemplate::walk(int(*cb)(const char*, uint64_t, uint64_t)) { + m_store->walk(cb); +} + typedef FileSystemTemplate FileSystem16; typedef FileSystemTemplate FileSystem32; typedef FileSystemTemplate FileSystem64; diff --git a/src/ox/fs/oxfstool.cpp b/src/ox/fs/oxfstool.cpp index ee241245..4d52e5b3 100644 --- a/src/ox/fs/oxfstool.cpp +++ b/src/ox/fs/oxfstool.cpp @@ -20,7 +20,7 @@ using namespace ox; using namespace std; -const static auto oxfstoolVersion = "1.3.0"; +const static auto oxfstoolVersion = "1.4.0"; const static auto usage = "usage:\n" "\toxfs format [16,32,64] \n" "\toxfs read \n" @@ -28,6 +28,7 @@ const static auto usage = "usage:\n" "\toxfs write-expand \n" "\toxfs rm \n" "\toxfs compact \n" +"\toxfs walk \n" "\toxfs version\n"; uint8_t *loadFileBuff(FILE *file, ::size_t *sizeOut = nullptr) { @@ -148,7 +149,7 @@ int read(int argc, char **args) { size_t fileSize; auto fsBuff = loadFileBuff(fsPath, &fsSize); - + if (fsBuff) { auto fs = createFileSystem(fsBuff, fsSize); @@ -333,6 +334,31 @@ int remove(int argc, char **args) { return err; } +int walk(int argc, char **args) { + int err = 0; + size_t fsSize; + auto fsPath = args[2]; + auto fsBuff = loadFileBuff(fsPath, &fsSize); + if (fsBuff) { + auto fs = createFileSystem(fsBuff, fsSize); + if (fs) { + fs->walk([](const char *type, uint64_t start, uint64_t end) { + cout << "narf\n"; + cout << type << ", start: " << start << ", end: " << end << endl; + return 0; + }); + delete fs; + } else { + cerr << "Invalid file system.\n"; + err = 1; + } + delete []fsBuff; + } else { + err = 2; + } + return err; +} + int main(int argc, char **args) { auto err = 0; if (argc > 1) { @@ -349,6 +375,8 @@ int main(int argc, char **args) { err = compact(argc, args); } else if (ox_strcmp(cmd, "rm") == 0) { err = remove(argc, args); + } else if (ox_strcmp(cmd, "walk") == 0) { + err = walk(argc, args); } else if (ox_strcmp(cmd, "help") == 0) { printf("%s\n", usage); } else if (ox_strcmp(cmd, "version") == 0) { diff --git a/src/ox/fs/test/tests.cpp b/src/ox/fs/test/tests.cpp index d29d3b32..47e5a4a2 100644 --- a/src/ox/fs/test/tests.cpp +++ b/src/ox/fs/test/tests.cpp @@ -314,9 +314,11 @@ map tests = { fs->ls("/usr/share/", &files); - retval |= !(files[0].name == "a.txt"); - retval |= !(files[1].name == "b.txt"); - retval |= !(files[2].name == "c.txt"); + retval |= !(files[0].name == "."); + retval |= !(files[1].name == ".."); + retval |= !(files[2].name == "a.txt"); + retval |= !(files[3].name == "b.txt"); + retval |= !(files[4].name == "c.txt"); delete fs; delete []buff;