mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Convert mkinitrd to C.
This commit is contained in:
parent
f16a7693d6
commit
9ea3edf36f
7 changed files with 120 additions and 167 deletions
|
@ -4,12 +4,16 @@ include ../build-aux/version.mak
|
||||||
include ../build-aux/dirs.mak
|
include ../build-aux/dirs.mak
|
||||||
|
|
||||||
OPTLEVEL?=$(DEFAULT_OPTLEVEL)
|
OPTLEVEL?=$(DEFAULT_OPTLEVEL)
|
||||||
CXXFLAGS?=$(OPTLEVEL)
|
CFLAGS?=$(OPTLEVEL)
|
||||||
|
|
||||||
SORTIXKERNEL=../kernel
|
SORTIXKERNEL=../kernel
|
||||||
|
|
||||||
CPPFLAGS:=$(CPPFLAGS) -DVERSIONSTR=\"$(VERSION)\" -I$(SORTIXKERNEL)/include -I.
|
CPPFLAGS:=$(CPPFLAGS) -DVERSIONSTR=\"$(VERSION)\" -I$(SORTIXKERNEL)/include -I.
|
||||||
CXXFLAGS:=$(CXXFLAGS) -Wall -Wextra -fno-exceptions -fno-rtti
|
CFLAGS:=$(CFLAGS) -Wall -Wextra
|
||||||
|
|
||||||
|
ifeq ($(HOST_IS_SORTIX),0)
|
||||||
|
CPPFLAGS+=-D_GNU_SOURCE
|
||||||
|
endif
|
||||||
|
|
||||||
BINARIES=mkinitrd initrdfs
|
BINARIES=mkinitrd initrdfs
|
||||||
|
|
||||||
|
@ -17,8 +21,8 @@ all: $(BINARIES)
|
||||||
|
|
||||||
.PHONY: all install clean
|
.PHONY: all install clean
|
||||||
|
|
||||||
%: %.cpp crc32.cpp rules.cpp serialize.cpp zcrc32.c
|
%: %.c crc32.c rules.c serialize.c zcrc32.c
|
||||||
$(CXX) -std=gnu++11 $(CPPFLAGS) $(CXXFLAGS) $< crc32.cpp rules.cpp serialize.cpp zcrc32.c -o $@
|
$(CC) -std=gnu11 $(CFLAGS) $(CPPFLAGS) $< crc32.c rules.c serialize.c zcrc32.c -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(BINARIES)
|
rm -f $(BINARIES)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
crc32.cpp
|
crc32.c
|
||||||
Calculates a CRC32 Checksum on binary data.
|
Calculates a CRC32 Checksum on binary data.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
// TODO: Remove this file and this feature after releasing Sortix 1.0. Change
|
// TODO: Remove this file and this feature after releasing Sortix 1.0. Change
|
||||||
// the checksum algorithm in the initrd header to say none.
|
// the checksum algorithm in the initrd header to say none.
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
|
@ -17,7 +17,7 @@
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
initrdfs.cpp
|
initrdfs.c
|
||||||
Provides access to filesystems in the Sortix kernel initrd format.
|
Provides access to filesystems in the Sortix kernel initrd format.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
#include <error.h>
|
#include <error.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <ioleast.h>
|
#include <ioleast.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -112,8 +113,8 @@ bool ReadInodeData(int fd, initrd_superblock_t* sb, initrd_inode_t* inode,
|
||||||
return preadall(fd, dest, size, inode->dataoffset) == size;
|
return preadall(fd, dest, size, inode->dataoffset) == size;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* GetInodeData(int fd, initrd_superblock_t* sb, initrd_inode_t* inode,
|
uint8_t* GetInodeDataSize(int fd, initrd_superblock_t* sb,
|
||||||
size_t size)
|
initrd_inode_t* inode, size_t size)
|
||||||
{
|
{
|
||||||
uint8_t* buf = (uint8_t*) malloc(size);
|
uint8_t* buf = (uint8_t*) malloc(size);
|
||||||
if ( !buf ) { return NULL; }
|
if ( !buf ) { return NULL; }
|
||||||
|
@ -123,7 +124,7 @@ uint8_t* GetInodeData(int fd, initrd_superblock_t* sb, initrd_inode_t* inode,
|
||||||
|
|
||||||
uint8_t* GetInodeData(int fd, initrd_superblock_t* sb, initrd_inode_t* inode)
|
uint8_t* GetInodeData(int fd, initrd_superblock_t* sb, initrd_inode_t* inode)
|
||||||
{
|
{
|
||||||
return GetInodeData(fd, sb, inode, inode->size);
|
return GetInodeDataSize(fd, sb, inode, inode->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Traverse(int fd, initrd_superblock_t* sb, initrd_inode_t* inode,
|
uint32_t Traverse(int fd, initrd_superblock_t* sb, initrd_inode_t* inode,
|
||||||
|
@ -280,7 +281,8 @@ int main(int argc, char* argv[])
|
||||||
break;
|
break;
|
||||||
if ( arg[1] != '-' )
|
if ( arg[1] != '-' )
|
||||||
{
|
{
|
||||||
while ( char c = *++arg ) switch ( c )
|
char c;
|
||||||
|
while ( (c = *++arg) ) switch ( c )
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s: unknown option -- '%c'\n", argv0, c);
|
fprintf(stderr, "%s: unknown option -- '%c'\n", argv0, c);
|
|
@ -17,7 +17,7 @@
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
mkinitrd.cpp
|
mkinitrd.c
|
||||||
Produces a simple ramdisk filesystem readable by the Sortix kernel.
|
Produces a simple ramdisk filesystem readable by the Sortix kernel.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -32,6 +32,8 @@
|
||||||
#include <error.h>
|
#include <error.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <ioleast.h>
|
#include <ioleast.h>
|
||||||
|
#include <stdalign.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -80,18 +82,18 @@ struct DirEntry;
|
||||||
struct DirEntry
|
struct DirEntry
|
||||||
{
|
{
|
||||||
char* name;
|
char* name;
|
||||||
Node* node;
|
struct Node* node;
|
||||||
};
|
};
|
||||||
|
|
||||||
int DirEntryCompare(const DirEntry* a, const DirEntry* b)
|
int DirEntryCompare(const struct DirEntry* a, const struct DirEntry* b)
|
||||||
{
|
{
|
||||||
return strcmp(a->name, b->name);
|
return strcmp(a->name, b->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
int DirEntryCompareIndirect(const void* a_ptr, const void* b_ptr)
|
int DirEntryCompareIndirect(const void* a_ptr, const void* b_ptr)
|
||||||
{
|
{
|
||||||
const DirEntry* a = (const DirEntry*) a_ptr;
|
const struct DirEntry* a = (const struct DirEntry*) a_ptr;
|
||||||
const DirEntry* b = (const DirEntry*) b_ptr;
|
const struct DirEntry* b = (const struct DirEntry*) b_ptr;
|
||||||
return DirEntryCompare(a, b);
|
return DirEntryCompare(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +104,7 @@ struct Node
|
||||||
uint32_t nlink;
|
uint32_t nlink;
|
||||||
size_t direntsused;
|
size_t direntsused;
|
||||||
size_t direntslength;
|
size_t direntslength;
|
||||||
DirEntry* dirents;
|
struct DirEntry* dirents;
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
time_t ctime;
|
time_t ctime;
|
||||||
time_t mtime;
|
time_t mtime;
|
||||||
|
@ -110,14 +112,14 @@ struct Node
|
||||||
size_t refcount;
|
size_t refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
void FreeNode(Node* node)
|
void FreeNode(struct Node* node)
|
||||||
{
|
{
|
||||||
if ( !node )
|
if ( !node )
|
||||||
return;
|
return;
|
||||||
if ( 1 < node->nlink ) { node->nlink--; return; }
|
if ( 1 < node->nlink ) { node->nlink--; return; }
|
||||||
for ( size_t i = 0; i < node->direntsused; i++ )
|
for ( size_t i = 0; i < node->direntsused; i++ )
|
||||||
{
|
{
|
||||||
DirEntry* entry = node->dirents + i;
|
struct DirEntry* entry = node->dirents + i;
|
||||||
if ( !entry->name )
|
if ( !entry->name )
|
||||||
continue;
|
continue;
|
||||||
if ( strcmp(entry->name, ".") != 0 && strcmp(entry->name, "..") != 0 )
|
if ( strcmp(entry->name, ".") != 0 && strcmp(entry->name, "..") != 0 )
|
||||||
|
@ -136,16 +138,14 @@ struct CacheEntry
|
||||||
{
|
{
|
||||||
ino_t ino;
|
ino_t ino;
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
Node* node;
|
struct Node* node;
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t cacheused = 0;
|
static size_t cacheused = 0;
|
||||||
size_t cachelen = 0;
|
static size_t cachelen = 0;
|
||||||
CacheEntry* cache = NULL;
|
static struct CacheEntry* cache = NULL;
|
||||||
|
|
||||||
InclusionRules path_filter;
|
struct Node* LookupCache(dev_t dev, ino_t ino)
|
||||||
|
|
||||||
Node* LookupCache(dev_t dev, ino_t ino)
|
|
||||||
{
|
{
|
||||||
for ( size_t i = 0; i < cacheused; i++ )
|
for ( size_t i = 0; i < cacheused; i++ )
|
||||||
if ( cache[i].dev == dev && cache[i].ino == ino )
|
if ( cache[i].dev == dev && cache[i].ino == ino )
|
||||||
|
@ -153,13 +153,14 @@ Node* LookupCache(dev_t dev, ino_t ino)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddToCache(Node* node, dev_t dev, ino_t ino)
|
bool AddToCache(struct Node* node, dev_t dev, ino_t ino)
|
||||||
{
|
{
|
||||||
if ( cacheused == cachelen )
|
if ( cacheused == cachelen )
|
||||||
{
|
{
|
||||||
size_t newcachelen = cachelen ? 2 * cachelen : 256;
|
size_t newcachelen = cachelen ? 2 * cachelen : 256;
|
||||||
size_t newcachesize = newcachelen * sizeof(CacheEntry);
|
size_t newcachesize = newcachelen * sizeof(struct CacheEntry);
|
||||||
CacheEntry* newcache = (CacheEntry*) realloc(cache, newcachesize);
|
struct CacheEntry* newcache =
|
||||||
|
(struct CacheEntry*) realloc(cache, newcachesize);
|
||||||
if ( !newcache )
|
if ( !newcache )
|
||||||
return false;
|
return false;
|
||||||
cache = newcache;
|
cache = newcache;
|
||||||
|
@ -172,8 +173,8 @@ bool AddToCache(Node* node, dev_t dev, ino_t ino)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* RecursiveSearch(const char* real_path, const char* virt_path,
|
struct Node* RecursiveSearch(const char* real_path, const char* virt_path,
|
||||||
uint32_t* ino, Node* parent = NULL)
|
uint32_t* ino, struct Node* parent)
|
||||||
{
|
{
|
||||||
printf("%s\n", virt_path);
|
printf("%s\n", virt_path);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
@ -190,12 +191,12 @@ Node* RecursiveSearch(const char* real_path, const char* virt_path,
|
||||||
|
|
||||||
if ( !S_ISDIR(st.st_mode) && 2 <= st.st_nlink )
|
if ( !S_ISDIR(st.st_mode) && 2 <= st.st_nlink )
|
||||||
{
|
{
|
||||||
Node* cached = LookupCache(st.st_dev, st.st_ino);
|
struct Node* cached = LookupCache(st.st_dev, st.st_ino);
|
||||||
if ( cached )
|
if ( cached )
|
||||||
return cached->nlink++, cached->refcount++, cached;
|
return cached->nlink++, cached->refcount++, cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* node = (Node*) calloc(1, sizeof(Node));
|
struct Node* node = (struct Node*) calloc(1, sizeof(struct Node));
|
||||||
if ( !node )
|
if ( !node )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -256,7 +257,7 @@ Node* RecursiveSearch(const char* real_path, const char* virt_path,
|
||||||
|
|
||||||
if ( strcmp(entry->d_name, ".") != 0 &&
|
if ( strcmp(entry->d_name, ".") != 0 &&
|
||||||
strcmp(entry->d_name, "..") != 0 &&
|
strcmp(entry->d_name, "..") != 0 &&
|
||||||
!path_filter.IncludesPath(virt_subpath) )
|
!IncludesPath(virt_subpath) )
|
||||||
{
|
{
|
||||||
free(virt_subpath);
|
free(virt_subpath);
|
||||||
continue;
|
continue;
|
||||||
|
@ -273,7 +274,7 @@ Node* RecursiveSearch(const char* real_path, const char* virt_path,
|
||||||
}
|
}
|
||||||
stpcpy(stpcpy(stpcpy(real_subpath, real_path), "/"), entry->d_name);
|
stpcpy(stpcpy(stpcpy(real_subpath, real_path), "/"), entry->d_name);
|
||||||
|
|
||||||
Node* child = NULL;
|
struct Node* child = NULL;
|
||||||
if ( !strcmp(entry->d_name, ".") )
|
if ( !strcmp(entry->d_name, ".") )
|
||||||
child = node;
|
child = node;
|
||||||
if ( !strcmp(entry->d_name, "..") )
|
if ( !strcmp(entry->d_name, "..") )
|
||||||
|
@ -292,8 +293,8 @@ Node* RecursiveSearch(const char* real_path, const char* virt_path,
|
||||||
{
|
{
|
||||||
size_t oldlength = node->direntslength;
|
size_t oldlength = node->direntslength;
|
||||||
size_t newlength = oldlength ? 2 * oldlength : 8;
|
size_t newlength = oldlength ? 2 * oldlength : 8;
|
||||||
size_t newsize = sizeof(DirEntry) * newlength;
|
size_t newsize = sizeof(struct DirEntry) * newlength;
|
||||||
DirEntry* newdirents = (DirEntry*) realloc(node->dirents, newsize);
|
struct DirEntry* newdirents = (struct DirEntry*) realloc(node->dirents, newsize);
|
||||||
if ( !newdirents )
|
if ( !newdirents )
|
||||||
{
|
{
|
||||||
error(0, errno, "realloc");
|
error(0, errno, "realloc");
|
||||||
|
@ -312,7 +313,7 @@ Node* RecursiveSearch(const char* real_path, const char* virt_path,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DirEntry* entry = node->dirents + node->direntsused++;
|
struct DirEntry* entry = node->dirents + node->direntsused++;
|
||||||
|
|
||||||
entry->name = nameclone;
|
entry->name = nameclone;
|
||||||
entry->node = child;
|
entry->node = child;
|
||||||
|
@ -324,12 +325,12 @@ Node* RecursiveSearch(const char* real_path, const char* virt_path,
|
||||||
FreeNode(node);
|
FreeNode(node);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
qsort(node->dirents, node->direntsused, sizeof(DirEntry),
|
qsort(node->dirents, node->direntsused, sizeof(struct DirEntry),
|
||||||
DirEntryCompareIndirect);
|
DirEntryCompareIndirect);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* MergeNodes(Node* a, Node* b)
|
struct Node* MergeNodes(struct Node* a, struct Node* b)
|
||||||
{
|
{
|
||||||
if ( !S_ISDIR(a->mode) || !S_ISDIR(b->mode) )
|
if ( !S_ISDIR(a->mode) || !S_ISDIR(b->mode) )
|
||||||
{
|
{
|
||||||
|
@ -338,7 +339,8 @@ Node* MergeNodes(Node* a, Node* b)
|
||||||
}
|
}
|
||||||
size_t dirents_used = 0;
|
size_t dirents_used = 0;
|
||||||
size_t dirents_length = a->direntsused + b->direntsused;
|
size_t dirents_length = a->direntsused + b->direntsused;
|
||||||
DirEntry* dirents = (DirEntry*) malloc(sizeof(DirEntry) * dirents_length);
|
struct DirEntry* dirents = (struct DirEntry*)
|
||||||
|
malloc(sizeof(struct DirEntry) * dirents_length);
|
||||||
if ( !dirents )
|
if ( !dirents )
|
||||||
{
|
{
|
||||||
error(0, errno, "malloc");
|
error(0, errno, "malloc");
|
||||||
|
@ -406,12 +408,12 @@ Node* MergeNodes(Node* a, Node* b)
|
||||||
b->direntsused = 0;
|
b->direntsused = 0;
|
||||||
FreeNode(b);
|
FreeNode(b);
|
||||||
if ( failure )
|
if ( failure )
|
||||||
return FreeNode(b), (Node*) NULL;
|
return FreeNode(b), (struct Node*) NULL;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WriteNode(struct initrd_superblock* sb, int fd, const char* outputname,
|
bool WriteNode(struct initrd_superblock* sb, int fd, const char* outputname,
|
||||||
Node* node)
|
struct Node* node)
|
||||||
{
|
{
|
||||||
if ( node->written )
|
if ( node->written )
|
||||||
return true;
|
return true;
|
||||||
|
@ -459,7 +461,7 @@ bool WriteNode(struct initrd_superblock* sb, int fd, const char* outputname,
|
||||||
{
|
{
|
||||||
for ( size_t i = 0; i < node->direntsused; i++ )
|
for ( size_t i = 0; i < node->direntsused; i++ )
|
||||||
{
|
{
|
||||||
DirEntry* entry = node->dirents + i;
|
struct DirEntry* entry = node->dirents + i;
|
||||||
const char* name = entry->name;
|
const char* name = entry->name;
|
||||||
size_t namelen = strlen(entry->name);
|
size_t namelen = strlen(entry->name);
|
||||||
struct initrd_dirent dirent;
|
struct initrd_dirent dirent;
|
||||||
|
@ -513,7 +515,7 @@ bool WriteNode(struct initrd_superblock* sb, int fd, const char* outputname,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WriteNodeRecursive(struct initrd_superblock* sb, int fd,
|
bool WriteNodeRecursive(struct initrd_superblock* sb, int fd,
|
||||||
const char* outputname, Node* node)
|
const char* outputname, struct Node* node)
|
||||||
{
|
{
|
||||||
if ( !WriteNode(sb, fd, outputname, node) )
|
if ( !WriteNode(sb, fd, outputname, node) )
|
||||||
return false;
|
return false;
|
||||||
|
@ -523,9 +525,9 @@ bool WriteNodeRecursive(struct initrd_superblock* sb, int fd,
|
||||||
|
|
||||||
for ( size_t i = 0; i < node->direntsused; i++ )
|
for ( size_t i = 0; i < node->direntsused; i++ )
|
||||||
{
|
{
|
||||||
DirEntry* entry = node->dirents + i;
|
struct DirEntry* entry = node->dirents + i;
|
||||||
const char* name = entry->name;
|
const char* name = entry->name;
|
||||||
Node* child = entry->node;
|
struct Node* child = entry->node;
|
||||||
if ( !strcmp(name, ".") || !strcmp(name, ".." ) )
|
if ( !strcmp(name, ".") || !strcmp(name, ".." ) )
|
||||||
continue;
|
continue;
|
||||||
if ( !WriteNodeRecursive(sb, fd, outputname, child) )
|
if ( !WriteNodeRecursive(sb, fd, outputname, child) )
|
||||||
|
@ -535,14 +537,15 @@ bool WriteNodeRecursive(struct initrd_superblock* sb, int fd,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Format(const char* outputname, int fd, uint32_t inodecount, Node* root)
|
bool FormatFD(const char* outputname, int fd, uint32_t inodecount,
|
||||||
|
struct Node* root)
|
||||||
{
|
{
|
||||||
struct initrd_superblock sb;
|
struct initrd_superblock sb;
|
||||||
memset(&sb, 0, sizeof(sb));
|
memset(&sb, 0, sizeof(sb));
|
||||||
strncpy(sb.magic, "sortix-initrd-2", sizeof(sb.magic));
|
strncpy(sb.magic, "sortix-initrd-2", sizeof(sb.magic));
|
||||||
sb.revision = 0;
|
sb.revision = 0;
|
||||||
sb.fssize = sizeof(sb);
|
sb.fssize = sizeof(sb);
|
||||||
sb.inodesize = sizeof(initrd_inode);
|
sb.inodesize = sizeof(struct initrd_inode);
|
||||||
sb.inodeoffset = sizeof(sb);
|
sb.inodeoffset = sizeof(sb);
|
||||||
sb.inodecount = inodecount;
|
sb.inodecount = inodecount;
|
||||||
sb.root = root->ino;
|
sb.root = root->ino;
|
||||||
|
@ -587,10 +590,10 @@ bool Format(const char* outputname, int fd, uint32_t inodecount, Node* root)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Format(const char* pathname, uint32_t inodecount, Node* root)
|
bool Format(const char* pathname, uint32_t inodecount, struct Node* root)
|
||||||
{
|
{
|
||||||
int fd = open(pathname, O_RDWR | O_CREAT | O_TRUNC, 0666);
|
int fd = open(pathname, O_RDWR | O_CREAT | O_TRUNC, 0666);
|
||||||
bool result = Format(pathname, fd, inodecount, root);
|
bool result = FormatFD(pathname, fd, inodecount, root);
|
||||||
close(fd);
|
close(fd);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -673,7 +676,8 @@ int main(int argc, char* argv[])
|
||||||
break;
|
break;
|
||||||
if ( arg[1] != '-' )
|
if ( arg[1] != '-' )
|
||||||
{
|
{
|
||||||
while ( char c = *++arg ) switch ( c )
|
char c;
|
||||||
|
while ( (c = *++arg) ) switch ( c )
|
||||||
{
|
{
|
||||||
case 'o':
|
case 'o':
|
||||||
free(arg_output);
|
free(arg_output);
|
||||||
|
@ -707,7 +711,7 @@ int main(int argc, char* argv[])
|
||||||
FILE* fp = fopen(arg_filter, "r");
|
FILE* fp = fopen(arg_filter, "r");
|
||||||
if ( !fp )
|
if ( !fp )
|
||||||
error(1, errno, "%s", arg_filter);
|
error(1, errno, "%s", arg_filter);
|
||||||
if ( !path_filter.AddRulesFromFile(fp, stderr, arg_filter) )
|
if ( !AddRulesFromFile(fp, arg_filter) )
|
||||||
exit(1);
|
exit(1);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
free(arg_filter);
|
free(arg_filter);
|
||||||
|
@ -718,7 +722,7 @@ int main(int argc, char* argv[])
|
||||||
FILE* fp = fopen(arg_manifest, "r");
|
FILE* fp = fopen(arg_manifest, "r");
|
||||||
if ( !fp )
|
if ( !fp )
|
||||||
error(1, errno, "%s", arg_manifest);
|
error(1, errno, "%s", arg_manifest);
|
||||||
if ( !path_filter.AddManifestFromFile(fp, stderr, arg_manifest) )
|
if ( !AddManifestFromFile(fp, arg_manifest) )
|
||||||
exit(1);
|
exit(1);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
free(arg_manifest);
|
free(arg_manifest);
|
||||||
|
@ -769,10 +773,10 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t inodecount = 1;
|
uint32_t inodecount = 1;
|
||||||
Node* root = NULL;
|
struct Node* root = NULL;
|
||||||
for ( int i = 1; i < argc; i++ )
|
for ( int i = 1; i < argc; i++ )
|
||||||
{
|
{
|
||||||
Node* node = RecursiveSearch(argv[i], "/", &inodecount);
|
struct Node* node = RecursiveSearch(argv[i], "/", &inodecount, NULL);
|
||||||
if ( !node )
|
if ( !node )
|
||||||
exit(1);
|
exit(1);
|
||||||
if ( root )
|
if ( root )
|
|
@ -17,7 +17,7 @@
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
rules.cpp
|
rules.c
|
||||||
Determines whether a given path is included in the filesystem.
|
Determines whether a given path is included in the filesystem.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
#include <error.h>
|
#include <error.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -34,21 +35,14 @@
|
||||||
|
|
||||||
#include "rules.h"
|
#include "rules.h"
|
||||||
|
|
||||||
static void error_fp(FILE* fp, int status, int errnum, const char* format, ...)
|
static struct InclusionRule** rules;
|
||||||
{
|
static size_t num_rules;
|
||||||
fprintf(fp, "%s: ", program_invocation_name);
|
static size_t num_rules_allocated;
|
||||||
|
static bool default_inclusion = true;
|
||||||
va_list list;
|
static bool default_inclusion_determined;
|
||||||
va_start(list, format);
|
static char** manifest;
|
||||||
vfprintf(fp, format, list);
|
static size_t manifest_used;
|
||||||
va_end(list);
|
static size_t manifest_length;
|
||||||
|
|
||||||
if ( errnum )
|
|
||||||
fprintf(fp, ": %s", strerror(errnum));
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
if ( status )
|
|
||||||
exit(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* SkipCharacters(const char* str, char c)
|
static const char* SkipCharacters(const char* str, char c)
|
||||||
{
|
{
|
||||||
|
@ -84,36 +78,6 @@ static bool PathMatchesPattern(const char* path, const char* pattern)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InclusionRule::InclusionRule(const char* pattern, InclusionRuleType rule)
|
|
||||||
{
|
|
||||||
this->pattern = strdup(pattern);
|
|
||||||
this->rule = rule;
|
|
||||||
}
|
|
||||||
|
|
||||||
InclusionRule::~InclusionRule()
|
|
||||||
{
|
|
||||||
free(pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InclusionRule::MatchesPath(const char* path) const
|
|
||||||
{
|
|
||||||
return PathMatchesPattern(path, pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
InclusionRules::InclusionRules()
|
|
||||||
{
|
|
||||||
rules = NULL;
|
|
||||||
num_rules = num_rules_allocated = 0;
|
|
||||||
default_inclusion = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
InclusionRules::~InclusionRules()
|
|
||||||
{
|
|
||||||
for ( size_t i = 0; i < num_rules; i++ )
|
|
||||||
delete rules[i];
|
|
||||||
delete[] rules;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int search_path(const void* a_ptr, const void* b_ptr)
|
static int search_path(const void* a_ptr, const void* b_ptr)
|
||||||
{
|
{
|
||||||
const char* key = (const char*) a_ptr;
|
const char* key = (const char*) a_ptr;
|
||||||
|
@ -121,14 +85,14 @@ static int search_path(const void* a_ptr, const void* b_ptr)
|
||||||
return strcmp(key, path);
|
return strcmp(key, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InclusionRules::IncludesPath(const char* path) const
|
bool IncludesPath(const char* path)
|
||||||
{
|
{
|
||||||
bool determined = false;
|
bool determined = false;
|
||||||
bool included = false;
|
bool included = false;
|
||||||
for ( size_t i = 0; i < num_rules; i++ )
|
for ( size_t i = 0; i < num_rules; i++ )
|
||||||
{
|
{
|
||||||
InclusionRule* rule = rules[i];
|
struct InclusionRule* rule = rules[i];
|
||||||
if ( !rule->MatchesPath(path) )
|
if ( !PathMatchesPattern(path, rule->pattern) )
|
||||||
continue;
|
continue;
|
||||||
switch ( rules[i]->rule )
|
switch ( rules[i]->rule )
|
||||||
{
|
{
|
||||||
|
@ -152,21 +116,25 @@ bool InclusionRules::IncludesPath(const char* path) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InclusionRules::ChangeRulesAmount(size_t new_length)
|
bool ChangeRulesAmount(size_t new_length)
|
||||||
{
|
{
|
||||||
size_t new_num_rules = new_length < num_rules ? new_length : num_rules;
|
size_t new_num_rules = new_length < num_rules ? new_length : num_rules;
|
||||||
for ( size_t i = new_num_rules; i < num_rules; i++ )
|
for ( size_t i = new_num_rules; i < num_rules; i++ )
|
||||||
delete rules[i];
|
{
|
||||||
|
free(rules[i]->pattern);
|
||||||
|
free(rules[i]);
|
||||||
|
}
|
||||||
num_rules = new_num_rules;
|
num_rules = new_num_rules;
|
||||||
InclusionRule** new_rules = new InclusionRule*[new_length];
|
struct InclusionRule** new_rules = (struct InclusionRule**)
|
||||||
|
malloc(sizeof(struct InclusionRule*) * new_length);
|
||||||
for ( size_t i = 0; i < new_length && i < num_rules; i++ )
|
for ( size_t i = 0; i < new_length && i < num_rules; i++ )
|
||||||
new_rules[i] = rules[i];
|
new_rules[i] = rules[i];
|
||||||
delete[] rules; rules = new_rules;
|
free(rules); rules = new_rules;
|
||||||
num_rules_allocated = new_length;
|
num_rules_allocated = new_length;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InclusionRules::AddRule(InclusionRule* rule)
|
bool AddRule(struct InclusionRule* rule)
|
||||||
{
|
{
|
||||||
if ( num_rules == num_rules_allocated )
|
if ( num_rules == num_rules_allocated )
|
||||||
{
|
{
|
||||||
|
@ -185,11 +153,6 @@ static const char* SkipWhitespace(const char* line)
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* SkipWhitespace(char* line)
|
|
||||||
{
|
|
||||||
return (char*) SkipWhitespace((const char*) line);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool IsLineComment(const char* line)
|
static bool IsLineComment(const char* line)
|
||||||
{
|
{
|
||||||
return !*line || *line == '#';
|
return !*line || *line == '#';
|
||||||
|
@ -209,7 +172,7 @@ static const char* IsLineCommand(const char* line, const char* command)
|
||||||
return line + cmdlen;
|
return line + cmdlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InclusionRules::AddRulesFromFile(FILE* fp, FILE* err, const char* fpname)
|
bool AddRulesFromFile(FILE* fp, const char* fpname)
|
||||||
{
|
{
|
||||||
size_t rules_at_start = num_rules;
|
size_t rules_at_start = num_rules;
|
||||||
size_t line_size;
|
size_t line_size;
|
||||||
|
@ -222,7 +185,7 @@ bool InclusionRules::AddRulesFromFile(FILE* fp, FILE* err, const char* fpname)
|
||||||
line_num++;
|
line_num++;
|
||||||
if ( line_len && line[line_len-1] == '\n' )
|
if ( line_len && line[line_len-1] == '\n' )
|
||||||
line[line_len-1] = '\0';
|
line[line_len-1] = '\0';
|
||||||
line = SkipWhitespace(line);
|
line = (char*) SkipWhitespace((char*) line);
|
||||||
if ( IsLineComment(line) )
|
if ( IsLineComment(line) )
|
||||||
continue;
|
continue;
|
||||||
const char* parameter;
|
const char* parameter;
|
||||||
|
@ -235,7 +198,7 @@ bool InclusionRules::AddRulesFromFile(FILE* fp, FILE* err, const char* fpname)
|
||||||
value = false;
|
value = false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_fp(err, 0, 0, "%s:%zu: not a boolean '%s'", fpname,
|
error(0, 0, "%s:%zu: not a boolean '%s'", fpname,
|
||||||
line_num, parameter);
|
line_num, parameter);
|
||||||
goto error_out;
|
goto error_out;
|
||||||
}
|
}
|
||||||
|
@ -250,19 +213,22 @@ bool InclusionRules::AddRulesFromFile(FILE* fp, FILE* err, const char* fpname)
|
||||||
{
|
{
|
||||||
if ( !*parameter )
|
if ( !*parameter )
|
||||||
{
|
{
|
||||||
error_fp(err, 0, 0, "%s:%zu: no parameter given", fpname,
|
error(0, 0, "%s:%zu: no parameter given", fpname,
|
||||||
line_num);
|
line_num);
|
||||||
goto error_out;
|
goto error_out;
|
||||||
}
|
}
|
||||||
const char* pattern = parameter;
|
const char* pattern = parameter;
|
||||||
InclusionRuleType type = line[0] == 'e' ? RULE_EXCLUDE : RULE_INCLUDE;
|
enum InclusionRuleType type = line[0] == 'e' ? RULE_EXCLUDE : RULE_INCLUDE;
|
||||||
InclusionRule* rule = new InclusionRule(pattern, type);
|
struct InclusionRule* rule =
|
||||||
|
(struct InclusionRule*) malloc(sizeof(struct InclusionRule));
|
||||||
|
rule->pattern = strdup(pattern);
|
||||||
|
rule->rule = type;
|
||||||
if ( !AddRule(rule) )
|
if ( !AddRule(rule) )
|
||||||
goto error_out_errno;
|
goto error_out_errno;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_fp(err, 0, 0, "%s:%zu: line not understood: '%s'", fpname,
|
error(0, 0, "%s:%zu: line not understood: '%s'", fpname,
|
||||||
line_num, line);
|
line_num, line);
|
||||||
goto error_out;
|
goto error_out;
|
||||||
}
|
}
|
||||||
|
@ -271,7 +237,7 @@ bool InclusionRules::AddRulesFromFile(FILE* fp, FILE* err, const char* fpname)
|
||||||
if ( ferror(fp) )
|
if ( ferror(fp) )
|
||||||
{
|
{
|
||||||
error_out_errno:
|
error_out_errno:
|
||||||
error_fp(err, 0, errno, "%s", fpname);
|
error(0, errno, "%s", fpname);
|
||||||
error_out:
|
error_out:
|
||||||
ChangeRulesAmount(rules_at_start);
|
ChangeRulesAmount(rules_at_start);
|
||||||
return false;
|
return false;
|
||||||
|
@ -286,7 +252,7 @@ int compare_path(const void* a_ptr, const void* b_ptr)
|
||||||
return strcmp(a, b);
|
return strcmp(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InclusionRules::AddManifestPath(const char* path, FILE* err)
|
bool AddManifestPath(const char* path)
|
||||||
{
|
{
|
||||||
if ( manifest_used == manifest_length )
|
if ( manifest_used == manifest_length )
|
||||||
{
|
{
|
||||||
|
@ -297,7 +263,7 @@ bool InclusionRules::AddManifestPath(const char* path, FILE* err)
|
||||||
char** new_manifest = (char**) realloc(manifest, new_size);
|
char** new_manifest = (char**) realloc(manifest, new_size);
|
||||||
if ( !new_manifest )
|
if ( !new_manifest )
|
||||||
{
|
{
|
||||||
error_fp(err, 0, errno, "malloc");
|
error(0, errno, "malloc");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
manifest = new_manifest;
|
manifest = new_manifest;
|
||||||
|
@ -306,14 +272,14 @@ bool InclusionRules::AddManifestPath(const char* path, FILE* err)
|
||||||
char* copy = strdup(path);
|
char* copy = strdup(path);
|
||||||
if ( !copy )
|
if ( !copy )
|
||||||
{
|
{
|
||||||
error_fp(err, 0, errno, "malloc");
|
error(0, errno, "malloc");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
manifest[manifest_used++] = copy;
|
manifest[manifest_used++] = copy;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InclusionRules::AddManifestFromFile(FILE* fp, FILE* err, const char* fpname)
|
bool AddManifestFromFile(FILE* fp, const char* fpname)
|
||||||
{
|
{
|
||||||
char* line = NULL;
|
char* line = NULL;
|
||||||
size_t line_size = 0;
|
size_t line_size = 0;
|
||||||
|
@ -322,23 +288,23 @@ bool InclusionRules::AddManifestFromFile(FILE* fp, FILE* err, const char* fpname
|
||||||
{
|
{
|
||||||
if ( line_len && line[line_len-1] == '\n' )
|
if ( line_len && line[line_len-1] == '\n' )
|
||||||
line[line_len-1] = '\0';
|
line[line_len-1] = '\0';
|
||||||
if ( !AddManifestPath(line, err) )
|
if ( !AddManifestPath(line) )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
free(line);
|
free(line);
|
||||||
if ( ferror(fp) )
|
if ( ferror(fp) )
|
||||||
{
|
{
|
||||||
error_fp(err, 0, errno, "%s", fpname);
|
error(0, errno, "%s", fpname);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( !AddManifestPath("/", err) ||
|
if ( !AddManifestPath("/") ||
|
||||||
!AddManifestPath("/tix", err) ||
|
!AddManifestPath("/tix") ||
|
||||||
!AddManifestPath("/tix/manifest", err) )
|
!AddManifestPath("/tix/manifest") )
|
||||||
return false;
|
return false;
|
||||||
char* fpname_copy = strdup(fpname);
|
char* fpname_copy = strdup(fpname);
|
||||||
if ( !fpname_copy )
|
if ( !fpname_copy )
|
||||||
{
|
{
|
||||||
error_fp(err, 0, errno, "malloc");
|
error(0, errno, "malloc");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const char* fpname_basename = basename(fpname_copy);
|
const char* fpname_basename = basename(fpname_copy);
|
||||||
|
@ -346,11 +312,11 @@ bool InclusionRules::AddManifestFromFile(FILE* fp, FILE* err, const char* fpname
|
||||||
if ( asprintf(&manifest_path, "/tix/manifest/%s", fpname_basename) < 0 )
|
if ( asprintf(&manifest_path, "/tix/manifest/%s", fpname_basename) < 0 )
|
||||||
{
|
{
|
||||||
free(fpname_copy);
|
free(fpname_copy);
|
||||||
error_fp(err, 0, errno, "malloc");
|
error(0, errno, "malloc");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
free(fpname_copy);
|
free(fpname_copy);
|
||||||
if ( !AddManifestPath(manifest_path, err) )
|
if ( !AddManifestPath(manifest_path) )
|
||||||
return free(manifest_path), false;
|
return free(manifest_path), false;
|
||||||
free(manifest_path);
|
free(manifest_path);
|
||||||
qsort(manifest, manifest_used, sizeof(char*), compare_path);
|
qsort(manifest, manifest_used, sizeof(char*), compare_path);
|
|
@ -31,41 +31,17 @@ enum InclusionRuleType
|
||||||
RULE_EXCLUDE,
|
RULE_EXCLUDE,
|
||||||
};
|
};
|
||||||
|
|
||||||
class InclusionRule
|
struct InclusionRule
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
InclusionRule(const char* pattern, InclusionRuleType rule);
|
|
||||||
~InclusionRule();
|
|
||||||
bool MatchesPath(const char* path) const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
char* pattern;
|
char* pattern;
|
||||||
InclusionRuleType rule;
|
enum InclusionRuleType rule;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class InclusionRules
|
bool IncludesPath(const char* path);
|
||||||
{
|
bool AddRule(struct InclusionRule* rule);
|
||||||
public:
|
bool AddRulesFromFile(FILE* fp, const char* fpname);
|
||||||
InclusionRules();
|
bool AddManifestFromFile(FILE* fp, const char* fpname);
|
||||||
~InclusionRules();
|
bool AddManifestPath(const char* path);
|
||||||
bool IncludesPath(const char* path) const;
|
bool ChangeRulesAmount(size_t newnum);
|
||||||
bool AddRule(InclusionRule* rule);
|
|
||||||
bool AddRulesFromFile(FILE* fp, FILE* err, const char* fpname);
|
|
||||||
bool AddManifestFromFile(FILE* fp, FILE* err, const char* fpname);
|
|
||||||
bool AddManifestPath(const char* path, FILE* err);
|
|
||||||
bool ChangeRulesAmount(size_t newnum);
|
|
||||||
|
|
||||||
public:
|
|
||||||
InclusionRule** rules;
|
|
||||||
size_t num_rules;
|
|
||||||
size_t num_rules_allocated;
|
|
||||||
bool default_inclusion;
|
|
||||||
bool default_inclusion_determined;
|
|
||||||
char** manifest;
|
|
||||||
size_t manifest_used;
|
|
||||||
size_t manifest_length;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
serialize.cpp
|
serialize.c
|
||||||
Import and export binary data structures
|
Import and export binary data structures
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
Loading…
Reference in a new issue