From 4533a2ade28a8b70e77ca3aad3ab7aa85c16718b Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sun, 16 Jul 2023 14:56:31 +0200 Subject: [PATCH] Remove mkinitrd(8). --- Makefile | 4 - kernel/include/sortix/initrd.h | 92 ---- kernel/initrd.cpp | 268 +----------- mkinitrd/.gitignore | 2 - mkinitrd/Makefile | 35 -- mkinitrd/initrdfs.8 | 67 --- mkinitrd/initrdfs.c | 395 ----------------- mkinitrd/ioleast.h | 150 ------- mkinitrd/mkinitrd.8 | 126 ------ mkinitrd/mkinitrd.c | 776 --------------------------------- mkinitrd/rules.c | 317 -------------- mkinitrd/rules.h | 42 -- mkinitrd/serialize.c | 84 ---- mkinitrd/serialize.h | 32 -- share/man/man7/development.7 | 2 - share/man/man7/kernel.7 | 4 - 16 files changed, 3 insertions(+), 2393 deletions(-) delete mode 100644 kernel/include/sortix/initrd.h delete mode 100644 mkinitrd/.gitignore delete mode 100644 mkinitrd/Makefile delete mode 100644 mkinitrd/initrdfs.8 delete mode 100644 mkinitrd/initrdfs.c delete mode 100644 mkinitrd/ioleast.h delete mode 100644 mkinitrd/mkinitrd.8 delete mode 100644 mkinitrd/mkinitrd.c delete mode 100644 mkinitrd/rules.c delete mode 100644 mkinitrd/rules.h delete mode 100644 mkinitrd/serialize.c delete mode 100644 mkinitrd/serialize.h diff --git a/Makefile b/Makefile index 1c0b5098..e40230ba 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,6 @@ init \ kblayout \ kblayout-compiler \ login \ -mkinitrd \ ping \ regress \ rw \ @@ -101,7 +100,6 @@ sysmerge-wait: sysroot clean-build-tools: $(MAKE) -C carray clean $(MAKE) -C kblayout-compiler clean - $(MAKE) -C mkinitrd clean $(MAKE) -C sf clean $(MAKE) -C tix clean @@ -109,7 +107,6 @@ clean-build-tools: build-tools: $(MAKE) -C carray $(MAKE) -C kblayout-compiler - $(MAKE) -C mkinitrd $(MAKE) -C sf $(MAKE) -C tix @@ -117,7 +114,6 @@ build-tools: install-build-tools: $(MAKE) -C carray install $(MAKE) -C kblayout-compiler install - $(MAKE) -C mkinitrd install $(MAKE) -C sf install $(MAKE) -C tix install diff --git a/kernel/include/sortix/initrd.h b/kernel/include/sortix/initrd.h deleted file mode 100644 index 06944d01..00000000 --- a/kernel/include/sortix/initrd.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2012, 2016 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * sortix/initrd.h - * The Sortix init ramdisk filesystem format. - */ - -#ifndef _INCLUDE_SORTIX_INITRD_H -#define _INCLUDE_SORTIX_INITRD_H - -#include - -#define INITRD_ALGO_CRC32 0 -#define INITRD_ALGO_NONE 1 - -#define INITRD_S_IXOTH 01 -#define INITRD_S_IWOTH 02 -#define INITRD_S_IROTH 03 -#define INITRD_S_IRWXO 07 -#define INITRD_S_IXGRP 010 -#define INITRD_S_IWGRP 020 -#define INITRD_S_IRGRP 040 -#define INITRD_S_IRWXG 070 -#define INITRD_S_IXUSR 0100 -#define INITRD_S_IWUSR 0200 -#define INITRD_S_IRUSR 0400 -#define INITRD_S_IRWXU 0700 -#define INITRD_S_IFMT 0xF000 -#define INITRD_S_IFSOCK 0xC000 -#define INITRD_S_IFLNK 0xA000 -#define INITRD_S_IFREG 0x8000 -#define INITRD_S_IFBLK 0x6000 -#define INITRD_S_IFDIR 0x4000 -#define INITRD_S_IFCHR 0x2000 -#define INITRD_S_IFIFO 0x1000 -#define INITRD_S_ISUID 0x0800 -#define INITRD_S_ISGID 0x0400 -#define INITRD_S_ISVTX 0x0200 -#define INITRD_S_ISSOCK(mode) ((mode & INITRD_S_IFMT) == INITRD_S_IFSOCK) -#define INITRD_S_ISLNK(mode) ((mode & INITRD_S_IFMT) == INITRD_S_IFLNK) -#define INITRD_S_ISREG(mode) ((mode & INITRD_S_IFMT) == INITRD_S_IFREG) -#define INITRD_S_ISBLK(mode) ((mode & INITRD_S_IFMT) == INITRD_S_IFBLK) -#define INITRD_S_ISDIR(mode) ((mode & INITRD_S_IFMT) == INITRD_S_IFDIR) -#define INITRD_S_ISCHR(mode) ((mode & INITRD_S_IFMT) == INITRD_S_IFCHR) -#define INITRD_S_ISFIFO(mode) ((mode & INITRD_S_IFMT) == INITRD_S_IFIFO) - -typedef struct initrd_superblock -{ - char magic[16]; /* "sortix-initrd-2" */ - uint32_t fssize; - uint32_t revision; - uint32_t inodesize; - uint32_t inodecount; - uint32_t inodeoffset; - uint32_t root; - uint32_t sumalgorithm; - uint32_t sumsize; -} initrd_superblock_t; - -typedef struct initrd_inode -{ - uint32_t mode; - uint32_t uid; - uint32_t gid; - uint32_t nlink; - uint64_t ctime; - uint64_t mtime; - uint32_t dataoffset; - uint32_t size; -} initrd_inode_t; - -typedef struct initrd_dirent -{ - uint32_t inode; - uint16_t reclen; - uint16_t namelen; - char name[0]; -} initrd_dirent_t; - -#endif diff --git a/kernel/initrd.cpp b/kernel/initrd.cpp index 50bb3a36..5cc50cd4 100644 --- a/kernel/initrd.cpp +++ b/kernel/initrd.cpp @@ -31,7 +31,6 @@ #include #include -#include #include #include #include @@ -51,17 +50,12 @@ namespace Sortix { -// TODO: The initrd is not being properly verified. -// TODO: The initrd is not handled in an endian-neutral manner. - struct initrd_context { uint8_t* initrd; size_t initrd_size; addr_t initrd_unmap_start; addr_t initrd_unmap_end; - struct initrd_superblock* sb; - Ref links; ioctx_t ioctx; }; @@ -81,262 +75,6 @@ static void UnmapInitrdPage(struct initrd_context* ctx, addr_t vaddr) Page::Put(addr, PAGE_USAGE_WASNT_ALLOCATED); } -static mode_t initrd_mode_to_host_mode(uint32_t mode) -{ - mode_t result = mode & 0777; - if ( INITRD_S_ISVTX & mode ) result |= S_ISVTX; - if ( INITRD_S_ISSOCK(mode) ) result |= S_IFSOCK; - if ( INITRD_S_ISLNK(mode) ) result |= S_IFLNK; - if ( INITRD_S_ISREG(mode) ) result |= S_IFREG; - if ( INITRD_S_ISBLK(mode) ) result |= S_IFBLK; - if ( INITRD_S_ISDIR(mode) ) result |= S_IFDIR; - if ( INITRD_S_ISCHR(mode) ) result |= S_IFCHR; - if ( INITRD_S_ISFIFO(mode) ) result |= S_IFIFO; - return result; -} - -static struct initrd_inode* initrd_get_inode(struct initrd_context* ctx, - uint32_t inode) -{ - if ( ctx->sb->inodecount <= inode ) - return errno = EINVAL, (struct initrd_inode*) NULL; - uint32_t pos = ctx->sb->inodeoffset + ctx->sb->inodesize * inode; - return (struct initrd_inode*) (ctx->initrd + pos); -} - -static uint8_t* initrd_inode_get_data(struct initrd_context* ctx, - struct initrd_inode* inode, - size_t* size) -{ - return *size = inode->size, ctx->initrd + inode->dataoffset; -} - -static uint32_t initrd_directory_open(struct initrd_context* ctx, - struct initrd_inode* inode, - const char* name) -{ - if ( !INITRD_S_ISDIR(inode->mode) ) - return errno = ENOTDIR, 0; - uint32_t offset = 0; - while ( offset < inode->size ) - { - uint32_t pos = inode->dataoffset + offset; - struct initrd_dirent* dirent = - (struct initrd_dirent*) (ctx->initrd + pos); - if ( dirent->namelen && !strcmp(dirent->name, name) ) - return dirent->inode; - offset += dirent->reclen; - } - return errno = ENOENT, 0; -} - -static const char* initrd_directory_get_filename(struct initrd_context* ctx, - struct initrd_inode* inode, - size_t index) -{ - if ( !INITRD_S_ISDIR(inode->mode) ) - return errno = ENOTDIR, (const char*) NULL; - uint32_t offset = 0; - while ( offset < inode->size ) - { - uint32_t pos = inode->dataoffset + offset; - struct initrd_dirent* dirent = - (struct initrd_dirent*) (ctx->initrd + pos); - if ( index-- == 0 ) - return dirent->name; - offset += dirent->reclen; - } - return errno = EINVAL, (const char*) NULL; -} - -static size_t initrd_directory_get_num_files(struct initrd_context* ctx, - struct initrd_inode* inode) -{ - if ( !INITRD_S_ISDIR(inode->mode) ) - return errno = ENOTDIR, 0; - uint32_t offset = 0; - size_t numentries = 0; - while ( offset < inode->size ) - { - uint32_t pos = inode->dataoffset + offset; - const struct initrd_dirent* dirent = - (const struct initrd_dirent*) (ctx->initrd + pos); - numentries++; - offset += dirent->reclen; - } - return numentries; -} - -static void ExtractNode(struct initrd_context* ctx, - struct initrd_inode* inode, - Ref node); - -static void ExtractFile(struct initrd_context* ctx, - struct initrd_inode* inode, - Ref file) -{ - size_t filesize; - uint8_t* data = initrd_inode_get_data(ctx, inode, &filesize); - if ( file->truncate(&ctx->ioctx, filesize) != 0 ) - PanicF("initrd: truncate: %m"); - size_t sofar = 0; - while ( sofar < filesize ) - { - size_t left = filesize - sofar; - size_t chunk = 1024 * 1024; - size_t count = left < chunk ? left : chunk; - ssize_t numbytes = file->write(&ctx->ioctx, data + sofar, count); - if ( numbytes <= 0 ) - PanicF("initrd: write: %m"); - sofar += numbytes; - } -} - -static void ExtractDir(struct initrd_context* ctx, - struct initrd_inode* inode, - Ref dir) -{ - size_t numfiles = initrd_directory_get_num_files(ctx, inode); - for ( size_t i = 0; i < numfiles; i++ ) - { - const char* name = initrd_directory_get_filename(ctx, inode, i); - if ( !name ) - PanicF("initrd_directory_get_filename: %m"); - if ( IsDotOrDotDot(name) ) - continue; - uint32_t childino = initrd_directory_open(ctx, inode, name); - if ( !childino ) - PanicF("initrd_directory_open: %s: %m", name); - struct initrd_inode* child = - (struct initrd_inode*) initrd_get_inode(ctx, childino); - if ( !child ) - PanicF("initrd_get_inode(%u): %s: %m", childino, name); - mode_t mode = initrd_mode_to_host_mode(child->mode); - if ( INITRD_S_ISDIR(child->mode) ) - { - if ( dir->mkdir(&ctx->ioctx, name, mode) && errno != EEXIST ) - PanicF("initrd: mkdir: %s: %m", name); - Ref desc = dir->open(&ctx->ioctx, name, - O_SEARCH | O_DIRECTORY, 0); - if ( !desc ) - PanicF("initrd: %s: %m", name); - ExtractNode(ctx, child, desc); - } - if ( INITRD_S_ISREG(child->mode) ) - { - assert(child->nlink != 0); - char link_path[sizeof(childino) * 3]; - snprintf(link_path, sizeof(link_path), "%ju", (uintmax_t) childino); - Ref existing(ctx->links->open(&ctx->ioctx, link_path, - O_READ, 0)); - if ( !existing || dir->link(&ctx->ioctx, name, existing) != 0 ) - { - Ref desc(dir->open(&ctx->ioctx, name, - O_WRITE | O_CREATE, mode)); - if ( !desc ) - PanicF("initrd: %s: %m", name); - ExtractNode(ctx, child, desc); - if ( 2 <= child->nlink ) - ctx->links->link(&ctx->ioctx, link_path, desc); - } - if ( --child->nlink == 0 && INITRD_S_ISREG(child->mode) ) - { - size_t filesize; - const uint8_t* data = - initrd_inode_get_data(ctx, child, &filesize); - uintptr_t from = (uintptr_t) data; - uintptr_t size = filesize; - uintptr_t from_aligned = Page::AlignUp(from); - uintptr_t from_distance = from_aligned - from; - if ( from_distance <= size ) - { - uintptr_t size_aligned = - Page::AlignDown(size - from_distance); - for ( size_t i = 0; i < size_aligned; i += Page::Size() ) - UnmapInitrdPage(ctx, from_aligned + i); - Memory::Flush(); - } - } - } - if ( INITRD_S_ISLNK(child->mode) ) - { - size_t filesize; - uint8_t* data = initrd_inode_get_data(ctx, child, &filesize); - char* oldname = new char[filesize + 1]; - if ( !oldname ) - PanicF("initrd: malloc: %m"); - memcpy(oldname, data, filesize); - oldname[filesize] = '\0'; - int ret = dir->symlink(&ctx->ioctx, oldname, name); - delete[] oldname; - if ( ret < 0 ) - PanicF("initrd: symlink: %s", name); - Ref desc = dir->open(&ctx->ioctx, name, - O_READ | O_SYMLINK_NOFOLLOW, 0); - if ( desc ) - ExtractNode(ctx, child, desc); - } - } -} - -static void ExtractNode(struct initrd_context* ctx, - struct initrd_inode* inode, - Ref node) -{ - if ( node->chmod(&ctx->ioctx, initrd_mode_to_host_mode(inode->mode)) < 0 ) - PanicF("initrd: chmod: %m"); - if ( node->chown(&ctx->ioctx, inode->uid, inode->gid) < 0 ) - PanicF("initrd: chown: %m"); - if ( INITRD_S_ISDIR(inode->mode) ) - ExtractDir(ctx, inode, node); - if ( INITRD_S_ISREG(inode->mode) ) - ExtractFile(ctx, inode, node); - struct timespec times[2]; - times[0] = timespec_make((time_t) inode->mtime, 0); - times[1] = timespec_make((time_t) inode->mtime, 0); - if ( node->utimens(&ctx->ioctx, times) < 0 ) - PanicF("initrd: utimens: %m"); -} - -static void ExtractInitrd(Ref desc, struct initrd_context* ctx) -{ - ctx->sb = (struct initrd_superblock*) ctx->initrd; - - if ( ctx->initrd_size < ctx->sb->fssize ) - Panic("Initrd header does not match its size"); - - if ( desc->mkdir(&ctx->ioctx, ".initrd-links", 0777) != 0 ) - PanicF("initrd: .initrd-links: %m"); - - if ( !(ctx->links = desc->open(&ctx->ioctx, ".initrd-links", - O_READ | O_DIRECTORY, 0)) ) - PanicF("initrd: .initrd-links: %m"); - - struct initrd_inode* root = initrd_get_inode(ctx, ctx->sb->root); - if ( !root ) - PanicF("initrd: initrd_get_inode(%u): %m", ctx->sb->root); - ExtractNode(ctx, root, desc); - - union - { - struct dirent dirent; - uint8_t dirent_data[sizeof(struct dirent) + sizeof(uintmax_t) * 3]; - }; - - while ( 0 < ctx->links->readdirents(&ctx->ioctx, &dirent, sizeof(dirent_data)) && - ((const char*) dirent.d_name)[0] ) - { - if ( ((const char*) dirent.d_name)[0] == '.' ) - continue; - ctx->links->unlinkat(&ctx->ioctx, dirent.d_name, AT_REMOVEFILE); - ctx->links->lseek(&ctx->ioctx, 0, SEEK_SET); - } - - ctx->links.Reset(); - - desc->unlinkat(&ctx->ioctx, ".initrd-links", AT_REMOVEDIR); -} - struct TAR { unsigned char* tar_file; @@ -614,9 +352,10 @@ static void ExtractModule(struct multiboot_mod_list* module, else if ( !strncmp(cmdline, "--create-to ", strlen("--create-to ")) || !strncmp(cmdline, "--create-to=", strlen("--create-to=")) ) ExtractTo(desc, ctx, cmdline + strlen("--create-to "), O_EXCL); - else if ( sizeof(struct initrd_superblock) <= ctx->initrd_size && + // TODO: After releasing Sortix 1.1, remove this nice error message. + else if ( strlen("sortix-initrd-2") <= ctx->initrd_size && !memcmp(ctx->initrd, "sortix-initrd-2", strlen("sortix-initrd-2")) ) - ExtractInitrd(desc, ctx); + Panic("The sortix-initrd-2 format is no longer supported"); else if ( sizeof(struct tar) <= ctx->initrd_size && !memcmp(ctx->initrd + offsetof(struct tar, magic), "ustar", 5) ) ExtractTar(desc, ctx); @@ -640,7 +379,6 @@ static void ExtractModule(struct multiboot_mod_list* module, UnmapInitrdPage(ctx, mapat + i); Memory::Flush(); - // Free the used virtual address space. FreeKernelAddress(&initrd_addr_alloc); } diff --git a/mkinitrd/.gitignore b/mkinitrd/.gitignore deleted file mode 100644 index deee3b80..00000000 --- a/mkinitrd/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -mkinitrd -initrdfs diff --git a/mkinitrd/Makefile b/mkinitrd/Makefile deleted file mode 100644 index 6f8c53fc..00000000 --- a/mkinitrd/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -include ../build-aux/platform.mak -include ../build-aux/compiler.mak -include ../build-aux/version.mak -include ../build-aux/dirs.mak - -OPTLEVEL?=$(DEFAULT_OPTLEVEL) -CFLAGS?=$(OPTLEVEL) - -SORTIXKERNEL=../kernel - -CPPFLAGS:=$(CPPFLAGS) -DVERSIONSTR=\"$(VERSION)\" -I$(SORTIXKERNEL)/include -I. -CFLAGS:=$(CFLAGS) -Wall -Wextra - -ifeq ($(HOST_IS_SORTIX),0) - CPPFLAGS+=-D_GNU_SOURCE -endif - -BINARIES=mkinitrd initrdfs - -all: $(BINARIES) - -.PHONY: all install clean - -%: %.c rules.c serialize.c - $(CC) -std=gnu11 $(CFLAGS) $(CPPFLAGS) $< rules.c serialize.c -o $@ - -clean: - rm -f $(BINARIES) - -install: all - mkdir -p $(DESTDIR)$(SBINDIR) - install $(BINARIES) $(DESTDIR)$(SBINDIR) - mkdir -p $(DESTDIR)$(MANDIR)/man8 - cp initrdfs.8 $(DESTDIR)$(MANDIR)/man8/initrdfs.8 - cp mkinitrd.8 $(DESTDIR)$(MANDIR)/man8/mkinitrd.8 diff --git a/mkinitrd/initrdfs.8 b/mkinitrd/initrdfs.8 deleted file mode 100644 index 8266712b..00000000 --- a/mkinitrd/initrdfs.8 +++ /dev/null @@ -1,67 +0,0 @@ -.Dd October 7, 2015 -.Dt INITRDFS 8 -.Os -.Sh NAME -.Nm initrdfs -.Nd view initialization ramdisk -.Sh SYNOPSIS -.Nm -.Ar initrd -cat -.Ar path ... -.Nm -.Ar initrd -extract -.Op Fl C Ar destination -.Ar path ... -.Nm -.Ar initrd -ls -.Op Fl a -.Ar path ... -.Sh DESCRIPTION -.Nm -opens a -.Xr initrd 7 -made with -.Xr mkinitrd 8 -and lets you view the stored directories and files. -.Pp -The options are as follows: -.Bl -tag -width "12345678" -.It Fl a -.Sy ( ls ) -Include directory entries whose names begin with a -dot -.Pq Sq \&. . -.It Fl C Ar destination -.Sy ( extract ) -Extract to the specified -.Ar destination -rather than the default current directory. -.El -.Pp -.Nm -supports these commands: -.Bl -tag -width "12345678" -.It Sy cat -Show the contents of each -.Ar path . -.It Sy extract -Extract each -.Ar path -recursively to the current directory. -.It Sy ls -List each directory -.Ar path . -.El -.Sh EXIT STATUS -.Nm -will exit 0 on success and non-zero otherwise. -.Sh SEE ALSO -.Xr initrd 7 , -.Xr mkinitrd 8 -.Sh BUGS -.Nm -is feature limited and doesn't let you view all the contained meta information. -It's also not a filesystem driver. diff --git a/mkinitrd/initrdfs.c b/mkinitrd/initrdfs.c deleted file mode 100644 index 711b799e..00000000 --- a/mkinitrd/initrdfs.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright (c) 2012, 2015, 2016, 2017 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * initrdfs.c - * Provides access to filesystems in the Sortix kernel initrd format. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "serialize.h" - -char* Substring(const char* str, size_t start, size_t length) -{ - char* result = (char*) malloc(length+1); - strncpy(result, str + start, length); - result[length] = 0; - return result; -} - -bool ReadSuperBlock(int fd, initrd_superblock_t* dest) -{ - if ( preadall(fd, dest, sizeof(*dest), 0) != sizeof(*dest) ) - return false; - import_initrd_superblock(dest); - return true; -} - -initrd_superblock_t* GetSuperBlock(int fd) -{ - size_t sbsize = sizeof(initrd_superblock_t); - initrd_superblock_t* sb = (initrd_superblock_t*) malloc(sbsize); - if ( !sb ) { return NULL; } - if ( !ReadSuperBlock(fd, sb) ) { free(sb); return NULL; } - return sb; -} - -bool ReadInode(int fd, initrd_superblock_t* sb, uint32_t ino, - initrd_inode_t* dest) -{ - uint32_t inodepos = sb->inodeoffset + sb->inodesize * ino; - if ( preadall(fd, dest, sizeof(*dest), inodepos) != sizeof(*dest) ) - return false; - import_initrd_inode(dest); - return true; -} - -initrd_inode_t* GetInode(int fd, initrd_superblock_t* sb, uint32_t ino) -{ - initrd_inode_t* inode = (initrd_inode_t*) malloc(sizeof(initrd_inode_t)); - if ( !inode ) { return NULL; } - if ( !ReadInode(fd, sb, ino, inode) ) { free(inode); return NULL; } - return inode; -} - -initrd_inode_t* CloneInode(const initrd_inode_t* src) -{ - initrd_inode_t* result = (initrd_inode_t*) malloc(sizeof(*src)); - if ( !result ) { return NULL; } - memcpy(result, src, sizeof(*src)); - return result; -} - -bool ReadInodeData(int fd, initrd_superblock_t* sb, initrd_inode_t* inode, - uint8_t* dest, size_t size, off_t offset) -{ - (void) sb; - if ( offset < 0 ) - return errno = EINVAL, false; - if ( inode->size < (uintmax_t) offset ) - return errno = EINVAL, false; - size_t available = inode->size - offset; - if ( inode->size < available ) - return errno = EINVAL, false; - return preadall(fd, dest, size, inode->dataoffset + offset) == 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; - if ( !ReadInodeData(fd, sb, inode, buf, size, 0) ) - { - free(buf); - return NULL; - } - return buf; -} - -uint8_t* GetInodeData(int fd, initrd_superblock_t* sb, initrd_inode_t* inode) -{ - return GetInodeDataSize(fd, sb, inode, inode->size); -} - -uint32_t Traverse(int fd, initrd_superblock_t* sb, initrd_inode_t* inode, - const char* name) -{ - if ( !INITRD_S_ISDIR(inode->mode) ) { errno = ENOTDIR; return 0; } - uint8_t* direntries = GetInodeData(fd, sb, inode); - if ( !direntries ) { return 0; } - uint32_t result = 0; - uint32_t offset = 0; - while ( offset < inode->size ) - { - initrd_dirent_t* dirent = (initrd_dirent_t*) (direntries + offset); - import_initrd_dirent(dirent); - if ( dirent->namelen && !strcmp(dirent->name, name) ) - { - result = dirent->inode; - export_initrd_dirent(dirent); - break; - } - offset += dirent->reclen; - export_initrd_dirent(dirent); - } - free(direntries); - if ( !result ) { errno = ENOENT; } - return result; -} - -initrd_inode_t* ResolvePath(int fd, initrd_superblock_t* sb, - initrd_inode_t* inode, const char* path) -{ - if ( !path[0] ) { return CloneInode(inode); } - if ( path[0] == '/' ) - { - if ( !INITRD_S_ISDIR(inode->mode) ) { errno = ENOTDIR; return NULL; } - return ResolvePath(fd, sb, inode, path+1); - } - size_t elemlen = strcspn(path, "/"); - char* elem = Substring(path, 0, elemlen); - uint32_t ino = Traverse(fd, sb, inode, elem); - free(elem); - if ( !ino ) { return NULL; } - initrd_inode_t* child = GetInode(fd, sb, ino); - if ( !child ) { return NULL; } - if ( !path[elemlen] ) { return child; } - initrd_inode_t* result = ResolvePath(fd, sb, child, path + elemlen); - free(child); - return result; -} - -bool ListDirectory(int fd, initrd_superblock_t* sb, initrd_inode_t* dir, - bool all) -{ - if ( !INITRD_S_ISDIR(dir->mode) ) { errno = ENOTDIR; return false; } - uint8_t* direntries = GetInodeData(fd, sb, dir); - if ( !direntries ) { return false; } - uint32_t offset = 0; - while ( offset < dir->size ) - { - initrd_dirent_t* dirent = (initrd_dirent_t*) (direntries + offset); - if ( dirent->namelen && (all || dirent->name[0] != '.')) - { - printf("%s\n", dirent->name); - } - offset += dirent->reclen; - } - free(direntries); - return true; -} - -bool PrintFile(int fd, initrd_superblock_t* sb, initrd_inode_t* inode) -{ - if ( INITRD_S_ISDIR(inode->mode ) ) { errno = EISDIR; return false; } - uint32_t sofar = 0; - while ( sofar < inode->size ) - { - const size_t BUFFER_SIZE = 16UL * 1024UL; - uint8_t buffer[BUFFER_SIZE]; - uint32_t available = inode->size - sofar; - uint32_t count = available < BUFFER_SIZE ? available : BUFFER_SIZE; - if ( !ReadInodeData(fd, sb, inode, buffer, count, 0) ) { return false; } - if ( writeall(1, buffer, count) != count ) { return false; } - sofar += count; - } - return true; -} - -void Extract(int fd, - const char* fd_path, - initrd_superblock_t* sb, - initrd_inode_t* inode, - const char* out_path, - bool verbose) -{ - if ( verbose ) - printf("%s\n", out_path); - if ( INITRD_S_ISLNK(inode->mode) ) - { - char* buffer = (char*) malloc(inode->size + 1); - if ( !buffer ) - err(1, "malloc"); - if ( !ReadInodeData(fd, sb, inode, (uint8_t*) buffer, inode->size, 0) ) - err(1, "%s", fd_path); - buffer[inode->size] = '\0'; - // TODO: What if it already exists. - if ( symlink(buffer, out_path) < 0 ) - err(1, "%s", out_path); - return; - } - else if ( INITRD_S_ISREG(inode->mode) ) - { - int out_fd = open(out_path, O_WRONLY | O_CREAT | O_TRUNC, 0200); - if ( out_fd < 0 ) - err(1, "%s", out_path); - uint32_t sofar = 0; - while ( sofar < inode->size ) - { - const size_t BUFFER_SIZE = 16UL * 1024UL; - uint8_t buffer[BUFFER_SIZE]; - uint32_t available = inode->size - sofar; - uint32_t count = available < BUFFER_SIZE ? available : BUFFER_SIZE; - if ( !ReadInodeData(fd, sb, inode, buffer, count, sofar) ) - err(1, "%s", fd_path); - if ( writeall(out_fd, buffer, count) != count ) - err(1, "%s", out_path); - sofar += count; - } - if ( fchmod(out_fd, inode->mode & 07777) < 0 ) - err(1, "%s", out_path); - close(out_fd); - return; - } - else if ( !INITRD_S_ISDIR(inode->mode) ) - errx(1, "%s: Unsupported kind of file", out_path); - bool made = true; - if ( mkdir(out_path, 0700) < 0 ) - { - if ( errno != EEXIST ) - err(1, "%s", out_path); - made = false; - } - uint8_t* direntries = GetInodeData(fd, sb, inode); - if ( !direntries ) - err(1, "%s", out_path); - uint32_t offset = 0; - while ( offset < inode->size ) - { - initrd_dirent_t* dirent = (initrd_dirent_t*) (direntries + offset); - offset += dirent->reclen; - if ( !dirent->namelen ) // TODO: Possible? - continue; - if ( !strcmp(dirent->name, ".") || !strcmp(dirent->name, "..") ) - continue; - char* child_path; - if ( asprintf(&child_path, "%s/%s", out_path, dirent->name) < 0 ) - err(1, "asprintf"); - initrd_inode_t* child_inode = ResolvePath(fd, sb, inode, dirent->name); - if ( !child_inode ) - err(1, "%s: %s", fd_path, out_path); - Extract(fd, fd_path, sb, child_inode, child_path, verbose); - free(child_path); - } - free(direntries); - // TODO: Time of check to time of use race condition, a concurrent rename - // and we may assign the permissions to the wrong file, potentially - // exploitable. - if ( made && chmod(out_path, inode->mode & 07777) < 0 ) - err(1, " %s", out_path); -} - -static void compact_arguments(int* argc, char*** argv) -{ - for ( int i = 0; i < *argc; i++ ) - { - while ( i < *argc && !(*argv)[i] ) - { - for ( int n = i; n < *argc; n++ ) - (*argv)[n] = (*argv)[n+1]; - (*argc)--; - } - } -} - -int main(int argc, char* argv[]) -{ - bool all = false; - const char* destination = "."; - bool verbose = false; - - for ( int i = 1; i < argc; i++ ) - { - const char* arg = argv[i]; - if ( arg[0] != '-' || !arg[1] ) - continue; - argv[i] = NULL; - if ( !strcmp(arg, "--") ) - break; - if ( arg[1] != '-' ) - { - char c; - while ( (c = *++arg) ) switch ( c ) - { - case 'a': all = true; break; - case 'C': - if ( !*(destination = arg + 1) ) - { - if ( i + 1 == argc ) - errx(1, "option requires an argument -- 'C'"); - destination = argv[i+1]; - argv[++i] = NULL; - } - arg = "C"; - break; - case 'v': verbose = true; break; - default: - errx(1, "unknown option -- '%c'", c); - } - } - else - errx(1, "unknown option: %s", arg); - } - - compact_arguments(&argc, &argv); - - if ( argc == 1 ) - errx(1, "No initrd specified"); - const char* initrd = argv[1]; - if ( argc == 2 ) - errx(1, "No command specified"); - const char* cmd = argv[2]; - - int fd = open(initrd, O_RDONLY); - if ( fd < 0 ) - err(1, "open: %s", initrd); - - initrd_superblock_t* sb = GetSuperBlock(fd); - if ( !sb ) - err(1, "read: %s", initrd); - - initrd_inode_t* root = GetInode(fd, sb, sb->root); - if ( !root ) - err(1, "read: %s", initrd); - - for ( int i = 3; i < argc; i++ ) - { - const char* path = argv[i]; - if ( path[0] != '/' ) - { - errno = ENOENT; - errx(1, "%s", path); - } - - initrd_inode_t* inode = ResolvePath(fd, sb, root, path+1); - if ( !inode ) - err(1, "%s", path); - - if ( !strcmp(cmd, "cat") ) - { - if ( !PrintFile(fd, sb, inode) ) - err(1, "%s", path); - } - else if ( !strcmp(cmd, "ls") ) - { - if ( !ListDirectory(fd, sb, inode, all) ) - err(1, "%s", path); - } - else if ( !strcmp(cmd, "extract") ) - Extract(fd, initrd, sb, inode, destination, verbose); - else - errx(1, "unrecognized command: %s", cmd); - - free(inode); - } - - return 0; -} diff --git a/mkinitrd/ioleast.h b/mkinitrd/ioleast.h deleted file mode 100644 index 5648de48..00000000 --- a/mkinitrd/ioleast.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 2015 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * ioleast.h - * Versions of {,p}{read,write} that don't return until it has returned as much - * data as requested, end of file, or an error occurs. This is sometimes needed - * as read(2) and write(2) is not always guaranteed to fill up the entire - * buffer or write it all. - */ - -#ifndef SORTIX_COMPATIBILITY_INCLUDE_IOLEAST_H -#define SORTIX_COMPATIBILITY_INCLUDE_IOLEAST_H - -#if defined(__sortix__) || defined(__sortix_libc__) - -#include_next - -#else - -#include - -#include -#include -#include -#include -#include - -#if !defined(EEOF) && defined(EIO) -#define EEOF EIO -#endif - -__attribute__((unused)) static inline -size_t readleast(int fd, void* buf_ptr, size_t least, size_t max) -{ - assert(least <= max); - unsigned char* buf = (unsigned char*) buf_ptr; - size_t done = 0; - do - { - ssize_t amount = read(fd, buf + done, max - done); - if ( amount < 0 ) - return done; - if ( !amount && done < least ) - return errno = EEOF, done; - if ( !amount ) - break; - done += amount; - } while ( done < least ); - return done; -} - -__attribute__((unused)) static inline -size_t writeleast(int fd, const void* buf_ptr, size_t least, size_t max) -{ - assert(least <= max); - const unsigned char* buf = (const unsigned char*) buf_ptr; - size_t done = 0; - do - { - ssize_t amount = write(fd, buf + done, max - done); - if ( amount < 0 ) - return done; - if ( !amount && done < least ) - return errno = EEOF, done; - if ( !amount ) - break; - done += amount; - } while ( done < least ); - return done; -} - -__attribute__((unused)) static inline -size_t preadleast(int fd, void* buf_ptr, size_t least, size_t max, off_t off) -{ - assert(least <= max); - unsigned char* buf = (unsigned char*) buf_ptr; - size_t done = 0; - do - { - ssize_t amount = pread(fd, buf + done, max - done, off + done); - if ( amount < 0 ) - return done; - if ( !amount && done < least ) - return errno = EEOF, done; - if ( !amount ) - break; - done += amount; - } while ( done < least ); - return done; -} - -__attribute__((unused)) static inline -size_t pwriteleast(int fd, const void* buf_ptr, size_t least, size_t max, off_t off) -{ - assert(least <= max); - const unsigned char* buf = (const unsigned char*) buf_ptr; - size_t done = 0; - do - { - ssize_t amount = pwrite(fd, buf + done, max - done, off + done); - if ( amount < 0 ) - return done; - if ( !amount && done < least ) - return errno = EEOF, done; - if ( !amount ) - break; - done += amount; - } while ( done < least ); - return done; -} - -__attribute__((unused)) static inline -size_t readall(int fd, void* buf, size_t count) -{ - return readleast(fd, buf, count, count); -} - -__attribute__((unused)) static inline -size_t writeall(int fd, const void* buf, size_t count) -{ - return writeleast(fd, buf, count, count); -} - -__attribute__((unused)) static inline -size_t preadall(int fd, void* buf, size_t count, off_t off) -{ - return preadleast(fd, buf, count, count, off); -} - -__attribute__((unused)) static inline -size_t pwriteall(int fd, const void* buf, size_t count, off_t off) -{ - return pwriteleast(fd, buf, count, count, off); -} - -#endif - -#endif diff --git a/mkinitrd/mkinitrd.8 b/mkinitrd/mkinitrd.8 deleted file mode 100644 index 2a550608..00000000 --- a/mkinitrd/mkinitrd.8 +++ /dev/null @@ -1,126 +0,0 @@ -.Dd October 7, 2015 -.Dt MKINITRD 8 -.Os -.Sh NAME -.Nm mkinitrd -.Nd make initialization ramdisk -.Sh SYNOPSIS -.Nm mkinitrd -.Op Fl \-filter Ns "=" Ns Ar rules-file -.Op Fl \-format Ns "=" Ns Ar format -.Op Fl \-manifest Ns "=" Ns Ar manifest-file -.Fl o Ar destination -.Ar directory ... -.Sh DESCRIPTION -.Nm -produces a -.Xr initrd 7 -for the Sortix -.Xr kernel 7 -at the -.Ar destination . -It is an archive in the -.In sortix/initrd.h -format of files and directories. -.Pp -Every specified -.Ar directory -is used as a root directory and is recursively searched for files and -directories matching the filter. -If multiple directories are specified, the directories are merged together. -In case two files with the same path conflict, precedence is given to the file -in the root directory specified first. -.Pp -Hardlinks are detected and preserved to avoid data duplication. -Inode times are truncated to second precision due to format limitations. -Inodes are stored with uid 0 and gid 0 of the root user. -The format is not compressed but can be compressed externally if it is -decompressed during bootloading. -.Pp -.Xr initrdfs 8 -can be used to view the files produced by -.Nm . -.Pp -The options are as follows: -.Bl -tag -width "12345678" -.It Fl \-filter Ns "=" Ns Ar rule-file -Include only files and directories during the recursive search that matches -rules in the -.Ar rule-file -in the format specified under -.Sx FILTER RULES . -.It Fl \-format Ns "=" Ns Ar format -Produce the archive in the specified format. -This is for forward compatibility and only -.Sy sortix-initrd-2 -is supported. -.Sy default -is an alias for the newest format -.Sy sortix-initrd-2 . -.Nm -will default to a newer format when one is introduced and this allows -.Nm -to support old callers during the transitional period. -.It Fl \-manifest Ns "=" Ns Ar manifest-file -Include only files and directories during the recursive search whose path -exactly matches a line in the -.Ar manifest-file . -.It Fl o , Fl \-output Ns "=" Ns Ar destination -Store the produced -.Xr initrd 7 -at the specified -.Ar destination . -.El -.Sh FILTER RULES -The rule format is line based and leading whitespace is skipped. -Lines starting with a -.Li # -character are ignored as comments. -The first word on a line must be one of the following commands and the rest of -the line is its parameter. -Trailing whitespace is not ignored. -.Bl -tag -width "12345678" -.It Sy default Ar boolean -The -.Ar boolean -parameter is either -.Sy true -or -.Sy false -and determines whether a file or directory is included if no other rules match -it. -This defaults to -.Sy true . -.It Sy include Ar path -Include the file or directory if it matches -.Ar path . -.It Sy exclude Ar path -Exclude the file or directory if it matches -.Ar path . -.El -.Pp -The rules are checked on the paths relative to the root directories during the -recursive descent. -The last rule to match a path decides whether it is included or not. -Directory are not descended into if they are excluded. -The pattern patch is simple and matches paths exactly. -.Sh EXIT STATUS -.Nm -will exit 0 on success and non-zero otherwise. -.Sh EXAMPLES -.Bd -literal -# By default include everything except these directories: -exclude /dev -exclude /src/sysroot -exclude /tmp -.Ed -.Sh SEE ALSO -.Xr initrd 7 , -.Xr kernel 7 , -.Xr initrdfs 8 , -.Xr update-initrd 8 -.Sh BUGS -The path pattern matching should be upgraded to use -.Xr fnmatch 3 . -The initrd format does not losslessly represent the Sortix -.Li struct stat . diff --git a/mkinitrd/mkinitrd.c b/mkinitrd/mkinitrd.c deleted file mode 100644 index f35a18a5..00000000 --- a/mkinitrd/mkinitrd.c +++ /dev/null @@ -1,776 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 2014, 2015, 2016 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * mkinitrd.c - * Produces a simple ramdisk filesystem readable by the Sortix kernel. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define DEFAULT_FORMAT "sortix-initrd-2" - -#include "rules.h" -#include "serialize.h" - -uint32_t HostModeToInitRD(mode_t mode) -{ - uint32_t result = mode & 0777; // Lower 9 bits per POSIX and tradition. - if ( S_ISVTX & mode ) { result |= INITRD_S_ISVTX; } - if ( S_ISSOCK(mode) ) { result |= INITRD_S_IFSOCK; } - if ( S_ISLNK(mode) ) { result |= INITRD_S_IFLNK; } - if ( S_ISREG(mode) ) { result |= INITRD_S_IFREG; } - if ( S_ISBLK(mode) ) { result |= INITRD_S_IFBLK; } - if ( S_ISDIR(mode) ) { result |= INITRD_S_IFDIR; } - if ( S_ISCHR(mode) ) { result |= INITRD_S_IFCHR; } - if ( S_ISFIFO(mode) ) { result |= INITRD_S_IFIFO; } - return result; -} - -mode_t InitRDModeToHost(uint32_t mode) -{ - mode_t result = mode & 0777; // Lower 9 bits per POSIX and tradition. - if ( INITRD_S_ISVTX & mode ) { result |= S_ISVTX; } - if ( INITRD_S_ISSOCK(mode) ) { result |= S_IFSOCK; } - if ( INITRD_S_ISLNK(mode) ) { result |= S_IFLNK; } - if ( INITRD_S_ISREG(mode) ) { result |= S_IFREG; } - if ( INITRD_S_ISBLK(mode) ) { result |= S_IFBLK; } - if ( INITRD_S_ISDIR(mode) ) { result |= S_IFDIR; } - if ( INITRD_S_ISCHR(mode) ) { result |= S_IFCHR; } - if ( INITRD_S_ISFIFO(mode) ) { result |= S_IFIFO; } - return result; -} - -struct Node; -struct DirEntry; - -struct DirEntry -{ - char* name; - struct Node* node; -}; - -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 struct DirEntry* a = (const struct DirEntry*) a_ptr; - const struct DirEntry* b = (const struct DirEntry*) b_ptr; - return DirEntryCompare(a, b); -} - -struct Node -{ - char* path; - uint32_t ino; - uint32_t nlink; - size_t direntsused; - size_t direntslength; - struct DirEntry* dirents; - mode_t mode; - time_t ctime; - time_t mtime; - bool written; - size_t refcount; -}; - -void FreeNode(struct Node* node) -{ - if ( !node ) - return; - if ( 1 < node->nlink ) { node->nlink--; return; } - for ( size_t i = 0; i < node->direntsused; i++ ) - { - struct DirEntry* entry = node->dirents + i; - if ( !entry->name ) - continue; - if ( strcmp(entry->name, ".") != 0 && strcmp(entry->name, "..") != 0 ) - { - if ( --entry->node->refcount == 0 ) - FreeNode(entry->node); - } - free(entry->name); - } - free(node->dirents); - free(node->path); - free(node); -} - -struct CacheEntry -{ - ino_t ino; - dev_t dev; - struct Node* node; -}; - -static size_t cacheused = 0; -static size_t cachelen = 0; -static struct CacheEntry* cache = NULL; - -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 ) - return cache[i].node; - return NULL; -} - -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(struct CacheEntry); - struct CacheEntry* newcache = - (struct CacheEntry*) realloc(cache, newcachesize); - if ( !newcache ) - return false; - cache = newcache; - cachelen = newcachelen; - } - size_t index = cacheused++; - cache[index].ino = ino; - cache[index].dev = dev; - cache[index].node = node; - return true; -} - -struct Node* RecursiveSearch(const char* real_path, const char* virt_path, - uint32_t* ino, struct Node* parent) -{ - printf("%s\n", virt_path); - fflush(stdout); - - if ( virt_path[0] == '/' && !virt_path[1] ) - virt_path = ""; - - struct stat st; - if ( lstat(real_path, &st) != 0 ) - { - warn("stat: %s", real_path); - return NULL; - } - - if ( !S_ISDIR(st.st_mode) && 2 <= st.st_nlink ) - { - struct Node* cached = LookupCache(st.st_dev, st.st_ino); - if ( cached ) - return cached->nlink++, cached->refcount++, cached; - } - - struct Node* node = (struct Node*) calloc(1, sizeof(struct Node)); - if ( !node ) - return NULL; - - node->nlink = 1; - node->refcount = 1; - node->mode = st.st_mode; - node->ino = (*ino)++; - node->ctime = st.st_ctim.tv_sec; - node->mtime = st.st_mtim.tv_sec; - - char* real_path_clone = strdup(real_path); - if ( !real_path_clone ) - { - warn("strdup"); - free(node); - return NULL; - } - - node->path = real_path_clone; - - if ( !S_ISDIR(st.st_mode)) - { - if ( 2 <= st.st_nlink && !AddToCache(node, st.st_dev, st.st_ino) ) - { - free(real_path_clone); - free(node); - return NULL; - } - return node; - } - - DIR* dir = opendir(real_path); - if ( !dir ) - { - warn("opendir: %s", real_path); - FreeNode(node); - return NULL; - } - - size_t real_path_len = strlen(real_path); - size_t virt_path_len = strlen(virt_path); - - bool successful = true; - struct dirent* entry; - while ( (entry = readdir(dir)) ) - { - size_t namelen = strlen(entry->d_name); - - size_t virt_subpath_len = virt_path_len + 1 + namelen; - char* virt_subpath = (char*) malloc(virt_subpath_len+1); - if ( !virt_subpath ) - { - warn("malloc"); - successful = false; - break; - } - stpcpy(stpcpy(stpcpy(virt_subpath, virt_path), "/"), entry->d_name); - - if ( strcmp(entry->d_name, ".") != 0 && - strcmp(entry->d_name, "..") != 0 && - !IncludesPath(virt_subpath) ) - { - free(virt_subpath); - continue; - } - - size_t real_subpath_len = real_path_len + 1 + namelen; - char* real_subpath = (char*) malloc(real_subpath_len+1); - if ( !real_subpath ) - { - free(virt_subpath); - warn("malloc"); - successful = false; - break; - } - stpcpy(stpcpy(stpcpy(real_subpath, real_path), "/"), entry->d_name); - - struct Node* child = NULL; - if ( !strcmp(entry->d_name, ".") ) - child = node; - if ( !strcmp(entry->d_name, "..") ) - child = parent ? parent : node; - if ( !child ) - child = RecursiveSearch(real_subpath, virt_subpath, ino, node); - free(real_subpath); - free(virt_subpath); - if ( !child ) - { - successful = false; - break; - } - - if ( node->direntsused == node->direntslength ) - { - size_t oldlength = node->direntslength; - size_t newlength = oldlength ? 2 * oldlength : 8; - size_t newsize = sizeof(struct DirEntry) * newlength; - struct DirEntry* newdirents = (struct DirEntry*) realloc(node->dirents, newsize); - if ( !newdirents ) - { - warn("realloc"); - successful = false; - break; - } - node->dirents = newdirents; - node->direntslength = newlength; - } - - char* nameclone = strdup(entry->d_name); - if ( !nameclone ) - { - warn("strdup"); - successful = false; - break; - } - - struct DirEntry* entry = node->dirents + node->direntsused++; - - entry->name = nameclone; - entry->node = child; - } - - closedir(dir); - if ( !successful ) - { - FreeNode(node); - return NULL; - } - qsort(node->dirents, node->direntsused, sizeof(struct DirEntry), - DirEntryCompareIndirect); - return node; -} - -struct Node* MergeNodes(struct Node* a, struct Node* b) -{ - if ( !S_ISDIR(a->mode) || !S_ISDIR(b->mode) ) - { - FreeNode(b); - return a; - } - size_t dirents_used = 0; - size_t dirents_length = a->direntsused + b->direntsused; - struct DirEntry* dirents = (struct DirEntry*) - malloc(sizeof(struct DirEntry) * dirents_length); - if ( !dirents ) - { - warn("malloc"); - FreeNode(a); - FreeNode(b); - return NULL; - } - bool failure = false; - size_t ai = 0; - size_t bi = 0; - while ( ai != a->direntsused || bi != b->direntsused ) - { - if ( bi == b->direntsused || - (ai != a->direntsused && - bi != b->direntsused && - DirEntryCompare(&a->dirents[ai], &b->dirents[bi]) < 0) ) - { - dirents[dirents_used++] = a->dirents[ai]; - a->dirents[ai].name = NULL; - a->dirents[ai].node = NULL; - ai++; - continue; - } - if ( ai == a->direntsused || - (ai != a->direntsused && - bi != b->direntsused && - DirEntryCompare(&a->dirents[ai], &b->dirents[bi]) > 0) ) - { - dirents[dirents_used++] = b->dirents[bi]; - for ( size_t i = 0; i < b->dirents[bi].node->direntsused; i++ ) - { - if ( strcmp(b->dirents[bi].node->dirents[i].name, "..") != 0 ) - continue; - b->dirents[bi].node->dirents[i].node = a; - } - b->dirents[bi].name = NULL; - b->dirents[bi].node = NULL; - bi++; - continue; - } - const char* name = a->dirents[ai].name; - dirents[dirents_used].name = a->dirents[ai].name; - if ( !strcmp(name, ".") || !strcmp(name, "..") ) - dirents[dirents_used].node = a->dirents[ai].node; - else - { - dirents[dirents_used].node = - MergeNodes(a->dirents[ai].node, b->dirents[bi].node); - if ( !dirents[dirents_used].node ) - failure = true; - } - dirents_used++; - a->dirents[ai].name = NULL; - a->dirents[ai].node = NULL; - ai++; - free(b->dirents[bi].name); - b->dirents[bi].name = NULL; - b->dirents[bi].node = NULL; - bi++; - } - free(a->dirents); - a->dirents = dirents; - a->direntsused = dirents_used; - a->direntslength = dirents_length; - b->direntsused = 0; - FreeNode(b); - if ( failure ) - return FreeNode(b), (struct Node*) NULL; - return a; -} - -bool WriteNode(struct initrd_superblock* sb, int fd, const char* outputname, - struct Node* node) -{ - if ( node->written ) - return true; - - uint32_t filesize = 0; - uint32_t origfssize = sb->fssize; - uint32_t dataoff = origfssize; - uint32_t filestart = dataoff; - - if ( S_ISLNK(node->mode) ) // Symbolic link - { - const size_t NAME_SIZE = 1024UL; - char name[NAME_SIZE]; - ssize_t namelen = readlink(node->path, name, NAME_SIZE); - if ( namelen < 0 ) - return warn("readlink: %s", node->path), false; - filesize = (uint32_t) namelen; - if ( pwriteall(fd, name, filesize, dataoff) < filesize ) - return warn("read: %s", node->path), false; - dataoff += filesize; - } - else if ( S_ISREG(node->mode) ) // Regular file - { - int nodefd = open(node->path, O_RDONLY); - if ( nodefd < 0 ) - return warn("open: %s", node->path), false; - const size_t BUFFER_SIZE = 16UL * 1024UL; - uint8_t buffer[BUFFER_SIZE]; - ssize_t amount; - while ( 0 < (amount = read(nodefd, buffer, BUFFER_SIZE)) ) - { - if ( pwriteall(fd, buffer, amount, dataoff) < (size_t) amount ) - { - close(nodefd); - return warn("write: %s", outputname), false; - } - dataoff += amount; - filesize += amount; - } - close(nodefd); - if ( amount < 0 ) - return warn("read: %s", node->path), false; - } - else if ( S_ISDIR(node->mode) ) // Directory - { - for ( size_t i = 0; i < node->direntsused; i++ ) - { - struct DirEntry* entry = node->dirents + i; - const char* name = entry->name; - size_t namelen = strlen(entry->name); - struct initrd_dirent dirent; - dirent.inode = entry->node->ino; - dirent.namelen = (uint16_t) namelen; - dirent.reclen = sizeof(dirent) + dirent.namelen + 1; - dirent.reclen = (dirent.reclen+3)/4*4; // Align entries. - size_t entsize = sizeof(dirent); - export_initrd_dirent(&dirent); - assert((dataoff & (alignof(dirent)-1)) == 0 ); - ssize_t hdramt = pwriteall(fd, &dirent, entsize, dataoff); - import_initrd_dirent(&dirent); - ssize_t nameamt = pwriteall(fd, name, namelen+1, dataoff + entsize); - if ( hdramt < (ssize_t) entsize || nameamt < (ssize_t) (namelen+1) ) - return warn("write: %s", outputname), false; - size_t padding = dirent.reclen - (entsize + (namelen+1)); - for ( size_t n = 0; n < padding; n++ ) - { - uint8_t nul = 0; - if ( pwrite(fd, &nul, 1, dataoff+entsize+namelen+1+n) != 1 ) - return warn("write: %s", outputname), false; - } - filesize += dirent.reclen; - dataoff += dirent.reclen; - } - } - - struct initrd_inode inode; - inode.mode = HostModeToInitRD(node->mode); - inode.uid = 0; - inode.gid = 0; - inode.nlink = node->nlink; - inode.ctime = (uint64_t) node->ctime; - inode.mtime = (uint64_t) node->mtime; - inode.dataoffset = filestart; - inode.size = filesize; - - uint32_t inodepos = sb->inodeoffset + node->ino * sb->inodesize; - uint32_t inodesize = sizeof(inode); - export_initrd_inode(&inode); - assert((inodepos & (alignof(inode)-1)) == 0 ); - if ( pwriteall(fd, &inode, inodesize, inodepos) < inodesize ) - return warn("write: %s", outputname), false; - import_initrd_inode(&inode); - - uint32_t increment = dataoff - origfssize; - sb->fssize += increment; - sb->fssize = (sb->fssize+7)/8*8; // Align upwards. - - return node->written = true; -} - -bool WriteNodeRecursive(struct initrd_superblock* sb, int fd, - const char* outputname, struct Node* node) -{ - if ( !WriteNode(sb, fd, outputname, node) ) - return false; - - if ( !S_ISDIR(node->mode) ) - return true; - - for ( size_t i = 0; i < node->direntsused; i++ ) - { - struct DirEntry* entry = node->dirents + i; - const char* name = entry->name; - struct Node* child = entry->node; - if ( !strcmp(name, ".") || !strcmp(name, ".." ) ) - continue; - if ( !WriteNodeRecursive(sb, fd, outputname, child) ) - return false; - } - - return true; -} - -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(struct initrd_inode); - sb.inodeoffset = sizeof(sb); - sb.inodecount = inodecount; - sb.root = root->ino; - - uint32_t inodebytecount = sb.inodesize * sb.inodecount; - sb.fssize += inodebytecount; - sb.fssize = (sb.fssize+7)/8*8; // Align upwards. - - if ( !WriteNodeRecursive(&sb, fd, outputname, root) ) - return false; - - sb.sumalgorithm = INITRD_ALGO_NONE; - sb.sumsize = 0; - sb.fssize = (sb.fssize+3)/4*4; // Align upwards. - sb.fssize += sb.sumsize; - - export_initrd_superblock(&sb); - if ( pwriteall(fd, &sb, sizeof(sb), 0) < sizeof(sb) ) - { - warn("write: %s", outputname); - return false; - } - import_initrd_superblock(&sb); - - if ( ftruncate(fd, sb.fssize) < 0 ) - { - warn("truncate: %s", outputname); - return false; - } - - return true; -} - -bool Format(const char* pathname, uint32_t inodecount, struct Node* root) -{ - int fd = open(pathname, O_RDWR | O_CREAT | O_TRUNC, 0666); - bool result = FormatFD(pathname, fd, inodecount, root); - close(fd); - return result; -} - -static void compact_arguments(int* argc, char*** argv) -{ - for ( int i = 0; i < *argc; i++ ) - { - while ( i < *argc && !(*argv)[i] ) - { - for ( int n = i; n < *argc; n++ ) - (*argv)[n] = (*argv)[n+1]; - (*argc)--; - } - } -} - -bool get_option_variable(const char* option, char** varptr, - const char* arg, int argc, char** argv, int* ip, - const char* argv0) -{ - size_t option_len = strlen(option); - if ( strncmp(option, arg, option_len) != 0 ) - return false; - if ( arg[option_len] == '=' ) - { - *varptr = strdup(arg + option_len + 1); - return true; - } - if ( arg[option_len] != '\0' ) - return false; - if ( *ip + 1 == argc ) - { - fprintf(stderr, "%s: expected operand after `%s'\n", argv0, option); - exit(1); - } - *varptr = strdup(argv[++*ip]), argv[*ip] = NULL; - return true; -} - -#define GET_OPTION_VARIABLE(str, varptr) \ - get_option_variable(str, varptr, arg, argc, argv, &i, argv0) - -static void help(FILE* fp, const char* argv0) -{ - fprintf(fp, "Usage: %s [OPTION]... ROOT... -o OUTPUT\n", argv0); - fprintf(fp, "Creates a init ramdisk for the Sortix kernel.\n"); - fprintf(fp, "\n"); - fprintf(fp, "Mandatory arguments to long options are mandatory for short options too.\n"); - fprintf(fp, " --filter=FILE import filter rules from FILE\n"); - fprintf(fp, " --format=FORMAT format version [%s]\n", DEFAULT_FORMAT); - fprintf(fp, " -o, --output=FILE write result to FILE\n"); - fprintf(fp, " --help display this help and exit\n"); - fprintf(fp, " --version output version information and exit\n"); -} - -static void version(FILE* fp, const char* argv0) -{ - fprintf(fp, "%s (Sortix) %s\n", argv0, VERSIONSTR); -} - -int main(int argc, char* argv[]) -{ - char* arg_filter = NULL; - char* arg_format = strdup(DEFAULT_FORMAT); - char* arg_manifest = NULL; - char* arg_output = NULL; - - const char* argv0 = argv[0]; - for ( int i = 1; i < argc; i++ ) - { - const char* arg = argv[i]; - if ( arg[0] != '-' || !arg[1] ) - continue; - argv[i] = NULL; - if ( !strcmp(arg, "--") ) - break; - if ( arg[1] != '-' ) - { - char c; - while ( (c = *++arg) ) switch ( c ) - { - case 'o': - free(arg_output); - if ( *(arg+1) ) - arg_output = strdup(arg + 1); - else - { - if ( i + 1 == argc ) - { - warnx("option requires an argument -- 'o'"); - fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]); - exit(125); - } - arg_output = strdup(argv[i+1]); - argv[++i] = NULL; - } - arg = "o"; - break; - default: - fprintf(stderr, "%s: unknown option -- '%c'\n", argv0, c); - help(stderr, argv0); - exit(1); - } - } - else if ( !strcmp(arg, "--help") ) - help(stdout, argv0), exit(0); - else if ( !strcmp(arg, "--version") ) - version(stdout, argv0), exit(0); - else if ( GET_OPTION_VARIABLE("--filter", &arg_filter) ) - { - FILE* fp = fopen(arg_filter, "r"); - if ( !fp ) - err(1, "%s", arg_filter); - if ( !AddRulesFromFile(fp, arg_filter) ) - exit(1); - fclose(fp); - free(arg_filter); - arg_filter = NULL; - } - else if ( GET_OPTION_VARIABLE("--manifest", &arg_manifest) ) - { - FILE* fp = fopen(arg_manifest, "r"); - if ( !fp ) - err(1, "%s", arg_manifest); - if ( !AddManifestFromFile(fp, arg_manifest) ) - exit(1); - fclose(fp); - free(arg_manifest); - arg_manifest = NULL; - } - else if ( GET_OPTION_VARIABLE("--format", &arg_format) ) { } - else if ( GET_OPTION_VARIABLE("--output", &arg_output) ) { } - else - { - fprintf(stderr, "%s: unknown option: %s\n", argv0, arg); - help(stderr, argv0); - exit(1); - } - } - - if ( argc < 2 ) - { - help(stdout, argv0); - exit(1); - } - - compact_arguments(&argc, &argv); - - if ( argc < 2 ) - { - fprintf(stderr, "%s: No root specified\n", argv0), - help(stderr, argv0); - exit(1); - } - - if ( !arg_output ) - { - fprintf(stderr, "%s: No output file specified\n", argv0), - help(stderr, argv0); - exit(1); - } - - const char* format = arg_format; - - if ( !strcmp(format, "default") ) - format = DEFAULT_FORMAT; - - if ( strcmp(format, "sortix-initrd-2") != 0 ) - { - fprintf(stderr, "%s: Unsupported format `%s'\n", argv0, format); - fprintf(stderr, "Try `%s --help' for more information.\n", argv0); - exit(1); - } - - uint32_t inodecount = 1; - struct Node* root = NULL; - for ( int i = 1; i < argc; i++ ) - { - struct Node* node = RecursiveSearch(argv[i], "/", &inodecount, NULL); - if ( !node ) - exit(1); - if ( root ) - root = MergeNodes(root, node); - else - root = node; - if ( !root ) - exit(1); - } - - if ( !Format(arg_output, inodecount, root) ) - exit(1); - - FreeNode(root); - - return 0; -} diff --git a/mkinitrd/rules.c b/mkinitrd/rules.c deleted file mode 100644 index ad88eed5..00000000 --- a/mkinitrd/rules.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright (c) 2013, 2015, 2016 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * rules.c - * Determines whether a given path is included in the filesystem. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rules.h" - -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) -{ - while ( *str == c) - str++; - return str; -} - -// /usr/bin/foobar match /usr = true -// /usr/bin/foobar match usr = false -// ///usr////bin//foobar match //usr// = true -// ///usr////bin//foobar match //usr//./evince = false -// TODO: Should this support . and .. too? -static bool PathMatchesPattern(const char* path, const char* pattern) -{ - bool last_was_slash = false; - while ( true ) - { - if ( !*pattern ) - return !*path || last_was_slash; - if ( (last_was_slash = *pattern == '/') ) - { - if ( *path == '/' ) - { - path = SkipCharacters(path, '/'); - pattern = SkipCharacters(pattern, '/'); - continue; - } - return false; - } - if ( *pattern++ != *path++ ) - return false; - } -} - -static int search_path(const void* a_ptr, const void* b_ptr) -{ - const char* key = (const char*) a_ptr; - char* path = *(char**) b_ptr; - return strcmp(key, path); -} - -bool IncludesPath(const char* path) -{ - bool determined = false; - bool included = false; - for ( size_t i = 0; i < num_rules; i++ ) - { - struct InclusionRule* rule = rules[i]; - if ( !PathMatchesPattern(path, rule->pattern) ) - continue; - switch ( rules[i]->rule ) - { - case RULE_INCLUDE: - included = true; - determined = true; - break; - case RULE_EXCLUDE: - included = false; - determined = true; - break; - } - } - if ( !determined ) - included = default_inclusion; - if ( !included ) - return false; - if ( manifest_used && - !bsearch(path, manifest, manifest_used, sizeof(char*), search_path) ) - return false; - return true; -} - -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++ ) - { - free(rules[i]->pattern); - free(rules[i]); - } - num_rules = new_num_rules; - 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]; - free(rules); rules = new_rules; - num_rules_allocated = new_length; - return true; -} - -bool AddRule(struct InclusionRule* rule) -{ - if ( num_rules == num_rules_allocated ) - { - size_t new_length = num_rules_allocated ? 2 * num_rules_allocated : 32; - if ( !ChangeRulesAmount(new_length) ) - return false; - } - rules[num_rules++] = rule; - return true; -} - -static const char* SkipWhitespace(const char* line) -{ - while ( *line && isspace((unsigned char) *line) ) - line++; - return line; -} - -static bool IsLineComment(const char* line) -{ - return !*line || *line == '#'; -} - -static const char* IsLineCommand(const char* line, const char* command) -{ - while ( *line && isspace((unsigned char) *line) ) - line++; - size_t cmdlen = strlen(command); - if ( strncmp(line, command, cmdlen) != 0 ) - return NULL; - if ( line[cmdlen] && !isspace((unsigned char) line[cmdlen]) ) - return NULL; - while ( line[cmdlen] && isspace((unsigned char) line[cmdlen]) ) - cmdlen++; - return line + cmdlen; -} - -bool AddRulesFromFile(FILE* fp, const char* fpname) -{ - size_t rules_at_start = num_rules; - size_t line_size; - size_t line_num = 0; - char* mem = NULL; - ssize_t line_len; - while ( 0 < (line_len = getline(&mem, &line_size, fp)) ) - { - char* line = mem; - line_num++; - if ( line[line_len-1] == '\n' ) - line[--line_len] = '\0'; - line = (char*) SkipWhitespace((char*) line); - if ( IsLineComment(line) ) - continue; - const char* parameter; - if ( (parameter = IsLineCommand(line, "default")) ) - { - bool value; - if ( !strcmp(parameter, "true") ) - value = true; - else if ( !strcmp(parameter, "false") ) - value = false; - else - { - warnx("%s:%zu: not a boolean '%s'", fpname, line_num, parameter); - goto error_out; - } - if ( !default_inclusion_determined ) - default_inclusion = value, - default_inclusion_determined = true; - else - default_inclusion = default_inclusion || value; - } - else if ( (parameter = IsLineCommand(line, "exclude")) || - (parameter = IsLineCommand(line, "include")) ) - { - if ( !*parameter ) - { - warnx("%s:%zu: no parameter given", fpname, line_num); - goto error_out; - } - const char* pattern = parameter; - 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 - { - warnx("%s:%zu: line not understood: '%s'", fpname, line_num, line); - goto error_out; - } - } - if ( ferror(fp) ) - { - error_out_errno: - warn("%s", fpname); - error_out: - free(mem); - ChangeRulesAmount(rules_at_start); - return false; - } - free(mem); - return true; -} - -int compare_path(const void* a_ptr, const void* b_ptr) -{ - const char* a = *(const char* const*) a_ptr; - const char* b = *(const char* const*) b_ptr; - return strcmp(a, b); -} - -bool AddManifestPath(const char* path) -{ - if ( manifest_used == manifest_length ) - { - size_t new_length = 2 * manifest_length; - if ( new_length == 0 ) - new_length = 64; - size_t new_size = new_length * sizeof(char*); - char** new_manifest = (char**) realloc(manifest, new_size); - if ( !new_manifest ) - { - warn("malloc"); - return false; - } - manifest = new_manifest; - manifest_length = new_length; - } - char* copy = strdup(path); - if ( !copy ) - { - warn("malloc"); - return false; - } - manifest[manifest_used++] = copy; - return true; -} - -bool AddManifestFromFile(FILE* fp, const char* fpname) -{ - char* line = NULL; - size_t line_size = 0; - ssize_t line_len; - while ( 0 < (line_len = getline(&line, &line_size, fp)) ) - { - if ( line[line_len-1] == '\n' ) - line[--line_len] = '\0'; - if ( !AddManifestPath(line) ) - return false; - } - free(line); - if ( ferror(fp) ) - { - warn("%s", fpname); - return false; - } - if ( !AddManifestPath("/") || - !AddManifestPath("/tix") || - !AddManifestPath("/tix/manifest") ) - return false; - char* fpname_copy = strdup(fpname); - if ( !fpname_copy ) - { - warn("malloc"); - return false; - } - const char* fpname_basename = basename(fpname_copy); - char* manifest_path; - if ( asprintf(&manifest_path, "/tix/manifest/%s", fpname_basename) < 0 ) - { - free(fpname_copy); - warn("malloc"); - return false; - } - free(fpname_copy); - if ( !AddManifestPath(manifest_path) ) - return free(manifest_path), false; - free(manifest_path); - qsort(manifest, manifest_used, sizeof(char*), compare_path); - return true; -} diff --git a/mkinitrd/rules.h b/mkinitrd/rules.h deleted file mode 100644 index a0de42b9..00000000 --- a/mkinitrd/rules.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2013 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * rules.h - * Determines whether a given path is included in the filesystem. - */ - -#ifndef RULES_H -#define RULES_H - -enum InclusionRuleType -{ - RULE_INCLUDE, - RULE_EXCLUDE, -}; - -struct InclusionRule -{ - char* pattern; - enum InclusionRuleType rule; -}; - -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 diff --git a/mkinitrd/serialize.c b/mkinitrd/serialize.c deleted file mode 100644 index 9852d3b1..00000000 --- a/mkinitrd/serialize.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2015 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * serialize.c - * Import and export binary data structures - */ - -#include - -#include - -#include "serialize.h" - -void import_initrd_superblock(struct initrd_superblock* obj) -{ - obj->fssize = le32toh(obj->fssize); - obj->revision = le32toh(obj->revision); - obj->inodesize = le32toh(obj->inodesize); - obj->inodecount = le32toh(obj->inodecount); - obj->inodeoffset = le32toh(obj->inodeoffset); - obj->root = le32toh(obj->root); - obj->sumalgorithm = le32toh(obj->sumalgorithm); - obj->sumsize = le32toh(obj->sumsize); -} - -void export_initrd_superblock(struct initrd_superblock* obj) -{ - obj->fssize = htole32(obj->fssize); - obj->revision = htole32(obj->revision); - obj->inodesize = htole32(obj->inodesize); - obj->inodecount = htole32(obj->inodecount); - obj->inodeoffset = htole32(obj->inodeoffset); - obj->root = htole32(obj->root); - obj->sumalgorithm = htole32(obj->sumalgorithm); - obj->sumsize = htole32(obj->sumsize); -} - -void import_initrd_inode(struct initrd_inode* obj) -{ - obj->mode = le32toh(obj->mode); - obj->uid = le32toh(obj->uid); - obj->nlink = le32toh(obj->nlink); - obj->ctime = le64toh(obj->ctime); - obj->mtime = le64toh(obj->mtime); - obj->dataoffset = le32toh(obj->dataoffset); - obj->size = le32toh(obj->size); -} - -void export_initrd_inode(struct initrd_inode* obj) -{ - obj->mode = htole32(obj->mode); - obj->uid = htole32(obj->uid); - obj->nlink = htole32(obj->nlink); - obj->ctime = htole64(obj->ctime); - obj->mtime = htole64(obj->mtime); - obj->dataoffset = htole32(obj->dataoffset); - obj->size = htole32(obj->size); -} - -void import_initrd_dirent(struct initrd_dirent* obj) -{ - obj->inode = le32toh(obj->inode); - obj->reclen = le16toh(obj->reclen); - obj->namelen = le16toh(obj->namelen); -} - -void export_initrd_dirent(struct initrd_dirent* obj) -{ - obj->inode = htole32(obj->inode); - obj->reclen = htole16(obj->reclen); - obj->namelen = htole16(obj->namelen); -} diff --git a/mkinitrd/serialize.h b/mkinitrd/serialize.h deleted file mode 100644 index 18842eb2..00000000 --- a/mkinitrd/serialize.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2015 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * serialize.h - * Import and export binary data structures - */ - -#ifndef SERIALIZE_H -#define SERIALIZE_H - -#include - -void import_initrd_superblock(struct initrd_superblock* obj); -void export_initrd_superblock(struct initrd_superblock* obj); -void import_initrd_inode(struct initrd_inode* obj); -void export_initrd_inode(struct initrd_inode* obj); -void import_initrd_dirent(struct initrd_dirent* obj); -void export_initrd_dirent(struct initrd_dirent* obj); - -#endif diff --git a/share/man/man7/development.7 b/share/man/man7/development.7 index 23e4aa35..b9323053 100644 --- a/share/man/man7/development.7 +++ b/share/man/man7/development.7 @@ -344,8 +344,6 @@ carray .It kblayout-compiler .It -mkinitrd -.It sf .It tix diff --git a/share/man/man7/kernel.7 b/share/man/man7/kernel.7 index 8af8d67d..3db231fb 100644 --- a/share/man/man7/kernel.7 +++ b/share/man/man7/kernel.7 @@ -80,10 +80,6 @@ The format of each multiboot module is automatically detected by default: .Pp .Bl -bullet -compact .It -Initialization ramdisks produced by -.Xr mkinitrd 8 -are extracted in the root directory. -.It .Xr tar 7 archives in the ustar format are extracted into the root directory. The bootloader must already have decompressed the archive.