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
This commit is contained in:
parent
feb7e4c184
commit
2d1b146abf
5
.liccor
5
.liccor
@ -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/.
|
9
.liccor.yml
Normal file
9
.liccor.yml
Normal file
@ -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/.
|
@ -1 +0,0 @@
|
||||
clang-check `find . | grep "\.cpp" | grep -v CMakeFiles | grep -v editormodels\.cpp`
|
@ -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)
|
@ -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<Header>::Inode::getId() {
|
||||
return bigEndianAdapt(m_id);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
void FileStore<Header>::Inode::setLinks(InodeId_t links) {
|
||||
this->m_links = bigEndianAdapt(links);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
typename Header::InodeId_t FileStore<Header>::Inode::getLinks() {
|
||||
return bigEndianAdapt(m_links);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
void FileStore<Header>::Inode::setFileType(uint8_t fileType) {
|
||||
this->m_fileType = bigEndianAdapt(fileType);
|
||||
@ -441,7 +470,6 @@ void FileStore<Header>::Inode::setData(void *data, typename Header::FsSize_t siz
|
||||
setDataLen(size);
|
||||
}
|
||||
|
||||
|
||||
template<typename Header>
|
||||
uint8_t *FileStore<Header>::Inode::getData() {
|
||||
return (uint8_t*) (this + 1);
|
||||
@ -511,6 +539,36 @@ int FileStore<Header>::remove(InodeId_t id) {
|
||||
return remove(ptr<Inode*>(m_header.getRootInode()), id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the links of the inode of the given ID.
|
||||
* @param id the id of the inode
|
||||
*/
|
||||
template<typename Header>
|
||||
int FileStore<Header>::incLinks(InodeId_t id) {
|
||||
auto inode = getInode(ptr<Inode*>(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<typename Header>
|
||||
int FileStore<Header>::decLinks(InodeId_t id) {
|
||||
auto inode = getInode(ptr<Inode*>(m_header.getRootInode()), id);
|
||||
if (inode) {
|
||||
inode->setLinks(inode->getLinks() - 1);
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
int FileStore<Header>::remove(Inode *root, InodeId_t id) {
|
||||
auto err = 1;
|
||||
@ -664,6 +722,7 @@ typename FileStore<Header>::StatInfo FileStore<Header>::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<Header>::version() {
|
||||
return m_header.getVersion();
|
||||
};
|
||||
|
||||
template<typename Header>
|
||||
void FileStore<Header>::walk(int(*cb)(const char*, uint64_t start, uint64_t end)) {
|
||||
auto err = cb("Header", 0, sizeof(Header));
|
||||
auto inode = ptr<Inode*>(firstInode());
|
||||
while (!err && inode != (Inode*) begin()) {
|
||||
inode = ptr<Inode*>(inode->getNext());
|
||||
auto start = ptr(inode);
|
||||
err = cb("Inode", start, start + inode->size());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
uint8_t *FileStore<Header>::format(uint8_t *buffer, typename Header::FsSize_t size, uint16_t fsType) {
|
||||
ox_memset(buffer, 0, size);
|
||||
|
@ -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);
|
||||
|
@ -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<typename String>
|
||||
bool operator<(const DirectoryListing<String> &a, const DirectoryListing<String> &b) {
|
||||
return a.name < b.name;
|
||||
}
|
||||
|
||||
template<typename InodeId_t>
|
||||
struct __attribute__((packed)) DirectoryEntry {
|
||||
InodeId_t inode;
|
||||
@ -81,7 +87,7 @@ struct __attribute__((packed)) Directory {
|
||||
return size ? (DirectoryEntry<InodeId_t>*) (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<typename InodeId_t, typename FsSize_t>
|
||||
uint64_t Directory<InodeId_t, FsSize_t>::getFileInode(const char *name, uint64_t buffSize) {
|
||||
uint64_t Directory<InodeId_t, FsSize_t>::getFileInode(const char *name) {
|
||||
uint64_t inode = 0;
|
||||
auto current = files();
|
||||
if (current) {
|
||||
@ -120,7 +126,9 @@ int Directory<InodeId_t, FsSize_t>::getChildrenInodes(InodeId_t *inodes, size_t
|
||||
auto current = files();
|
||||
if (current) {
|
||||
for (uint64_t i = 0; i < this->children; i++) {
|
||||
if (ox_strcmp(current->getName(), ".") and ox_strcmp(current->getName(), "..")) {
|
||||
inodes[i] = current->inode;
|
||||
}
|
||||
current = (DirectoryEntry<InodeId_t>*) (((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<typename List>
|
||||
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<uint64_t, uint64_t> *dirOut) = 0;
|
||||
};
|
||||
|
||||
template<typename List>
|
||||
int FileSystem::ls(const char *path, List *list) {
|
||||
int err = 0;
|
||||
auto s = stat(path);
|
||||
if (s.fileType == FileType_Directory) {
|
||||
uint8_t dirBuff[s.size * 4];
|
||||
auto dir = (Directory<uint64_t, uint64_t>*) dirBuff;
|
||||
auto err = readDirectory(path, dir);
|
||||
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<FileStore, FS_TYPE>::stripDirectories() {
|
||||
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::mkdir(const char *path) {
|
||||
if (!stat(path).inode) {
|
||||
Directory<typename FileStore::InodeId_t, typename FileStore::FsSize_t> 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;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
@ -392,6 +437,7 @@ FileStat FileSystemTemplate<FileStore, FS_TYPE>::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<typename FileStore, FsType FS_TYPE>
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::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,11 +549,14 @@ int FileSystemTemplate<FileStore, FS_TYPE>::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) {
|
||||
if (i) {
|
||||
err |= remove(i, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
err |= m_store->remove(inode);
|
||||
@ -542,7 +591,8 @@ int FileSystemTemplate<FileStore, FS_TYPE>::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<FileStore, FS_TYPE>::findInodeOf(const char *path) {
|
||||
auto dir = (Directory<typename FileStore::InodeId_t, typename FileStore::FsSize_t>*) 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<FileStore, FS_TYPE>::insertDirectoryEntry(const char *dir
|
||||
auto entry = (DirectoryEntry<typename FileStore::InodeId_t>*) &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<FileStore, FS_TYPE>::rmDirectoryEntry(const char *path) {
|
||||
}
|
||||
|
||||
auto dir = (Directory<typename FileStore::InodeId_t, typename FileStore::FsSize_t>*) 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<FileStore, FS_TYPE>::expand(uint64_t newSize) {
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
void FileSystemTemplate<FileStore, FS_TYPE>::walk(int(*cb)(const char*, uint64_t, uint64_t)) {
|
||||
m_store->walk(cb);
|
||||
}
|
||||
|
||||
typedef FileSystemTemplate<FileStore16, OxFS_16> FileSystem16;
|
||||
typedef FileSystemTemplate<FileStore32, OxFS_32> FileSystem32;
|
||||
typedef FileSystemTemplate<FileStore64, OxFS_64> FileSystem64;
|
||||
|
@ -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] <size> <path>\n"
|
||||
"\toxfs read <FS file> <inode>\n"
|
||||
@ -28,6 +28,7 @@ const static auto usage = "usage:\n"
|
||||
"\toxfs write-expand <FS file> <inode> <insertion file>\n"
|
||||
"\toxfs rm <FS file> <inode>\n"
|
||||
"\toxfs compact <FS file>\n"
|
||||
"\toxfs walk <FS file>\n"
|
||||
"\toxfs version\n";
|
||||
|
||||
uint8_t *loadFileBuff(FILE *file, ::size_t *sizeOut = nullptr) {
|
||||
@ -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) {
|
||||
|
@ -314,9 +314,11 @@ map<string, int(*)(string)> 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;
|
||||
|
Loading…
Reference in New Issue
Block a user