From d2cba7e833acbf93d7b62752036ed561a88f77bf Mon Sep 17 00:00:00 2001 From: Zach van Rijn Date: Sun, 23 Feb 2025 03:29:54 -0600 Subject: binsub.c: attempt to handle read-only files. Some files may be r--r--r-- (0444), which would have failed in the previous version. Also fixed a subtle bug where the 'fopen' was being called with "rb+" instead of "rb" which caused a premature failure. bootstrap: ensure string offsets remain consistent. This has been thoroughly analyzed and tested in the discussion in #26, but a mechanistic understanding of the root cause has not yet been realized. That would still be worth doing. Fixes: #26. --- binsub.c | 50 ++++++++++++++++++++++++++++++++++++++++++-------- bootstrap | 17 ++++++----------- 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/binsub.c b/binsub.c index c66148c..892646e 100644 --- a/binsub.c +++ b/binsub.c @@ -1,7 +1,7 @@ /** - * binsub.c / 2022-12-09 + * binsub.c / 2025-02-23 * - * (C) 2022 Zach van Rijn + * (C) 2022-2025 Zach van Rijn * * MIT License * @@ -18,6 +18,8 @@ #include #include #include +#include +#include /** * Basic memory structure. @@ -145,17 +147,40 @@ scanner (const char *file, const char *find, const char *repl) FILE *fp = NULL; size_t nb = 0; + struct stat st; + mode_t pold, pnew; + struct buffer buf; memset(&buf, 0, sizeof(struct buffer)); - fp = fopen(file, "rb+"); + if (stat(file, &st) == -1) + { + fprintf(stderr, + "E: Could not stat FILE '%s' at all!\n", + file + ); + return; + } + + pold = st.st_mode; /* don't want to modify this */ + pnew = pold | S_IWUSR; /* could be read-only file */ + + if (chmod(file, pnew) == -1) + { + fprintf(stderr, + "E: Could not chmod FILE '%s' for writing!\n", + file + ); + } + + fp = fopen(file, "rb"); if (!fp) { fprintf(stderr, "E: Could not open FILE '%s' for reading!\n", file ); - return; + goto restore; } fseek(fp, 0, SEEK_END); @@ -175,7 +200,7 @@ scanner (const char *file, const char *find, const char *repl) buf.len, file ); - return; + goto restore; } buf.data[buf.len] = 0; /* extra byte needs to be nil */ @@ -191,7 +216,7 @@ scanner (const char *file, const char *find, const char *repl) buf.len, file ); - return; + goto restore; } fclose(fp); @@ -205,7 +230,7 @@ scanner (const char *file, const char *find, const char *repl) "E: Could not open FILE '%s' for writing!\n", file ); - return; + goto restore; } nb = fwrite(buf.data, 1, buf.len, fp); @@ -220,11 +245,20 @@ scanner (const char *file, const char *find, const char *repl) buf.len, file ); - return; + goto restore; } fclose(fp); free(buf.data); + +restore: + if (chmod(file, pold) == -1) + { + fprintf(stderr, + "E: Could not restore FILE '%s' permissions!\n", + file + ); + } } diff --git a/bootstrap b/bootstrap index 0171ad9..d2344f2 100755 --- a/bootstrap +++ b/bootstrap @@ -5,7 +5,7 @@ # Purpose : Bootstraps Adélie from source for any architecture. # Authors : Zach van Rijn # License : MIT -# Revision : 20250222 +# Revision : 20250223 #=============================================================== #=============================================================== @@ -783,19 +783,14 @@ if ! test -f rootfs-${TARGET}-patched.tgz; then ; ## - # Replace needle with the empty string. + # Maintain needle length but canonically replace with '/'. + # Length requirement only seems to affect 'perl'; truncating + # appears to be sufficient for all other binaries and files. + # Please refer to #26 for more information. # x="${BASE}"/mcmtools-${TARGET}/sys; grep -rl "${x}" ${t} | while read k; do - # exceptions - - case "${k}" in - "${t}"/bin/perl) continue; ;; # @INC fuckery - esac - - # delete needle - ./binsub ${k} "${x}"; # alternatively use "/" - + ./binsub ${k} "${x}" $(printf "%${#x}s" | tr ' ' '/'); done ## -- cgit v1.2.3-70-g09d2