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
|
||||
|
||||
OPTLEVEL?=$(DEFAULT_OPTLEVEL)
|
||||
CXXFLAGS?=$(OPTLEVEL)
|
||||
CFLAGS?=$(OPTLEVEL)
|
||||
|
||||
SORTIXKERNEL=../kernel
|
||||
|
||||
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
|
||||
|
||||
|
@ -17,8 +21,8 @@ all: $(BINARIES)
|
|||
|
||||
.PHONY: all install clean
|
||||
|
||||
%: %.cpp crc32.cpp rules.cpp serialize.cpp zcrc32.c
|
||||
$(CXX) -std=gnu++11 $(CPPFLAGS) $(CXXFLAGS) $< crc32.cpp rules.cpp serialize.cpp zcrc32.c -o $@
|
||||
%: %.c crc32.c rules.c serialize.c zcrc32.c
|
||||
$(CC) -std=gnu11 $(CFLAGS) $(CPPFLAGS) $< crc32.c rules.c serialize.c zcrc32.c -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(BINARIES)
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
You should have received a copy of the GNU General Public License along
|
||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
crc32.cpp
|
||||
crc32.c
|
||||
Calculates a CRC32 Checksum on binary data.
|
||||
|
||||
*******************************************************************************/
|
||||
|
@ -25,6 +25,7 @@
|
|||
// TODO: Remove this file and this feature after releasing Sortix 1.0. Change
|
||||
// the checksum algorithm in the initrd header to say none.
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
|
@ -17,7 +17,7 @@
|
|||
You should have received a copy of the GNU General Public License along
|
||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
initrdfs.cpp
|
||||
initrdfs.c
|
||||
Provides access to filesystems in the Sortix kernel initrd format.
|
||||
|
||||
*******************************************************************************/
|
||||
|
@ -27,6 +27,7 @@
|
|||
#include <error.h>
|
||||
#include <fcntl.h>
|
||||
#include <ioleast.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.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;
|
||||
}
|
||||
|
||||
uint8_t* GetInodeData(int fd, initrd_superblock_t* sb, initrd_inode_t* inode,
|
||||
size_t size)
|
||||
uint8_t* GetInodeDataSize(int fd, initrd_superblock_t* sb,
|
||||
initrd_inode_t* inode, size_t size)
|
||||
{
|
||||
uint8_t* buf = (uint8_t*) malloc(size);
|
||||
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)
|
||||
{
|
||||
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,
|
||||
|
@ -280,7 +281,8 @@ int main(int argc, char* argv[])
|
|||
break;
|
||||
if ( arg[1] != '-' )
|
||||
{
|
||||
while ( char c = *++arg ) switch ( c )
|
||||
char c;
|
||||
while ( (c = *++arg) ) switch ( c )
|
||||
{
|
||||
default:
|
||||
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
|
||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
mkinitrd.cpp
|
||||
mkinitrd.c
|
||||
Produces a simple ramdisk filesystem readable by the Sortix kernel.
|
||||
|
||||
*******************************************************************************/
|
||||
|
@ -32,6 +32,8 @@
|
|||
#include <error.h>
|
||||
#include <fcntl.h>
|
||||
#include <ioleast.h>
|
||||
#include <stdalign.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -80,18 +82,18 @@ struct DirEntry;
|
|||
struct DirEntry
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
int DirEntryCompareIndirect(const void* a_ptr, const void* b_ptr)
|
||||
{
|
||||
const DirEntry* a = (const DirEntry*) a_ptr;
|
||||
const DirEntry* b = (const DirEntry*) b_ptr;
|
||||
const struct DirEntry* a = (const struct DirEntry*) a_ptr;
|
||||
const struct DirEntry* b = (const struct DirEntry*) b_ptr;
|
||||
return DirEntryCompare(a, b);
|
||||
}
|
||||
|
||||
|
@ -102,7 +104,7 @@ struct Node
|
|||
uint32_t nlink;
|
||||
size_t direntsused;
|
||||
size_t direntslength;
|
||||
DirEntry* dirents;
|
||||
struct DirEntry* dirents;
|
||||
mode_t mode;
|
||||
time_t ctime;
|
||||
time_t mtime;
|
||||
|
@ -110,14 +112,14 @@ struct Node
|
|||
size_t refcount;
|
||||
};
|
||||
|
||||
void FreeNode(Node* node)
|
||||
void FreeNode(struct Node* node)
|
||||
{
|
||||
if ( !node )
|
||||
return;
|
||||
if ( 1 < node->nlink ) { node->nlink--; return; }
|
||||
for ( size_t i = 0; i < node->direntsused; i++ )
|
||||
{
|
||||
DirEntry* entry = node->dirents + i;
|
||||
struct DirEntry* entry = node->dirents + i;
|
||||
if ( !entry->name )
|
||||
continue;
|
||||
if ( strcmp(entry->name, ".") != 0 && strcmp(entry->name, "..") != 0 )
|
||||
|
@ -136,16 +138,14 @@ struct CacheEntry
|
|||
{
|
||||
ino_t ino;
|
||||
dev_t dev;
|
||||
Node* node;
|
||||
struct Node* node;
|
||||
};
|
||||
|
||||
size_t cacheused = 0;
|
||||
size_t cachelen = 0;
|
||||
CacheEntry* cache = NULL;
|
||||
static size_t cacheused = 0;
|
||||
static size_t cachelen = 0;
|
||||
static struct CacheEntry* cache = NULL;
|
||||
|
||||
InclusionRules path_filter;
|
||||
|
||||
Node* LookupCache(dev_t dev, ino_t ino)
|
||||
struct Node* LookupCache(dev_t dev, ino_t ino)
|
||||
{
|
||||
for ( size_t i = 0; i < cacheused; i++ )
|
||||
if ( cache[i].dev == dev && cache[i].ino == ino )
|
||||
|
@ -153,13 +153,14 @@ Node* LookupCache(dev_t dev, ino_t ino)
|
|||
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 )
|
||||
{
|
||||
size_t newcachelen = cachelen ? 2 * cachelen : 256;
|
||||
size_t newcachesize = newcachelen * sizeof(CacheEntry);
|
||||
CacheEntry* newcache = (CacheEntry*) realloc(cache, newcachesize);
|
||||
size_t newcachesize = newcachelen * sizeof(struct CacheEntry);
|
||||
struct CacheEntry* newcache =
|
||||
(struct CacheEntry*) realloc(cache, newcachesize);
|
||||
if ( !newcache )
|
||||
return false;
|
||||
cache = newcache;
|
||||
|
@ -172,8 +173,8 @@ bool AddToCache(Node* node, dev_t dev, ino_t ino)
|
|||
return true;
|
||||
}
|
||||
|
||||
Node* RecursiveSearch(const char* real_path, const char* virt_path,
|
||||
uint32_t* ino, Node* parent = NULL)
|
||||
struct Node* RecursiveSearch(const char* real_path, const char* virt_path,
|
||||
uint32_t* ino, struct Node* parent)
|
||||
{
|
||||
printf("%s\n", virt_path);
|
||||
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 )
|
||||
{
|
||||
Node* cached = LookupCache(st.st_dev, st.st_ino);
|
||||
struct Node* cached = LookupCache(st.st_dev, st.st_ino);
|
||||
if ( 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 )
|
||||
return NULL;
|
||||
|
||||
|
@ -256,7 +257,7 @@ Node* RecursiveSearch(const char* real_path, const char* virt_path,
|
|||
|
||||
if ( strcmp(entry->d_name, ".") != 0 &&
|
||||
strcmp(entry->d_name, "..") != 0 &&
|
||||
!path_filter.IncludesPath(virt_subpath) )
|
||||
!IncludesPath(virt_subpath) )
|
||||
{
|
||||
free(virt_subpath);
|
||||
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);
|
||||
|
||||
Node* child = NULL;
|
||||
struct Node* child = NULL;
|
||||
if ( !strcmp(entry->d_name, ".") )
|
||||
child = node;
|
||||
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 newlength = oldlength ? 2 * oldlength : 8;
|
||||
size_t newsize = sizeof(DirEntry) * newlength;
|
||||
DirEntry* newdirents = (DirEntry*) realloc(node->dirents, newsize);
|
||||
size_t newsize = sizeof(struct DirEntry) * newlength;
|
||||
struct DirEntry* newdirents = (struct DirEntry*) realloc(node->dirents, newsize);
|
||||
if ( !newdirents )
|
||||
{
|
||||
error(0, errno, "realloc");
|
||||
|
@ -312,7 +313,7 @@ Node* RecursiveSearch(const char* real_path, const char* virt_path,
|
|||
break;
|
||||
}
|
||||
|
||||
DirEntry* entry = node->dirents + node->direntsused++;
|
||||
struct DirEntry* entry = node->dirents + node->direntsused++;
|
||||
|
||||
entry->name = nameclone;
|
||||
entry->node = child;
|
||||
|
@ -324,12 +325,12 @@ Node* RecursiveSearch(const char* real_path, const char* virt_path,
|
|||
FreeNode(node);
|
||||
return NULL;
|
||||
}
|
||||
qsort(node->dirents, node->direntsused, sizeof(DirEntry),
|
||||
qsort(node->dirents, node->direntsused, sizeof(struct DirEntry),
|
||||
DirEntryCompareIndirect);
|
||||
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) )
|
||||
{
|
||||
|
@ -338,7 +339,8 @@ Node* MergeNodes(Node* a, Node* b)
|
|||
}
|
||||
size_t dirents_used = 0;
|
||||
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 )
|
||||
{
|
||||
error(0, errno, "malloc");
|
||||
|
@ -406,12 +408,12 @@ Node* MergeNodes(Node* a, Node* b)
|
|||
b->direntsused = 0;
|
||||
FreeNode(b);
|
||||
if ( failure )
|
||||
return FreeNode(b), (Node*) NULL;
|
||||
return FreeNode(b), (struct Node*) NULL;
|
||||
return a;
|
||||
}
|
||||
|
||||
bool WriteNode(struct initrd_superblock* sb, int fd, const char* outputname,
|
||||
Node* node)
|
||||
struct Node* node)
|
||||
{
|
||||
if ( node->written )
|
||||
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++ )
|
||||
{
|
||||
DirEntry* entry = node->dirents + i;
|
||||
struct DirEntry* entry = node->dirents + i;
|
||||
const char* name = entry->name;
|
||||
size_t namelen = strlen(entry->name);
|
||||
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,
|
||||
const char* outputname, Node* node)
|
||||
const char* outputname, struct Node* node)
|
||||
{
|
||||
if ( !WriteNode(sb, fd, outputname, node) )
|
||||
return false;
|
||||
|
@ -523,9 +525,9 @@ bool WriteNodeRecursive(struct initrd_superblock* sb, int fd,
|
|||
|
||||
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;
|
||||
Node* child = entry->node;
|
||||
struct Node* child = entry->node;
|
||||
if ( !strcmp(name, ".") || !strcmp(name, ".." ) )
|
||||
continue;
|
||||
if ( !WriteNodeRecursive(sb, fd, outputname, child) )
|
||||
|
@ -535,14 +537,15 @@ bool WriteNodeRecursive(struct initrd_superblock* sb, int fd,
|
|||
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;
|
||||
memset(&sb, 0, sizeof(sb));
|
||||
strncpy(sb.magic, "sortix-initrd-2", sizeof(sb.magic));
|
||||
sb.revision = 0;
|
||||
sb.fssize = sizeof(sb);
|
||||
sb.inodesize = sizeof(initrd_inode);
|
||||
sb.inodesize = sizeof(struct initrd_inode);
|
||||
sb.inodeoffset = sizeof(sb);
|
||||
sb.inodecount = inodecount;
|
||||
sb.root = root->ino;
|
||||
|
@ -587,10 +590,10 @@ bool Format(const char* outputname, int fd, uint32_t inodecount, Node* root)
|
|||
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);
|
||||
bool result = Format(pathname, fd, inodecount, root);
|
||||
bool result = FormatFD(pathname, fd, inodecount, root);
|
||||
close(fd);
|
||||
return result;
|
||||
}
|
||||
|
@ -673,7 +676,8 @@ int main(int argc, char* argv[])
|
|||
break;
|
||||
if ( arg[1] != '-' )
|
||||
{
|
||||
while ( char c = *++arg ) switch ( c )
|
||||
char c;
|
||||
while ( (c = *++arg) ) switch ( c )
|
||||
{
|
||||
case 'o':
|
||||
free(arg_output);
|
||||
|
@ -707,7 +711,7 @@ int main(int argc, char* argv[])
|
|||
FILE* fp = fopen(arg_filter, "r");
|
||||
if ( !fp )
|
||||
error(1, errno, "%s", arg_filter);
|
||||
if ( !path_filter.AddRulesFromFile(fp, stderr, arg_filter) )
|
||||
if ( !AddRulesFromFile(fp, arg_filter) )
|
||||
exit(1);
|
||||
fclose(fp);
|
||||
free(arg_filter);
|
||||
|
@ -718,7 +722,7 @@ int main(int argc, char* argv[])
|
|||
FILE* fp = fopen(arg_manifest, "r");
|
||||
if ( !fp )
|
||||
error(1, errno, "%s", arg_manifest);
|
||||
if ( !path_filter.AddManifestFromFile(fp, stderr, arg_manifest) )
|
||||
if ( !AddManifestFromFile(fp, arg_manifest) )
|
||||
exit(1);
|
||||
fclose(fp);
|
||||
free(arg_manifest);
|
||||
|
@ -769,10 +773,10 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
uint32_t inodecount = 1;
|
||||
Node* root = NULL;
|
||||
struct Node* root = NULL;
|
||||
for ( int i = 1; i < argc; i++ )
|
||||
{
|
||||
Node* node = RecursiveSearch(argv[i], "/", &inodecount);
|
||||
struct Node* node = RecursiveSearch(argv[i], "/", &inodecount, NULL);
|
||||
if ( !node )
|
||||
exit(1);
|
||||
if ( root )
|
|
@ -17,7 +17,7 @@
|
|||
You should have received a copy of the GNU General Public License along
|
||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
rules.cpp
|
||||
rules.c
|
||||
Determines whether a given path is included in the filesystem.
|
||||
|
||||
*******************************************************************************/
|
||||
|
@ -27,6 +27,7 @@
|
|||
#include <error.h>
|
||||
#include <libgen.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -34,21 +35,14 @@
|
|||
|
||||
#include "rules.h"
|
||||
|
||||
static void error_fp(FILE* fp, int status, int errnum, const char* format, ...)
|
||||
{
|
||||
fprintf(fp, "%s: ", program_invocation_name);
|
||||
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
vfprintf(fp, format, list);
|
||||
va_end(list);
|
||||
|
||||
if ( errnum )
|
||||
fprintf(fp, ": %s", strerror(errnum));
|
||||
fprintf(fp, "\n");
|
||||
if ( status )
|
||||
exit(status);
|
||||
}
|
||||
static struct InclusionRule** rules;
|
||||
static size_t num_rules;
|
||||
static size_t num_rules_allocated;
|
||||
static bool default_inclusion = true;
|
||||
static bool default_inclusion_determined;
|
||||
static char** manifest;
|
||||
static size_t manifest_used;
|
||||
static size_t manifest_length;
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
bool InclusionRules::IncludesPath(const char* path) const
|
||||
bool IncludesPath(const char* path)
|
||||
{
|
||||
bool determined = false;
|
||||
bool included = false;
|
||||
for ( size_t i = 0; i < num_rules; i++ )
|
||||
{
|
||||
InclusionRule* rule = rules[i];
|
||||
if ( !rule->MatchesPath(path) )
|
||||
struct InclusionRule* rule = rules[i];
|
||||
if ( !PathMatchesPattern(path, rule->pattern) )
|
||||
continue;
|
||||
switch ( rules[i]->rule )
|
||||
{
|
||||
|
@ -152,21 +116,25 @@ bool InclusionRules::IncludesPath(const char* path) const
|
|||
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;
|
||||
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;
|
||||
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++ )
|
||||
new_rules[i] = rules[i];
|
||||
delete[] rules; rules = new_rules;
|
||||
free(rules); rules = new_rules;
|
||||
num_rules_allocated = new_length;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InclusionRules::AddRule(InclusionRule* rule)
|
||||
bool AddRule(struct InclusionRule* rule)
|
||||
{
|
||||
if ( num_rules == num_rules_allocated )
|
||||
{
|
||||
|
@ -185,11 +153,6 @@ static const char* SkipWhitespace(const char* line)
|
|||
return line;
|
||||
}
|
||||
|
||||
static char* SkipWhitespace(char* line)
|
||||
{
|
||||
return (char*) SkipWhitespace((const char*) line);
|
||||
}
|
||||
|
||||
static bool IsLineComment(const char* line)
|
||||
{
|
||||
return !*line || *line == '#';
|
||||
|
@ -209,7 +172,7 @@ static const char* IsLineCommand(const char* line, const char* command)
|
|||
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 line_size;
|
||||
|
@ -222,7 +185,7 @@ bool InclusionRules::AddRulesFromFile(FILE* fp, FILE* err, const char* fpname)
|
|||
line_num++;
|
||||
if ( line_len && line[line_len-1] == '\n' )
|
||||
line[line_len-1] = '\0';
|
||||
line = SkipWhitespace(line);
|
||||
line = (char*) SkipWhitespace((char*) line);
|
||||
if ( IsLineComment(line) )
|
||||
continue;
|
||||
const char* parameter;
|
||||
|
@ -235,7 +198,7 @@ bool InclusionRules::AddRulesFromFile(FILE* fp, FILE* err, const char* fpname)
|
|||
value = false;
|
||||
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);
|
||||
goto error_out;
|
||||
}
|
||||
|
@ -250,19 +213,22 @@ bool InclusionRules::AddRulesFromFile(FILE* fp, FILE* err, const char* fpname)
|
|||
{
|
||||
if ( !*parameter )
|
||||
{
|
||||
error_fp(err, 0, 0, "%s:%zu: no parameter given", fpname,
|
||||
error(0, 0, "%s:%zu: no parameter given", fpname,
|
||||
line_num);
|
||||
goto error_out;
|
||||
}
|
||||
const char* pattern = parameter;
|
||||
InclusionRuleType type = line[0] == 'e' ? RULE_EXCLUDE : RULE_INCLUDE;
|
||||
InclusionRule* rule = new InclusionRule(pattern, type);
|
||||
enum InclusionRuleType type = line[0] == 'e' ? RULE_EXCLUDE : RULE_INCLUDE;
|
||||
struct InclusionRule* rule =
|
||||
(struct InclusionRule*) malloc(sizeof(struct InclusionRule));
|
||||
rule->pattern = strdup(pattern);
|
||||
rule->rule = type;
|
||||
if ( !AddRule(rule) )
|
||||
goto error_out_errno;
|
||||
}
|
||||
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);
|
||||
goto error_out;
|
||||
}
|
||||
|
@ -271,7 +237,7 @@ bool InclusionRules::AddRulesFromFile(FILE* fp, FILE* err, const char* fpname)
|
|||
if ( ferror(fp) )
|
||||
{
|
||||
error_out_errno:
|
||||
error_fp(err, 0, errno, "%s", fpname);
|
||||
error(0, errno, "%s", fpname);
|
||||
error_out:
|
||||
ChangeRulesAmount(rules_at_start);
|
||||
return false;
|
||||
|
@ -286,7 +252,7 @@ int compare_path(const void* a_ptr, const void* b_ptr)
|
|||
return strcmp(a, b);
|
||||
}
|
||||
|
||||
bool InclusionRules::AddManifestPath(const char* path, FILE* err)
|
||||
bool AddManifestPath(const char* path)
|
||||
{
|
||||
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);
|
||||
if ( !new_manifest )
|
||||
{
|
||||
error_fp(err, 0, errno, "malloc");
|
||||
error(0, errno, "malloc");
|
||||
return false;
|
||||
}
|
||||
manifest = new_manifest;
|
||||
|
@ -306,14 +272,14 @@ bool InclusionRules::AddManifestPath(const char* path, FILE* err)
|
|||
char* copy = strdup(path);
|
||||
if ( !copy )
|
||||
{
|
||||
error_fp(err, 0, errno, "malloc");
|
||||
error(0, errno, "malloc");
|
||||
return false;
|
||||
}
|
||||
manifest[manifest_used++] = copy;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InclusionRules::AddManifestFromFile(FILE* fp, FILE* err, const char* fpname)
|
||||
bool AddManifestFromFile(FILE* fp, const char* fpname)
|
||||
{
|
||||
char* line = NULL;
|
||||
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' )
|
||||
line[line_len-1] = '\0';
|
||||
if ( !AddManifestPath(line, err) )
|
||||
if ( !AddManifestPath(line) )
|
||||
return false;
|
||||
}
|
||||
free(line);
|
||||
if ( ferror(fp) )
|
||||
{
|
||||
error_fp(err, 0, errno, "%s", fpname);
|
||||
error(0, errno, "%s", fpname);
|
||||
return false;
|
||||
}
|
||||
if ( !AddManifestPath("/", err) ||
|
||||
!AddManifestPath("/tix", err) ||
|
||||
!AddManifestPath("/tix/manifest", err) )
|
||||
if ( !AddManifestPath("/") ||
|
||||
!AddManifestPath("/tix") ||
|
||||
!AddManifestPath("/tix/manifest") )
|
||||
return false;
|
||||
char* fpname_copy = strdup(fpname);
|
||||
if ( !fpname_copy )
|
||||
{
|
||||
error_fp(err, 0, errno, "malloc");
|
||||
error(0, errno, "malloc");
|
||||
return false;
|
||||
}
|
||||
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 )
|
||||
{
|
||||
free(fpname_copy);
|
||||
error_fp(err, 0, errno, "malloc");
|
||||
error(0, errno, "malloc");
|
||||
return false;
|
||||
}
|
||||
free(fpname_copy);
|
||||
if ( !AddManifestPath(manifest_path, err) )
|
||||
if ( !AddManifestPath(manifest_path) )
|
||||
return free(manifest_path), false;
|
||||
free(manifest_path);
|
||||
qsort(manifest, manifest_used, sizeof(char*), compare_path);
|
|
@ -31,41 +31,17 @@ enum InclusionRuleType
|
|||
RULE_EXCLUDE,
|
||||
};
|
||||
|
||||
class InclusionRule
|
||||
struct InclusionRule
|
||||
{
|
||||
public:
|
||||
InclusionRule(const char* pattern, InclusionRuleType rule);
|
||||
~InclusionRule();
|
||||
bool MatchesPath(const char* path) const;
|
||||
|
||||
public:
|
||||
char* pattern;
|
||||
InclusionRuleType rule;
|
||||
|
||||
enum InclusionRuleType rule;
|
||||
};
|
||||
|
||||
class InclusionRules
|
||||
{
|
||||
public:
|
||||
InclusionRules();
|
||||
~InclusionRules();
|
||||
bool IncludesPath(const char* path) const;
|
||||
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;
|
||||
|
||||
};
|
||||
bool IncludesPath(const char* path);
|
||||
bool AddRule(struct InclusionRule* rule);
|
||||
bool AddRulesFromFile(FILE* fp, const char* fpname);
|
||||
bool AddManifestFromFile(FILE* fp, const char* fpname);
|
||||
bool AddManifestPath(const char* path);
|
||||
bool ChangeRulesAmount(size_t newnum);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
You should have received a copy of the GNU General Public License along
|
||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
serialize.cpp
|
||||
serialize.c
|
||||
Import and export binary data structures
|
||||
|
||||
*******************************************************************************/
|
Loading…
Reference in a new issue