Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
tag: 0.2
Fetching contributors…

Cannot retrieve contributors at this time

235 lines (179 sloc) 6.033 kB
#!/bin/bash
#
# geninit.api
#
# This file is part of geninit.
#
# declares intended public API calls for builders to use. These functions
# should be used over other functions in geninit such as __add_file, which have
# no awareness of things such as $basedir or $kernver.
#
add_dir() { # {{{
# add a directory (with parents)
# $1: absolute path on initcpio
# $2: mode (optional, defaults to 755)
(( ! $# )) && return 1 # NOOP
local path=$1 mode=${2:-755}
__add_dir "$path" "$mode"
} # }}}
add_file() { # {{{
# add a regular file. no parsing done.
# $1: source on disk
# $2: destination on initcpio (optional: assumes same as source)
(( $# )) || return 1 # NOOP
# determine source and destination
local src= dest=${2:-$1} mode=
if [[ "${1:0:1}" == @ ]]; then # assert an absolute path
src=${1:1}
else
src=$basedir$1
fi
[[ -f "$src" ]] || { error "$src: No such file"; return 1; }
mode=$(stat -c %a "$src")
if [[ -z "$mode" ]]; then
error "failed to stat file: \`$src'"
return 1
fi
__add_file "${dest#$basedir}" "$src" "$mode"
} # }}}
add_symlink() { # {{{
# add a symlink
# $1: target of $2
# $2: name on initcpio
(( $# == 2 )) || return 1
add_path_to_file "$1"
__add_slink "$2" "$1"
} # }}}
add_path_to_file() { # {{{
# add the path leading up to a file
# $1: filename with full path
(( $# )) || return 1
add_dir "${1%/*}"
} # }}}
add_module() { # {{{
# add a kernel module with dependencies
# $1: kernel module by name (no path, with or without extension)
(( $# )) || return 1
local -a firmware moddeps
local modpath= module= mod= dep=
module=${1%.ko?(.gz)}
if [[ -z "$basedir" ]]; then # fast path =)
read -rd '' modpath < <(__kmodinfo -n "$module" 2>/dev/null)
else # slow path =(
read -rd '' modpath < <(find "$basedir$moduledir/kernel" -type f \
-name "$module.ko" -o -name "$module.ko.gz" -print0)
fi
[[ -z "$modpath" ]] && return 1
__add_file "${modpath#$basedir}" "$modpath" 644 || return 1
# grab firmware
IFS=',' read -rd '' -a firmware < <(__kmodinfo -F firmware "$modpath")
for fw in "${firmware[@]}"; do
if [[ -e $basedir/lib/firmware/$fw ]]; then
__add_file "/lib/firmware/$fw" "$basedir/lib/firmware/$fw" 644
fi
done
# resolve deps
IFS=',' read -rd '' -a moddeps < <(__kmodinfo -F depends "$modpath")
for dep in "${moddeps[@]}"; do
add_module "$dep"
done
# add in any quirks
for mod in ${modquirks[$module]}; do
add_module "$mod"
done
return 0
} # }}}
add_binary() { # {{{
# add a binary file with .so depends
# $1: path to binary
# $2: destination on initcpio (optional: assumes same as source)
(( $# )) || return 1
local -a sodeps
local regex= binary= dest= mode= sodep= resolved= dirname=
if [[ "${1:0:1}" == @ ]]; then # assert an absolute path
binary=${1:1}
else
binary=$basedir$1
fi
[[ -f "$binary" ]] || { error "$binary not found"; return 1; }
dest=${2:-$binary}
mode=$(stat -c %a "$binary")
if ! "$ld_so" --verify "$binary" &>/dev/null; then
# this isn't a binary!
__add_file "${binary#$basedir}" "$binary" "$mode"
return $? # return with __add_file's return val
fi
# the binary itself
__add_file "${dest#$basedir}" "${binary#$basedir}" 755 || return 1
# resolve sodeps
regex='^[[:space:]]*[^/].+ => (.*) \(.*\)'
while read line; do
[[ "$line" =~ $regex ]] && sodep="${BASH_REMATCH[1]}" || continue
if [[ -f "$sodep" ]]; then # -f follows symlinks, don't believe it!
if [[ ! -L $sodep ]]; then
__add_file "$sodep" "$basedir$sodep" "$(stat -c %a "$sodep")"
else
resolved=$(readlink -e "$basedir$sodep")
dirname=${resolved%/*}
__add_dir "${dirname#$basedir}" 755
__add_slink "$sodep" "${resolved#$basedir}"
__add_file "${resolved#$basedir}" "$resolved" 755
fi
fi
done < <(__ldd "$binary")
} # }}}
add_pipe() { # {{{
# add a fifo
# $1: path of pipe
# $2: mode (optional, defaults to 644)
(( $# )) || return 1
add_path_to_file "$1"
__add_pipe "$1" "${2:-644}"
} # }}}
use_hookscript() { # {{{
# specifies that a builder should install a hookscript
# "$builder" comes from the builder parsing loop in main
# $1: script name (optional, defaults to the name of the builder)
local script=${1:-$builder}
if [[ ! -f $basedir$_sharedir/hooks/$script ]]; then
error "unable to find hook script: $script"
return 1
fi
__add_file "/hooks/$script" "$basedir$_sharedir/hooks/$script" 755
} # }}}
add_checked_modules() { # {{{
# add a class of modules, as a dir relative to /lib/modules/$kernver/kernel.
# if you need to block addition of modules, you can add glob patterns to the
# 'MODFILTER' array within your builder. They must be quoted and the
# filter is cleared after parsing of each builder.
# $@: directories
local -a mods
local -i ret=0
local mod=
# find modules by class (e.g. drivers/ata)
pushd "$basedir$moduledir/kernel" &>/dev/null
while read -rd '' mod; do
mod=${mod##*/}
mods+=("${mod%.ko?(.gz)}")
done < <(find "$@" -type f \( -name '*.ko' -o -name '*.ko.gz' \) -print0 2>/dev/null)
popd &>/dev/null
# only add what autodetect found if we have a module cache
[[ -s "$autodetect_cache" && -z "$NOAUTO" ]] &&
IFS=$'\n' read -rd '' -a mods < <(grep -xFf <(printf '%s\n' "${mods[@]//-/_}") "$autodetect_cache")
for mod in "${mods[@]}"; do
# check for filter match
for filter in "${MODFILTER[@]}"; do
[[ "$mod" == $filter ]] && continue 2
done
add_module "$mod" && (( ++ret ))
done
# return 0 on modules added, else 1
return $(( ! ret ))
} # }}}
add_all_modules() { # {{{
# add a class of modules, as a dir relative to /lib/modules/$kernver/kernel.
# this function honors 'MODFILTER', but does not check against the autodetected
# cache of modules.
NOAUTO=1 add_checked_modules "$@"
} # }}}
# vim: set et sw=2 ft=sh:
Jump to Line
Something went wrong with that request. Please try again.