diff options
author | Ian Moffett <ian@osmora.org> | 2025-09-13 14:53:43 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-09-13 14:53:43 -0400 |
commit | e698061ebaf0cf1a10c11c51a6c6cd46a331959c (patch) | |
tree | 19faff0de74be4661e55478ee7d31a8427c067c6 |
initial commit
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r-- | .gitignore | 7 | ||||
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | src/Makefile | 38 | ||||
-rw-r--r-- | src/arch/i386/conf/e0.ld | 46 | ||||
-rw-r--r-- | src/data/boot/limine.conf | 11 | ||||
-rwxr-xr-x | src/tools/bootstrap | 61 | ||||
-rw-r--r-- | src/tools/build-toolchain.sh | 33 | ||||
-rwxr-xr-x | src/tools/checknl.pl | 87 | ||||
-rw-r--r-- | src/tools/omar/Makefile | 12 | ||||
-rw-r--r-- | src/tools/omar/README | 9 | ||||
-rw-r--r-- | src/tools/omar/omar.c | 470 | ||||
-rw-r--r-- | src/tools/predock.sh | 77 |
12 files changed, 852 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d0c81e --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +/src/cc +/src/shim/ +/src/tools/omar/bin/omar +/src/root/ +*.o +*.d +*.iso diff --git a/README.md b/README.md new file mode 100644 index 0000000..b7b443f --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# LUNOS diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..ea6c7aa --- /dev/null +++ b/src/Makefile @@ -0,0 +1,38 @@ +TARGET = x86_64 +SHIMDIR = shim +SHIMBIN = BOOTX64.EFI +SYSROOT = root +OMAR = tools/omar/bin/omar +ISO = lunos.iso + +# QEMU emulator flags +QEMU_FLAGS = --enable-kvm -serial stdio -cdrom $(ISO) \ + -M q35 -cpu host -smp 4 -m 2G + +.PHONY: all +all: root image + +root: + mkdir -p root/ + mkdir -p root/boot/ + +.PHONY: sysroot +image: + $(OMAR) -i $(SYSROOT) -o $(SYSROOT)/boot/initrd.omar + cp $(SHIMDIR)/limine/limine-bios-cd.bin $(SYSROOT)/ + cp $(SHIMDIR)/limine/limine-uefi-cd.bin $(SYSROOT)/ + cp $(SHIMDIR)/limine/limine-bios.sys $(SYSROOT)/ + cp data/boot/limine.conf $(SYSROOT)/boot/limine.conf + xorriso -as mkisofs -b limine-bios-cd.bin -no-emul-boot -boot-load-size 4\ + -boot-info-table --efi-boot limine-uefi-cd.bin -efi-boot-part \ + --efi-boot-image --protective-msdos-label $(SYSROOT) -o $(ISO) 1>/dev/null + $(SHIMDIR)/limine/limine bios-install $(ISO) 1>/dev/null + + +.PHONY: qemu-amd64 +run: + qemu-system-$(TARGET) $(QEMU_FLAGS) + +.PHONY: clean +clean: + rm -f lunos.iso diff --git a/src/arch/i386/conf/e0.ld b/src/arch/i386/conf/e0.ld new file mode 100644 index 0000000..5b7c7fc --- /dev/null +++ b/src/arch/i386/conf/e0.ld @@ -0,0 +1,46 @@ +OUTPUT_FORMAT(elf64-x86-64) +OUTPUT_ARCH(i386:x86-64) +ENTRY(__bsp_entry) + +PHDRS +{ + text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; + rodata PT_LOAD FLAGS((1 << 2)) ; + data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; +} + +SECTIONS +{ + . = 0xFFFFFFFF80000000; + + .text : { + *(.text .text.*) + } :text + + . += CONSTANT(MAXPAGESIZE); + + .rodata : { + *(.rodata .rodata.*) + } :rodata + + . += CONSTANT(MAXPAGESIZE); + + .data : { + *(.data) + } :data + + .bss : { + *(COMMON) + *(.bss .bss.*) + } :data + + . = ALIGN(64); + .data.cacheline_aligned : { + *(.data.cacheline_aligned) + } + + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + *(.note .note.*) + } +} diff --git a/src/data/boot/limine.conf b/src/data/boot/limine.conf new file mode 100644 index 0000000..6d33d8a --- /dev/null +++ b/src/data/boot/limine.conf @@ -0,0 +1,11 @@ +timeout: 15 +randomize_hhdm_base: no +${WALLPAPER_PATH}=boot():/boot/wallpaper.jpg +wallpaper: ${WALLPAPER_PATH} +term_background: 40000000 +resolution: 1280x720 + +/e0 + protocol: multiboot2 + kernel_path: boot():/boot/e0 + module_path: boot():/boot/initrd.omar diff --git a/src/tools/bootstrap b/src/tools/bootstrap new file mode 100755 index 0000000..66664fa --- /dev/null +++ b/src/tools/bootstrap @@ -0,0 +1,61 @@ +#!/bin/bash +set -e + +SYSTEM_NAME="$(uname -s)" +MAKE="make" +GIT="git" +GCC="gcc" +CLANG="clang" + +if [ "$SYSTEM_NAME" = "OpenBSD" ] +then + MAKE="$(which gmake)" +fi + +# arg0: Output path. +# arg1: Command for downloading +try_fetch() { + if [[ -d $2 ]] + then + echo "try_fetch: Skipping $2: already exists" + else + ${@:1} + fi +} + +fetch() { + mkdir -p cc/ + try_fetch "git clone https://github.com/limine-bootloader/limine.git --branch=v9.3.0-binary --depth=1" "shim/limine" + try_fetch "git clone https://github.com/EthosZero/toolchain --depth=1" "cc/toolchain" +} + +build_limine() { + $MAKE -C shim/limine/ +} + +build_omar() { + $MAKE -C tools/omar +} + +build() { + build_limine + build_omar +} + +echo "----------------------------------" +echo +echo " Fetching sources... " +echo +echo "----------------------------------" +echo -e "\n" + +fetch # Fetch sources + +echo "----------------------------------" +echo +echo " Building sources... " +echo +echo "----------------------------------" +echo -e "\n" + +build # Build sources diff --git a/src/tools/build-toolchain.sh b/src/tools/build-toolchain.sh new file mode 100644 index 0000000..ca7fd58 --- /dev/null +++ b/src/tools/build-toolchain.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +TARGET=x86_64-pc-ethos +MAKE=make + +# Don't build again if the lock exists +if [[ -f cc/.lock ]] +then + echo "cc/.lock exists, skipping toolchain build" + exit 1 +fi + +# Build binutils and patch gcc +cd cc/toolchain/ +bash build.sh + +# Prep the build directory +cd ../ +mkdir -p gcc +cd gcc/ + +# Configure gcc +../toolchain/gcc-patched/configure --target=$TARGET \ + --prefix=$(pwd) --with-sysroot=$(pwd)/../../root/ \ + --disable-nls --enable-languages=c --disable-multilib + +# Build gcc +$MAKE all-gcc +$MAKE install-gcc + +# Lock the directory +cd ../ +touch .lock diff --git a/src/tools/checknl.pl b/src/tools/checknl.pl new file mode 100755 index 0000000..48f8c5d --- /dev/null +++ b/src/tools/checknl.pl @@ -0,0 +1,87 @@ +#!/bin/perl +# +# Copyright (c) 2025 Ian Marco Moffett and Ethos0 engineers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the project nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +use strict; +use warnings; + +# +# Fetch a single line from a file, returns eof when there +# are no more lines to fetch. +# +# Arg0: File handle +# +sub get_line { + my $fhand = shift; + return <$fhand> || die "Failed to read file..."; +} + +my $argc = 0+@ARGV; + +if ($argc < 1) { + die "Usage: $0 <filename>"; +} + +# Grab the file +my $clean = 1; +my $lineno = 1; +my $RS = undef; +my $file = shift; +open my $fhand, '<', $file || die "Failed to open $file: $^E"; +my $tmp = get_line($fhand); + +# Is there a newline at the start of the file? +if ($tmp =~ /^\n/) { + print STDERR "Found redundant newline at start of file\n"; + $clean = 0; +} + +while (!eof($fhand)) { + my $cur = get_line($fhand); + + if ($cur =~ /^\n$/ && $tmp =~ /^\n$/) { + print STDERR "Found redundant newline @ $lineno\n"; + $clean = 0; + } + + ++$lineno; + $tmp = $cur; +} + +# What about at the end? +if ($tmp =~ /^\n/) { + print STDERR "Found redundant newline at end of file\n"; + $clean = 0; +} + +if (!$clean) { + exit(1); +} + +print STDOUT "File is clean\n" diff --git a/src/tools/omar/Makefile b/src/tools/omar/Makefile new file mode 100644 index 0000000..ee30260 --- /dev/null +++ b/src/tools/omar/Makefile @@ -0,0 +1,12 @@ +CFILES = $(shell find . -name "*.c") +CFLAGS = -pedantic +CC = gcc + +.PHONY: all +all: + mkdir -p bin/ + $(CC) $(CFLAGS) $(CFILES) -o bin/omar + +.PHONY: clean +clean: + rm -rf bin/ diff --git a/src/tools/omar/README b/src/tools/omar/README new file mode 100644 index 0000000..3c74d78 --- /dev/null +++ b/src/tools/omar/README @@ -0,0 +1,9 @@ +------------------------------ +OMAR - OSMORA Archive Format +------------------------------ + +OMAR is a minimal, bullshit free archive format aimed to replace +the old and outdated CPIO (copy in/out) format. + +OMAR is designed for readonly in-memory filesystems (such as initramfs), +with simplicity, clarity and "getting it done" in mind. diff --git a/src/tools/omar/omar.c b/src/tools/omar/omar.c new file mode 100644 index 0000000..a4c7ad6 --- /dev/null +++ b/src/tools/omar/omar.c @@ -0,0 +1,470 @@ +/* + * Copyright (c) 2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/stat.h> +#include <sys/errno.h> +#include <stdio.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stdlib.h> +#include <unistd.h> +#include <stddef.h> +#include <stdint.h> +#include <assert.h> +#include <dirent.h> +#include <string.h> +#include <libgen.h> + +/* OMAR magic constants */ +#define OMAR_MAGIC "OMAR" +#define OMAR_EOF "RAMO" + +/* OMAR type constants */ +#define OMAR_REG 0 +#define OMAR_DIR 1 + +/* OMAR modes */ +#define OMAR_ARCHIVE 0 +#define OMAR_EXTRACT 1 + +/* Revision */ +#define OMAR_REV 2 + +#define ALIGN_UP(value, align) (((value) + (align)-1) & ~((align)-1)) +#define BLOCK_SIZE 512 + +static int mode = OMAR_ARCHIVE; +static int outfd; +static const char *inpath = NULL; +static const char *outpath = NULL; + +/* + * The OMAR file header, describes the basics + * of a file. + * + * @magic: Header magic ("OMAR") + * @len: Length of the file + * @namelen: Length of the filename + * @rev: OMAR revision + * @mode: File permissions + */ +struct omar_hdr { + char magic[4]; + uint8_t type; + uint8_t namelen; + uint32_t len; + uint8_t rev; + uint32_t mode; +} __attribute__((packed)); + +static inline void +help(void) +{ + printf("--------------------------------------\n"); + printf("The OSMORA archive format\n"); + printf("Usage: omar -i [input_dir] -o [output]\n"); + printf("-h Show this help screen\n"); + printf("-x Extract an OMAR archive\n"); + printf("--------------------------------------\n"); +} + +/* + * Strip out root dir + * + * XXX: This is added code to work with Hyra + * initramfs. + */ +static const char * +strip_root(const char *path) +{ + const char *p; + + for (p = path; *p != '\0'; ++p) { + if (*p == '/') { + ++p; + return p; + } + } + + return NULL; +} + +/* + * Recursive mkdir + */ +static void +mkpath(struct omar_hdr *hdr, const char *path) +{ + size_t len; + char buf[256]; + char cwd[256]; + char *p = NULL; + + len = snprintf(buf, sizeof(buf), "%s", path); + if (buf[len - 1] == '/') { + buf[len - 1] = '\0'; + } + for (p = (char *)buf + 1; *p != '\0'; ++p) { + if (*p == '/') { + *p = '\0'; + mkdir(buf, hdr->mode); + *p = '/'; + } + } + + mkdir(buf, hdr->mode); +} + +/* + * Push a file into the archive output + * + * @pathname: Full path name of file (NULL if EOF) + * @name: Name of file (for EOF, set to "EOF") + */ +static int +file_push(const char *pathname, const char *name) +{ + struct omar_hdr hdr; + struct stat sb; + int infd, rem, error; + int pad_len; + size_t len; + char *buf; + + hdr.type = OMAR_REG; + + /* Attempt to open the input file if not EOF */ + if (pathname != NULL) { + if ((infd = open(pathname, O_RDONLY)) < 0) { + perror("open"); + return infd; + } + + if ((error = fstat(infd, &sb)) < 0) { + return error; + } + + if (S_ISDIR(sb.st_mode)) { + hdr.type = OMAR_DIR; + } + hdr.mode = sb.st_mode; + } + + hdr.len = (pathname == NULL) ? 0 : sb.st_size; + hdr.rev = OMAR_REV; + hdr.namelen = strlen(name); + + /* + * If we are at the end of the file, use the OMAR_EOF + * magic constant instant of the usual OMAR_MAGIC. + */ + if (pathname == NULL) { + memcpy(hdr.magic, OMAR_EOF, sizeof(hdr.magic)); + } else { + memcpy(hdr.magic, OMAR_MAGIC, sizeof(hdr.magic)); + } + + write(outfd, &hdr, sizeof(hdr)); + write(outfd, name, hdr.namelen); + + /* If we are at the end of file, we are done */ + if (pathname == NULL) { + close(infd); + return 0; + } + + /* Pad directories to zero */ + if (hdr.type == OMAR_DIR) { + len = sizeof(hdr) + hdr.namelen; + rem = len & (BLOCK_SIZE - 1); + pad_len = BLOCK_SIZE - rem; + + buf = malloc(pad_len); + memset(buf, 0, pad_len); + write(outfd, buf, pad_len); + free(buf); + return 0; + } + + /* We need the file data now */ + buf = malloc(hdr.len); + if (buf == NULL) { + printf("out of memory\n"); + close(infd); + return -ENOMEM; + } + if (read(infd, buf, hdr.len) <= 0) { + perror("read"); + close(infd); + return -EIO; + } + + /* + * Write the actual file contents, if the file length is not + * a multiple of the block size, we'll need to pad out the rest + * to zero. + */ + write(outfd, buf, hdr.len); + len = sizeof(hdr) + (hdr.namelen + hdr.len); + rem = len & (BLOCK_SIZE - 1); + if (rem != 0) { + /* Compute the padding length */ + pad_len = BLOCK_SIZE - rem; + + buf = realloc(buf, pad_len); + memset(buf, 0, pad_len); + write(outfd, buf, pad_len); + } + close(infd); + free(buf); + return 0; +} + +/* + * Start creating an archive from the + * basepath of a directory. + */ +static int +archive_create(const char *base, const char *dirname) +{ + DIR *dp; + struct dirent *ent; + struct omar_hdr hdr; + const char *p = NULL, *p1; + char pathbuf[256]; + char namebuf[256]; + + dp = opendir(base); + if (dp == NULL) { + perror("opendir"); + return -ENOENT; + } + + while ((ent = readdir(dp)) != NULL) { + if (ent->d_name[0] == '.') { + continue; + } + + snprintf(pathbuf, sizeof(pathbuf), "%s/%s", base, ent->d_name); + snprintf(namebuf, sizeof(namebuf), "%s/%s", dirname, ent->d_name); + p1 = strip_root(namebuf); + + if (ent->d_type == DT_DIR) { + printf("%s [d]\n", p1); + file_push(pathbuf, p1); + archive_create(pathbuf, namebuf); + } else if (ent->d_type == DT_REG) { + printf("%s [f]\n", p1); + file_push(pathbuf, p1); + } + } + + return 0; +} + +/* + * Extract a single file + * + * @hp: File header + * @data: Data to extract + * @len: Length of data + * @path: Path to output file + */ +static int +extract_single(struct omar_hdr *hp, char *data, size_t len, const char *path) +{ + int fd; + + if ((fd = open(path, O_WRONLY | O_CREAT, hp->mode)) < 0) { + return fd; + } + + return write(fd, data, len) > 0 ? 0 : -1; +} + +/* + * Extract an OMAR archive. + * + * XXX: The input file [-i] will be the OMAR archive to + * be extracted, the output directory [-o] will be + * where the files get extracted. + */ +static int +archive_extract(void) +{ + char *buf, *name, *p; + struct stat sb; + struct omar_hdr *hdr; + int fd, error; + size_t len; + off_t off; + char namebuf[256]; + char pathbuf[256]; + + if ((fd = open(inpath, O_RDONLY)) < 0) { + perror("open"); + return fd; + } + + if ((error = fstat(fd, &sb)) != 0) { + perror("fstat"); + close(fd); + return error; + } + + buf = malloc(sb.st_size); + if (buf == NULL) { + fprintf(stderr, "out of memory\n"); + close(fd); + return -ENOMEM; + } + + if (read(fd, buf, sb.st_size) <= 0) { + fprintf(stderr, "omar: no data read\n"); + close(fd); + return -EIO; + } + + hdr = (struct omar_hdr *)buf; + for (;;) { + if (memcmp(hdr->magic, OMAR_EOF, sizeof(OMAR_EOF)) == 0) { + printf("EOF!\n"); + return 0; + } + + /* Ensure the header is valid */ + if (memcmp(hdr->magic, "OMAR", 4) != 0) { + fprintf(stderr, "bad magic\n"); + break; + } + if (hdr->rev != OMAR_REV) { + fprintf(stderr, "cannot extract rev %d archive\n", hdr->rev); + fprintf(stderr, "current OMAR revision: %d\n", OMAR_REV); + } + + name = (char *)hdr + sizeof(struct omar_hdr); + memcpy(namebuf, name, hdr->namelen); + namebuf[hdr->namelen] = '\0'; + + /* Get the full path */ + len = snprintf(pathbuf, sizeof(pathbuf), "%s/%s", outpath, namebuf); + if (len < 0) { + free(buf); + return len; + } + printf("unpacking %s\n", pathbuf); + + if (hdr->type == OMAR_DIR) { + off = 512; + mkpath(hdr, pathbuf); + } else { + off = ALIGN_UP(sizeof(*hdr) + hdr->namelen + hdr->len, BLOCK_SIZE); + p = (char *)hdr + sizeof(struct omar_hdr); + p += hdr->namelen; + extract_single(hdr, p, hdr->len, pathbuf); + } + + hdr = (struct omar_hdr *)((char *)hdr + off); + memset(namebuf, 0, sizeof(namebuf)); + } + + free(buf); +} + +int +main(int argc, char **argv) +{ + int optc, retval; + int error, flags; + + if (argc < 2) { + help(); + return -1; + } + + while ((optc = getopt(argc, argv, "xhi:o:")) != -1) { + switch (optc) { + case 'x': + mode = OMAR_EXTRACT; + break; + case 'i': + inpath = optarg; + break; + case 'o': + outpath = optarg; + break; + case 'h': + help(); + return 0; + default: + help(); + return -1; + } + } + + if (inpath == NULL) { + fprintf(stderr, "omar: no input path\n"); + help(); + return -1; + } + if (outpath == NULL) { + fprintf(stderr, "omar: no output path\n"); + help(); + return -1; + } + + /* + * Do our specific job based on the mode + * OMAR is set to be in. + */ + switch (mode) { + case OMAR_ARCHIVE: + /* Begin archiving the file */ + outfd = open(outpath, O_WRONLY | O_CREAT, 0700); + if (outfd < 0) { + printf("omar: failed to open output file\n"); + return outfd; + } + + retval = archive_create(inpath, basename((char *)inpath)); + file_push(NULL, "EOF"); + break; + case OMAR_EXTRACT: + /* Begin extracting the file */ + if ((error = mkdir(outpath, 0700) != 0)) { + perror("mkdir"); + return error; + } + + retval = archive_extract(); + break; + } + close(outfd); + return retval; +} diff --git a/src/tools/predock.sh b/src/tools/predock.sh new file mode 100644 index 0000000..f2f74ac --- /dev/null +++ b/src/tools/predock.sh @@ -0,0 +1,77 @@ +#!/bin/bash +# +# Copyright (c) 2025 Ian Marco Moffett and Ethos0 engineers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the project nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +# +# Description: Checks if 'bay-0' is OK to merge with 'main' +# Author: Ian Marco Moffett +# +set -e + +# Directories to check +SYSTEM=$(find sys/ -type f -name "[!.]*") +LIB=$(find lib/ -type f -name "[!.]*") +TOOLS=$(find tools/ -type f -name "[!.]*") + +fail() { + echo "!! TEST FAILURE !!" + exit 1 +} + +# +# $1: List of files +# +check_folder() { + for file in $1 + do + echo "predock: check $file..." + if [[ ! -f $file ]] + then + echo "skip $file" + continue + fi + tools/checknl.pl $file || fail + echo "OK" + done +} + +echo "predock: checking bay..." +echo "predock: nuking artifacts..." +make distclean || fail +./build.sh || fail + +echo "predock: CHECK SYSTEM" +check_folder "$SYSTEM" +echo "predock: OK, CHECK LIB..." +check_folder "$LIB" +echo "predock: OK, CHECK TOOLS..." +check_folder "$TOOLS" +echo "---------------------------------------" +echo "predock: ALL CHECKS PASSED" +echo "predock: IT IS SAFE TO DOCK BAY WITH 'main'" +git status -s |