Convert mkinitrd to C.

This commit is contained in:
Jonas 'Sortie' Termansen 2016-02-28 23:03:16 +01:00
parent f16a7693d6
commit 9ea3edf36f
7 changed files with 120 additions and 167 deletions

View File

@ -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)

View File

@ -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>

View File

@ -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);

View File

@ -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 )

View File

@ -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);

View File

@ -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

View File

@ -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
*******************************************************************************/ *******************************************************************************/