#!/bin/bash # Freetz script to modify AVM FRITZ!Box and OEM firmware images # # Copyright (C) 2005-2006 Daniel Eiband # Copyright (C) 2006-2012 by the Freetz developers (http://freetz.org) # # Licensed under the GPL v2, see the file COPYING in this tarball. # # This script is based on Christian Volkmann's fritzbox mod-0.57. # Legacy URL: http://www.ip-phone-forum.de/showthread.php?t=65894 # # Special thanks to Andreas Buehmann, Christian Volkmann, Enrik Berkhan, # SpeedyBZ and all members on ip-phone-forum.de who contributed to this mod. usage() { cat << EOF Usage: $SELF [-u|-m|-p|-a] [-z] [-c ] [-n] [-f] [-i ] [-d ] [ []] main actions -u unpack firmware image -m modify previously unpacked image -p pack firmware image -a all: unpack, modify and pack firmware image special actions -s sign firmware image -z zip file system into archive for USB/NFS root -c copy file system to target directory for NFS/USB root (implies -z) options -n firmware-nocompile: do not install kernel and busybox -f force pack even if image is too big for flash (AVM SDK) input/output -i input file for configuration data (default: .config) -d build directory (default: .mod) original firmware name 2nd firmware name (e.g. for merging in web UI) 3rd firmware name (e.g. to borrow missing files) EOF } ################################################## ## Initialise and check command line parameters ## ################################################## # This script's name ("fwmod" if not linked/renamed) SELF="$(basename "$0")" # No parameters -> print usage info to stdout [ $# -eq 0 ] && usage && exit 0 # Backup command line parameters [$0..$n] to save them from getopts eating them # away, because we need them again later for the recursive fakerooted call. for ((i=0; i<=$#; i++)); do CMDLINE_ORIG[i]="${!i}" done # Default values for unset command line parameters DOT_CONFIG="$(dirname "$0")/.config" DO_UNPACK=0; DO_MOD=0; DO_PACK=0; DO_SIGN=0 FIRMWARE_NOCOMPILE=0; FORCE_PACK=0; DO_ZIP=0; COPY_FS_DIR=; DIR= # Parse command line parameters while getopts umpsanfzc:i:d: opt; do case "$opt" in u) DO_UNPACK=1 ;; m) DO_MOD=1 ;; p) DO_PACK=1 ;; s) DO_SIGN=1 ;; a) DO_UNPACK=1; DO_MOD=1; DO_PACK=1 ;; n) FIRMWARE_NOCOMPILE=1 ;; f) FORCE_PACK=1 ;; z) DO_ZIP=1 ;; c) COPY_FS_DIR="$OPTARG"; [ "$COPY_FS_DIR" ] && DO_ZIP=1 ;; i) DOT_CONFIG="$OPTARG" ;; d) DIR="$OPTARG" ;; *) usage >&2; exit 1 ;; esac done shift $((OPTIND-1)) # At least one action and one (non-empty) firmware image name must be specified [ $(($DO_UNPACK + $DO_MOD + $DO_PACK + $DO_ZIP)) -eq 0 -o $# -lt 1 -o $# -gt 3 -o ! "$1" ] && usage >&2 && exit 1 # Check if it's a completely automated run in the "no freetz"-mode and cache the value. # We are interested in what the user asked us for and not what we are actually doing, # the UNPACK step might be skipped (and the value of DO_UNPACK changed) if the already # unpacked firmware is found on the disk. [ "$DO_UNPACK" -gt 0 -a "$DO_MOD" -eq 0 -a "$DO_PACK" -gt 0 ] && NO_FREETZ_AUTOMATED_RUN=1 || NO_FREETZ_AUTOMATED_RUN=0 # Freetz base + tools directories BASE_DIR="$(dirname "$0")" ABS_BASE_DIR="$(readlink -f "$BASE_DIR")" TOOLS_DIR="${ABS_BASE_DIR}/tools" # Include common helper functions (isFreetzType, echo*, error, modunsqfs* etc.) source "${TOOLS_DIR}/freetz_functions" || (echo "cannot find script freetz_functions" >&2; exit 1) if [ "$DO_SIGN" -gt 0 -a $(($DO_PACK + $DO_ZIP)) -eq 0 ]; then error 1 "Firmware signing without packing is not supported, please use PeterPawn's sign_image tool directly if you plan to sign some already existing .image file" fi # Initialise firmware image names FIRMWARE="$1" FIRMWARE2="$2" FIRMWARE3="$3" FIRMWARE_EXTENSION="${FIRMWARE##*.}" FIRMWARE_EXTENSION="${FIRMWARE_EXTENSION,,}" # Given firmware image(s) must exist [ -r "$FIRMWARE" ] || error 1 "firmware image $(basename "$FIRMWARE") not found" [ "$FIRMWARE2" -a ! -r "$FIRMWARE2" ] && error 1 "firmware image $(basename "$FIRMWARE2") not found" [ "$FIRMWARE3" -a ! -r "$FIRMWARE3" ] && error 1 "firmware image $(basename "$FIRMWARE3") not found" # Config file must exist [ -r "$DOT_CONFIG" ] || error 1 "not configured" # Set default output directory, if not specified on command line : ${DIR:=$FIRMWARE.mod} # Create output directory if necessary mkdir -p "$DIR" ################################# ## Initialise script variables ## ################################# # Relative subdirectories SOURCE_SUBDIR="source" FIRMWARE_SUBDIR="firmware" FILESYSTEM_SUBDIR="filesystem" FILESYSTEM_OUTER_SUBDIR="filesystem.outer" AVMPLUGINS_SUBDIR="plugins.image" EXTERNAL_SUBDIR="external" KERNEL_SUBDIR="kernel" VARTAR_SUBDIR="var.tar" HTML_SUBDIR="usr/www" GRAPHICS_SUBDIR="graphics" # (temporary) files created during firmware unpacking RAW_KERNEL_FILE="kernel.raw" RAW_HIDDEN_FILE="kernelsquashfs.raw" VARTAR_FILE="var.tar" UNPACKED_FILE="$DIR/.unpacked" # Path to bash (shell required by fwmod) SHELL=$BASH # Tools used by fwmod FINDSQUASHFS_TOOL="find-squashfs" TICHKSUM_TOOL="tichksum" MAKEDEVS_TOOL="makedevs" DEBUGFS_TOOL="debugfs" EXTERNAL_TOOL="external" TAR_TOOL="tar" MD5SUM_TOOL="md5sum" BUSYBOX_TOOL="busybox" # Absolute tools paths EXTERNAL="${TOOLS_DIR}/${EXTERNAL_TOOL}" DEBUGFS="${TOOLS_DIR}/${DEBUGFS_TOOL}" FINDSQUASHFS="${TOOLS_DIR}/${FINDSQUASHFS_TOOL}" TICHKSUM="${TOOLS_DIR}/${TICHKSUM_TOOL}" MAKEDEVS="${TOOLS_DIR}/${MAKEDEVS_TOOL}" MAKEDEVS_FILE="${TOOLS_DIR}/device_table.txt" TAR="${TOOLS_DIR}/${TAR_TOOL}" TAR_GNU="${TOOLS_DIR}/tar-gnu" MD5SUM="${TOOLS_DIR}/${MD5SUM_TOOL}" BUSYBOX="${TOOLS_DIR}/${BUSYBOX_TOOL}" BLKID="${TOOLS_DIR}/blkid" # Freetz directores relative to base dir PACKAGES_DIR_ROOT="${BASE_DIR}/packages" PATCHES_DIR="${BASE_DIR}/patches" PATCHES_COND_DIR="${PATCHES_DIR}/cond" PATCHES_DEVICES_DIR="${PATCHES_DIR}/devices" PATCHES_SCRIPTS_DIR="${PATCHES_DIR}/scripts" ROOT_DIR="${BASE_DIR}/root" KERNEL_REP_DIR="${BASE_DIR}/kernel" ADDON_DIR="${BASE_DIR}/addon" GRAPHICS_DIR="${BASE_DIR}/${GRAPHICS_SUBDIR}" # Freetz branding directories relative to graphics subdirectory FAVICON_DIR="${GRAPHICS_DIR}/favicon" TAGGING_DIR="${GRAPHICS_DIR}/tagging" # Package files STATIC_PACKAGES_FILE="${BASE_DIR}/.static" STATIC_ADDON_FILE="${ADDON_DIR}/static.pkg" # Alien variables TK_DIR="${DIR}/.tk/original" FIRMWARE_TK_DIR="${TK_DIR}/${FIRMWARE_SUBDIR}" FILESYSTEM_TK_DIR="${TK_DIR}/${FILESYSTEM_SUBDIR}" KERNEL_TK_DIR="${TK_DIR}/${KERNEL_SUBDIR}" VARTAR_TK_DIR="${KERNEL_TK_DIR}/${VARTAR_SUBDIR}" AUX_DIR="${DIR}/.aux/original" FIRMWARE_AUX_DIR="${AUX_DIR}/${FIRMWARE_SUBDIR}" FILESYSTEM_AUX_DIR="${AUX_DIR}/${FILESYSTEM_SUBDIR}" KERNEL_AUX_DIR="${AUX_DIR}/${KERNEL_SUBDIR}" VARTAR_AUX_DIR="${KERNEL_AUX_DIR}/${VARTAR_SUBDIR}" ########################################################## ## Include config file + initialise some more variables ## ########################################################## # Include config file, but do not override variables which are already defined # in the environment, e.g. via "make FREETZ_SOMETHING=y" sed -nr 's/^([^=]+)=(.*)/: ${\1:=\2}/p' "$DOT_CONFIG" > "$DOT_CONFIG.fwmod" source "$DOT_CONFIG.fwmod" rm "$DOT_CONFIG.fwmod" # Set default verbosity level, just in case none was defined in the (possibly # user-defined and minimal) config file : ${FREETZ_VERBOSITY_LEVEL:=0} # Kernel/SquashFS images contained in firmware KERNEL_IMAGE="${FREETZ_AVM_IMAGES_SUBDIR}/kernel.image" FILESYSTEM_IMAGE="${FREETZ_AVM_IMAGES_SUBDIR}/filesystem.image" FILESYSTEM_INNER_IMAGE="filesystem_core.squashfs" AVMPLUGINS_FILE="${FREETZ_AVM_IMAGES_SUBDIR}/plugins.update" # Use FREETZ_TARGET_CROSS to determine build tool paths NM="${ABS_BASE_DIR}/toolchain/target/bin/${FREETZ_TARGET_CROSS}nm" STRIP="${ABS_BASE_DIR}/toolchain/target/bin/${FREETZ_TARGET_CROSS}strip" # Tools and options for (un)packing SquashFS UNSQUASHFS_TOOL="unsquashfs4-avm-${FREETZ_AVM_SQUASHFS_ENDIANNESS}" UNSQUASHFS="${TOOLS_DIR}/${UNSQUASHFS_TOOL}" UNSQUASHFS_OPTIONS="-no-progress -processors 1 -exit-on-error" MKSQUASHFS_TOOL[2]="mksquashfs2-lzma" MKSQUASHFS_TOOL[3]="mksquashfs3-multi" MKSQUASHFS_TOOL[4]="mksquashfs4-avm-${FREETZ_AVM_SQUASHFS_ENDIANNESS}" MKSQUASHFS="${TOOLS_DIR}/${MKSQUASHFS_TOOL[${FREETZ_SQUASHFS_VERSION}]}" MKSQUASHFS_OPTIONS="-all-root -info" if [ "${FREETZ_SQUASHFS_VERSION}" -gt 2 ]; then MKSQUASHFS_OPTIONS+=" -no-progress -no-exports -no-sparse" fi if [ "${FREETZ_SQUASHFS_VERSION}" -lt 4 ]; then MKSQUASHFS_OPTIONS+=" -noappend" MKSQUASHFS_OPTIONS+=" -${FREETZ_AVM_SQUASHFS_ENDIANNESS}" fi if [ "${FREETZ_SQUASHFS_VERSION}" -eq 3 -a "${FREETZ_AVM_SQUASHFS_COMPRESSION}" == "lzma" ]; then MKSQUASHFS_OPTIONS+=" -lzma1" fi ####################################### ## Initialise fakeroot incl. caching ## ####################################### # Create id string based on MD5 hashes of firmware images if [ "$FIRMWARE2" ]; then FIRMWARE_MD5="$("$MD5SUM" "$FIRMWARE2" | cut -d ' ' -f 1)" fi FIRMWARE_MD5="$("$MD5SUM" "$FIRMWARE" | cut -d ' ' -f 1)_$FIRMWARE_MD5" FAKEROOT="$TOOLS_DIR/build/bin/fakeroot" FAKEROOT_CACHE_DIR="$ABS_BASE_DIR/.fakeroot-cache" FAKEROOT_CACHE="$FAKEROOT_CACHE_DIR/$FIRMWARE_MD5" if [ ! -e "$FAKEROOT_CACHE_DIR" ]; then mkdir -p "$FAKEROOT_CACHE_DIR" fi # Are we in a fakeroot context? if [ "$FAKEROOTKEY" ] && [ $UID -eq 0 ]; then # Yes -> fakeroot is active # Make sure fakeroot call came from ourselves so we can assume the cache settings to be correct if [ $((FWMOD_RECURSIVE)) -eq 0 ] || [ "$SELF" != "$(sed -nr 's/^Name:[[:blank:]]+(.*)/\1/p' /proc/$FWMOD_RECURSIVE/status)" ]; then error 1 "$SELF must not run in a fakeroot environment" fi # Does fakeroot cache (size>0) exist for current combination of firmwares and has this combination already been unpacked? if [ -s "$FAKEROOT_CACHE" ] && [ -s "$UNPACKED_FILE" ] && [ "$(cat "$UNPACKED_FILE")" == "$FIRMWARE_MD5" ]; then # Yes -> skip unpack [ $DO_UNPACK -gt 0 ] && SKIP_UNPACK="STEP 1: UNPACK (SKIPPED)\n\n" DO_UNPACK=0 else # No -> force unpack [ $DO_UNPACK -eq 0 ] && FORCE_UNPACK=" (FORCED)" DO_UNPACK=1 fi else # No -> fakeroot is inactive # Does fakeroot cache (size>0) exist for current combination of firmwares and has this combination already been unpacked? if [ -s "$FAKEROOT_CACHE" ] && [ -s "$UNPACKED_FILE" ] && [ "$(cat "$UNPACKED_FILE")" == "$FIRMWARE_MD5" ]; then # Yes -> use existing cache and firmwares (no unpack necessary) NON_FAKEROOT_USERNAME=$(id -u -n) FWMOD_RECURSIVE=$$ "$FAKEROOT" -i "$FAKEROOT_CACHE" -s "$FAKEROOT_CACHE" '--' "${CMDLINE_ORIG[@]}" else # No -> create new fakeroot cache and unpack firmwares NON_FAKEROOT_USERNAME=$(id -u -n) FWMOD_RECURSIVE=$$ "$FAKEROOT" -s "$FAKEROOT_CACHE" '--' "${CMDLINE_ORIG[@]}" fi retval=$? [ $retval -eq 0 ] || exit $retval # ------------------------------------------------------------------ # -- Copy file system to target folder (NFS root, maybe USB root) -- # ------------------------------------------------------------------ # This cannot be done in the pack/zip section (needs real sudo, not fakeroot) if [ "$COPY_FS_DIR" ]; then echo0 "copying root file system to directory $COPY_FS_DIR" rootfs_archive="$(cat "${DIR}/.rootfs_archive")" || error 1 "cannot determine root file system archive name" [ -d "$COPY_FS_DIR" ] && (sudo rm -rf "$COPY_FS_DIR"/* || error 1 "cannot clean up directory $COPY_FS_DIR") mkdir -p "$COPY_FS_DIR" || error 1 "cannot create directory $COPY_FS_DIR" sudo "$TAR" -C "$COPY_FS_DIR" -xf "$rootfs_archive" || error 1 "cannot unpack root file system" echo -e "done.\n" echo0 -b "FINISHED" fi exit 0 fi ############################################ ## Unpack and unsquash the firmware image ## ############################################ ORG_DIR="${DIR}/original" FIRMWARE_DIR="${ORG_DIR}/${FIRMWARE_SUBDIR}" FILESYSTEM_DIR="${ORG_DIR}/${FILESYSTEM_SUBDIR}" FILESYSTEM_OUTER_DIR="${ORG_DIR}/${FILESYSTEM_OUTER_SUBDIR}" KERNEL_DIR="${ORG_DIR}/${KERNEL_SUBDIR}" AVMPLUGINS_DIR="${KERNEL_DIR}/${AVMPLUGINS_SUBDIR}" VARTAR_DIR="${KERNEL_DIR}/${VARTAR_SUBDIR}" HTML_DIR="${FILESYSTEM_DIR}/${HTML_SUBDIR}" RAW_KERNEL="${KERNEL_DIR}/${RAW_KERNEL_FILE}" RAW_FILESYSTEM="${KERNEL_DIR}/${RAW_HIDDEN_FILE}" KERNEL="${FIRMWARE_DIR}/${KERNEL_IMAGE}" if [ "${FREETZ_AVM_HAS_SEPARATE_FILESYSTEM_IMAGE}" == "y" ]; then if [ "${FREETZ_AVM_HAS_INNER_OUTER_FILESYSTEM}" == "y" ]; then FILESYSTEM="${FILESYSTEM_OUTER_DIR}/${FILESYSTEM_INNER_IMAGE}" INNER_FS_PREFIX="inner-" else FILESYSTEM="${FIRMWARE_DIR}/${FILESYSTEM_IMAGE}" fi else FILESYSTEM="${RAW_FILESYSTEM}" fi AVMPLUGINS="${FIRMWARE_DIR}/${AVMPLUGINS_FILE}" VARTAR="${FILESYSTEM_DIR}/${VARTAR_FILE}" if [ "$DO_UNPACK" -gt 0 ]; then [ "$FIRMWARE2" ] && UNPACK_SUBSTEP="A" && UNPACK_MAIN=" MAIN" && FIRMWARE_MAIN=" main" echo0 -b "STEP 1${UNPACK_SUBSTEP}: UNPACK${UNPACK_MAIN}${FORCE_UNPACK}" # Remove old "unpacked" marker to avoid an undefined state in case of # interruption before unpacking operation is finished rm -f "$UNPACKED_FILE" rm -rf "$ORG_DIR" mkdir "$ORG_DIR" echo "unpacking firmware image" mkdir "$FIRMWARE_DIR" if [ "$FIRMWARE_EXTENSION" != "exe" ]; then # Unpack standard *.image file in tar format "$TAR_GNU" -xif "$FIRMWARE" -C "$FIRMWARE_DIR" || untar_failed=1 fi if [ "$FIRMWARE_EXTENSION" == "exe" ] || [ "$untar_failed" ]; then # Unpack Windows recover.exe file or mtdblock dump exe_images=($("${TOOLS_DIR}/extract-images" "$ABS_BASE_DIR" "$FIRMWARE" | sed -nr 's/^ *(.*\.image) - .*/\1/p')) [ "$exe_images" ] || exit 1 mkdir -p "$FIRMWARE_DIR/${FREETZ_AVM_IMAGES_SUBDIR}" mkdir "$KERNEL_DIR" unset exe_hr_mode # NOTE: This loop is sensitive to the order and format of output of # "tools/extract-images", e.g. a hidden root image is always listed # before its parts. for (( i=0; i<${#exe_images[@]}; i++ )); do exe_image="${exe_images[i]}" case "$exe_image" in */urlader.image) mv "$exe_image" "$FIRMWARE_DIR/${FREETZ_AVM_IMAGES_SUBDIR}" ;; */hr_kernel.image) exe_hr_mode=1 mv "$exe_image" "$FIRMWARE_DIR/${FREETZ_AVM_IMAGES_SUBDIR}/kernel.image" touch "$FIRMWARE_DIR/${FREETZ_AVM_IMAGES_SUBDIR}/filesystem.image" ;; */kernel.image) [ "$exe_hr_mode" ] || cp "$exe_image" "$FIRMWARE_DIR/${FREETZ_AVM_IMAGES_SUBDIR}/kernel.image" mv "$exe_image" "$KERNEL_DIR/kernel.raw" ;; */filesystem.image) if [ "$exe_hr_mode" ]; then mv "$exe_image" "$KERNEL_DIR/kernelsquashfs.raw" else mv "$exe_image" "$FIRMWARE_DIR/${FREETZ_AVM_IMAGES_SUBDIR}/filesystem.image" fi ;; esac done rm -r "$(dirname "$exe_image")" fi # Do the images exist ? [ ! -r "${KERNEL}" ] && error 1 "cannot find kernel.image (${KERNEL})" [ ! -r "${FIRMWARE_DIR}/${FILESYSTEM_IMAGE}" ] && error 1 "cannot find filesystem.image (${FIRMWARE_DIR}/${FILESYSTEM_IMAGE})" # Do we have the tool ? for tool in "$UNSQUASHFS" "$FINDSQUASHFS" "$TICHKSUM"; do [ ! -x $tool ] && error 1 "cannot find the tool $tool" done # Remove NMI vector from SquashFS if [ "$FREETZ_AVM_HAS_NMI_VECTOR" == "y" ]; then echo0 "removing NMI vector from SquashFS" [ "$FREETZ_AVM_HAS_SEPARATE_FILESYSTEM_IMAGE" == "y" ] && FILE_WITH_NMI_VECTOR_TO_PROCESS="${FIRMWARE_DIR}/${FILESYSTEM_IMAGE}" || FILE_WITH_NMI_VECTOR_TO_PROCESS="$KERNEL" if [ "$FREETZ_VERBOSITY_LEVEL" -lt 2 ]; then "$TOOLS_DIR/remove-nmi-vector" "$FILE_WITH_NMI_VECTOR_TO_PROCESS" "$FILE_WITH_NMI_VECTOR_TO_PROCESS.no-nmi" >/dev/null 2>&1 else "$TOOLS_DIR/remove-nmi-vector" "$FILE_WITH_NMI_VECTOR_TO_PROCESS" "$FILE_WITH_NMI_VECTOR_TO_PROCESS.no-nmi" fi case "$?" in 0) mv -f "$FILE_WITH_NMI_VECTOR_TO_PROCESS.no-nmi" "$FILE_WITH_NMI_VECTOR_TO_PROCESS" ;; 1) warn2 "NMI vector not found. Assuming Freetz or Freetz-repacked image." ;; *) error 1 "fatal error while removing NMI vector from SquashFS." ;; esac fi "$TICHKSUM" -r "${KERNEL}" > /dev/null "$TICHKSUM" -r "${FIRMWARE_DIR}/${FILESYSTEM_IMAGE}" > /dev/null mkdir -p "$KERNEL_DIR" if [ "${FREETZ_AVM_HAS_SEPARATE_FILESYSTEM_IMAGE}" == "y" ]; then cp "${KERNEL}" "${RAW_KERNEL}" [ ! -r "$RAW_KERNEL" ] && error 1 "copying kernel image failed" if [ "${FREETZ_AVM_HAS_INNER_OUTER_FILESYSTEM}" == "y" ]; then echo "unpacking outer-filesystem image" modunpack_autodetect_fs "${FILESYSTEM_OUTER_DIR}" "${FIRMWARE_DIR}/${FILESYSTEM_IMAGE}" [ ! -r "$FILESYSTEM" ] && error 1 "unpacking outer-filesystem image failed" fi echo "unpacking ${INNER_FS_PREFIX}filesystem image" modunpack_autodetect_fs "$FILESYSTEM_DIR" "$FILESYSTEM" || error 1 "unpacking ${INNER_FS_PREFIX}filesystem image failed" else echo "splitting kernel image" ( cd "$KERNEL_DIR" && "${TOOLS_DIR}/${FINDSQUASHFS_TOOL}" "../${FIRMWARE_SUBDIR}/${KERNEL_IMAGE}" > /dev/null 2>&1 ) if [ ! -r "$RAW_KERNEL" -o ! -r "$FILESYSTEM" ]; then if [ -r "${FIRMWARE_DIR}/${FILESYSTEM_IMAGE}" ] && [ $(stat -c %s "${FIRMWARE_DIR}/${FILESYSTEM_IMAGE}") -gt 0 ]; then _config_hint=" - maybe you should configure a firmware with FREETZ_AVM_HAS_SEPARATE_FILESYSTEM_IMAGE/FREETZ_AVM_HAS_INNER_OUTER_FILESYSTEM" fi error 1 "kernel splitting failed${_config_hint}" fi echo "unpacking filesystem image" modunpack_autodetect_fs "$FILESYSTEM_DIR" "$FILESYSTEM" || error 1 "unpacking filesystem image failed" fi if [ -r "$AVMPLUGINS" ]; then echo0 "unpacking AVM plugins" mkdir -p "$AVMPLUGINS_DIR" "$TAR_GNU" -xif "$AVMPLUGINS" -C "$AVMPLUGINS_DIR" || exit 1 for i in "${AVMPLUGINS_DIR}/var/"*.image; do AVMPLUGIN="${i##*/plugin-}" AVMPLUGIN="${AVMPLUGIN%\.image}" echo2 "$AVMPLUGIN image" modunpack_autodetect_fs "$AVMPLUGINS_DIR/plugin-${AVMPLUGIN}" "$i" > /dev/null done chmod -R +w "$AVMPLUGINS_DIR" fi if [ ! -r "$FILESYSTEM_DIR/var" ]; then error 1 "could not unpack the filesystem image" fi if [ ! -r "$VARTAR" ]; then error 1 "no var.tar found" fi echo "unpacking var.tar" mkdir "$VARTAR_DIR" "$TAR_GNU" -xipf "$VARTAR" -C "$VARTAR_DIR" || exit 1 echo -e "done.\n" # Unpack secondary firmware image if [ -n "$FIRMWARE2" ]; then echo0 -b "FINISHED" rm -rf "${DIR}/.tk" "$0" -u -d "${DIR}/.tk" "$FIRMWARE2" | sed "s/STEP 1: UNPACK/STEP 1B: UNPACK SECONDARY${FORCE_UNPACK}/;s/ firmware/ secondary&/" fi # Unpack auxiliary firmware image if [ -n "$FIRMWARE3" ]; then rm -rf "${DIR}/.aux" "$0" -u -d "${DIR}/.aux" "$FIRMWARE3" | sed "s/STEP 1: UNPACK/STEP 1C: UNPACK AUXILIARY${FORCE_UNPACK}/;s/ firmware/ auxiliary&/" fi # Create "unpacked" marker, recording exactly *what* was unpacked (MD5) echo "$FIRMWARE_MD5" > "$UNPACKED_FILE" fi echo0 -n -b "$SKIP_UNPACK" ############################################### # Lets copy and modify the unpacked firmware ## ############################################### # FREETZ_LIBRARY_DIR is the 1st FREETZ_RPATH entry FREETZ_LIBRARY_DIR=$(stripTrailingSlash "${FREETZ_RPATH%%:*}") MOD_DIR="${DIR}/modified" FIRMWARE_MOD_DIR="${MOD_DIR}/${FIRMWARE_SUBDIR}" FILESYSTEM_MOD_DIR="${MOD_DIR}/${FILESYSTEM_SUBDIR}" FILESYSTEM_OUTER_MOD_DIR="${MOD_DIR}/${FILESYSTEM_OUTER_SUBDIR}" EXTERNAL_MOD_DIR="${MOD_DIR}/${EXTERNAL_SUBDIR}" KERNEL_MOD_DIR="${MOD_DIR}/${KERNEL_SUBDIR}" AVMPLUGINS_MOD_DIR="${KERNEL_MOD_DIR}/${AVMPLUGINS_SUBDIR}" AVMPLUGINS_FILESYSTEM_MOD_DIR="${FILESYSTEM_MOD_DIR}/usr/share/avmplugins" VARTAR_MOD_DIR="${KERNEL_MOD_DIR}/${VARTAR_SUBDIR}" KERNEL_MOD="${FIRMWARE_MOD_DIR}/${KERNEL_IMAGE}" FILESYSTEM_MOD="${FIRMWARE_MOD_DIR}/${FILESYSTEM_IMAGE}" RAW_KERNEL_MOD="${KERNEL_MOD_DIR}/${RAW_KERNEL_FILE}" RAW_FILESYSTEM_MOD="${KERNEL_MOD_DIR}/${RAW_HIDDEN_FILE}" if [ "${FREETZ_AVM_HAS_SEPARATE_FILESYSTEM_IMAGE}" == "y" ]; then if [ "${FREETZ_AVM_HAS_INNER_OUTER_FILESYSTEM}" == "y" ]; then MAIN_FILESYSTEM_MOD="${FILESYSTEM_OUTER_MOD_DIR}/${FILESYSTEM_INNER_IMAGE}" else MAIN_FILESYSTEM_MOD="$RAW_FILESYSTEM_MOD" fi else MAIN_FILESYSTEM_MOD="$RAW_FILESYSTEM_MOD" fi VARTAR_MOD="${FILESYSTEM_MOD_DIR}/${VARTAR_FILE}" [ "${FREETZ_AVM_UCLIBC_NPTL_ENABLED}" == "y" ] && TARGET_TOOLCHAIN_ID__UCLIBC_SUFFIX="-nptl" [ "${FREETZ_KERNEL_VERSION_3_10_MIN}" == "y" ] && TARGET_TOOLCHAIN_ID__KERNEL_SUFFIX="_kernel-${FREETZ_KERNEL_VERSION_MAJOR}" TARGET_TOOLCHAIN_ID="${FREETZ_TARGET_ARCH_ENDIANNESS_DEPENDENT}_gcc-${FREETZ_TARGET_GCC_VERSION}_uClibc-${FREETZ_TARGET_UCLIBC_VERSION}${TARGET_TOOLCHAIN_ID__UCLIBC_SUFFIX}${TARGET_TOOLCHAIN_ID__KERNEL_SUFFIX}" PACKAGES_DIR="${PACKAGES_DIR_ROOT}/target-${TARGET_TOOLCHAIN_ID}" TARGET_SPECIFIC_ROOT_DIR="${PACKAGES_DIR}/root" HTML_MOD_DIR="${FILESYSTEM_MOD_DIR}/${HTML_SUBDIR}" # $LUA_MOD_DIR can't be defined here. eg: ${FILESYSTEM_MOD_DIR}/usr/www/all/lua # $HTML_LANG_MOD_DIR can't be defined here. eg: ${FILESYSTEM_MOD_DIR}/usr/www/all # $HTML_SPEC_MOD_DIR can't be defined here. eg: ${FILESYSTEM_MOD_DIR}/usr/www/all/html/de if [ -z "$FREETZ_SQUASHFS_BLOCKSIZE" ]; then # expected to be empty only if FREETZ_SQUASHFS_BLOCKSIZE_ORIG is set echo -n "determining SquashFS block size of the original firmware: " FREETZ_SQUASHFS_BLOCKSIZE=$("$UNSQUASHFS" -s "$FILESYSTEM" 2>/dev/null | sed -nr 's/Block size ([0-9]+)/\1/p') [ -z "$FREETZ_SQUASHFS_BLOCKSIZE" ] && error 1 "failed" || echo -e "$((FREETZ_SQUASHFS_BLOCKSIZE/1024)) kB\n" fi MKSQUASHFS_OPTIONS+=" -b $FREETZ_SQUASHFS_BLOCKSIZE" #echo "Using '$MKSQUASHFS_OPTIONS' as MKSQUASHFS_OPTIONS" if [ "$FREETZ_SIZEINFO_COMPRESSED" == "y" ]; then let FILESYSTEM_BLOCKSIZE_KB=$FREETZ_SQUASHFS_BLOCKSIZE/1024 SIZEINFO_CACHEDIR=${PACKAGES_DIR}/freetzcachedsizes mkdir -p ${SIZEINFO_CACHEDIR} fi function sizeinfo() { [ "$FREETZ_VERBOSITY_LEVEL" -lt 1 ] && return #formated output if [ $# -eq 1 ]; then if [ "$FREETZ_SIZEINFO_COMPRESSED" != "y" ]; then echo1 "$1" else echo1 -n "$(printf "%-34s " "$1" | sed 's/ /\./g;s/\.\./ ./;s/\.(addon)/ (addon)/')" fi return fi [ "$FREETZ_SIZEINFO_COMPRESSED" != "y" ] && return #cache file local sizeinfo_mode=$1 shift case $sizeinfo_mode in lib) #libraries: multiple files local shash="$(ls -l $@ | sort | $MD5SUM)" local sfile="${SIZEINFO_CACHEDIR}/$(echo $@ | sed -rn 's!.*/(.*)\.so.*!\1!p').sizeinfo.MD5_${shash/ */}.BS_${FILESYSTEM_BLOCKSIZE_KB}" ;; mod) #modules: one .ko file local shash="$(ls -l $1 | $MD5SUM)" local sfile="${SIZEINFO_CACHEDIR}/${1##*/}.sizeinfo.MD5_${shash/ */}.BS_${FILESYSTEM_BLOCKSIZE_KB}" ;; pkg) #packages: files (without .excluded) local shash="$(echo $* | sort | $MD5SUM)" local sfile="${1}/.sizeinfo.MD5_${shash/ */}.BS_${FILESYSTEM_BLOCKSIZE_KB}" shift ;; add) #addons: one directory local shash="$(find $1 -type f -exec ls -l {} ';' | $MD5SUM)" local sfile="${SIZEINFO_CACHEDIR}/${1##*/}.sizeinfo.MD5_${shash/ */}.BS_${FILESYSTEM_BLOCKSIZE_KB}" ;; *) echo "invalid" return ;; esac #compressed size if [ ! -s "$sfile" ]; then if [ $# -eq 0 ]; then echo -n " 0.00 kB (uncompressed: 0.00 kB)" > ${sfile} else local tempf=/tmp/freetz-sizeinfo-$$.tmp "$MKSQUASHFS" $@ $tempf $MKSQUASHFS_OPTIONS 2>/dev/null | grep -A1 ^Filesystem \ | sed -n 'N;s!Filesystem size \(.*\)ytes (.*\n.*(\(.*\)ytes.*$!\1 \2!p' \ | awk '{printf "%8s%3s (uncompressed:%8s%3s)",$1,$2,$3,$4}' > ${sfile} rm -rf $tempf 2>/dev/null fi fi #uncompressed size if [ "$FREETZ_SIZEINFO_UNCOMPRESSED" = "y" ]; then cat ${sfile} else cat ${sfile} | sed 's/(uncompressed.*//' fi echo } # show avm image details AVM_FW_PRODUCT="$(sed -rn 's/export CONFIG_PRODUKT_NAME=".*([0-9]{3}[0-9V].*)"/\1/p' ${FILESYSTEM_DIR}/etc/init.d/rc.conf | head -n1)" # 4-digits in /etc/init.d/rc.conf [ -z "${AVM_FW_PRODUCT}" ] && AVM_FW_PRODUCT="$(sed -rn 's/export CONFIG_PRODUKT_NAME="(FRITZ!Box|Speedport|Sinus|Eumex) ([^"]+)"/\2/p' ${FILESYSTEM_DIR}/etc/init.d/rc.conf | head -n1 | tr ' ' '-')" # symbolic name in /etc/init.d/rc.conf if [ -e "${FILESYSTEM_DIR}/etc/init.d/rc.init" ]; then # /etc/init.d/rc.init is not available in all firmwares [ -z "${AVM_FW_PRODUCT}" ] && AVM_FW_PRODUCT="$(sed -rn 's/^HW=[0-9]* OEM=all _PRODUKT_NAME=(FRITZ!Box|Speedport|Sinus|Eumex)#//p' ${FILESYSTEM_DIR}/etc/init.d/rc.init | head -n1 | sed 's/#//g;s/Annex.//;s/WLAN/-&/g;s/^$/FritzBox/g')" # symbolic name in /etc/init.d/rc.init [ -z "${AVM_FW_PRODUCT}" ] && AVM_FW_PRODUCT="$(sed -rn 's/^HW=[0-9]* OEM=all _PRODUKT_NAME=([0-9A-Z\#]{4,6}).*/\1/p' ${FILESYSTEM_DIR}/etc/init.d/rc.init)" # 4-digits in /etc/init.d/rc.init fi [ -z "${AVM_FW_PRODUCT}" ] && warn "Failed to determine AVM_FW_PRODUCT, even though this is a cosmetic bug only please report it to the Freetz developers and provide your .config" AVM_FW_PRODUCT="${AVM_FW_PRODUCT%% Edition*}" AVM_FW_PRODUCT="${AVM_FW_PRODUCT% }" AVM_FW_LANGUAGE="$(sed -n 's/^language /_/p' ${FILESYSTEM_DIR}/etc/default.language)" #primary language AVM_FW_LANGUAGE="${AVM_FW_LANGUAGE}$(for x in $(ls ${FILESYSTEM_DIR}/etc/htmltext_??.db 2>/dev/null| sed 's/.*_//g;s/\.db//g'); do [ "_$x" != "${AVM_FW_LANGUAGE}" ] && echo -en "-$x"; done; echo)" # other languages AVM_FW_MAJOR="$(sed -rn 's/^export CONFIG_VERSION_MAJOR="(.*)"/\1/p' ${FILESYSTEM_DIR}/etc/init.d/rc.conf | tail -n1)" # newer firmware [ -z "${AVM_FW_MAJOR}" ] && AVM_FW_MAJOR="$(sed -n 's/^HW=[0-9].*VERSION_MAJOR=//p' ${FILESYSTEM_DIR}/etc/init.d/rc.init)" # older firmware AVM_FW_VERSION="$(sed -n 's/^export FIRMWARE_VERSION=.*}[.]//p' ${FILESYSTEM_DIR}/etc/version)" AVM_FW_LABOR="$(sed -rn 's/^export CONFIG_LABOR_ID_NAME="(.*)"/-\1/p' ${FILESYSTEM_DIR}/etc/init.d/rc.conf)" AVM_FW_REVISION="$(sed -n '/--project)$/{N;s/.*echo //p}' ${FILESYSTEM_DIR}/etc/version)" AVM_FW_DATE="$(sed -rn 's/^export FIRMWARE_DATE="(.*)"/\1/p' ${FILESYSTEM_DIR}/etc/version)" echo1 -l "detected${FIRMWARE_MAIN} firmware ${AVM_FW_PRODUCT/ /-}${AVM_FW_LANGUAGE} ${AVM_FW_MAJOR}.${AVM_FW_VERSION}${AVM_FW_LABOR} rev${AVM_FW_REVISION} (${AVM_FW_DATE})\n" if [ "$DO_MOD" -gt 0 ]; then echo0 -b "STEP 2: MODIFY" # Check if firmware is unpacked if [ ! -r "$UNPACKED_FILE" ]; then error 1 "firmware image has to be unpacked before modifying" fi rm -rf "$MOD_DIR" rm -f "${DIR}/.modified" # Copy the unpacked directory mkdir -p "$MOD_DIR" [ "$FREETZ_AVM_HAS_UDEV" == y ] || exclude_dev="--exclude=./filesystem/dev" "$TAR" -c -C "$ORG_DIR" $exclude_dev --exclude='*.log' . | "$TAR" -x -C "$MOD_DIR" || exit 1 # Fix some permissions chmod -R u+w "$FILESYSTEM_MOD_DIR" find "${FILESYSTEM_MOD_DIR}" "${VARTAR_MOD_DIR}" -type d -exec chmod 755 {} '+' # Give all users write permissions to /var/tmp to allow it to be used as a temp-directory. # Set sticky bit to prevent users from deleting/renaming files they are not the owners of. # NB: The permissions set are the regular temp-directory permissions on Unix-like systems. chmod 1777 "${VARTAR_MOD_DIR}/var/tmp" # determine OEMs supported by the original firmware all_known_oems="1und1 aol arcor avm avme ewetel freenet otwo tcom versatel" iterate_over_oems_pattern='for[ ]+i[ ]+in[ ]+('"${all_known_oems// /|}"')[^;]*;[ ]*do' oems=$(sed -n -r -e '/'"${iterate_over_oems_pattern}"'/ { s/^.*for[ ]+i[ ]+in[ ]+([^;]+);[ ]+do.*$/\1/p; q }' "${FIRMWARE_MOD_DIR}/var/install") [ -z "$oems" ] && error 1 "failed to determine OEMs supported by the original firmware" echo0 -n "applying symlinks, deleting additional webinterfaces in:" for webdir in \ ${FILESYSTEM_MOD_DIR}/usr/www \ ${FILESYSTEM_MOD_DIR}/usr/www.nas \ ${FILESYSTEM_MOD_DIR}/usr/www.myfritz \ ; do [ ! -d ${webdir} ] && continue for edition in ewetel; do [ ! -d ${webdir}/$edition ] && continue [ -d ${webdir}/avm ] && continue [ -d ${webdir}/all ] && continue # force creation of /usr/www/all/ mv ${webdir}/$edition ${webdir}/avm done # some recent LTE firmwares contain both avm and avme OEMs (identical in all firmwares seen so far) # use the 1st of them (according to the alphabetical order) as the main one main_oem=$(find "${webdir}" -maxdepth 1 -type d -name "avm*" -printf "%P\n" | sort | head -n 1) if [ -n "${main_oem}" ]; then echo0 -n " ${webdir#${FILESYSTEM_MOD_DIR}/}" mv ${webdir}/${main_oem} ${webdir}/all for i in $oems; do rm -rf ${webdir}/$i ln -s all ${webdir}/$i done fi done echo0 echo0 "applying patches" # Include patching helper function (modpatch) source "${TOOLS_DIR}/freetz_patch" || error 1 "cannot find script freetz_patch" PATCHES_DEVICES_DIR_FW_SERIES_SPECIFIC="${PATCHES_DEVICES_DIR}/${FREETZ_TYPE_PREFIX_SERIES_SUBDIR}" PATCHES_DEVICES_DIR_BOX_SPECIFIC="${PATCHES_DEVICES_DIR_FW_SERIES_SPECIFIC}/${FREETZ_TYPE_PREFIX%_*}" declare -a PATCHES_DEVICES_DIR_FULL_LIST=($( for j in \ ${PATCHES_DEVICES_DIR_FW_SERIES_SPECIFIC} \ ${PATCHES_DEVICES_DIR_BOX_SPECIFIC} \ $( [ -n "${FREETZ_TYPE_PREFIX_LABOR_FIRMWARE}" ] && echo "${PATCHES_DEVICES_DIR_BOX_SPECIFIC}/${FREETZ_TYPE_PREFIX_LABOR_FIRMWARE:1}" ) \ ; do for i in $j $j/${FREETZ_TYPE_LANGUAGE}; do echo "${i}" done done )) echo1 "applying patches: ${FREETZ_TYPE_PREFIX_SERIES_SUBDIR}/${FREETZ_TYPE_PREFIX}${FREETZ_TYPE_PREFIX_LABOR_FIRMWARE}-${FREETZ_TYPE_LANGUAGE} (${PATCHES_DEVICES_DIR_FULL_LIST[@]#${PATCHES_DEVICES_DIR}/})" # Apply patches if [ ! -d "${PATCHES_DEVICES_DIR_BOX_SPECIFIC}" -a ! -d "${PATCHES_DEVICES_DIR_FW_SERIES_SPECIFIC}" ]; then error 1 "missing ${PATCHES_DEVICES_DIR_BOX_SPECIFIC}" fi # Execute firmware-series-specific and box-specific patch scripts (both common for all languages and language-specific) shopt -s nullglob for j in ${PATCHES_DEVICES_DIR_FULL_LIST[@]}; do for i in $j/*.sh; do echo2 "applying patch file $i" source $i done done shopt -u nullglob # Now we are in place to check html directory for i in all/en all ewetel; do if [ -d "${HTML_MOD_DIR}/$i" ]; then HTML_LANG_MOD_DIR="${HTML_MOD_DIR}/$i" break fi done # Now check language specific html directory (if there is any) for i in de en; do if [ -d "${HTML_LANG_MOD_DIR}/html/$i" ]; then HTML_SPEC_MOD_DIR="${HTML_LANG_MOD_DIR}/html/$i" break fi done echo1 "Language specific HTML directory: ${HTML_SPEC_MOD_DIR:-none}" if [ -z "$HTML_SPEC_MOD_DIR" ]; then HTML_SPEC_MOD_DIR="${HTML_LANG_MOD_DIR}/html/doesnotexist" FREETZ_AVM_HAS_ONLY_LUA=y [ -e "${FILESYSTEM_MOD_DIR}/usr/www/all/css/rd/images/fritzLogo.svg" ] && FREETZ_AVM_HAS_LUA_SCALABLE=y fi # Check for LUA directory LUA_MOD_DIR="${FILESYSTEM_MOD_DIR}/usr/lua" [ -d "$LUA_MOD_DIR" ] || LUA_MOD_DIR="${HTML_LANG_MOD_DIR}/lua" [ -d "$LUA_MOD_DIR" ] && echo1 "LUA directory: ${LUA_MOD_DIR}" || FREETZ_AVM_HAS_ONLY_HTML=y # Determine $MODULES_DIR in AVM image, eg: "${FILESYSTEM_MOD_DIR}/lib/modules/2.6.19.2 MODULES_DIR="$(find ${FILESYSTEM_MOD_DIR}/lib/modules/2.6.* ${FILESYSTEM_MOD_DIR}/lib/modules/[34].*.* -maxdepth 0 -type d 2>/dev/null)" [ ! -d "$MODULES_DIR" ] && error 1 "Cannot find modules dir." # Set $MODULES_SUBDIR relative to root dir in AVM image, eg: "lib/modules/2.6.19.2 MODULES_SUBDIR="${MODULES_DIR#${FILESYSTEM_MOD_DIR}/}" # Apply firmware-series-specific and box-specific patches (both common for all languages and language-specific) shopt -s nullglob for ((j=0; j<${#PATCHES_DEVICES_DIR_FULL_LIST[@]}; j++)); do for i in ${PATCHES_DEVICES_DIR_FULL_LIST[$j]}/*.patch; do # Check if a more specific version of the patch exists, # i.e. define an order on all patches with the same name # FW_SERIES/XY.patch # FW_SERIES/LANG/XY.patch # FW_SERIES/BOXID/XY.patch # FW_SERIES/BOXID/LANG/XY.patch # and do NOT apply patch XY.patch from dir FOO # if it also exists in a directory with a higher order. # # This makes it possible in situations where one box needs # a box-specific version of the patch to have just two versions # of it: one box-specific and one for all other boxes. i_basename=$(basename "$i") for ((jj=j+1; jj<${#PATCHES_DEVICES_DIR_FULL_LIST[@]}; jj++)); do if [ -f "${PATCHES_DEVICES_DIR_FULL_LIST[$jj]}/${i_basename}" ]; then continue 2 fi done modpatch "$FILESYSTEM_MOD_DIR" "$i" done done shopt -u nullglob echo1 "creating symlinks /tmp, /mod and /home" rm -rf "$FILESYSTEM_MOD_DIR"/tmp ln -s var/{tmp,mod} "$FILESYSTEM_MOD_DIR"/ ln -s var/mod/home "$FILESYSTEM_MOD_DIR"/ echo1 "creating /mnt and /opt" mkdir -p "$FILESYSTEM_MOD_DIR"/mnt # 7390: /opt is symlink to /var/InternerSpeicher/opt [ ! -L "$FILESYSTEM_MOD_DIR"/opt ] && mkdir -p "$FILESYSTEM_MOD_DIR"/opt # Set version and options SUBVERSION_FILE="${BASE_DIR}/.version" if [ ! -r "$SUBVERSION_FILE" ]; then error 1 "cannot determine version" fi if [ -d .svn ]; then # be compatible: older versions of svnversion need WC_PATH if REVISION="$(svnversion . 2>/dev/null | tr ":" "_")"; then [ "${REVISION:0:6}" == "export" ] && REVISION="" fi elif [ -d .git ]; then REVISION="$(git log 2>/dev/null | sed -rn 's!.*git-svn-id.*\@([^ ]*).*!\1!p' | head -n1)" fi [ -n "$REVISION" ] && REVISION="-$REVISION" SUBVERSION="$(cat $SUBVERSION_FILE)${REVISION}" for i in $(set | sed -rn 's:^FREETZ_REMOVE_(.*)=y$:\1:gp' | tr '[:upper:]' '[:lower:]' | sort); do OPTIONS+=" -$i" done OPTIONS_ADD=" +busybox" for i in $(set | sed -rn 's:^FREETZ_PATCH_(.*)=y$:\1:gp' | tr '[:upper:]' '[:lower:]'); do OPTIONS_ADD+=" +$i" done PACKAGES_LIST_FILE="${BASE_DIR}/.packages" rm -f "${PACKAGES_LIST_FILE}" for pkg in $(static_packages) $(static_addons); do OPTIONS_ADD+=" +$pkg" echo "$pkg" >> "${PACKAGES_LIST_FILE}" done KERNEL_ID="${FREETZ_SYSTEM_TYPE}${FREETZ_SYSTEM_TYPE_CORE_SUFFIX}-${FREETZ_AVM_SOURCE_ID}" if [ "$FIRMWARE_NOCOMPILE" != "1" -a "$FREETZ_REPLACE_KERNEL" == "y" -a "$FWMOD_PATCH_TEST" != "y" ]; then KERNEL_SUBVERSION_FILE="${KERNEL_REP_DIR}/.version-${KERNEL_ID}" if [ ! -r "$KERNEL_SUBVERSION_FILE" ]; then error 1 "cannot determine kernel version" fi KERNEL_SUBVERSION="$(cat $KERNEL_SUBVERSION_FILE)" OPTIONS_ADD+=" +kernel ($KERNEL_SUBVERSION)" fi for i in $(echo ${OPTIONS_ADD}|sed -e's: +:\n+:g'|sort); do OPTIONS+=" $i" done echo1 "setting freetz-version '${SUBVERSION}'" echo "$SUBVERSION" > "${FILESYSTEM_MOD_DIR}/etc/.freetz-version" if [ "$FREETZ_MODIFY_AVM_VERSION" == "y" ]; then echo1 "setting AVM firmware subversion '${SUBVERSION}'" echo "$SUBVERSION" > "${FILESYSTEM_MOD_DIR}/etc/.subversion" sed -i -e "s/\export\ FIRMWARE_SUBVERSION=.*\$/export\ FIRMWARE_SUBVERSION=\"${SUBVERSION}\"/g" "${FILESYSTEM_MOD_DIR}/etc/version" if [ ! -e "${FILESYSTEM_MOD_DIR}/etc/init.d/rc.init" ]; then AVM_SUBVERSION=`grep "SUBVERSION=" "${FILESYSTEM_MOD_DIR}/etc/init.d/rc.conf" | sed -e "s/[^-0-9]//g"` sed -i -e "s/SUBVERSION=\"$AVM_SUBVERSION\"/SUBVERSION=\"-$SUBVERSION\"/" "${FILESYSTEM_MOD_DIR}/etc/init.d/rc.conf" fi sed -i -e "s//${SUBVERSION}/g" "${FILESYSTEM_MOD_DIR}/usr/bin/system_status" sed -i -e "s//${OPTIONS}/g" "${FILESYSTEM_MOD_DIR}/usr/bin/system_status" fi # Execute general patch scripts for i in "${PATCHES_SCRIPTS_DIR}/"*.sh; do [ -r "$i" ] || continue echo2 "applying patch file $i" source $i done # stop execution if in patch test mode if [ "$FWMOD_PATCH_TEST" == "y" ]; then echo0 -b "Patch test mode: exiting without error." exit fi # remove oems [ "$FREETZ_VERBOSITY_LEVEL" -ge 1 ] && echo -n "${L1}removing oem:" oem_removed=0 oem_kept=0 oem_list= ln -sf /usr/www/cgi-bin/freetz_status "${HTML_LANG_MOD_DIR}/cgi-bin/freetz_status" [ "$FREETZ_PACKAGE_WOL_CGI" == "y" ] && ln -sf /usr/www/cgi-bin/freetz_wol "${HTML_LANG_MOD_DIR}/cgi-bin/freetz_wol" for i in $oems; do if [ "$(eval "echo \"\$FREETZ_REMOVE_BRANDING_${i}\"")" == "y" ]; then [ "$FREETZ_VERBOSITY_LEVEL" -ge 1 ] && echo -n " $i" # delete webinterface symlinks otherwise user can choose branding in status.cgi rm -rf "${FILESYSTEM_MOD_DIR}/usr/www/${i}" rm -rf "${FILESYSTEM_MOD_DIR}/usr/www.nas/${i}" rm -rf "${FILESYSTEM_MOD_DIR}/usr/www.myfritz/${i}" find ${FILESYSTEM_MOD_DIR}/etc/default.* -name "*${i}*" | xargs rm -rf oem_removed=1 else oem_list+=" $i" oem_kept=1 fi done if [ "$FREETZ_VERBOSITY_LEVEL" -ge 1 ]; then [ "$oem_removed" -eq 0 ] && echo -n " none" echo fi if isFreetzType W501V; then oem_list="tcom avm" fi sed -i -r -e 's/'"${iterate_over_oems_pattern}"'/for i in '"$oem_list"' ; do/' "${FIRMWARE_MOD_DIR}/var/install" if [ "$oem_kept" -eq 0 ]; then error 1 "please choose at least one OEM (branding) in menuconfig: AVM, 1&1, Freenet etc." fi # Copy selected avmplugins to the firmware if [ "$FREETZ_AVMPLUGINS_INTEGRATE" == "y" ]; then echo0 "integrating AVM plugins" echo "#" > ${FILESYSTEM_MOD_DIR}/sbin/start_plugin.sh rm -rf ${FIRMWARE_MOD_DIR}/${AVMPLUGINS_FILE} mkdir "${AVMPLUGINS_FILESYSTEM_MOD_DIR}" for i in `find "${AVMPLUGINS_MOD_DIR}" -maxdepth 1 -type d -name var -prune -false , -type d -name "plugin-*" 2>/dev/null`; do AVMPLUGIN="${i##*plugin-}" if [ "$(eval "echo \"\$FREETZ_AVMPLUGINS_$(echo "$AVMPLUGIN" | tr [:lower:] [:upper:])\"")" == "y" ]; then echo1 "$AVMPLUGIN plugin" cp -a "${AVMPLUGINS_MOD_DIR}/plugin-${AVMPLUGIN}" "${AVMPLUGINS_FILESYSTEM_MOD_DIR}/plugin-${AVMPLUGIN}" ln -s "/usr/share/avmplugins/plugin-${AVMPLUGIN}" "${VARTAR_MOD_DIR}/var/plugin-${AVMPLUGIN}" for module in `cd "${AVMPLUGINS_FILESYSTEM_MOD_DIR}/plugin-${AVMPLUGIN}";find -type f -name "*.ko"`; do echo2 "moving ${module##*/} to standard modules dir" mv "${AVMPLUGINS_FILESYSTEM_MOD_DIR}/plugin-${AVMPLUGIN}/$module" "${FILESYSTEM_MOD_DIR}/$module" done case "$AVMPLUGIN" in tam) modsed \ "s/ CONFIG_TAM_ONRAM=.*$/ CONFIG_TAM_ONRAM=\"n\"/g" \ "${FILESYSTEM_MOD_DIR}/etc/init.d/rc.conf" ;; wlan) modsed -r \ 's,(if) (.+ plugin-wlan),\1 test -d "/usr/share/avmplugins/plugin-wlan" || \2,' \ "${FILESYSTEM_MOD_DIR}/etc/init.d/rc.wlan" ;; esac fi done fi if [ "$FREETZ_INSTALL_BASE" == "y" ]; then echo "installing mod base" MOD_CRON="${VARTAR_MOD_DIR}/var/spool/cron/crontabs" MOD_ROOT="${VARTAR_MOD_DIR}/var/mod" # Remove symlink before creating directory rm -rf ${VARTAR_MOD_DIR}/var/spool mkdir -p "$MOD_CRON" mkdir -p "${MOD_ROOT}/pkg" "${MOD_ROOT}/home" "${MOD_ROOT}/lib" "${MOD_ROOT}/root" mkdir -p "${MOD_ROOT}/bin" "${MOD_ROOT}/sbin" mkdir -p "${MOD_ROOT}/var/cache" mkdir -p "${MOD_ROOT}/usr/bin" "${MOD_ROOT}/usr/sbin" "${MOD_ROOT}/usr/share" \ "${MOD_ROOT}/usr/lib" "${MOD_ROOT}/usr/lib/cgi-bin" "${MOD_ROOT}${FREETZ_LIBRARY_DIR}" mkdir -p "${MOD_ROOT}/etc/conf" "${MOD_ROOT}/etc/init.d" "${MOD_ROOT}/etc/reg" ln -s /tmp/flash/mod/.profile "${MOD_ROOT}/root/.profile" # AVM compatibility symlink ln -s ../sys "${VARTAR_MOD_DIR}/var/sysfs" echo "root:x:0:0:root:/mod/root:/bin/sh" > "${VARTAR_MOD_DIR}/var/tmp/passwd" echo 'root:$1$$zO6d3zi9DefdWLMB.OHaO.:12332:0:99999:7:::' > "${VARTAR_MOD_DIR}/var/tmp/shadow" echo "root:x:0:" > "${VARTAR_MOD_DIR}/var/tmp/group" echo "users:x:1:" >> "${VARTAR_MOD_DIR}/var/tmp/group" touch "${VARTAR_MOD_DIR}/var/tmp/ethers" touch "${VARTAR_MOD_DIR}/var/tmp/exports" touch "${VARTAR_MOD_DIR}/var/tmp/gshadow" chmod 644 "${VARTAR_MOD_DIR}/var/tmp/passwd" "${VARTAR_MOD_DIR}/var/tmp/group" chmod 600 "${VARTAR_MOD_DIR}/var/tmp/shadow" "${VARTAR_MOD_DIR}/var/tmp/gshadow" # Fix permissions set by AVM, in particular revoke write permissions for g- and o-users. chmod 644 "${VARTAR_MOD_DIR}/var/tmp/hosts" "${VARTAR_MOD_DIR}/var/tmp/resolv.conf" mkdir -p "${VARTAR_MOD_DIR}/var/tmp/onlinechanged" mkdir -p "${VARTAR_MOD_DIR}/var/mod/etc/onlinechanged" mkdir -p "${VARTAR_MOD_DIR}/var/mod/etc/cron.d" ln -s ../var/tmp/ethers "${FILESYSTEM_MOD_DIR}/etc/ethers" ln -s ../var/tmp/exports "${FILESYSTEM_MOD_DIR}/etc/exports" ln -s ../var/tmp/gshadow "${FILESYSTEM_MOD_DIR}/etc/gshadow" rm -f ${VARTAR_MOD_DIR}/var/*/.dummy echo0 "installing libs" for i in $(set | grep ^FREETZ_LIB_.*=y | grep -v ^FREETZ_LIB_STDCXXLIB); do all_files="" found=0 conf=${i%%=*} [ "$conf" != "${conf%%_WITH_*}" ] && continue # skip suboptions bn=${conf#FREETZ_LIB_} if [ "$FREETZ_KEEP_AVM_UCLIBC" == "y" ]; then # libutil is actually also a uClibc lib, but it's not provided by AVM, so keep installing Freetz version if echo "${bn}" | grep -qE '^(ld_uClibc|libcrypt|libdl|libm|libpthread|librt|libthread_db|libubacktrace|libuClibc)$'; then echo1 "keeping AVM version of uClibc library $bn" continue fi fi fn=${bn//_/[-+._]} sizeinfo "$bn" for dn in lib usr/lib ${FREETZ_LIBRARY_DIR#/} usr/lib/xtables; do files=$(shopt -s nullglob; echo ${TARGET_SPECIFIC_ROOT_DIR}/$dn/$fn[-.]*so*) if [ -z "$files" ]; then continue; fi found=1 [ -d "${FILESYSTEM_MOD_DIR}/${dn}" ] || mkdir -p "${FILESYSTEM_MOD_DIR}/${dn}" cp -a $files "${FILESYSTEM_MOD_DIR}/${dn}/" if [ "${FREETZ_AVM_HAS_INNER_OUTER_FILESYSTEM}" == "y" ]; then wrapper_fs_required_libs="ld_uClibc libuClibc" # replaced busybox might require some additional libraries not available in AVM's wrapper filesystem [ "$FREETZ_REPLACE_BUSYBOX" == "y" -a -r "${PACKAGES_DIR}/busybox/busybox" ] && \ wrapper_fs_required_libs+=" $(getNeededEntries ${PACKAGES_DIR}/busybox/busybox | sed -r -e 's,[.]so([.].+)?$,,' | sort | tr $'\n' " ")" if echo "${bn}" | grep -qE "^($(join '|' ${wrapper_fs_required_libs}))$"; then cp -a $files "${FILESYSTEM_OUTER_MOD_DIR}/${dn}/" fi fi all_files="$all_files $files" done if [ "$found" = 0 ]; then warn "Library $bn selected, but no files found" else sizeinfo lib "$all_files" fi done if [ "$FREETZ_KEEP_AVM_UCLIBC" != "y" -a "$FREETZ_LIB_libuClibc" == "y" ]; then cp -a "${TARGET_SPECIFIC_ROOT_DIR}/lib/libc.so.${FREETZ_TARGET_UCLIBC_MAJOR_VERSION}" "${FILESYSTEM_MOD_DIR}/lib/" [ "${FREETZ_AVM_HAS_INNER_OUTER_FILESYSTEM}" == "y" ] && cp -a "${TARGET_SPECIFIC_ROOT_DIR}/lib/libc.so.${FREETZ_TARGET_UCLIBC_MAJOR_VERSION}" "${FILESYSTEM_OUTER_MOD_DIR}/lib/" fi echo1 "checking uClibc version" DETECTED_UCLIBC_VER="$(find ${FILESYSTEM_DIR}/lib/libuClibc-*.so | sed -rn 's@.*/.*-(.*)\.so@\1@p')" echo2 "... used by AVM ...... $DETECTED_UCLIBC_VER" echo2 "... used by Freetz ... ${FREETZ_TARGET_UCLIBC_VERSION}" if [ "${FREETZ_TARGET_UCLIBC_VERSION#$DETECTED_UCLIBC_VER}" == "$FREETZ_TARGET_UCLIBC_VERSION" \ -a "${FREETZ_TARGET_UCLIBC_VERSION}" != "$DETECTED_UCLIBC_VER" ]; then warn2 "Freetz and AVM uClibc versions do not match" fi unset DETECTED_UCLIBC_VER if [ "$FREETZ_SHARE_terminfo" == "y" ]; then echo1 "installing terminfos" for i in $(set | grep ^FREETZ_SHARE_terminfo_.*=y |grep -v '^FREETZ_SHARE_terminfo_showall=' ); do dn=usr/share/terminfo conf=${i%%=*} bn=${conf#FREETZ_SHARE_terminfo_} fn=$(echo "$bn" | sed 's/MINUS/-/g;s/PLUS/+/g;s/\DOT/./g') echo2 "$fn" fn="${fn:0:1}/$fn" file="${TARGET_SPECIFIC_ROOT_DIR}/$dn/$fn" if [ ! -e "$file" ]; then warn "Terminfo $bn selected, but no file found" continue; fi dest="${FILESYSTEM_MOD_DIR}/$dn/${fn:0:1}" [ -d "$dest" ] || mkdir -p "$dest" cp -a $file "$dest/" done fi else error 1 "installation of base system is mandatory" fi if [ "$FIRMWARE_NOCOMPILE" != "1" ]; then [ "$FREETZ_REPLACE_BUSYBOX" != "y" ] && error 1 "installation of busybox replacement is mandatory" echo0 "installing busybox" DIRS_BUSYBOX_TO_REPLACE_WITHIN="${FILESYSTEM_MOD_DIR}" [ "${FREETZ_AVM_HAS_INNER_OUTER_FILESYSTEM}" == "y" ] && DIRS_BUSYBOX_TO_REPLACE_WITHIN+=" ${FILESYSTEM_OUTER_MOD_DIR}" echo1 "replacing busybox" [ ! -r "${PACKAGES_DIR}/busybox/busybox" ] && error 1 "cannot find busybox replacement" for d in ${DIRS_BUSYBOX_TO_REPLACE_WITHIN}; do cp -pf "${PACKAGES_DIR}/busybox/busybox" "${d}/bin/busybox"; done echo1 "installing symlinks" [ ! -r "${PACKAGES_DIR}/busybox/busybox.links" ] && error 1 "cannot find busybox links" # Remove old busybox links # be compatible: do not use -delete (not found in older versions of find) find ${DIRS_BUSYBOX_TO_REPLACE_WITHIN} \( -lname "busybox" -or -lname "*/busybox" \) -print0 | xargs -0 rm # Install new busybox links for link in $(cat "${PACKAGES_DIR}/busybox/busybox.links"); do LINK_DIR="$(dirname "$link")" LINK_NAME="$(basename "$link")" case "$LINK_DIR" in /) BUSYBOX_PATH="bin/busybox" ;; /bin) BUSYBOX_PATH="busybox" ;; /sbin) BUSYBOX_PATH="../bin/busybox" ;; /usr/bin|/usr/sbin) BUSYBOX_PATH="../../bin/busybox" ;; *) error 1 "unknown installation directory: $link" ;; esac for d in ${DIRS_BUSYBOX_TO_REPLACE_WITHIN}; do mkdir -p "${d}${LINK_DIR}" ln -sf "$BUSYBOX_PATH" "${d}${LINK_DIR}/$LINK_NAME" || error 1 "could not create link for $link" done done || exit 1 fi echo0 "installing packages" for pkg in $(static_packages); do sizeinfo "$pkg" pkg_name=$(pkg_name "$pkg") "$TAR" -c -C "${PACKAGES_DIR}/${pkg}/root" \ $(find "${PACKAGES_DIR}/${pkg}/" -maxdepth 1 -type f -name ".exclude*" -printf '--exclude-from=%p ') \ . | \ "$TAR" -x -C "$FILESYSTEM_MOD_DIR" || exit 1 [ -d "${PACKAGES_DIR}/${pkg}/${VARTAR_SUBDIR}" ] && \ $( "$TAR" -c -C "${PACKAGES_DIR}/${pkg}/${VARTAR_SUBDIR}" . | \ "$TAR" -x -C ${VARTAR_MOD_DIR} || exit 1 ) [ -r "${PACKAGES_DIR}/${pkg}/.language" ] && \ modlang "${PACKAGES_DIR}/${pkg}/.language" "${FILESYSTEM_MOD_DIR}" if ! grep -q "^$pkg_name$" "${VARTAR_MOD_DIR}/var/mod/etc/static.pkg" >/dev/null 2>&1; then echo "$pkg_name" >> "${VARTAR_MOD_DIR}/var/mod/etc/static.pkg" fi pkgfiles=$(collect_pkg_files "${pkg}" | sed -e "s,^,${PACKAGES_DIR}/${pkg}/root,") sizeinfo pkg "${PACKAGES_DIR}/${pkg}" $pkgfiles done for pkg in $(static_addons); do sizeinfo "$pkg (addon)" pkg_name=$(pkg_name "$pkg") if [ -e "${ADDON_DIR}/${pkg}/etc/init.d/rc.${pkg_name}" ]; then echo "NOTICE: addon '$pkg' is in old-style format (no language support)." 1>&2 "$TAR" -c -C "${ADDON_DIR}/${pkg}" . | "$TAR" -x -C "$FILESYSTEM_MOD_DIR" || exit 1 else "$TAR" -c -C "${ADDON_DIR}/${pkg}/root" \ $(find "${ADDON_DIR}/${pkg}/" -maxdepth 1 -type f -name ".exclude*" -printf '--exclude-from=%p ') \ . | \ "$TAR" -x -C "$FILESYSTEM_MOD_DIR" || exit 1 [ -d "${ADDON_DIR}/${pkg}/${VARTAR_SUBDIR}" ] && \ $( "$TAR" -c -C "${ADDON_DIR}/${pkg}/${VARTAR_SUBDIR}" . | \ "$TAR" -x -C ${VARTAR_MOD_DIR} || exit 1 ) [ -r "${ADDON_DIR}/${pkg}/.language" ] && \ modlang "${ADDON_DIR}/${pkg}/.language" "${FILESYSTEM_MOD_DIR}" fi if ! grep -q "^$pkg_name$" "${VARTAR_MOD_DIR}/var/mod/etc/static.pkg" >/dev/null 2>&1; then echo "$pkg_name" >> "${VARTAR_MOD_DIR}/var/mod/etc/static.pkg" fi sizeinfo add "${ADDON_DIR}/${pkg}" done if [ "$NOCOMPILE" != "1" -a "$FREETZ_REPLACE_KERNEL" == "y" ]; then echo0 "replacing kernel" if [ ! -r "${KERNEL_REP_DIR}/kernel-${KERNEL_ID}.bin" ]; then error 1 "can't find kernel for ref ${KERNEL_ID}" fi echo1 "replacing kernel-${KERNEL_ID} (${KERNEL_SUBVERSION})" cp "${KERNEL_REP_DIR}/kernel-${KERNEL_ID}.bin" "$RAW_KERNEL_MOD" fi # modules directory / correctly configured kernel version echo1 "checking kernel version" echo2 "... used by AVM ...... ${MODULES_SUBDIR##*/}" echo2 "... used by Freetz ... ${FREETZ_KERNEL_VERSION_MODULES_SUBDIR}" if [ "lib/modules/${FREETZ_KERNEL_VERSION_MODULES_SUBDIR}" != "$MODULES_SUBDIR" ]; then if [ "$FREETZ_REPLACE_MODULE_AVAILABLE" == "y" ]; then error 1 "Freetz and AVM kernel versions do not match. Wrong kernel version configuration in Freetz?" else warn2 "Freetz and AVM kernel versions do not match. Wrong kernel version\nconfiguration in Freetz or no sources matching firmware version provided by AVM?" fi fi if [ "$FREETZ_REPLACE_KERNEL" == "y" -o -n "$(set|grep ^FREETZ_MODULE_.*=y)" ]; then [ "$FREETZ_STRIP_MODULES_FREETZ" == "y" ] && strip_output=" and stripping" echo0 "installing$strip_output modules" for i in \ $( \ cd "${KERNEL_REP_DIR}/modules-${KERNEL_ID}" && \ find . -type d -name .svn -prune -false , -type f \( -name modules.dep -o -name "*.ko" \) \ ); do bn="$(basename "$i")" ko_install="$(eval "echo \"\$FREETZ_MODULE_$(echo "${bn%\.ko}" | tr '\-+' '_x')\"")" [ "$FREETZ_MODULES_ALL" = "y" -o "$ko_install" == "y" ] || continue sizeinfo "$bn" ko_file_src="${KERNEL_REP_DIR}/modules-${KERNEL_ID}/${i}" ko_path_dst="${MODULES_DIR}/kernel/$(dirname "$i")" [ -d "$ko_path_dst" ] || mkdir -p "$ko_path_dst" cp -a $ko_file_src "$ko_path_dst/" if [ "$FREETZ_STRIP_MODULES_FREETZ" == "y" ]; then ${ABS_BASE_DIR}/toolchain/kernel/bin/${FREETZ_KERNEL_CROSS}strip -p --strip-unneeded \ --remove-section={.comment,.pdr,.mdebug.abi32,.note.gnu.build-id} "$ko_path_dst/$bn" fi sizeinfo mod "$ko_path_dst/$bn" done echo1 "generating modules.dep" DEPMOD_TEMP="$(mktemp)" NM=$NM ${TOOLS_DIR}/depmod.pl -e -b "$MODULES_DIR" \ -F ${KERNEL_REP_DIR}/System-${KERNEL_ID}.map \ 2>&1 | tee "$DEPMOD_TEMP" if grep -q "^unresolved symbol " "$DEPMOD_TEMP"; then warn "Unresolved symbols detected, not all AVM-features may work.\nNo current sources by AVM? Error in kernel's .config?" fi rm -rf "$DEPMOD_TEMP" 2>/dev/null # add plugin kernel modules for 7270v1 if plugins are not enabled if [ "$FREETZ_TYPE_7270_V1" == "y" -a "$FREETZ_AVMPLUGINS_INTEGRATE" != "y" ]; then echo "kernel/drivers/net/rfcntl/rfcntl.ko: kernel/drivers/char/audio/avm_audio.ko" >> $MODULES_DIR/modules.dep echo "kernel/drivers/char/audio/avm_audio.ko:" >> $MODULES_DIR/modules.dep fi fi for f in modules.dep.bin modules.alias.bin modules.builtin.bin modules.symbols.bin; do if [ -e "$MODULES_DIR/$f" ]; then echo1 "removing (unused) $f" rm -f "$MODULES_DIR/$f" fi done kolinecnt="$(cat $MODULES_DIR/modules.dep | wc -l)" kofilecnt="$(find $MODULES_DIR -type f -name '*.ko' | wc -l)" echo1 "kernel modules installed: $kolinecnt entries in modules.dep and $kofilecnt .ko-files found." if [ "$FREETZ_KERNEL_VERSION_2_6_28" == "y" ]; then if [ "$FREETZ_REPLACE_KERNEL" != "y" ];then koreplacek=", try 'replace kernel'" komaxcount=50 else komaxcount=99 fi if [ $kolinecnt -gt $komaxcount -o $kofilecnt -gt $komaxcount ]; then warn0 "This kernel can only load $komaxcount modules at the same time${koreplacek}." fi fi echo1 "removing empty kernel module directories" for dir in $(find ${MODULES_DIR} -type d -empty -delete -printf "%P\n"); do echo2 $dir done invoke_fwmod_custom all # Processing some options, must be done after base package is in place if [ "$FREETZ_INSTALL_BASE" == "y" ]; then echo0 "processing mod base options" # color scheme if [ "$FREETZ_STYLE" == "grey" ]; then echo1 "setting grey style as default" ln -s colorscheme-grey.css ${FILESYSTEM_MOD_DIR}/usr/share/style/colorscheme.css else echo1 "setting colored style as default" ln -s colorscheme-colored.css ${FILESYSTEM_MOD_DIR}/usr/share/style/colorscheme.css fi # favicon if [ "$FREETZ_FAVICON_STRING" != "none" ]; then echo1 "adding favicon(s) (${FREETZ_FAVICON_STRING})" cp "${FAVICON_DIR}/${FREETZ_FAVICON_STRING}/freetz.ico" "${FILESYSTEM_MOD_DIR}/usr/share/favicon.ico" ln -s "../share/favicon.ico" "${FILESYSTEM_MOD_DIR}/usr/mww/favicon.ico" if [ -e "${FAVICON_DIR}/${FREETZ_FAVICON_STRING}/box.ico" ]; then cp "${FAVICON_DIR}/${FREETZ_FAVICON_STRING}/box.ico" "${HTML_LANG_MOD_DIR}/html/favicon.ico" ln -fs "./html/favicon.ico" "${HTML_LANG_MOD_DIR}/favicon.ico" fi fi # security level echo1 "patching security level ($FREETZ_SECURITY_LEVEL)" sed -i -e "s/sec_level=1/sec_level=$FREETZ_SECURITY_LEVEL/g" ${FILESYSTEM_MOD_DIR}/usr/lib/libmodcgi.sh # external [ ! "$EXTERNAL_ENABLED" != "y" ] && echo1 "integrated external" # FREETZMOUNT [ ! "$FREETZ_PATCH_FREETZMOUNT" != "y" ] && echo1 "integrated FREETZMOUNT" # Box-Info [ "$FREETZ_REMOVE_BOX_INFO" != "y" ] && echo1 "integrated Box-Info" # FREETZ-Info [ "$FREETZ_REMOVE_FREETZ_INFO" != "y" ] && echo1 "integrated FREETZ-Info" # .config if [ ! "$FREETZ_REMOVE_DOT_CONFIG" == "y" ]; then { grep '^[^#].*$' "$DOT_CONFIG"; grep '^#.*$' "$DOT_CONFIG.compressed"; echo "FREETZ_LIBRARY_DIR=\"${FREETZ_LIBRARY_DIR}\""; } \ | grep -v "FREETZ_FWMOD_SIGN_PRIVATE_KEY_PASSWORD" > "${FILESYSTEM_MOD_DIR}/etc/.config" echo1 "integrated .config (stripped)" fi # logo tagging if [ "$FREETZ_TAGGING_STRING" != "none" ]; then tagging() { [ $# -lt 3 ] && return local tagging_geo="$1" shift local tagging_pos="$1" shift local tagging_arg="$*" local tagging_pic="${TAGGING_DIR}/${FREETZ_TAGGING_STRING}.png" for tagging_file in $tagging_arg; do echo2 "${tagging_file}" composite -dissolve 100% -gravity $tagging_pos -geometry $tagging_geo -quality 100 $tagging_pic $tagging_file $tagging_file [ $? -ne 0 ] && error 1 "tagging failed while processing ${tagging_file#${FILESYSTEM_MOD_DIR}/}" done } echo1 "tagging avm webif (tag by ${FREETZ_TAGGING_STRING})" for d in "${HTML_MOD_DIR}" "${HTML_MOD_DIR}.nas"; do [ -d "${d}" ] || continue # lua since Fritz!OS 6.2x (small logo @left, eg 7390 06.23) tagging "+0+6" "center" $(find "${d}" -name kopfbalken_links.png) # lua before Fritz!OS 6.2x (small logo @left, eg 7270 04.88) tagging "+0+0" "center" $(find "${d}" -name kopfbalken_links.gif) # newer html (big header @top, eg 7320 05.29) tagging "-20+0" "west" $(find "${d}" -name kopfbalken.gif) # older (big header @top, eg 7141 04.76) tagging "+0+0" "west" $(find "${d}" -name fw_header980.gif) # even older (big header @top, eg 7050 04.03) tagging "+0-5" "west" $(find "${d}" -name fw_header.gif) done fi fi if [ "$FREETZ_STRIP_LIBRARIES" == "y" ]; then echo0 "shrinking shared libs" source ${TOOLS_DIR}/freetz_mklibs mklibs || error 1 "mklibs returned an error. Please see mklibs.log." fi if [ "$FREETZ_STRIP_MODULES_ALL" == "y" ]; then echo0 "stripping all kernel modules" for i in $(find ${MODULES_DIR} -name '*.ko'); do echo2 $i ${ABS_BASE_DIR}/toolchain/kernel/bin/${FREETZ_KERNEL_CROSS}strip -p --strip-unneeded \ --remove-section={.comment,.pdr,.mdebug.abi32,.note.gnu.build-id} $i done fi if [ "$FREETZ_STRIP_SCRIPTS" == "y" ]; then echo0 "stripping shell scripts" # This is (necessarily) slow because it checks *all* files for f in $(find ${FILESYSTEM_MOD_DIR} -type f); do # Syntax check. Use ash (not bash) because on target we also have ash. # This is the first step because it is faster than 'file'. $BUSYBOX ash -n "$f" 2>/dev/null && # Sometimes the ash syntax check succeeds on binaries. # So we need to check we really have a text file here. file -b --mime-type "$f" | grep -sq '^text/' && # Only strip scripts (possibly also stuff like awk or perl) with # shebang. This excludes dot-included files without shebang, but # anything else would be too unsafe. We do not want plain text # files stripped. grep -sq '#[^!]' "$f" || # continue the loop with the next file if one of the conditions above is false continue # Strip ... STRIP_SCRIPTS_SED_SCRIPT='/^[ \t]*$/d;' # blank lines # TODO: doesn't work because of multiline IFS definitions, i.e. IFS='\t\n' #STRIP_SCRIPTS_SED_SCRIPT+='s/[ \t]+$//;' # trailing white spaces STRIP_SCRIPTS_SED_SCRIPT+='/^[ \t]*#[^!].*/d;' # shell comments (not shebangs) if [ "${f: -3:3}" != ".py" ]; then STRIP_SCRIPTS_SED_SCRIPT+='s/^[ \t]*//g;' # and indentation if it's not a python script fi sed -i -r "${STRIP_SCRIPTS_SED_SCRIPT}" "$f" && echo2 "${f##${FILESYSTEM_MOD_DIR}}" done fi if [ "$FREETZ_STRIP_BINARIES" == "y" ]; then echo0 "stripping leftover unstripped binaries" for i in $(find \ "${FILESYSTEM_MOD_DIR}" $([ "${FREETZ_AVM_HAS_INNER_OUTER_FILESYSTEM}" == "y" ] && echo "${FILESYSTEM_OUTER_MOD_DIR}") \ ! \( -name '*.ko' -o -path '*/usr/www/*' -o -path '*/etc/default*' -o -path '*/lib/modules*' \) \ \( -perm /100 -o -name "*.so*" \) \ -type f \ -exec file {} '+' | sed -n 's|^\(.*\):.*MIPS.*not stripped.*|\1|p' \ ); do echo2 $i chmod u+r $i $STRIP -p --remove-section={.comment,.note,.pdr} $i done fi # External should run after modifying, stripping etc. if [ "$EXTERNAL_ENABLED" == "y" ]; then echo0 "processing external" [ ! -x "$EXTERNAL" ] && error 1 "cannot find the tool $EXTERNAL_TOOL" source "${EXTERNAL}" fi touch "${DIR}/.modified" echo -e "done.\n" fi ################################################# ## Pack, sign, zip, copy the modified firmware ## ################################################# DO_AVOID_MOD_IN_STEP3=0 [ "$DO_PACK" -gt 0 ] && action_names+="/PACK" [ "$DO_SIGN" -gt 0 ] && action_names+="/SIGN" [ "$DO_ZIP" -gt 0 ] && action_names+="/ZIP" [ "$COPY_FS_DIR" ] && action_names+="/COPY" action_names=${action_names##/} # ------------------------------------------------------ # -- Common initial actions for pack, sign, zip, copy -- # ------------------------------------------------------ if [ "$action_names" ]; then echo0 -b "STEP 3: ${action_names}" if [ ! "$DO_MOD" -gt 0 ]; then echo "WARNING: Modifications (STEP 2) and this step should never" 1>&2 echo " ever be run with different configurations!" 1>&2 echo " This can result in invalid images!!!" 1>&2 fi [ "$FW_IMAGES_DIR" ] && mkdir -p "$FW_IMAGES_DIR" # Check if firmware is unpacked if [ ! -r "$UNPACKED_FILE" ]; then error 1 "firmware image has to be unpacked before packing" fi # Check if firmware is modified by the script if [ ! -r "${DIR}/.modified" ]; then warn "firmware does not seem to be modified by the script" DO_AVOID_MOD_IN_STEP3=1 # Check if this is a completely automated run in the "no freetz"-mode if [ "$NO_FREETZ_AUTOMATED_RUN" -gt 0 ]; then # Removing (possibly already existing) MOD_DIR is necessary # as Freetz doesn't have any checks if some of the patches # are already applied and might (try to) apply them over # and over again. rm -rf "$MOD_DIR" #else # In the manual "step by step"-mode it's up to the user to invoke # the script in a proper configuration so that the patches do not # get applied multiple times. fi if [ ! -d "$MOD_DIR" ]; then # Copy the unpacked directory cp -r "$ORG_DIR" "$MOD_DIR" fi invoke_fwmod_custom all_no_freetz fi # Remove left over Subversion directories echo1 "checking for left over Subversion directories" find "$MOD_DIR" \( -type d -name '.svn' \) -o -name '.gitignore' | xargs rm -rf # Delete all files that we are going to re-create now rm -f "$VARTAR_MOD" rm -f "$KERNEL_MOD" rm -f "$FILESYSTEM_MOD" rm -f "${DIR}/*.image" rm -f "${FIRMWARE_MOD_DIR}/var/signature" modmakedate=$(date +%Y%m%d-%H%M%S) modbaseimagename="${FREETZ_TYPE_PREFIX_ALIEN_HARDWARE}${FREETZ_TYPE_PREFIX%_0?_??}" modbaseimagename+="_${AVM_FW_VERSION}" if [ -n "$FREETZ_TYPE_PREFIX_LABOR_FIRMWARE" ]; then modbaseimagename+="-rev${AVM_FW_REVISION}${FREETZ_TYPE_PREFIX_LABOR_FIRMWARE}" fi modbaseimagename+="${SUBVERSION:+-}${SUBVERSION}" # missing in DO_MOD=0 mode modbaseimagename+=".${FREETZ_TYPE_LANGUAGE}" if [ "$FREETZ_CUSTOM_IMAGE_NAME" == "y" -a ! -z "$FREETZ_USER_DEFINED_COMMENT" ]; then modcustomimagestring=$(echo $FREETZ_USER_DEFINED_COMMENT | sed -e "s/ /_/g" | tr -cd 'a-zA-Z0-9_+-.<->') else modcustomimagestring="" fi if [ "$FREETZ_CUSTOM_IMAGE_NAME" == "y" -a ! -z "${modcustomimagestring}" ]; then if [ "$FREETZ_CUSTOM_IMAGE_NAME_PREFIX" == "y" ]; then modimagenameprefix="${modcustomimagestring}_" modimagenamesuffix="" else modimagenameprefix="" modimagenamesuffix="_${modcustomimagestring}" fi else modimagenameprefix="" modimagenamesuffix="" fi modstring="${modimagenameprefix}${modbaseimagename}${modimagenamesuffix}_${modmakedate}" modimage="${modstring}.image" # collect externalized files externalised_files=$(find "$EXTERNAL_MOD_DIR/" -type f 2>/dev/null | sed -e "/external[.]pkg/d;/[.]external/d;s,$EXTERNAL_MOD_DIR/,,") if [ ! "$DO_AVOID_MOD_IN_STEP3" -gt 0 ]; then # Create freetz-info echo1 "integrate freetz info file into image" freetz_info_file="$MOD_DIR/filesystem/etc/freetz_info.cfg" echo "export FREETZ_INFO_BOXTYPE='${FREETZ_TYPE_PREFIX_ALIEN_HARDWARE}${FREETZ_TYPE_PREFIX%_0?_??}${FREETZ_TYPE_PREFIX_LABOR_FIRMWARE}'" > "$freetz_info_file" echo "export FREETZ_INFO_FIRMWAREVERSION='${AVM_FW_VERSION}'" >> "$freetz_info_file" echo "export FREETZ_INFO_SUBVERSION='${SUBVERSION}'" >> "$freetz_info_file" echo "export FREETZ_INFO_LANG='${FREETZ_TYPE_LANGUAGE}'" >> "$freetz_info_file" echo "export FREETZ_INFO_MAKEDATE='${modmakedate}'" >> "$freetz_info_file" echo "export FREETZ_INFO_IMAGE_NAME='$modimage'" >> "$freetz_info_file" echo "export FREETZ_INFO_COMMENT='${FREETZ_USER_DEFINED_COMMENT}'" >> "$freetz_info_file" echo "export FREETZ_INFO_EXTERNAL_FILES='${externalised_files}'" >> "$freetz_info_file" fi # Pack var.tar (use old tar for compatibility) echo0 "packing var.tar" "$TAR" -C "$VARTAR_MOD_DIR" -cf "$VARTAR_MOD" . if [ $? -ne 0 ] || ! is_valid_tarball "$VARTAR_MOD"; then mv "${VARTAR_MOD}" "${VARTAR_MOD}.corrupted" 2>/dev/null error 1 "packing of var.tar failed" fi [ "$FREETZ_AVM_HAS_UDEV" == "y" ] || \ $MAKEDEVS -d $MAKEDEVS_FILE $FILESYSTEM_MOD_DIR > $MOD_DIR/filesystem.log 2>&1 fi if [ "$DO_SIGN" -gt 0 ]; then FREETZ_IMAGE_SIGNING_PREFIX="${HOME}/.freetz.image_signing" function getNumberOfImageSigningFiles() { local ret=0 for i in asc key pem; do [ -e "${FREETZ_IMAGE_SIGNING_PREFIX}.$i" ] && ret=$((ret+1)) done echo $ret } NO_IMAGE_SIGNING_FILES=$(getNumberOfImageSigningFiles) if [ "${NO_IMAGE_SIGNING_FILES}" -eq 0 ]; then echo0 "No image signing files found, generating them ..." if [ -z "${FREETZ_FWMOD_SIGN_PRIVATE_KEY_PASSWORD}" ]; then # be verbose if no private key password provided "${TOOLS_DIR}/yf/signimage/generate_signing_key" "${FREETZ_FWMOD_SIGN_PRIVATE_KEY_PASSWORD}" else "${TOOLS_DIR}/yf/signimage/generate_signing_key" "${FREETZ_FWMOD_SIGN_PRIVATE_KEY_PASSWORD}" 2>"${MOD_DIR}/generate_signing_key.log" fi if [ $? -ne 0 ]; then error 1 "failed to generate image signing files, see console output or ${MOD_DIR}/generate_signing_key.log for details" fi NO_IMAGE_SIGNING_FILES=$(getNumberOfImageSigningFiles) else echo0 "Image signing files found, checking their consistency" fi if [ "${NO_IMAGE_SIGNING_FILES}" -ne 3 ]; then error 1 "Unexpected/wrong number of image signing files" fi echo0 "Copying ${FREETZ_IMAGE_SIGNING_PREFIX}.asc to /etc/avm_firmware_public_key9" cp -a "${FREETZ_IMAGE_SIGNING_PREFIX}.asc" "${FILESYSTEM_MOD_DIR}/etc/avm_firmware_public_key9" fi # ------------------------------------------------------------------ # -- Zip file system to tar.gz archive (USB root, maybe NFS root) -- # ------------------------------------------------------------------ if [ "$DO_ZIP" -gt 0 ]; then if [ "$FW_IMAGES_DIR" ]; then zip_name="${FW_IMAGES_DIR}/${modstring}_rootfs.tar.gz" else zip_name="${DIR}/${modstring}_rootfs.tar.gz" fi echo0 "zipping root file system to $zip_name" "$TAR" -C "$FILESYSTEM_MOD_DIR" -czf "$zip_name" . if [ $? -ne 0 ] || ! is_valid_tarball "$zip_name"; then mv "${zip_name}" "${zip_name}.corrupted" 2>/dev/null error 1 "zipping of root file system failed" fi echo "$zip_name" > "${DIR}/.rootfs_archive" fi # ------------------------- # -- Pack firmware image -- # ------------------------- if [ "$DO_PACK" -gt 0 ]; then [ ! -x "$MKSQUASHFS" ] && error 1 "cannot find $MKSQUASHFS" echo0 "creating ${INNER_FS_PREFIX}filesystem image (SquashFS${FREETZ_SQUASHFS_VERSION}-${FREETZ_AVM_SQUASHFS_COMPRESSION})" echo1 "SquashFS block size: $(($FREETZ_SQUASHFS_BLOCKSIZE/1024)) kB ($FREETZ_SQUASHFS_BLOCKSIZE bytes)" rm -f $ABS_BASE_DIR/${MAIN_FILESYSTEM_MOD} "$MKSQUASHFS" $FILESYSTEM_MOD_DIR/* $ABS_BASE_DIR/${MAIN_FILESYSTEM_MOD} $MKSQUASHFS_OPTIONS >> $MOD_DIR/filesystem.log 2>&1 if [ "${FREETZ_AVM_HAS_SEPARATE_FILESYSTEM_IMAGE}" == "y" ]; then echo0 "copying kernel image" cp -a "$RAW_KERNEL_MOD" "$KERNEL_MOD" else [ ! -s "$RAW_FILESYSTEM_MOD" ] && error 1 "creation of filesystem failed" touch "$FILESYSTEM_MOD" echo0 "merging kernel image" dd if="$RAW_KERNEL_MOD" of="$KERNEL_MOD" bs=256 conv=sync 2> /dev/null cat "$RAW_FILESYSTEM_MOD" >> "$KERNEL_MOD" [ ! -s "$KERNEL_MOD" ] && error 1 "kernel merging failed" fi # Check size of kernel image (multiple of 64 kB blocks) if [ -n "$FREETZ_KERNEL_CUSTOM_MTD_SIZE" ]; then let KERNEL_LIMIT="$FREETZ_KERNEL_CUSTOM_MTD_SIZE*64*1024" else KERNEL_LIMIT="$(sed -nr 's/^kernel_size=(.*)/\1/p' ${FIRMWARE_DIR}/var/install)" [ -z "$KERNEL_LIMIT" ] && error 1 "Can't find kernel_size in var/install" fi let KERNEL_SIZE="$(wc -c < "$KERNEL_MOD")" let KERNEL_DIFF="KERNEL_SIZE-KERNEL_LIMIT" echo1 "kernel image size: $(byte_to_mb $KERNEL_SIZE), max $(byte_to_mb $KERNEL_LIMIT), free $(byte_to_mb $((-KERNEL_DIFF))) ($((-KERNEL_DIFF)) bytes)" [ "$KERNEL_SIZE" -eq 0 ] && error 1 "kernel image is empty" if [ "$KERNEL_SIZE" -gt "$KERNEL_LIMIT" ]; then if [ "${FREETZ_AVM_HAS_SEPARATE_FILESYSTEM_IMAGE}" == "y" ]; then error 1 -b "kernel image is $KERNEL_DIFF bytes too big. See http://freetz.org/wiki/FAQ#Filesystemimagetoobig for details." else if [ "$FORCE_PACK" -eq 0 -a "$DO_ZIP" -eq 0 ]; then error 1 -b "combined kernel+filesystem image is $KERNEL_DIFF bytes too big. See http://freetz.org/wiki/FAQ#Filesystemimagetoobig for details." fi if [ "$FORCE_PACK" -gt 0 -a "$DO_ZIP" -eq 0 ]; then echo0 -b "Use for SDK mode only. See http://wehavemorefun.de/fritzbox/index.php/SDK-Firmware" fi if [ "$FORCE_PACK" -eq 0 -a "$DO_ZIP" -gt 0 ]; then echo0 -b "Use for USBroot or NFSroot mode only." fi fi fi # --------------------------- # -- Pack filesystem image -- # --------------------------- if [ "${FREETZ_AVM_HAS_SEPARATE_FILESYSTEM_IMAGE}" == "y" ]; then if [ "${FREETZ_AVM_HAS_INNER_OUTER_FILESYSTEM}" == "y" ]; then if [ "${FREETZ_AVM_OUTER_FILESYSTEM_TYPE}" == "Ext2FS" ]; then echo0 "creating outer-filesystem image (Ext2FS)" PATH="$TOOLS_DIR:$PATH" $TOOLS_DIR/mke2img -G 2 -R 0 -d "${FILESYSTEM_OUTER_MOD_DIR}" -o "$ABS_BASE_DIR/$RAW_FILESYSTEM_MOD.ext2" >> $MOD_DIR/filesystem.log 2>&1 [ $? -ne 0 -o ! -s "$RAW_FILESYSTEM_MOD.ext2" ] && error 1 "creation of ext2 image failed" { # create pseudo SquashFS-header: "sqsh" followed by 252 zeros echo -n "sqsh" > "$RAW_FILESYSTEM_MOD" && \ dd if=/dev/zero of="$RAW_FILESYSTEM_MOD" bs=1 count=252 oflag=append conv=notrunc } >> $MOD_DIR/filesystem.log 2>&1 && \ cat "$RAW_FILESYSTEM_MOD.ext2" >> "$RAW_FILESYSTEM_MOD" && \ rm -f "$RAW_FILESYSTEM_MOD.ext2" elif [ "${FREETZ_AVM_OUTER_FILESYSTEM_TYPE}" == "SquashFS" ]; then echo0 "creating outer-filesystem image (SquashFS${FREETZ_SQUASHFS_VERSION}-${FREETZ_AVM_SQUASHFS_COMPRESSION})" "$MKSQUASHFS" ${FILESYSTEM_OUTER_MOD_DIR}/* $ABS_BASE_DIR/$RAW_FILESYSTEM_MOD $MKSQUASHFS_OPTIONS >> $MOD_DIR/filesystem.log 2>&1 else error 1 "unknown/unsupported outer-filesystem type \"${FREETZ_AVM_OUTER_FILESYSTEM_TYPE}\"" fi fi [ ! -s "$RAW_FILESYSTEM_MOD" ] && error 1 "creation of filesystem failed" let FILESYSTEM_SIZE="$(wc -c < "$RAW_FILESYSTEM_MOD")" [ "$FILESYSTEM_SIZE" -eq 0 ] && error 1 "filesystem image is empty" echo0 "copying filesystem image" rm -f "$FILESYSTEM_MOD" "$FILESYSTEM_MOD.ext2" cp -a "$RAW_FILESYSTEM_MOD" "$FILESYSTEM_MOD" # Check size of filesystem image (multiple of 64 kB blocks) if [ -n "$FREETZ_FILESYSTEM_CUSTOM_MTD_SIZE" ]; then let FILESYSTEM_LIMIT="$FREETZ_FILESYSTEM_CUSTOM_MTD_SIZE*64*1024" else FILESYSTEM_LIMIT="$(sed -nr 's/^filesystem_size=(.*)/\1/p' ${FIRMWARE_DIR}/var/install)" [ -z "$FILESYSTEM_LIMIT" ] && error 1 "Can't find filesystem_size in var/install" fi let FILESYSTEM_SIZE="$(wc -c < "$FILESYSTEM_MOD")" let FILESYSTEM_DIFF="FILESYSTEM_SIZE-FILESYSTEM_LIMIT" echo1 "filesystem image size: $(byte_to_mb $FILESYSTEM_SIZE), max $(byte_to_mb $FILESYSTEM_LIMIT), free $(byte_to_mb $((-FILESYSTEM_DIFF))) ($((-FILESYSTEM_DIFF)) bytes)" [ "$FILESYSTEM_SIZE" -eq 0 ] && error 1 "filesystem image is empty" if [ "$FILESYSTEM_SIZE" -gt "$FILESYSTEM_LIMIT" ]; then if [ "$FORCE_PACK" -eq 0 -a "$DO_ZIP" -eq 0 ]; then error 1 -b "filesystem image is $FILESYSTEM_DIFF bytes too big. See http://freetz.org/wiki/FAQ#Filesystemimagetoobig for details." fi if [ "$FORCE_PACK" -ne 0 -o "$DO_ZIP" -ne 0 ]; then echo0 -b "Use for USBroot or NFSroot mode only." fi fi fi if [ "$FREETZ_VERBOSITY_LEVEL" -ge 1 ]; then if [ "$FREETZ_AVM_HAS_TAM" = "y" -a "${FREETZ_AVM_HAS_SEPARATE_FILESYSTEM_IMAGE}" != "y" ]; then # Calculate aproximately free space in seconds for the answering machine # 5*64kB sectors needed, see http://freetz.org/ticket/1680#comment:4 FREE_BYTE_JFFS2=$((($KERNEL_LIMIT - $KERNEL_SIZE - 327680))) FREE_MINUTES=$((($FREE_BYTE_JFFS2 / 2017 / 60))) if [ "$FREE_BYTE_JFFS2" -gt 0 ]; then echo "${L1}Aproximately maximal time for the answering machine: ${FREE_MINUTES} min, $((($FREE_BYTE_JFFS2 / 2017 - $FREE_MINUTES * 60))) sec ($((($FREE_BYTE_JFFS2 / 2017))) sec)" else if [ "$FREETZ_REMOVE_JFFS2" != "y" ]; then echo "${L1}WARNING: Not enough free flash space for answering machine!" else echo "${L1}Telephone answering machine will need a usb storage device!" fi fi fi fi # Create in-memory image img_name="${FW_IMAGES_DIR:-$DIR}/${modimage}" if [ "${FREETZ_FWMOD_CREATE_IN_MEMORY_IMAGE}" == "y" ]; then echo0 "creating in-memory image ${img_name}.in-memory" { cat "$KERNEL_MOD" | dd bs=256 conv=sync 2>/dev/null; cat "$FILESYSTEM_MOD" | dd bs=256 conv=sync 2>/dev/null; } > "${img_name}.in-memory" fi # Write checksum for f in "$KERNEL_MOD" "$FILESYSTEM_MOD"; do [ -s "$f" ] || continue fbn=$(basename $f) echo0 "adding checksum to $fbn" "$TICHKSUM" -a "$f" > "${MOD_DIR}/$fbn-chksum.log" || { rm -f "${img_name}.in-memory"; error 1 "adding checksum to $fbn failed"; } done # Consistency check if [ -s "${FIRMWARE_DIR}/${KERNEL_IMAGE}" -a ! -s "${FIRMWARE_MOD_DIR}/${KERNEL_IMAGE}" ] || \ [ ! -s "${FIRMWARE_DIR}/${KERNEL_IMAGE}" -a -s "${FIRMWARE_MOD_DIR}/${KERNEL_IMAGE}" ]; then error 1 "inconsistency comparing size of old and new kernel.image" fi if [ ! "$DO_AVOID_MOD_IN_STEP3" -gt 0 ]; then # Last, but not least, include .config and addon/static.pkg into firmware # image for further reference, e.g. user support [ -r "$DOT_CONFIG" ] && { cat "$DOT_CONFIG" | grep -v "FREETZ_FWMOD_SIGN_PRIVATE_KEY_PASSWORD" > "$FIRMWARE_MOD_DIR/var/.config"; } [ -r "$PACKAGES_LIST_FILE" ] && cp "$PACKAGES_LIST_FILE" "$FIRMWARE_MOD_DIR/var" fi # Pack firmware image # use GNU tar with --format=gnu for compatibility TAR_FOR_IMAGE_TARBALL="$TAR_GNU" TAR_FOR_IMAGE_TARBALL_FORMAT_OPT="--format=gnu" echo0 "packing ${img_name}" "${TAR_FOR_IMAGE_TARBALL}" ${TAR_FOR_IMAGE_TARBALL_FORMAT_OPT} -C "$FIRMWARE_MOD_DIR" -cf "${img_name}.unsigned" ./var if [ $? -ne 0 ] || ! is_valid_tarball "${img_name}.unsigned"; then mv "${img_name}.unsigned" "${img_name}.unsigned.corrupted" 2>/dev/null error 1 "packing of firmware image failed" fi echo1 "unsigned image file size: $(byte_to_mb $(wc -c < "${img_name}.unsigned")) ($(wc -c < "${img_name}.unsigned") bytes)" if [ "$DO_SIGN" -gt 0 ]; then echo0 "signing ${img_name}" if [ -z "${FREETZ_FWMOD_SIGN_PRIVATE_KEY_PASSWORD}" ]; then # be verbose if no private key password provided YF_SIGNIMAGE_TAR="${TAR_FOR_IMAGE_TARBALL}" \ YF_SIGNIMAGE_9K_WORKAROUND_METHOD="${FREETZ_SIGNIMAGE_9K_WORKAROUND_METHOD}" \ "${TOOLS_DIR}/yf/signimage/sign_image" "${img_name}.unsigned" "${FREETZ_FWMOD_SIGN_PRIVATE_KEY_PASSWORD}" > "${img_name}.signed" else YF_SIGNIMAGE_TAR="${TAR_FOR_IMAGE_TARBALL}" \ YF_SIGNIMAGE_9K_WORKAROUND_METHOD="${FREETZ_SIGNIMAGE_9K_WORKAROUND_METHOD}" \ "${TOOLS_DIR}/yf/signimage/sign_image" "${img_name}.unsigned" "${FREETZ_FWMOD_SIGN_PRIVATE_KEY_PASSWORD}" 2>"${MOD_DIR}/sign_image.log" > "${img_name}.signed" fi if [ $? -ne 0 ] || ! is_valid_tarball "${img_name}.signed"; then mv "${img_name}.signed" "${img_name}.signed.corrupted" 2>/dev/null error 1 "signing of firmware image failed, see console output or ${MOD_DIR}/sign_image.log for details" fi echo1 "signed image file size: $(byte_to_mb $(wc -c < "${img_name}.signed")) ($(wc -c < "${img_name}.signed") bytes)" fi [ "$DO_SIGN" -gt 0 ] && final_img_suffix=signed || final_img_suffix=unsigned echo0 "using ${final_img_suffix} image as the final one" cp -a "${img_name}.${final_img_suffix}" "${img_name}" # delete temporary unsigned/signed files unless we're debugging [ "$DEBUG" != "1" ] && rm -f "${img_name}.unsigned" "${img_name}.signed" fi # ---------------------------------------------- # -- Common final actions for pack, zip, copy -- # ---------------------------------------------- if [ "$action_names" ]; then # Pack externalised files if [ "$EXTERNAL_CREATEPAK" == "y" -a -n "$externalised_files" ]; then tplexternal="${modimagenameprefix}${modbaseimagename}${modimagenamesuffix}_${modmakedate}" #static packages modexternal="${FW_IMAGES_DIR:-$DIR}/${tplexternal}.external" echo "packing ${modexternal}" "$TAR" -C "$EXTERNAL_MOD_DIR" -cf "$modexternal" . if [ $? -ne 0 ] || ! is_valid_tarball "$modexternal"; then mv "${modexternal}" "${modexternal}.corrupted" 2>/dev/null error 1 "packing of external tar failed" fi echo1 "external file size: $(byte_to_mb $(wc -c < "$modexternal"))" #dynamic packages if [ "$EXTERNAL_CREATEPAK_DYNAMIC" == "y" ]; then shopt -s nullglob for pkg in ${EXTERNAL_MOD_DIR}-*; do pkg=${pkg#${EXTERNAL_MOD_DIR}-} pkgexternal="${FW_IMAGES_DIR:-$DIR}/${tplexternal}_${pkg}.external" echo "packing ${pkgexternal}" "$TAR" -C "$EXTERNAL_MOD_DIR-${pkg}" -cf "$pkgexternal" . if [ $? -ne 0 ] || ! is_valid_tarball "$pkgexternal"; then mv "${pkgexternal}" "${pkgexternal}.corrupted" 2>/dev/null error 1 "packing of external-$pkg tar failed" fi echo1 "package file size: $(byte_to_mb $(wc -c < "$pkgexternal"))" done shopt -u nullglob fi fi if [ "$FREETZ_REPLACE_OPENSSL" == "y" ] && [ "$FREETZ_LIB_libcrypto" == "y" -o "$FREETZ_LIB_libssl" == "y" ]; then echo "Caution: Replacing libcrypto or libssl may cause an unusable image." echo "See http://freetz.org/wiki/FAQ#NachdemFlashenistdasAVM-Webinterfacenichtmehrerreichbar for details." fi [ "$COPY_FS_DIR" ] || echo -e "done.\n" fi [ "$COPY_FS_DIR" ] || echo0 -b "FINISHED" exit 0