Imported as-is from the source code tar ball.
--- /dev/null
+Version 0.4.1
+- Use syscall to call pivot_root() to avoid "warning: implicit declaration of function 'pivot_root'".
+- Replace /sbin/ paths with /bin/ paths.
+- Add additional mount flags to "floating_root" tmpfs options.
+- Move "floating_root" tmpfs options into a define.
+- Improve error logging in some cases and adding color highlight to the error.
+- Remove dead code involing the init string and init program.
+- Support ARCHITECTURE_BITS (and ARCHITECTURE_BITS_PATH) environment variables to designate architecture specific paths in the target system.
+- Improve detection of pre_init and init paths and use accordingly (prioritize pre_init and if not found then attempt init).
+- Fix the copyright license (should be lgpl-2.1-or-later, which is what the FLL library License is).
+- Add extern "C" macros to allow for c++ compiling.
+- Attempt arch-specific and simple on system umount call fallback.
+- Do lazy unmounting.
+- Perform system umount call failsafe if umount fails for "/tmp" (just like how it is done for "/proc").
+- Perform flush after printing while handling error and exiting.
+
+Version 0.4.0
+- use REG_OK instead of REG_NOERROR
+- the kernel has an rdinit= for the ramdisk init program and it seems root=/dev/ram0 is no longer necesasry.
+ - Replace finalroot= and finalinit= with just root= and init=.
+
+Version 0.3.0
+- add -s to grep statements in shell scripts to silence error messages.
+- add a 1 second sleep after the failed to mount warning for dynamic files.
+- add additional warning to do_dynamic_files().
+- give cdrom searches more time and chances to spin up so that the cdrom can be read during the detection process.
+- rewrite settings init to:
+ - perform mounts if not doing a live init.
+ - add support for sharedevice=, packagedevice=, perldevice=, and pythondevice=.
+ - process the following possible device mounts rootfs home etc share var tmp package perl python documentation.
+ - use (device).encrypted instead of (device).device for identifying encrypted partitions.
+ - use (device).device to identify the devices manual mount path.
+ - add support for settings.lock inside of the settings directory to force ignoring command line (device)device= options.
+ - check for settings directory at: ${device_directory}boot/settings/, ${device_directory}settings/, or ${device_directory}.
+- add mount_init.sh as a quick and dirty way to mount devices defined in the settings directory for non-live inits.
+- mount settings directory and /settings/ instead of /boot/ and leave it mounted so that it can be used later, such as during a live init or a mount init.
+- remove stale cdrom and mmc search code.
+- remove find_device.sh, blkid has long since added the necessary functionality that this script used to guess.
+- remove cdromsearch= and mmcsearch= boot options.
+- made the naming conventions of the floating root path and the root paths a little less confusing.
+- add /.settings/ directory as a valid settings path directory.
+- unmount the system directory in squash boot mode because it is not required.
+- fix raid array support which had stopped working at some point due to code changes.
+- use tag support from blkid instead of directly calling UUID and LABEL support so that more tags (such as UUID_SUB, which is useful for raid devices) can be supported.
+
+Version 0.2.1
+- add package directory support
+- cleanup firmware and kernel modules on error during live_init.sh
+- warn if the firmware or kernel modules are missing during live_init.sh
+- always float the squish and squash rootfs and remove the floating_root parameter
+- fix bug where I used squishpath= and should have used squashpath= because squish and squash should both use squashpath=
+- ensure that filesystemlimit starts with a number to reduce chances of injecting custom mount options
+
+Version 0.2.0
+- now using the new group naming convention created in turtle kevux 0.9.3 (at this time, group names are not dynamically detected)
+- ensure that the appropriate binaries exists before attempting a chroot
+- ensure that when any of the following (homedevice=, etcdevice=, vardevice=, or tmpdevice=) are passed to the kernel command line that symbolic links are not made for these paths during live or subroot boots
+- removed /var/tmp usage from the pre_init file
+- correct simple mistake in raid boot device detection that prevented raid devices from being auto-created during boot
+
+Version 0.1.18
+- ensure that the boot directory has world execute bit set during live init
+- add software raid array support
+- kernel modules now use the suffix .modules instead of .sfs
+- allow do_unsquash bash function to support dynamic file extensions so that .modules and .sfs can both be used
+- check to see if $init_string (/sbin/pre_init) exists before doing a pivot_root and drop to bash if it does not
+- make sure that the tmp directory exists within the pivot_root target
+- make quoted information inside of errors stand out
+
+Version 0.1.17
+- fix group permission on rootfs for squashboot to be set to root instead of boot
+- correct spelling mistake from fileystem to filesystem
+- removal of toolchain and documentation directories on live extract failure are now properly removed in squishboot
+- remove duplicate toolchain removal on live extract failure
+- squishboot=memory was not blacklisting /share during the symlink process
+- remove improper use of ${the_dir}
+- ensure that subroot works when using squishboot modes
+- if dev/console is missing after chroot, attempt to drop to a bash shell to prevent a kernel crash
+- correct dev group permission to be dev and not udev
+
+Version 0.1.16
+- make sure to check both the boot/settings path and the settings path for the settings files
+- add subroot support
+- add initial floating root support (required by subroot when not using the squash or squash boot methods)
+- correct a the parameters for the handle_error print command for the initrd_init program
+
+Version 0.1.15
+- make sure the squash and squish root directory is mounted with world executable bit
+- add installation mode support
+- add support for kiwi installation mode
+- only set install_files path if actually in install mode
+
+Version 0.1.14
+- add support for encrypted booting with LABEL and UUID
+- add documentation=yes boot parameter
+
+Version 0.1.13
+- change .squash file extensions to the now known squash standard of .sfs
+
+Version 0.1.12
+- added support for /modules and /firmware directory handling
+- removed use_xorg_driver as it is no longer needed
+- removed _without_xorg_ and _with_xorg_ as the processing code was moved to a qingy patch
+- added _squish_into_memory_ support
+- changed default squash_path and squish_paths from live/ to boot/live/
+- moved squish_init into squash_init script, removing the squish_init script
+- subroot has been temporarily removed
+- added tmpdevice= support
+- switched /live/ to /this/ to make it more obvious that that directory contains the files of the hardware that contains the boot files
+- replaced squash, squish, and cdrom boot options with: squashboot=, squishboot=, and cdromsearch=
+- added mmcsearch= option for searching MMC devices
+- pre_init now handles mounting: /var/run, /var/tmp, /var/log, and /mnt
+- renamed squash_init to live_init
+- synchronize boot delays between live_init script and the initrd_init program; apparently, they had different values
+- added encryption support for specific partitions: home, etc, tmp, var, rootfs
+- added find_device.sh for wrapping blkid device search calls for devices that are not auto-searched
+- added settings_init.sh for managing loading of dynamic boot settings, like encrypted boot or network boot
+- added settingscdromsearch= and settingsmmcsearch= options
+- change cdrom_search= and mmc_search= options to default to ignore
+- fix a bug that caused toolchain to improperly extract itself as /toolchain/squashfs-root instead of putting the contents inside of /toolchain
+- perform the settings init process prior to dropping into maintenance mode
+- Do not fail if toolchain.squash is missing, just print a warning
+
+Version 0.1.11
+- added _boot_to_squish_ boot option that is a hybrind between squashfs boot and a normal boot
+- fixed an issue where the end-system /var was not being created just before the mount command is called
+
+Version 0.1.10
+- Fix the case where the options specified on the first line are not caught by the regex pattern
+- Shrink binary size by 1 or 2 k
+- Fix potential memory leak of commandline parameter when dropping to failsafe environment
+- Add boot by UUID= support
+- Removed squash_init's creation and use of /mnt devices now that udev handles that
+
+Version 0.1.9
+- Don't allow squashfs to display its progress bar as it has a tendency to generate a floating point exception
+- Remove stale (commented out) code
+- Increase root boot delays from 8 retries to 10 retries to cope for very slow/buggy devices
+ - in particular the olpc mmc device sometimes takes a very long time.
+
+Version 0.1.8
+- Increase final root number of tries from 6 to 8, to give really slow devices
+an extra chance
+- Make sure that the squash_init will umount the tmpfs with the lazy umount
+flag set
+- Apparently in squash_init, there was another location where the root mount
+retry is attempted only 2 times, this was changed to 8
+- Added some extra critical failure catches when handling etc.squash and
+home.squash
+- Move the corrupt failure checks into a single function to reduce file size
+
+Version 0.1.7
+- memset the init_string to guarantee that there is a null
+- have the init_string max path be allocated max path + 1 so that there is always a trailing null no matter what
+- fix an issue with the finalroot= not always working
+ - Apparently, I was allocating the exact amount of space needed and no more.
+ - There must be space_used + 1 to guarantee that a null pointer exists to terminate the string
+ - Because there was no explicit null terminator, the finalroot= only terminated out of pure luck!
+ - This was a serious buffer overrun issue
+- Apparently, I never allocated the subroot array, it should now be allocated!
+
+Version 0.1.6
+- add pre_init to handle the mounting of the /proc, /dev, and /sys directories as well as fixing the initng boot process problem
+ - This improves the boot process and simplifies initng's initial work
+- added some verbosity and extra error handling to the initrd_init
+- for squash_init, make sure the proc is not mounted before trying to unmount /tmp
+- final fix initrd_init such that the initrd fs gets properly removed!
+
+Version 0.1.5
+- Fix regression in squash_init where run from live system always returns failure, even when things work.
+
+Version 0.1.4
+- Fixed a bug where the wrong ignore_length was used for the init regex
+ - This bug was not noticed because the values happened to be the same
+- Add _with_toolchain_ option
+- Add subroot= option
+- The return 0; statement should never be reached, but if it does, exec the failsafe environment
+- Fix a problem with squash_init does not copy the squashed data into memory
+- Added a Critical Failure error handler
+
+Version 0.1.3
+- Make sure the rootfs does not have +t set.
+- Make sure /var/run and /var/tmp have group writability
+
+Version 0.1.2
+- add a chdir command following the pivot_root
+- Change livecd_init to squash_init
+- Cleanup Color Codes
+- Add the squash_init script to this project
+- Add more boot options
+- Change the _drop_to_init_bash_ to _maintenance_mode_
+- make sure the _into_memory_ options are processed and executed correctly
+
+Version 0.1.1
+- Create This file
+- Modify regex to expect a space in front of the option (so that Bloblalbalasfasfinalroot= does not get processed as finalroot)
+- Repeat the modification to prevent trailing data that would otherwise cause the statement to be invalid
+- Add the programmers name: Kevin Day
+- Add _boot_to_livecd_ option for booting the live cd via grub. The livecd itself will be a seperate program or script called: /sbin/livecd_init.
+- Have bash perform a login
+
+Version 0.1.0
+- Initial Release
--- /dev/null
+// Programmer: Kevin Day
+// License: lgpl-2.1-or-later
+// NOTE: This is just a very quick implementation to get things off the ground. I inted to rewrite this accordingly and move it into the FLL project.
+// This provides the kernel with the ability to boot devices by LABEL or UUID.
+// This provides the kernel with the ability to not lock up on reboot
+
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <regex.h>
+#include <string.h>
+#include <malloc.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// To disable ARCHITECTURE_BITS entirely, set both ARCHITECTURE_BITS and ARCHITECTURE_BITS_PATH to an empty string.
+// The ARCHITECTURE_BITS and ARCHITECTURE_BITS_PATH must be strings (as in: gcc -O2 -fPIE -DARCHITECTURE_BITS="\"${architecture_bits}\"" initrd_init.c -o initrd_init).
+#ifdef ARCHITECTURE_BITS
+ #define arch_bits ARCHITECTURE_BITS
+#else
+ #define arch_bits "x64"
+#endif // ARCHITECTURE_BITS
+
+#ifdef ARCHITECTURE_BITS_PATH
+ #define arch_bits_path "" ARCHITECTURE_BITS_PATH "/"
+#else
+ #define arch_bits_path "" arch_bits "/"
+#endif // ARCHITECTURE_BITS_PATH
+
+#define the_init "\\<init=[[:alnum:][:punct:]]*"
+#define the_subroot "\\<subroot=[[:alnum:][:punct:]]*"
+#define the_maintenance "\\<maintenance\\>"
+#define the_squash "\\<squashboot=[[:alnum:][:punct:]]*"
+#define the_squish "\\<squishboot=[[:alnum:][:punct:]]*"
+#define the_settings "\\<settings=[[:alnum:][:punct:]]*"
+
+#define ignore_length_init 5
+#define ignore_length_subroot 8
+
+#define error_color "\033[1;31m"
+#define warning_color "\033[0;33m"
+#define notice_color "\033[0;1m"
+#define highlight_color "\033[1;32m"
+#define reset_color "\033[0;0m"
+
+#define rootfs_path "boot/system"
+#define float_path "/mnt"
+#define mount_program "/bin/mount"
+#define chroot_program "/bin/chroot"
+#define init_program_arch "/bin/" arch_bits_path "init"
+#define init_program_simple "/bin/init"
+#define preinit_program_arch "/bin/" arch_bits_path "pre_init"
+#define preinit_program_simple "/bin/pre_init"
+#define bash_program "/bin/bash"
+#define bash_program_target_arch "/bin/" arch_bits_path "bash"
+#define bash_program_target_simple "/bin/bash"
+#define squashinit_program "/bin/live_init"
+#define settingsinit_program "/bin/settings_init"
+#define mount_init_program "/bin/mount_init"
+#define umount_program_arch "/bin/" arch_bits_path " umount"
+#define umount_program_simple "/bin/umount"
+#define proc_path "/proc"
+#define tmp_path "/tmp"
+#define command_line_path "/proc/cmdline"
+#define init_path_max 4097
+#define float_root_opts "size=1M,mode=0751,gid=d_root,nosuid,dev,noatime"
+
+#define dropped_message "Dropped to the init programs bash environment"
+#define at_request_message "at your request"
+#define on_error_message "due to an error"
+
+#ifndef MNT_DETACH
+ #define MNT_DETACH 2
+#endif
+
+void handle_failure(const char *message, const int result) {
+ chdir("/");
+
+ if (message) {
+ printf("%sError: %s", error_color, message);
+
+ if (result) {
+ printf(", status code = %d", result);
+ }
+
+ printf("%s\n", reset_color);
+ }
+
+ printf("%s%s %s.%s\n", notice_color, dropped_message, on_error_message, reset_color);
+ fflush(stdout);
+
+ execl(bash_program, "", "--login", (char *) 0);
+ exit(0); // guarantee an exit
+}
+
+int mount_init() {
+
+ // " / \0" = 4
+ char * const mount_string = calloc(sizeof(char), strlen(mount_init_program) + strlen(float_path) + strlen(rootfs_path) + 4);
+ if (!mount_string) return -1;
+
+ strcat(mount_string, mount_init_program);
+ strcat(mount_string, " ");
+ strcat(mount_string, float_path);
+ strcat(mount_string, "/ ");
+ strcat(mount_string, rootfs_path);
+
+ const int mount_status = system(mount_string);
+
+ free(mount_string);
+ return mount_status;
+}
+
+int do_regex_match(regex_t *expression, regmatch_t *match, const char *string_to_search, const char *string_to_match) {
+ int reg_result = 0;
+
+ regcomp(expression, string_to_match, 0);
+ reg_result=regexec(expression, string_to_search, 1, match, 0);
+ regfree(expression);
+
+ return reg_result;
+}
+
+int main() {
+ int mount_status = 0;
+ int max_iter = 10;
+ FILE *proc_cmdline = 0;
+ char *cmdline = 0;
+ size_t length = 0;
+ regex_t expression;
+ regmatch_t match;
+ int reg_result = 0;
+ int string_length = 0;
+ char *subroot_string = 0;
+ struct stat file_status;
+
+ printf("%sTurtle Kevux System Now Starting to Boot%s\n", highlight_color, reset_color);
+
+ mount("proc", proc_path, "proc", 0, "");
+ proc_cmdline = fopen(command_line_path, "ro");
+ getline(&cmdline, &length, proc_cmdline);
+
+ if (proc_cmdline) fclose(proc_cmdline);
+
+
+ // CUSTOM SETTINGS
+ // ------------------------------------------------------------
+ // Look for the settings option
+ reg_result = do_regex_match(&expression, &match, cmdline, the_settings);
+
+ if (reg_result == REG_OK) {
+ printf("%sAttempting to load custom settings at your request.%s\n", notice_color, reset_color);
+ system(settingsinit_program);
+ }
+
+
+ // MAINTENANCE MODE
+ // -----------------------------------------------------------
+ // Look for the option that says to only drop to the bash shell
+ reg_result = do_regex_match(&expression, &match, cmdline, the_maintenance);
+
+ if (reg_result == REG_OK) {
+ if (cmdline) free(cmdline);
+ printf("%s%s %s.%s\n", dropped_message, at_request_message, notice_color, reset_color);
+ execl(bash_program, "", "--login", (char *) 0);
+ exit(0); // guarantee an exit
+ }
+
+
+ // LIVE BOOTING
+ // ------------------------------------------------------------
+ // Look for the option that says to boot a squash
+ reg_result = do_regex_match(&expression, &match, cmdline, the_squish);
+
+ if (reg_result == REG_OK) {
+ if (cmdline) free(cmdline);
+ printf("%sAttempting to boot squish at your request.%s\n", notice_color, reset_color);
+ execl(squashinit_program, (char *) 0);
+ exit(0); // guarantee an exit
+ }
+
+ // ------------------------------------------------------------
+ // Look for the option that says to boot a squash
+ reg_result=do_regex_match(&expression, &match, cmdline, the_squash);
+
+ if (reg_result == REG_OK) {
+ if (cmdline) free(cmdline);
+ printf("%sAttempting to boot squash at your request.%s\n", notice_color, reset_color);
+ execl(squashinit_program, (char *) 0);
+ exit(0); // guarantee an exit
+ }
+
+
+ // STANDARD OPTIONS
+ // ------------------------------------------------------------
+ // Look for the option that specifies the subroot path
+ reg_result = do_regex_match(&expression, &match, cmdline, the_subroot);
+
+ if (reg_result == REG_OK) {
+ if (cmdline[match.rm_so + ignore_length_subroot] == '/') {
+ string_length = match.rm_eo - match.rm_so - ignore_length_subroot - 1;
+ subroot_string = calloc(sizeof(char), string_length + 1);
+ strncpy(subroot_string, cmdline + match.rm_so + ignore_length_subroot + 1, string_length);
+ subroot_string[string_length] = '\0';
+ } else {
+ string_length = match.rm_eo - match.rm_so - ignore_length_subroot;
+ subroot_string = calloc(sizeof(char), string_length + 1);
+ strncpy(subroot_string, cmdline + match.rm_so + ignore_length_subroot, string_length);
+ subroot_string[string_length] = '\0';
+ }
+ }
+
+ // ------------------------------------------------------------
+ if (cmdline) free(cmdline);
+
+ int result = 0;
+
+ {
+ #define mount_float_root_string mount_program " -t tmpfs -o " float_root_opts " floating_root " float_path
+
+ result = system(mount_float_root_string);
+
+ if (result == -1) {
+ printf("%sError: Failed to mount the floating root filesystem: %s" mount_float_root_string "%s, status code = %d.%s\n", error_color, notice_color, error_color, result, reset_color);
+
+ if (subroot_string) free(subroot_string);
+
+ handle_failure(0, 0);
+ }
+ }
+
+ chdir(float_path);
+ mkdir("boot", S_ISGID | S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
+ mkdir("dev", S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
+ mkdir("proc", S_ISGID | S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
+ mkdir("sys", S_ISGID | S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
+ mkdir("tmp", S_ISGID | S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
+ mkdir("mnt", S_ISGID | S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
+ mkdir(rootfs_path, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
+
+ mount_status = mount_init();
+
+ if (mount_status == 0) {
+ int floating_root_status = 0;
+ char *floating_root_string = 0;
+
+ result = chdir(float_path "/" rootfs_path);
+
+ if (result != 0) {
+ printf("%sError: Failed to change to the floating mount point path '%s', status code = %d.%s\n", error_color, float_path "/" rootfs_path, result, reset_color);
+ if (subroot_string) free(subroot_string);
+
+ handle_failure(0, 0);
+ }
+
+ if (subroot_string) {
+ result = chdir(subroot_string);
+
+ if (result != 0) {
+ printf("%sError: Failed to change to the subroot path '%s', status code = %d.%s\n", error_color, subroot_string, result, reset_color);
+ free(subroot_string);
+
+ handle_failure(0, 0);
+ }
+ }
+
+ // "for i in * ; do if [[ ! -e /$i ]] ; then ln -s /$i /$i ; fi ; done\0" = 67
+ floating_root_string = calloc(sizeof(char), strlen(float_path) * 2 + strlen(rootfs_path) + (subroot_string ? strlen(subroot_string) + 1 : 0) + 67);
+
+ if (!floating_root_string) {
+ printf("%sError: Failed to allocate enough memory to perform floating root operations.%s\n", error_color, reset_color);
+ if (subroot_string) free(subroot_string);
+
+ handle_failure(0, 0);
+ }
+
+ strcat(floating_root_string, "for i in * ; do if [[ ! -e ");
+ strcat(floating_root_string, float_path);
+ strcat(floating_root_string, "/$i ]] ; then ln -s ");
+ strcat(floating_root_string, rootfs_path);
+ strcat(floating_root_string, "/");
+
+ if (subroot_string) {
+ strcat(floating_root_string, subroot_string);
+ strcat(floating_root_string, "/");
+ }
+
+ strcat(floating_root_string, "$i ");
+ strcat(floating_root_string, float_path);
+ strcat(floating_root_string, "/$i ; fi ; done");
+
+ result = system(floating_root_string);
+
+ free(floating_root_string);
+
+ if (result != 0) {
+ handle_failure("Failed to create the symolic links for the floating root.", result);
+ }
+ }
+
+ if (subroot_string) free(subroot_string);
+
+ // on failure, execute bash for now.
+ if (!mount_status) {
+ handle_failure("Failed to mount init filesystems", mount_status);
+ } else {
+ if (!umount2(proc_path, MNT_DETACH)) {
+ printf("%sWarning: Failed to unmount '%s%s%s', now trying the umount user space program.%s\n", warning_color, notice_color, proc_path, warning_color, reset_color);
+
+ if (!system(umount_program_arch " -l " proc_path)) {
+ system(umount_program_simple " -l " proc_path);
+ }
+ }
+
+ result = chdir(float_path);
+
+ if (!result) {
+ printf("%sError: Failed to change to the floating root mount point '%s%s%s', status code = %d.%s\n", error_color, notice_color, float_path, error_color, result, reset_color);
+ handle_failure(0, 0);
+ }
+
+ if (!stat(bash_program_target_arch, &file_status) && !stat(bash_program_target_simple, &file_status)) {
+ printf("%sError: Failed to find either '%s%s%s' or '%s%s%s' in the mount point '%s%s%s'.%s\n", error_color, notice_color, bash_program_target_arch, error_color, notice_color, bash_program_target_simple, error_color, notice_color, float_path, error_color, reset_color);
+ handle_failure(0, 0);
+ }
+
+ syscall(SYS_pivot_root, ".", "tmp");
+
+ if (chdir("/") != 0) {
+ printf("%sWarning: Failed to chdir to '%s/%s'%s\n", warning_color, notice_color, warning_color, reset_color);
+ }
+
+ char * this_init_program = preinit_program_arch;
+
+ if (!stat(preinit_program_arch, &file_status)) {
+ this_init_program = preinit_program_simple;
+
+ if (!stat(preinit_program_simple, &file_status)) {
+ this_init_program = init_program_arch;
+
+ if (!stat(init_program_arch, &file_status)) {
+ this_init_program = init_program_simple;
+
+ if (!stat(init_program_simple, &file_status)) {
+ printf("%sError: Failed to find '%s%s%s', '%s%s%s', in the mount point '%s%s%s'.%s\n", error_color, notice_color, preinit_program_arch, error_color, notice_color, preinit_program_simple, error_color);
+ printf("'%s%s%s', or '%s%s%s' within the floating root mount point '%s%s%s'.%s\n", notice_color, init_program_arch, error_color, notice_color, init_program_simple, error_color, notice_color, float_path, error_color, reset_color);
+ handle_failure(0, 0);
+ }
+ }
+ }
+ }
+
+ result = chroot("/");
+
+ if (!result) {
+ printf("%sWarning: Failed to chroot to '%s/%s', status code = %d%s\n", warning_color, notice_color, warning_color, result, reset_color);
+ } else {
+ result = umount2(tmp_path, MNT_DETACH);
+
+ if (!result) {
+ printf("%sWarning: Failed to unmount '%s%s%s', now trying the umount user space program.%s\n", warning_color, notice_color, tmp_path, warning_color, reset_color);
+
+ if (!system(umount_program_arch " -l " tmp_path)) {
+ system(umount_program_simple " -l " tmp_path);
+ }
+ }
+
+ execl(this_init_program, (char *) 0);
+ }
+
+ handle_failure(0, 0);
+ }
+
+ // regardless of what happens, if we make it this far, drop it to the init bash
+ chdir("/");
+ printf("%s%s %s.%s\n", notice_color, dropped_message, on_error_message, reset_color);
+ execl(bash_program, "", "--login", (char *) 0);
+ return 0;
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+License: FLLL
+license owner: Kevin Day
+programmer: Kevin Day
+see: www.kevux.org
--- /dev/null
+#!/bin/bash
+first_parameter=$1
+
+drop_to_init_bash(){
+ echo -e "\\033[1;31mERROR: Live Boot Failed: $1\\033[0m"
+ echo -e "\\033[1mDropping you to an almost useless bash shell.\\033[0m"
+ exec /bin/bash --login
+}
+
+corrupt_failure_check(){
+ if [[ $1 == "yes" ]] ; then
+ echo -e "\\033[1;31m!CRITICAL ERROR!\\033[0m"
+ drop_to_init_bash "Data is corrupted/missing, Media is bad/damaged, or an unsupported kernel is being used"
+ fi
+}
+
+missing_file_warning(){
+ echo -e "\\033[0;33mWarning: Unable to $1 '\\033[0;01m$2\\033[0;33m', it could not be found.\\033[0m"
+ sleep 2
+}
+
+do_unsquash(){
+ local d=$float_path$boot_dir$system_dir$sq_path
+ local exists=no
+
+ if [[ ! -f $d$2.$1 ]] ; then
+ if [[ $3 != "silent_on_missing" ]] ; then
+ echo -e "\\033[1;31mERROR: Could not find '\\033[0;01m${d}${2}.${1}\\033[1;31m'\\033[0m"
+ fi
+
+ return 1;
+ fi
+
+ echo -e -n "Unsquashing $2: "
+
+ if [[ -d $2 ]] ; then
+ exists=yes
+ unsquashfs -n $d$2.$1 &>/dev/null &&
+ mv --progress squashfs-root/* $2 &&
+ rmdir -p squashfs-root
+ else
+ unsquashfs -n $d$2.$1 &>/dev/null &&
+ mv --progress squashfs-root $2
+ fi
+
+ if [[ $? != 0 ]] ; then
+ if [[ -e squashfs-root ]] ; then
+ rm -Rf squashfs-root
+ fi
+
+ if [[ $exists == "no" && -d $2 ]] ; then
+ rm -Rf $2
+ fi
+
+ echo -e "\\033[1;31mFailure\\033[0m"
+ return 1
+ fi
+
+ echo -e "\\033[1mDone\\033[0m"
+}
+
+copy_squash_files(){
+ local d=$float_path$boot_dir$system_dir$sq_path
+ local l=$float_path$boot_dir$live_dir
+
+ cp --progress ${d}{bin,lib,sbin}.sfs $l || failure="yes"
+
+ if [[ $failure == "no" && $without_share == "" && $share_device == "" ]] ; then
+ cp --progress ${d}share.sfs $l || failure="yes"
+ fi
+
+ if [[ $failure == "no" ]] ; then
+ if [[ -f ${d}firmware.sfs ]] ; then
+ cp --progress ${d}firmware.sfs $l || failure="yes"
+ else
+ missing_file_warning copy ${d}firmware.sfs
+ fi
+ fi
+
+ if [[ $failure == "no" && -f ${d}$current_kernel.modules ]] ; then
+ if [[ -f ${d}$current_kernel.modules ]] ; then
+ cp --progress ${d}$current_kernel.modules $l || failure="yes"
+ else
+ missing_file_warning copy ${d}$current_kernel.modules
+ fi
+ fi
+
+ if [[ $failure == "no" && $with_toolchain != "" && $toolchain_device == "" ]] ; then
+ if [[ -f ${d}toolchain.sfs ]] ; then
+ cp --progress ${d}toolchain.sfs $l || failure="yes"
+ else
+ missing_file_warning copy ${d}toolchain.sfs
+ fi
+ fi
+
+ if [[ $failure == "no" && $with_documentation != "" && $documentation_device == "" ]] ; then
+ if [[ -f ${d}documentation.sfs ]] ; then
+ cp --progress ${d}documentation.sfs $l || failure="yes"
+ else
+ missing_file_warning copy ${d}documentation.sfs
+ fi
+ fi
+
+ if [[ $failure == "no" && $with_package != "" && $package_device == "" ]] ; then
+ if [[ -f ${d}package.sfs ]] ; then
+ cp --progress ${d}package.sfs $l || failure="yes"
+ else
+ missing_file_warning copy ${d}package.sfs
+ fi
+ fi
+
+ if [[ $failure == "no" && $with_perl != "" && $perl_device == "" ]] ; then
+ if [[ -f ${d}perl.sfs ]] ; then
+ cp --progress ${d}perl.sfs $l || failure="yes"
+ else
+ missing_file_warning copy ${d}perl.sfs
+ fi
+ fi
+
+ if [[ $failure == "no" && $with_python != "" && $python_device == "" ]] ; then
+ if [[ -f ${d}python.sfs ]] ; then
+ cp --progress ${d}python.sfs $l || failure="yes"
+ else
+ missing_file_warning copy ${d}python.sfs
+ fi
+ fi
+}
+
+do_dynamic_files(){
+ local d=$float_path$boot_dir$system_dir$sq_path
+ local l=$float_path$boot_dir$live_dir
+
+ do_unsquash sfs $1 || failure="yes"
+
+ if [[ $failure == "yes" ]] ; then
+ failure="no"
+
+ if [[ -f $d$1.sfs ]] ; then
+ mkdir -p $1
+ cp --progress $d$1.sfs $l &&
+ mount -o loop $l$1.sfs $1 || failure="yes"
+
+ corrupt_failure_check $failure
+ else
+ echo -e "\\033[0;33mWarning: Unable to find '\\033[0;01m$1.sfs\\033[0;33m' in '\\033[0;01m${d}\\033[0;33m'.\\033[0m"
+ sleep 1
+ fi
+ fi
+}
+
+mount_floating_root(){
+ if [[ $filesystem_limit == "" || $(echo $filesystem_limit | grep -s -o "^\<[[:digit:]]") == "" ]] ; then
+ mount -t tmpfs -o gid=d_root,mode=2751 live_system $float_path || drop_to_init_bash "Unable to mount the floating root filesystem"
+ else
+ mount -t tmpfs -o size=$filesystem_limit,gid=d_root,mode=2751 live_system $float_path || drop_to_init_bash "Unable to mount the floating root filesystem"
+ fi
+}
+
+create_basic_root_directories(){
+ local d=$float_path
+
+ mkdir -p ${d}{$boot_dir/{$live_dir,$system_dir},dev,mnt,proc,sys}
+ mkdir -p ${d}dev/pts
+
+ chmod o-r ${d}{mnt,proc,dev,boot,sys}
+ chmod o+x ${d}$boot_dir{,/$live_dir,/$system_dir}
+ chgrp d_root ${d}
+ chgrp d_boot ${d}$boot_dir{,/$live_dir,/$system_dir}
+ chgrp d_device ${d}dev
+ chgrp k_system ${d}sys
+ chgrp k_process ${d}proc
+ chgrp d_mount ${d}mnt
+ chmod -t ${d}
+ chmod g+s ${d}mnt ${d}$boot_dir{,/$live_dir,/$system_dir}
+}
+
+create_additional_root_directories(){
+ local d=$float_path
+ local i=
+
+ if [[ ! -e ${d}var ]] ; then
+ mkdir -p ${d}var
+ chgrp d_variable ${d}var
+ chmod u+rwx,g+rxs-w,o+x-rw ${d}var
+ fi
+
+ if [[ ! -e ${d}var/log ]] ; then
+ mkdir -p ${d}var/log
+ chgrp d_log ${d}var/log
+ chmod u+rwx,g+rxs-w,o+x-rw ${d}var/log
+ fi
+
+ if [[ ! -e ${d}var/run ]] ; then
+ mkdir -p ${d}var/run
+ chgrp d_run ${d}var/run
+ chmod u+rwx,g+rxs-w,o+x-rw ${d}var/run
+ fi
+
+ if [[ ! -d ${d}tmp ]] ; then
+ mkdir -p ${d}tmp &&
+ chgrp d_temporary ${d}tmp &&
+ chmod u+rwx,g+rwx,o-rwx ${d}tmp &&
+ chmod +t ${d}tmp ||
+ failure="yes"
+
+ if [[ $failure == "yes" ]] ; then
+ echo -e "\\033[1;31mERROR: Failed to create the '\\033[0;01m${d}tmp\\033[1;31m' directory\\033[0m"
+ fi
+ fi
+}
+
+# All of the boot time parameters available are here
+boot_string=$(/bin/grep -s -o "\<root=[[:alnum:][:punct:]]*\>" /proc/cmdline | sed -e 's|\<root=||')
+init_string=$(/bin/grep -s -o "\<init=[[:alnum:][:punct:]]*\>" /proc/cmdline | sed -e 's|\<init=||')
+filesystem_limit=$(/bin/grep -s -o "\<filesystemlimit=[[:digit:]]*[[:alpha:]]*\>" /proc/cmdline | sed -e 's|\<filesystemlimit=||')
+with_toolchain=$(/bin/grep -s -o "\<toolchain=yes\>" /proc/cmdline)
+with_documentation=$(/bin/grep -s -o "\<documentation=yes\>" /proc/cmdline)
+with_python=$(/bin/grep -s -o "\<python=yes\>" /proc/cmdline)
+with_perl=$(/bin/grep -s -o "\<perl=yes\>" /proc/cmdline)
+with_package=$(/bin/grep -s -o "\<package=yes\>" /proc/cmdline)
+without_share=$(/bin/grep -s -o "\<share=no\>" /proc/cmdline)
+current_kernel=$(/bin/uname -r)
+doing_squash=$(/bin/grep -s -o "\<squashboot=[[:alnum:][:punct:]]*\>" /proc/cmdline | sed -e 's|\<squashboot=||')
+doing_squish=$(/bin/grep -s -o "\<squishboot=[[:alnum:][:punct:]]*\>" /proc/cmdline | sed -e 's|\<squishboot=||')
+doing_install=$(/bin/grep -s -o "\<install=[[:alnum:][:punct:]]*\>" /proc/cmdline | sed -e 's|\<install=||')
+subroot_string=$(/bin/grep -s -o "\<subroot=[[:alnum:][:punct:]]*\>" /proc/cmdline | sed -e 's|\<subroot=||')
+sq_path=$(/bin/grep -s -o "\<squashpath=[[:alnum:][:punct:]]*" /proc/cmdline | sed -e 's|\<squashpath=||')
+live_dir="live/"
+live_undir="../"
+boot_dir="boot/"
+boot_undir="../"
+system_dir="system/"
+system_undir="../"
+rootfs_path="/mnt/"
+float_path="/this/"
+system_symlinks=
+
+home_device=
+etc_device=
+share_device=
+var_device=
+tmp_device=
+package_device=
+perl_device=
+python_device=
+documentation_device=
+toolchain_device=
+
+install_files=
+
+if [[ $doing_squash == "" && $doing_squish == "" ]] ; then
+ sq_command="invalid"
+elif [[ $doing_squash != "" && $doing_squash != "device" && $doing_squash != "memory" && $doing_squash != "extract" ]] ; then
+ sq_command="invalid"
+elif [[ $doing_squish != "" && $doing_squish != "device" && $doing_squish != "memory" && $doing_squish != "extract" ]] ; then
+ sq_command="invalid"
+fi
+
+if [[ $sq_command == "invalid" ]] ; then
+ drop_to_init_bash "No valid squashboot= nor squishboot= parameter was passed, valid choices are: device, memory, or extract"
+fi
+
+if [[ $doing_install != "" ]] ; then
+ if [[ $doing_install != "kiwi" ]] ; then
+ if [[ $(echo $doing_install | grep -s '^/.*') != "" ]] ; then
+ install_files=$doing_install
+ else
+ drop_to_init_bash "Only '\\033[0;01mkiwi\\033[1;31m' or path based installation mode is supported at this time, try install=kiwi or install=/directory/to/squash/files"
+ fi
+ else
+ install_files="/boot/live"
+ fi
+fi
+
+if [[ $subroot_string != "" ]] ; then
+ subroot_string=$(echo $subroot_string | sed -e 's|^/*||' -e 's|/*$|/|')
+fi
+
+if [[ $init_string == "" ]] ; then
+ init_string="/bin/pre_init"
+fi
+
+if [[ $doing_squash != "" ]] ; then
+ doing_squish=
+ sq_command=$doing_squash
+else
+ doing_squash=
+ sq_command=$doing_squish
+fi
+
+if [[ $sq_path == "" ]] ; then
+ sq_path="boot/live/"
+else
+ sq_path=$(echo ${sq_path} | sed -e 's|/*$|/|')
+fi
+
+if [[ -d ${float_path}home ]] ; then
+ home_device=mounted
+fi
+
+if [[ -d ${float_path}etc ]] ; then
+ etc_device=mounted
+fi
+
+if [[ -d ${float_path}share ]] ; then
+ share_device=mounted
+fi
+
+if [[ -d ${float_path}var ]] ; then
+ var_device=mounted
+fi
+
+if [[ -d ${float_path}tmp ]] ; then
+ tmp_device=mounted
+fi
+
+if [[ -d ${float_path}package ]] ; then
+ package_device=mounted
+fi
+
+if [[ -d ${float_path}perl ]] ; then
+ perl_device=mounted
+fi
+
+if [[ -d ${float_path}python ]] ; then
+ python_device=mounted
+fi
+
+if [[ -d ${float_path}toolchain ]] ; then
+ toolchain_device=mounted
+fi
+
+if [[ -d ${float_path}documentation ]] ; then
+ documentation_device=mounted
+fi
+
+# prepend the subroot path
+if [[ $subroot_string != "" ]] ; then
+ sq_path=$subroot_string$sq_path
+fi
+
+# Begin loading
+echo -e -n "\\033[1;32mNow Loading the "
+if [[ $doing_squash != "" ]] ; then
+ echo -n "Squashed"
+else
+ echo -n "Squished"
+fi
+echo -e " Filesystems\\033[0m"
+
+mount_floating_root
+
+# Now mount the boot device and directories
+mount_init $float_path $rootfs_path
+
+if [[ $? -ne 0 ]] ; then
+ drop_to_init_bash "Cannot boot: Unable to mount the root device: \\033[0;01m${boot_string}\\033[1;31m"
+fi
+
+create_basic_root_directories
+
+mount -n --move $rootfs_path $float_path$boot_dir$system_dir
+
+if [[ $? -ne 0 ]] ; then
+ drop_to_init_bash "Failed to move mount from '\\033[0;01m$rootfs_path\\033[1;31m' to '\\033[0;01m$float_path$boot_dir$system_dir\\033[1;31m'"
+fi
+
+failure="no"
+cd $float_path
+
+# prepare installation files
+if [[ $install_files != "" ]] ; then
+ mkdir -p ${float_path}installation/device &&
+ chgrp e_public ${float_path}installation{,/device} &&
+ chmod o-rx ${float_path}installation{,/device}
+
+ if [[ $? -ne 0 ]] ; then
+ echo -e "\\033[0;33mWarning: Failed to create or modify the installation directory '\\033[0;01m${float_path}installation/device\\033[0;33m'\\033[0m"
+ sleep 0.5
+ fi
+
+ mount -n $boot_string ${float_path}installation/device &> /dev/null
+ if [[ $? -ne 0 ]] ; then
+ echo -e "\\033[0;33mWarning: Failed to mount drive '\\033[0;01m${boot_string}\\033[0;33m' to installation directory '\\033[0;01m${float_path}installation/device\\033[0;33m'\\033[0m"
+ sleep 0.5
+ else
+ ln -s device$install_files ${float_path}installation/live
+ fi
+fi
+
+# Extract the following files & directories (or perform mounts)
+if [[ $failure == "no" && $doing_squash != "" ]] ; then
+ if [[ $etc_device == "" ]] ; then
+ do_dynamic_files etc || failure=yes
+ fi
+
+ if [[ $failure == "no" && $home_device == "" ]] ; then
+ do_dynamic_files home || failure=yes
+ fi
+
+ if [[ $failure == "yes" ]] ; then
+ drop_to_init_bash "Failed to extract squash files"
+ fi
+fi
+
+# Copy the devices
+if [[ ! -e ${float_path}dev/console ]] ; then
+ cp -pR /dev/console ${float_path}dev/
+fi
+
+# Mount the rest of the squashed files
+if [[ $sq_command == "extract" && $failure == "no" ]] ; then
+ echo -e "\\033[0;32mExtracting System Into Memory\\033[0m"
+
+ do_unsquash sfs bin &&
+ do_unsquash sfs lib &&
+ do_unsquash sfs sbin ||
+ failure="yes"
+
+ if [[ $failure == "no" && $without_share == "" && $share_device == "" ]] ; then
+ do_unsquash sfs share || failure="yes"
+ fi
+
+ # extract firmware & modules for currently running kernel, which are not critical
+ if [[ $failure == "no" ]] ; then
+ do_unsquash sfs firmware silent_on_missing
+
+ if [[ ! -d modules ]] ; then
+ mkdir -p modules
+ fi
+
+ cd modules/
+ do_unsquash modules $current_kernel silent_on_missing
+ cd ..
+ fi
+
+ if [[ $failure == "no" && $with_toolchain != "" && $toolchain_device == "" ]] ; then
+ if [[ -f $float_path$boot_dir$system_dir${sq_path}toolchain.sfs ]] ; then
+ do_unsquash sfs toolchain || failure="yes"
+ else
+ missing_file_warning unsquash $float_path$boot_dir$system_dir${sq_path}toolchain.sfs
+ fi
+ fi
+
+ if [[ $failure == "no" && $with_documentation != "" && $documentation_device == "" ]] ; then
+ if [[ -f $float_path$boot_dir${system_dir}documentation.sfs ]] ; then
+ do_unsquash sfs documentation || failure="yes"
+ else
+ missing_file_warning unsquash $float_path$boot_dir${system_dir}documentation.sfs
+ fi
+ fi
+
+ if [[ $failure == "no" && $with_package != "" && $package_device == "" ]] ; then
+ if [[ -f $float_path$boot_dir$system_dir${sq_path}package.sfs ]] ; then
+ do_unsquash sfs package || failure="yes"
+ else
+ missing_file_warning unsquash $float_path$boot_dir$system_dir${sq_path}package.sfs
+ fi
+ fi
+
+ if [[ $failure == "no" && $with_perl != "" && $perl_device == "" ]] ; then
+ if [[ -f $float_path$boot_dir$system_dir${sq_path}perl.sfs ]] ; then
+ do_unsquash sfs perl || failure="yes"
+ else
+ missing_file_warning unsquash $float_path$boot_dir$system_dir${sq_path}perl.sfs
+ fi
+ fi
+
+ if [[ $failure == "no" && $with_python != "" && $python_device == "" ]] ; then
+ if [[ -f $float_path$boot_dir$system_dir${sq_path}python.sfs ]] ; then
+ do_unsquash sfs python || failure="yes"
+ else
+ missing_file_warning unsquash $float_path$boot_dir$system_dir${sq_path}python.sfs
+ fi
+ fi
+
+ if [[ $failure == "yes" ]] ; then
+ echo -e "\\033[1;31mERROR: Failed to Extract the Filesystem into Memory\\033[0m"
+ echo -e "\\033[1mAttempting Compressed Memory Filesystem Load.\\033[0m"
+
+ rm -Rf bin lib sbin firmware modules
+
+ if [[ $share_device == "" ]] ; then
+ rm -Rf share
+ fi
+
+ if [[ $toolchain_device == "" ]] ; then
+ rm -Rf toolchain
+ fi
+
+ if [[ $documentation_device == "" ]] ; then
+ rm -Rf documentation
+ fi
+
+ if [[ $package_device == "" ]] ; then
+ rm -Rf package
+ fi
+
+ if [[ $perl_device == "" ]] ; then
+ rm -Rf perl
+ fi
+
+ if [[ $python_device == "" ]] ; then
+ rm -Rf python
+ fi
+
+ sq_command="memory"
+ sleep 3
+ fi
+fi
+
+if [[ $sq_command == "memory" ]] ; then
+ failure="no"
+
+ echo -e "\\033[0;32mCopying Squash System Data Into Memory\\033[0m"
+ copy_squash_files
+
+ if [[ $failure == "yes" ]] ; then
+ echo -e "\\033[1;31mERROR: Failed to Load the Compressed Filesystem into Memory\\033[0m"
+ echo -e "\\033[1mAttempting Device Filesystem Load.\\033[0m"
+
+ rm -f $float_path$boot_dir${live_dir}{bin,lib,sbin,share,firmware,toolchain,documentation,package,perl,python}.sfs
+ rm -f $float_path$boot_dir$live_dir$current_kernel.modules
+
+ sq_command="device"
+
+ sleep 3
+ fi
+fi
+
+if [[ $sq_command == "device" ]] ; then
+ failure="no"
+
+ cd $float_path$boot_dir$system_dir$sq_path || failure="yes"
+
+ if [[ $failure == "no" ]] ; then
+ for i in * ; do
+ ln -sf ../$system_dir$sq_path$i $float_path$boot_dir$live_dir$i &&
+ system_symlinks="$system_symlinks$i " || failure="yes"
+ done
+
+ cd $float_path
+ fi
+fi
+
+if [[ $failure == "no" && ( $sq_command == "memory" || $sq_command == "device" ) ]] ; then
+ mkdir -p bin lib sbin &&
+ mount -o loop $float_path$boot_dir${live_dir}bin.sfs bin &&
+ mount -o loop $float_path$boot_dir${live_dir}lib.sfs lib &&
+ mount -o loop $float_path$boot_dir${live_dir}sbin.sfs sbin ||
+ failure="yes"
+
+ if [[ $failure == "no" && $without_share == "" && $share_device == "" ]] ; then
+ mkdir -p share &&
+ mount -o loop $float_path$boot_dir${live_dir}share.sfs share || failure="yes"
+ fi
+
+ if [[ $failure == "no" && -f $float_path$boot_dir${live_dir}firmware.sfs ]] ; then
+ mkdir -p firmware &&
+ mount -o loop $float_path$boot_dir${live_dir}firmware.sfs firmware || failure="yes"
+ fi
+
+ if [[ $failure == "no" && -f $float_path$boot_dir$live_dir$current_kernel.modules ]] ; then
+ mkdir -p modules/$current_kernel &&
+ mount -o loop $float_path$boot_dir$live_dir$current_kernel.modules modules/$current_kernel || failure="yes"
+ fi
+
+ if [[ $failure == "no" && $with_toolchain != "" && $toolchain_device == "" ]] ; then
+ if [[ -f $float_path$boot_dir${live_dir}toolchain.sfs ]] ; then
+ mkdir -p toolchain &&
+ mount -o loop $float_path$boot_dir${live_dir}toolchain.sfs toolchain || failure="yes"
+ else
+ missing_file_warning mount $float_path$boot_dir${live_dir}toolchain.sfs
+ fi
+ fi
+
+ if [[ $failure == "no" && $with_documentation != "" && $documentation_device == "" ]] ; then
+ if [[ -f $float_path$boot_dir${live_dir}documentation.sfs ]] ; then
+ mkdir -p documentation &&
+ mount -o loop $float_path$boot_dir${live_dir}documentation.sfs documentation || failure="yes"
+ else
+ missing_file_warning mount $float_path$boot_dir${live_dir}documentation.sfs
+ fi
+ fi
+
+ if [[ $failure == "no" && $with_package != "" && $package_device == "" ]] ; then
+ if [[ -f $float_path$boot_dir${live_dir}package.sfs ]] ; then
+ mkdir -p package &&
+ mount -o loop $float_path$boot_dir${live_dir}package.sfs package || failure="yes"
+ else
+ missing_file_warning mount $float_path$boot_dir${live_dir}package.sfs
+ fi
+ fi
+
+ if [[ $failure == "no" && $with_perl != "" && $perl_device == "" ]] ; then
+ if [[ -f $float_path$boot_dir${live_dir}perl.sfs ]] ; then
+ mkdir -p perl &&
+ mount -o loop $float_path$boot_dir${live_dir}perl.sfs perl || failure="yes"
+ else
+ missing_file_warning mount $float_path$boot_dir${live_dir}perl.sfs
+ fi
+ fi
+
+ if [[ $failure == "no" && $with_python != "" && $python_device == "" ]] ; then
+ if [[ -f $float_path$boot_dir${live_dir}python.sfs ]] ; then
+ mkdir -p documentation &&
+ mount -o loop $float_path$boot_dir${live_dir}python.sfs python || failure="yes"
+ else
+ missing_file_warning mount $float_path$boot_dir${live_dir}python.sfs
+ fi
+ fi
+
+ if [[ $failure == "yes" ]] ; then
+ echo -e "\\033[1;31mERROR: Failed to mount the squashed filesystems\\033[0m"
+
+ for i in bin lib sbin share firmware toolchain documentation package perl python; do
+ if [[ $(mount -l | grep -s -o "^.* on $float_path$boot_dir$live_dir$i ") ]] ; then
+ umount -l $i
+ fi
+ done
+
+ if [[ $(mount -l | grep -s -o "^.* on $float_path$boot_dir${live_dir}modules/$current_kernel ") ]] ; then
+ umount -l modules/$current_kernel
+ fi
+
+ sleep 3
+ fi
+fi
+
+if [[ $failure == "no" && $doing_squish != "" ]] ; then
+ cd $float_path$boot_dir$system_dir$subroot_string || failure="yes"
+
+ if [[ $failure == "no" ]] ; then
+ for i in * ; do
+ if [[ ! -e $float_path$i ]] ; then
+ ln -sf $boot_dir$system_dir$subroot_string$i $float_path$i &&
+ system_symlinks="$system_symlinks$i " || failure="yes"
+ fi
+ done
+
+ cd $float_path
+ else
+ echo -e "\\033[1;31mERROR: Failed to change to the path '\\033[0;01m$float_path$boot_dir$system_dir$subroot_string\\033[1;31m'\\033[0m"
+ fi
+fi
+
+if [[ $failure == "no" ]] ; then
+ create_additional_root_directories
+
+ if [[ $squash_boot != "" ]] ; then
+ umount -l $float_path$boot_dir$system_dir
+ fi
+fi
+
+corrupt_failure_check $failure
+
+if [[ $system_symlinks == "" ]] ; then
+ umount -l $float_path$boot_dir$system_dir
+fi
+
+# make sure /proc is not mounted prior to chroot & pivot_root
+umount -n /proc
+
+# Now attempt to switch to the new system
+echo -e -n "\\033[1;32mNow Switching to the "
+if [[ $doing_squash != "" ]] ; then
+ echo -n "Squash"
+else
+ echo -n "Squish"
+fi
+echo -e " System\\033[0m"
+
+cd $float_path
+
+pivot_root . tmp/ || drop_to_init_bash "Failed to pivot root to the live system"
+cd /
+umount -l -n /tmp
+
+if [[ ! -e dev/console ]] ; then
+ echo -e "\\033[1;31mERROR: Failed to find console device at dev/console\\033[0m"
+ echo -e "\\033[1mDropping to system shell.\\033[0m"
+ exec /bin/bash
+fi
+
+if [[ ! -e $init_string ]] ; then
+ drop_to_init_bash "Could not find init binary: \\033[0;01m${init_string}\\033[1;31m"
+fi
+
+if [[ ! -e bin/bash ]] ; then
+ drop_to_init_bash "Could not find bash binary: \\033[0;01mbin/bash\\033[1;31m"
+fi
+
+exec chroot . /bin/bash -c "exec $init_string" < dev/console > dev/console 2>&1
--- /dev/null
+#!/bin/bash
+
+find_drive(){
+ local count=
+ local max=4
+ local custom=
+ local target=$drive
+
+ if [[ $target == "" ]] ; then
+ return 1
+ fi
+
+ if [[ $(echo $target | grep -o "^[[:alnum:]_-]*=") == "" ]] ; then
+ return 0
+ fi
+
+ drive=
+ let count=0
+ while [[ $count -lt $max ]] ; do
+ custom=$(blkid -o device -l -t $target)
+
+ if [[ $custom != "" ]] ; then
+ drive=$custom
+ break
+ fi
+
+ let count=$count+1
+ echo -e "\\033[0;33mWarning: Failed to find device by the id or name of: '\\033[0;01m${target}\\033[0;33m', trying again in 2 seconds.\\033[0m"
+ sleep 2
+ done
+
+ if [[ $drive == "" ]] ; then
+ return 1
+ fi
+}
+
+mount_drive(){
+ local directory=$1
+ local destination=$2
+ local drive=$3
+ local the_status=
+ local custom=
+
+ if [[ $drive == "" && -f $path${directory}.device ]] ; then
+ drive=$(cat ${path}${directory}.device)
+ fi
+
+ find_drive
+
+ if [[ $drive == "" ]] ; then
+ if [[ $directory == "rootfs" ]] ; then
+ echo -e "\\033[1;31mError: The rootfs device was either not given or it was not found.\\033[0m"
+ sleep 2
+ return 1
+ fi
+
+ return 2
+ fi
+
+ if [[ $directory != "rootfs" ]] ; then
+ mkdir -p $destination
+ fi
+
+ mount $drive $destination
+ the_status=$?
+
+ if [[ $the_status != 0 ]] ; then
+ sleep 2
+ mount $drive $destination
+ the_status=$?
+ fi
+
+ if [[ $the_status != 0 ]] ; then
+ if [[ $directory == "rootfs" ]] ; then
+ echo -e "\\033[1;31mError: Failed to mount the '\\033[0;01mrootfs\\033[1;31m' device.\\033[0m"
+ sleep 2
+ return 1
+ else
+ echo -e "\\033[0;33mWarning: Failed to mount '\\033[0;01m${directory}\\033[0;33m' device.\\033[0m"
+ sleep 2
+ return 2
+ fi
+ fi
+
+ return 0
+}
+
+perform_mounts(){
+ local path=${device_directory}boot/settings/
+ local status=
+ local drive=
+ local i=
+
+ if [[ ! -d $path ]] ; then
+ path=${device_directory}settings/
+
+ if [[ ! -d $path ]] ; then
+ path=${device_directory}/.settings/
+
+ if [[ ! -d $path ]] ; then
+ path=${device_directory}
+ fi
+ fi
+ fi
+
+ if [[ $settings_name != "" ]] ; then
+ path=$path${settings_name}/
+ fi
+
+ if [[ $rootfs_device != "" && ! -f ${path}settings.lock ]] ; then
+ mount_drive rootfs $rootfs_path $rootfs_device
+ status=$?
+ elif [[ -f ${path}rootfs.device ]] ; then
+ mount_drive rootfs $rootfs_path
+ status=$?
+ else
+ echo -e "\\033[1;31mError: Neither root= was passed nor was there a rootfs.device found in the settings directory.\\033[0m"
+ return 1
+ fi
+
+ if [[ $status -eq 0 ]] ; then
+ mounted_rootfs="y"
+ else
+ return 1
+ fi
+
+ for i in home etc share var tmp package perl python documentation toolchain ; do
+ drive=$(/bin/grep -s -o "\<${i}device=[[:alnum:][:punct:]]*\>" /proc/cmdline | sed -e "s|\<${i}device=||")
+
+ if [[ $drive != "" && ! -f ${path}settings.lock ]] ; then
+ mkdir -p $float_path$i &&
+ mount_drive $i $float_path$i $drive
+ status=$?
+ elif [[ -f $path$i.device ]] ; then
+ mkdir -p $float_path$i &&
+ mount_drive $i $float_path$i
+ status=$?
+ fi
+ done
+}
+
+process_parameters(){
+ local float_path=$1
+ local rootfs_path=$2
+ local rootfs_device=$(/bin/grep -s -o "\<root=[[:alnum:][:punct:]]*\>" /proc/cmdline | sed -e 's|\<root=||')
+ local settings_name=$(/bin/grep -s -o "\<settingsname=[[:alnum:][:punct:]]*" /proc/cmdline | sed -e 's|\<settingsname=||')
+ local device_directory=/settings/
+ local mounted_rootfs=
+
+ if [[ $float_path != "" && $rootfs_path != "" ]] ; then
+ perform_mounts
+ fi
+
+ umount -n $device_directory &> /dev/null
+
+ if [[ $float_path == "" || $mounted_rootfs == "" ]] ; then
+ return 1;
+ fi
+}
+
+
+process_parameters $1 $2
--- /dev/null
+// Programmer: Kevin Day
+// License: lgpl-2.1-or-later
+// NOTE: This is just a very quick implementation to get things off the ground. I inted to rewrite this accordingly and move it into the FLL project.
+// What this does is mount the /dev/ directory and then creates the appropriate /dev/console and /dev/null devices and finally calls the init program
+// To allow for a quick implementation, the settings are hardcoded
+// Accepts 1 parameter and it is the init parameter
+
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <regex.h>
+#include <string.h>
+#include <malloc.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef ARCHITECTURE_BITS
+ #define arch_bits ARCHITECTURE_BITS
+#else
+ #define arch_bits "x64"
+#endif // ARCHITECTURE_BITS
+
+#ifdef ARCHITECTURE_BITS_PATH
+ #define arch_bits_path "" ARCHITECTURE_BITS_PATH "/"
+#else
+ #define arch_bits_path "" arch_bits "/"
+#endif // ARCHITECTURE_BITS_PATH
+
+#define the_init "\\<init=[[:alnum:][:punct:]]*"
+#define the_tmp "\\<tmpdevice=[[:alnum:][:punct:]]*"
+#define the_tmp_label "\\<tmpdevice=LABEL=[[:alnum:][:punct:]]*"
+#define the_tmp_uuid "\\<tmpdevice=UUID=[[:alnum:][:punct:]]*"
+#define the_mounts_begin "^"
+#define the_mounts_end "[[:space:]]"
+#define ignore_length_init 5
+#define ignore_length_tmp 10
+#define ignore_length_tmp_label 16
+#define ignore_length_tmp_uuid 15
+#define error_color "\033[1;31m"
+#define warning_color "\033[0;33m"
+#define notice_color "\033[0;1m"
+#define highlight_color "\033[1;32m"
+#define reset_color "\033[0;0m"
+
+#define dev_path "/dev"
+#define proc_path "/proc"
+#define procbususb_path "/proc/bus/usb"
+#define sys_path "/sys"
+#define tmp_path "/tmp"
+#define var_log_path "/var/log"
+#define var_run_path "/var/run"
+#define mnt_path "/mnt"
+#define umount_program "/bin/" arch_bits_path "umount"
+#define mount_program "/bin/" arch_bits_path "mount"
+#define init_program "/bin/" arch_bits_path "init"
+#define mkdir_program "/bin/" arch_bits_path "mkdir"
+#define chmod_program "/bin/" arch_bits_path "chmod"
+#define chgrp_program "/bin/" arch_bits_path "chgrp"
+#define mknod_program "/bin/" arch_bits_path "mknod"
+#define ln_program "/bin/" arch_bits_path "ln"
+#define console_path dev_path "/console"
+#define zero_path dev_path "/zero"
+#define null_path dev_path "/null"
+#define random_path dev_path "/random"
+#define urandom_path dev_path "/urandom"
+#define command_line_path "/proc/cmdline"
+#define proc_mounts_path "/proc/mounts"
+#define init_path_max 4097
+
+// A generic class for testing whether or not specific devies were mounted with boot-time settings
+// Currently only tmpdevice= is supported at this time
+int detect_mounted_path(char *command_line, int match_start, int match_end, int string_length){
+ if (!command_line) return 0;
+
+ int relevant_length = match_end - match_start - string_length;
+ size_t length = 0;
+ char *string = NULL;
+ char *line = NULL;
+ FILE *proc_mounts=0;
+ regex_t expression;
+ regmatch_t match;
+ int reg_result=0;
+ int results=0;
+ int mounts_begin_length = strlen(the_mounts_begin);
+ int mounts_end_length = strlen(the_mounts_end);
+
+ string = calloc(relevant_length + mounts_begin_length + mounts_end_length + 1, sizeof(char));
+
+ if (!string) return results;
+
+ memset(string, 0, sizeof(char) * relevant_length + mounts_begin_length + mounts_end_length + 1);
+
+ strncpy(string, the_mounts_begin, mounts_begin_length);
+ strncpy(string + mounts_begin_length, command_line + match_start + string_length, relevant_length);
+ strncpy(string + mounts_begin_length + relevant_length, the_mounts_end, mounts_end_length);
+
+ // now handle searching for the device
+ proc_mounts = fopen(proc_mounts_path, "ro");
+
+ if (proc_mounts){
+ while (getline(&line, &length, proc_mounts) != -1){
+ if (length == 0) continue;
+
+ // ------------------------------------------------------------
+ regcomp(&expression, string, 0);
+ reg_result=regexec(&expression, line, 1, &match, 0);
+
+ if (reg_result == REG_OK){
+ results = 1;
+ regfree(&expression);
+ break;
+ }
+
+ regfree(&expression);
+ // ------------------------------------------------------------
+ }
+
+ if (line) free(line);
+ fclose(proc_mounts);
+ }
+
+ free(string);
+ return results;
+}
+
+int main(int argc, char *argv[]){
+ size_t length=0;
+ FILE *proc_cmdline=0;
+ char *cmdline=0;
+ char *tmp_name=0;
+ regex_t expression;
+ regmatch_t match;
+ int reg_result=0;
+ int string_length=0;
+ int custom_tmp=0;
+ char init_string[init_path_max]; // Use a static buffer so that when we exec, there is no memory needing to be free'd; 4096+1, the +1 is for the NULL
+
+ mount("proc", proc_path, "proc", 0, "");
+ proc_cmdline = fopen(command_line_path, "ro");
+ getline(&cmdline, &length, proc_cmdline);
+
+ if (proc_cmdline) fclose(proc_cmdline);
+
+ // ------------------------------------------------------------
+ // Look for the option that specifies the init path
+ regcomp(&expression, the_init, 0);
+ reg_result=regexec(&expression, cmdline, 1, &match, 0);
+
+ if (reg_result == REG_OK){
+ string_length = match.rm_eo - match.rm_so - ignore_length_init;
+ strncpy(init_string, cmdline + match.rm_so + ignore_length_init, string_length);
+ } else {
+ strncpy(init_string, init_program, init_path_max);
+ }
+
+ regfree(&expression);
+ // ------------------------------------------------------------
+ // See if a custom tmp path was used, and then check to see if it was successfully mounted
+ regcomp(&expression, the_tmp_label, 0);
+ reg_result=regexec(&expression, cmdline, 1, &match, 0);
+
+ if (reg_result == REG_OK){
+ custom_tmp = detect_mounted_path(cmdline, match.rm_so, match.rm_eo, ignore_length_tmp_label);
+ } else {
+ regfree(&expression);
+ regcomp(&expression, the_tmp_uuid, 0);
+ reg_result=regexec(&expression, cmdline, 1, &match, 0);
+
+ if (reg_result == REG_OK){
+ custom_tmp = detect_mounted_path(cmdline, match.rm_so, match.rm_eo, ignore_length_tmp_uuid);
+ } else {
+ regfree(&expression);
+ regcomp(&expression, the_tmp, 0);
+ reg_result=regexec(&expression, cmdline, 1, &match, 0);
+
+ if (reg_result == REG_OK){
+ custom_tmp = detect_mounted_path(cmdline, match.rm_so, match.rm_eo, ignore_length_tmp);
+ } else {
+ custom_tmp = 0;
+ }
+ }
+ }
+
+ regfree(&expression);
+ // ------------------------------------------------------------
+
+ if (cmdline) free(cmdline);
+
+ // lets cheat, now that we are actually on the destination system, just use system calls and hope they appropriate programs exist
+ // Mount the necessary paths
+ system(mount_program " " dev_path);
+ system(mount_program " " sys_path);
+ system(mount_program " " procbususb_path);
+ system(mkdir_program " -p " dev_path "/pts");
+ system(mount_program " -t " dev_path "/pts");
+ system(mount_program " " var_log_path);
+ system(mount_program " " var_run_path);
+ system(mount_program " " mnt_path);
+
+ // only mount this if it is not already mounted through the custom temp process
+ if (!custom_tmp){
+ system(mount_program " " tmp_path);
+ }
+
+ // create the required devices
+ system(mknod_program " -m 0660 " null_path " c 1 3");
+ system(mknod_program " -m 0660 " zero_path " c 1 5");
+ system(mknod_program " -m 0660 " console_path " c 5 1");
+ system(mknod_program " -m 0440 " random_path " c 1 8");
+ system(mknod_program " -m 0440 " urandom_path " c 1 9");
+ system(chgrp_program " p_null " null_path);
+ system(chgrp_program " p_zero " zero_path);
+ system(chgrp_program " p_terminal " console_path);
+ system(chgrp_program " p_random " random_path);
+ system(chgrp_program " p_random " urandom_path);
+
+ // enjoy!
+ execl(init_string, "", "", (char *) 0);
+
+ return 0;
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
--- /dev/null
+#!/bin/bash
+
+find_drive(){
+ local count=
+ local max=4
+ local custom=
+ local target=$drive
+
+ if [[ $target == "" ]] ; then
+ return 1
+ fi
+
+ if [[ $(echo $target | grep -o "^[[:alnum:]_-]*=") == "" ]] ; then
+ return 0
+ fi
+
+ drive=
+ let count=0
+ while [[ $count -lt $max ]] ; do
+ custom=$(blkid -o device -l -t $target)
+
+ if [[ $custom != "" ]] ; then
+ drive=$custom
+ break
+ fi
+
+ let count=$count+1
+ echo -e "\\033[0;33mWarning: Failed to find device by the id or name of: '\\033[0;01m${target}\\033[0;33m', trying again in 2 seconds.\\033[0m"
+ sleep 2
+ done
+
+ if [[ $drive == "" ]] ; then
+ return 1
+ fi
+}
+
+decrypt_drive(){
+ local directory=$1
+ local the_status=
+ local drive=
+ local custom=
+
+ drive=$(cat $path$directory.encrypted)
+
+ if [[ $(echo $drive | sed -e 's|[[:space:]]||g') == "" ]] ; then
+ return 1
+ fi
+
+ find_drive
+
+ if [[ $drive == "" ]] ; then
+ return 1
+ fi
+
+ if [[ -f $path$directory.key ]] ; then
+ cryptsetup luksOpen $drive $directory -d $path$directory.key
+ the_status=$?
+ fi
+
+ if [[ -f $path$directory.ask ]] ; then
+ if [[ $the_status != 0 ]] ; then
+ cryptsetup luksOpen $drive $directory
+ the_status=$?
+ fi
+ fi
+
+ if [[ $the_status != "" && $the_status != "0" ]] ; then
+ echo -e "\\033[0;33mWarning: Failed to decrypt '\\033[0;01m$directory\\033[0;33m' device.\\033[0m"
+ sleep 2
+ fi
+}
+
+assemble_array(){
+ local array=$1
+ local drives=
+ local drive=
+ local custom=
+ local i=
+
+ for i in $(cat $path$array.raid) ; do
+ drive=$i
+ find_drive
+
+ if [[ $drive != "" ]] ; then
+ drives="$drives$drive "
+ fi
+ done
+
+ if [[ $drives != "" ]] ; then
+ mdadm -A /dev/$array $drives
+ fi
+
+ if [[ $drives == "" || $? -ne 0 ]] ; then
+ echo -e "\\033[0;33mWarning: Failed to assemble raid array: '\\033[0;01mdadm -A /dev/$array $drives\\033[0;33m'.\\033[0m"
+ sleep 2
+ fi
+}
+
+process_settings_data(){
+ local path=${device_directory}boot/settings/
+ local raid_name=
+ local i=
+
+ if [[ ! -d $path ]] ; then
+ path=${device_directory}settings/
+
+ if [[ ! -d $path ]] ; then
+ path=${device_directory}.settings/
+
+ if [[ ! -d $path ]] ; then
+ path=${device_directory}
+
+ if [[ ! -d $path ]] ; then
+ echo -e "\\033[0;31mError: Unable to find settings directory at ${device_directory}boot/settings/, ${device_directory}settings/, ${device_directory}.settings/, or ${device_directory}\\033[0m"
+ sleep 2
+ return 1
+ fi
+ fi
+ fi
+ fi
+
+ if [[ $settings_name != "" ]] ; then
+ path=${path}${settings_name}
+ fi
+
+ if [[ -d $path ]] ; then
+ for i in ${path}*.raid ; do
+ if [[ -f $i ]] ; then
+ raid_name=$(echo $i | sed -e "s|^$path||g" -e 's|.raid$||')
+
+ echo -e "\\033[0;01mAttempting to Assemble Raid Array \\033[1;33m$raid_name\\033[0;01m\\033[0m"
+ assemble_array $raid_name
+ fi
+ done
+
+ for i in rootfs home etc share var tmp package perl python documentation toolchain; do
+ if [[ -f $path$i.encrypted ]] ; then
+ echo -e "\\033[0;01mAttempting to Decrypt \\033[1;33m$i\\033[0;01m Device\\033[0m"
+ decrypt_drive $i
+ fi
+ done
+
+ # TODO: add udev rule loading support
+ #if [[ -d ${path}udev.rules ]] ; then
+ # cp -R ${path}udev.rules/* /etc/udev/rules.d/
+ #fi
+ fi
+}
+
+process_parameters(){
+ local settings_string=$(/bin/grep -s -o "\<settings=[[:alnum:][:punct:]]*" /proc/cmdline | sed -e 's|\<settings=||')
+ local settings_name=$(/bin/grep -s -o "\<settingsname=[[:alnum:][:punct:]]*" /proc/cmdline | sed -e 's|\<settingsname=||')
+ local settings_drive=
+ local device_directory=/settings/
+ local grab_next=
+ local found_device=
+ local current_count=
+ local drive=
+
+ if [[ $settings_string == "" ]] ; then
+ return 1
+ fi
+
+ if [[ $settings_name != "" ]] ; then
+ settings_name=$(echo ${settings_name} | sed -e 's|/*$|/|')
+ fi
+
+ # Find the device
+ if [[ $settings_string != "" ]] ; then
+ drive=$settings_string
+ find_drive
+
+ if [[ $drive != "" ]] ; then
+ settings_drive=$drive
+ fi
+ fi
+
+ if [[ $settings_drive == "" ]] ; then
+ return 1
+ fi
+
+ let current_count=0
+
+ while [[ $current_count -lt 3 ]] ; do
+ mount -n $settings_drive $device_directory &> /dev/null
+
+ if [[ $? != 0 ]] ; then
+ echo -e "\\033[0;33mWarning: Unable to mount settings drive: '\\033[0;01m$settings_drive\\033[0;33m', trying again in 2 seconds.\\033[0m"
+ let current_count=${current_count}+1
+ sleep 2
+ else
+ current_count="success"
+ process_settings_data
+ return 0
+ fi
+ done
+}
+
+
+process_parameters