diff --git a/.liccor b/.liccor deleted file mode 100644 index 7fed3f1ed..000000000 --- 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 000000000..550251462 --- /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 74346523e..000000000 --- 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 c9ef12ab5..000000000 --- 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 20b261a5b..cff4611b5 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 @@ -268,7 +285,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 +422,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 +468,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 +537,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 +720,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; diff --git a/src/ox/fs/filesystem.cpp b/src/ox/fs/filesystem.cpp index ceeaa5fb7..b6f9b94ff 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 48efcc155..a7f08a9d4 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; }; @@ -86,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); @@ -99,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) { @@ -125,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; @@ -206,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); @@ -245,11 +255,14 @@ class FileSystem { 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; } @@ -318,13 +331,7 @@ class FileSystemTemplate: public FileSystem { uint64_t size() override; 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. @@ -375,7 +382,31 @@ template int FileSystemTemplate::mkdir(const char *path) { if (!stat(path).inode) { Directory dir; - return write(path, &dir, sizeof(dir), FileType::FileType_Directory); + 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; } @@ -401,6 +432,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; } @@ -485,7 +517,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; } @@ -512,10 +544,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) { @@ -551,7 +586,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) { @@ -596,7 +632,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; @@ -702,7 +738,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; } @@ -779,7 +817,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; diff --git a/src/ox/fs/test/tests.cpp b/src/ox/fs/test/tests.cpp index d29d3b323..47e5a4a21 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;