#!/bin/bash # Magellan Linux Installer Functions (mage.functions.sh) # $Header: /home/cvsd/magellan-cvs/magellan-src/mage/usr/lib/mage/mage4.functions.sh,v 1.38 2008-10-05 10:32:24 niro Exp $ COLRED="\033[1;6m\033[31m" COLGREEN="\033[1;6m\033[32m" COLYELLOW="\033[1;6m\033[33m" COLBLUE="\033[1;6m\033[34m" COLMAGENTA="\033[1;6m\033[35m" COLWHITE="\033[1;6m\033[37m" COLGRAY="\033[0;6m\033[37m" COLBOLD="\033[1m" COLDEFAULT="\033[0m" if [[ ${NOCOLORS} = true ]] then COLRED="" COLGREEN="" COLYELLOW="" COLBLUE="" COLMAGENTA="" COLWHITE="" COLGRAY="" COLBOLD="" COLDEFAULT="" fi mage_setup() { [ ! -d ${MROOT}${INSTALLDB} ] && \ install -d ${MROOT}${INSTALLDB} [ ! -f ${MROOT}${VIRTUALDB_FILE} ] && \ touch ${MROOT}${VIRTUALDB_FILE} [ ! -d ${PKGDIR} ] && install -d ${PKGDIR} [ ! -d ${BUILDDIR} ] && install -d ${BUILDDIR} [ ! -d ${MAGEDIR} ] && install -d ${MAGEDIR} return 0 } mchecksum() { local i local rundir local file local method local cmd local retval # very basic getops for i in $* do case $1 in --rundir|-r) shift; rundir="$1" ;; --file|-f) shift; file="$1" ;; --method|-m) shift; method="$1" ;; esac shift done # sanity checks [[ -z ${rundir} ]] && die "mchecksum(): rundir missing" [[ -z ${file} ]] && die "mchecksum(): file missing" [[ -z ${method} ]] && die "mchecksum(): method missing" case ${method} in md5) cmd="md5sum" ;; sha256) cmd="sha256sum" ;; *) die "mchecksum(): unknown method '${method}'" ;; esac if [[ -d ${rundir} ]] then pushd ${rundir} &> /dev/null # be verbose here ${cmd} -c ${file} #&> /dev/null retval="$?" popd &> /dev/null else retval=1 fi return "${retval}" } mcheckemptydir() { local dir="$1" local retval=1 if [[ ! -d ${dir} ]] then echo "mcheckemptydir(): '${dir}' is not a directory!" retval=3 else shopt -s nullglob dotglob files=( ${dir}/* ) (( ${#files[*]} )) || retval=0 shopt -u nullglob dotglob fi return ${retval} } unpack_packages() { local list="$@" local magefile local pkg local pkgtype local count_current local count_total local tar_opts # get count of total packages declare -i count_current=0 declare -i count_total=0 for i in ${list}; do (( count_total++ )); done for magefile in ${list} do pkg="$(get_value_from_magefile PKGNAME ${magefile}).${PKGSUFFIX}" pkgtype="$(get_value_from_magefile PKGTYPE ${magefile})" (( count_current++ )) xtitle "[ (${count_current}/${count_total}) Unpacking ${pkg} ]" # abort on virtual pkg if [[ ${pkgtype} = virtual ]] then echo -ne " ${COLBLUE}---${COLDEFAULT}" echo " !unpack virtual (${count_current}/${count_total}): ${pkg/.${PKGSUFFIX}/} ... " continue fi # abort on sources pkg if [[ ${pkgtype} = sources ]] then echo -ne " ${COLBLUE}---${COLDEFAULT}" echo " !unpack sources (${count_current}/${count_total}): ${pkg/.${PKGSUFFIX}/} ... " continue fi # busybox? if need_busybox_support tar then tar_opts="xjf" else tar_opts="xjmf" fi echo -e " ${COLBLUE}***${COLDEFAULT} unpacking (${count_current}/${count_total}): ${pkg} ... " tar ${tar_opts} ${PKGDIR}/${pkg} -C ${BUILDDIR} || die "Unpacking package ${pkg}" done # add a crlf for a better view if [ ${count_total} -gt 1 ]; then echo; fi } # fix_mtime path/to/$mtime/reffile $pathto/file # creates a given reference file and fixes given file # returns new mtime fix_mtime() { local reference="$1" local pathto="$2" local mtime mtime=$(stat -c %Y "${reference}") touch \ --no-create \ --time=mtime \ --reference "${reference}" \ "${pathto}" echo "${mtime}" } # fix_descriptor pkgname/.dir "foo1" "foo2" fix_descriptor() { local descriptor="$1" local output local i shift for i in $@ do if [[ -z ${output} ]] then output="${i}" else output="${output}§${i}" fi done echo "${output}" >> ${BUILDDIR}/${descriptor}_fixed } ################################################### # function install_direcories # # install_direcories $PKGNAME # ################################################### install_directories() { local pkgname="$1" local pathto local posix local user local group local IFS # sanity checks; abort if not given [ -z "${pkgname}" ] && die "install_directories() \$pkgname not given." # check needed global vars [ -z "${BUILDDIR}" ] && die "install_directories() \$BUILDDIR not set." [ ! -f ${BUILDDIR}/${pkgname}/.dirs ] && die "install_directories() .dirs not found" # sets fieldseperator to "§" instead of " " IFS=§ while read pathto posix user group do [ -z "${pathto}" ] && continue mqueryfeature "verbose" && echo -e "\t>>> DIR: ${MROOT}${pathto}" # monitors /etc/env.d -> env-rebuild [[ ${pathto} = /etc/env.d ]] && export MAGE_ENV_REBUILD=true # monitors /usr/share/info -> info-rebuild [[ ${pathto} = /usr/share/info ]] && export MAGE_INFO_REBUILD=true install -m "${posix}" -o "${user}" -g "${group}" -d "${MROOT}${pathto}" done < ${BUILDDIR}/${pkgname}/.dirs # very important: unsetting the '§' fieldseperator IFS=$'\n' } ################################################### # function install_files # # install_files $PKGNAME # ################################################### install_files() { local pkgname="$1" local pathto local posix local user local group local mtime local md5sum local retval local counter local filename local dest_dirname local dest_protected local IFS # sanity checks; abort if not given [ -z "${pkgname}" ] && die "install_files() \$pkgname not given." # check needed global vars [ -z "${BUILDDIR}" ] && die "install_files() \$BUILDDIR not set." [ ! -f ${BUILDDIR}/${pkgname}/.files ] && die "install_files() .files not found" # delete old files [ -f ${BUILDDIR}/${pkgname}/.files_fixed ] && rm ${BUILDDIR}/${pkgname}/.files_fixed # sets fieldseperator to "§" instead of " " IFS=§ while read pathto posix user group mtime md5sum do [ -z "${pathto}" ] && continue # final destination dir of file ${pathto} dest_dirname="$(dirname "${MROOT}${pathto}")" ### small hotfix fix ### [ ! -d "${dest_dirname}" ] && install -d "${dest_dirname}" # check if the file is config_protected # ${MROOT} will automatically added if set !! is_config_protected "${pathto}" retval="$?" # 0 - not protected # # 1 - error # # 2 - protected # # 3 - protected but masked # # 4 - protected but ignored # case ${retval} in # file is not protected - (over)write it 0|3) mqueryfeature "verbose" && echo -e "\t>>> FILE: ${MROOT}${pathto}" install -m "${posix}" -o "${user}" -g "${group}" \ ${BUILDDIR}/${pkgname}/binfiles/"${pathto}" \ "${MROOT}${pathto}" # fix mtime and db fix_descriptor ${pkgname}/.files \ "${pathto}" \ "${posix}" \ "${user}" \ "${group}" \ "$(fix_mtime "${BUILDDIR}/${pkgname}"/.mtime \ "${MROOT}${pathto}")" \ "${md5sum}" ;; # file is protected, write backup file 2) if mqueryfeature "verbose" then echo -en "${COLRED}" echo -n "! prot " echo -en "${COLDEFAULT}" echo " === FILE: ${MROOT}${pathto}" fi filename="$(basename "${pathto}")" counter=$(count_protected_files "${pathto}") dest_protected="${dest_dirname}/._cfg${counter}_${filename}" install -m "${posix}" -o "${user}" -g "${group}" \ ${BUILDDIR}/${pkgname}/binfiles/"${pathto}" \ "${dest_protected}" # fix mtime and db fix_descriptor ${pkgname}/.files \ "${pathto}" \ "${posix}" \ "${user}" \ "${group}" \ "$(fix_mtime "${BUILDDIR}/${pkgname}"/.mtime \ "${dest_protected}")" \ "${md5sum}" # update global MAGE_PROTECT_COUNTER (( MAGE_PROTECT_COUNTER++ )) export MAGE_PROTECT_COUNTER ;; # file is protected but ignored, delete the update/do nothing 4) if mqueryfeature "verbose" then echo -en "${COLRED}" echo -n "! ignr " echo -en "${COLDEFAULT}" echo " === FILE: ${MROOT}${pathto}" fi # simply do nothing here - only fix mtime fix_descriptor ${pkgname}/.files \ "${pathto}" \ "${posix}" \ "${user}" \ "${group}" \ "$(fix_mtime "${BUILDDIR}/${pkgname}"/.mtime \ "${MROOT}${pathto}")" \ "${md5sum}" ;; esac done < ${BUILDDIR}/${pkgname}/.files # now copy the fixed file over the old one [ -f ${BUILDDIR}/${pkgname}/.files_fixed ] && \ cp ${BUILDDIR}/${pkgname}/.files{_fixed,} # very important: unsetting the '§' fieldseperator IFS=$'\n' } ################################################### # function install_symlinks # # install_symlinks $PKGNAME # ################################################### install_symlinks() { local pkgname="$1" local pathto local posix local link local mtime local IFS # sanity checks; abort if not given [ -z "${pkgname}" ] && die "install_symlinks() \$pkgname not given." # check needed global vars [ -z "${BUILDDIR}" ] && die "install_symlinks() \$BUILDDIR not set." [ ! -f ${BUILDDIR}/${pkgname}/.symlinks ] && die "install_symlinks() .symlinks not found" # delete old files [ -f ${BUILDDIR}/${pkgname}/.symlinks_fixed ] && rm ${BUILDDIR}/${pkgname}/.symlinks_fixed # sets fieldseperator to "§" instead of " " IFS=§ while read pathto posix link mtime do [ -z "${pathto}" ] && continue mqueryfeature "verbose" && echo -e "\t>>> LINK: ${MROOT}${pathto}" ln -snf "${link}" "${MROOT}${pathto}" # # fix mtime and db # fix_descriptor ${pkgname}/.symlinks \ # "${pathto}" \ # "${posix}" \ # "${link}" \ # "$(fix_mtime "${BUILDDIR}/${pkgname}"/.mtime \ # "${MROOT}${pathto}")" done < ${BUILDDIR}/${pkgname}/.symlinks # # now copy the fixed file over the old one # [ -f ${BUILDDIR}/${pkgname}/.symlinks_fixed ] && \ # cp -f ${BUILDDIR}/${pkgname}/.symlinks{_fixed,} # very important: unsetting the '§' fieldseperator IFS=$'\n' } ################################################### # function install_blockdevices # # install_blockdevices $PKGNAME # ################################################### install_blockdevices() { local pkgname="$1" local pathto local posix local user local group local IFS # sanity checks; abort if not given [ -z "${pkgname}" ] && die "install_blockdevices() \$pkgname not given." # check needed global vars [ -z "${BUILDDIR}" ] && die "install_blockdevices() \$BUILDDIR not set." [ ! -f ${BUILDDIR}/${pkgname}/.pipes ] && die "install_blockdevices() .pipes not found" # sets fieldseperator to "§" instead of " " IFS=§ while read pathto posix major minor user group do [ -z "${pathto}" ] && continue mqueryfeature "verbose" && echo -e "\t>>> PIPE: ${MROOT}${pathto}" mknod -m "${posix}" "${MROOT}${pathto}" # make it optional atm !! if [[ ! -z ${user} ]] && [[ ! -z ${group} ]] then chown "${user}:${group}" "${MROOT}${pathto}" b "${major}" "${minor}" fi done < ${BUILDDIR}/${pkgname}/.pipes # very important: unsetting the '§' fieldseperator IFS=$'\n' } ################################################### # function install_characterdevices # # install_characterdevices $PKGNAME # ################################################### install_characterdevices() { local pkgname="$1" local pathto local posix local major local minor local user local group local IFS # sanity checks; abort if not given [ -z "${pkgname}" ] && die "install_characterdevices() \$pkgname not given." # check needed global vars [ -z "${BUILDDIR}" ] && die "install_characterdevices() \$BUILDDIR not set." [ ! -f ${BUILDDIR}/${pkgname}/.char ] && die "install_characterdevices() .char not found" # sets fieldseperator to "§" instead of " " IFS=§ while read pathto posix major minor user group do [ -z "${pathto}" ] && continue mqueryfeature "verbose" && echo -e "\t>>> CHAR: ${MROOT}${pathto}" mknod -m ${posix} "${MROOT}${pathto}" b "${major}" "${minor}" # make it optional atm !! if [[ ! -z ${user} ]] && [[ ! -z ${group} ]] then chown "${user}:${group}" "${MROOT}${pathto}" fi done < ${BUILDDIR}/${pkgname}/.char # very important: unsetting the '§' fieldseperator IFS=$'\n' } ################################################### # function install_fifos # # install_fifos $PKGNAME # ################################################### install_fifos() { local pkgname="$1" local pathto local posix local user local group local IFS # sanity checks; abort if not given [ -z "${pkgname}" ] && die "install_fifos() \$pkgname not given." # check needed global vars [ -z "${BUILDDIR}" ] && die "install_fifos() \$BUILDDIR not set." # make it optional atm !! #[ ! -f ${BUILDDIR}/${pkgname}/.fifo ] && die "install_fifos() .fifo not found" [ ! -f ${BUILDDIR}/${pkgname}/.fifo ] && return # sets fieldseperator to "§" instead of " " IFS=§ while read pathto posix user group do [ -z "${pathto}" ] && continue mqueryfeature "verbose" && echo -e "\t>>> FIFO: ${MROOT}${pathto}" mkfifo -m "${posix}" "${MROOT}${pathto}" chown "${user}:${group}" "${MROOT}${pathto}" done < ${BUILDDIR}/${pkgname}/.fifo # very important: unsetting the '§' fieldseperator IFS=$'\n' } ################################################### # function build_doinstall # # build_doinstall $PKGNAME # # NOTE: this is an wrapper to install packages # ################################################### build_doinstall() { local pkgname="$1" # sanity checks; abort if not given [ -z "${pkgname}" ] && die "build_doinstall() \$pkgname not given." # this is only a wrapper # NOTE: # !! we use § as field seperator !! # doing so prevent us to get errors by filenames with spaces # create a new mtime reference file touch ${BUILDDIR}/${pkgname}/.mtime install_directories ${pkgname} || die "install directories ${pkgname}" install_files ${pkgname} || die "install files ${pkgname}" install_symlinks ${pkgname} || die "install symlinks ${pkgname}" install_blockdevices ${pkgname} || die "install blockdevices ${pkgname}" install_characterdevices ${pkgname} || die "install chardevices ${pkgname}" install_fifos ${pkgname} || die "install fifos ${pkgname}" } ################################################### # function install_database_entry # # install_database_entry $PKGNAME $PKGTYPE # # PKGTYPE can be "virtual", "sources" or nothing # ################################################### install_database_entry() { local pcat local pname local pver local pbuild local pkgtype local pkgname local magefile local dbrecorddir local provide local i # very basic getops for i in $* do case $1 in --pcat|-c) shift; pcat="$1" ;; --pname|-n) shift; pname="$1" ;; --pver|-v) shift; pver="$1" ;; --pbuild|-b) shift; pbuild="$1" ;; --pkgname|-a) shift; pkgname="$1" ;; --pkgtype|-t) shift; pkgtype="$1" ;; esac shift done # sanity checks; abort if not given [ -z "${pcat}" ] && die "install_database_entry() \$pcat not given." [ -z "${pname}" ] && die "install_database_entry() \$pname not given." [ -z "${pver}" ] && die "install_database_entry() \$pver not given." [ -z "${pbuild}" ] && die "install_database_entry() \$pbuild not given." [ -z "${pkgname}" ] && die "install_database_entry() \$pkgname not given." # check needed global vars [ -z "${MAGEDIR}" ] && die "install_database_entry() \$MAGEDIR not set." [ -z "${INSTALLDB}" ] && die "install_database_entry() \$INSTALLDB not set." # set needed vars magefile="${MAGEDIR}/${pcat}/${pname}/${pname}-${pver}-${pbuild}.mage" dbrecorddir="${MROOT}${INSTALLDB}/${pcat}/${pname}-${pver}-${pbuild}" # abort if mage file not exists [ ! -f ${magefile} ] && die "install_database_entry() ${magefile} not exist." # add package to database install -d ${dbrecorddir} # install mage-file to database install -m 0644 -o root -g root ${magefile} ${dbrecorddir} # create fake file descriptors # used by virtual and source packages for i in .dirs .symlinks .files .pipes .char .fifo do touch ${dbrecorddir}/${i} done # put the category to database echo ${pcat} > ${dbrecorddir}/.categorie # now install PKGTYPE specific files case ${pkgtype} in virtual) touch ${dbrecorddir}/.virtual ;; sources) touch ${dbrecorddir}/.sources ;; *) # !move! .mtime to database (only mv modifies not the mtime!!) mv ${BUILDDIR}/${pkgname}/.mtime ${dbrecorddir}/.mtime # normal packages needs these files local i for i in .char .dirs .files .pipes .symlinks .fifo do # make .fifo optional atm if [[ -f ${BUILDDIR}/${pkgname}/${i} ]] then install -m 0644 ${BUILDDIR}/${pkgname}/${i} ${dbrecorddir}/${i} fi done ;; esac # last but not least register virtuals provide="$(get_value_from_magefile PROVIDE ${magefile})" if [ -n "${provide}" ] then for i in ${provide} do virtuals_add "${i}" "${pcat}/${pname}" done fi } ################################################### # function remove_database_entry # # remove_database_entry $PKGNAME $PKGTYPE # # PKGTYPE can be "virtual", "sources" or nothing # ################################################### remove_database_entry() { local pcat local pname local pver local pbuild local magefile local dbrecorddir local provide local i # very basic getops for i in $* do case $1 in --pcat|-c) shift; pcat="$1" ;; --pname|-n) shift; pname="$1" ;; --pver|-v) shift; pver="$1" ;; --pbuild|-b) shift; pbuild="$1" ;; esac shift done # sanity checks; abort if not given [ -z "${pcat}" ] && die "remove_database_entry() \$pcat not given." [ -z "${pname}" ] && die "remove_database_entry() \$pname not given." [ -z "${pver}" ] && die "remove_database_entry() \$pver not given." [ -z "${pbuild}" ] && die "remove_database_entry() \$pbuild not given." # check needed global vars [ -z "${INSTALLDB}" ] && die "remove_database_entry() \$INSTALLDB not set." # set needed vars magefile="${MROOT}${INSTALLDB}/${pcat}/${pname}-${pver}-${pbuild}/${pname}-${pver}-${pbuild}.mage" dbrecorddir="${MROOT}${INSTALLDB}/${pcat}/${pname}-${pver}-${pbuild}" # abort if mage file not exists [ ! -f ${magefile} ] && die "remove_database_entry() ${magefile} not exist." # remove virtuals only if no other exist if [[ $(count_installed_pkgs --pcat ${pcat} --pname ${pname}) -le 1 ]] then # first unregister virtuals provide="$(get_value_from_magefile PROVIDE ${magefile})" if [ -n "${provide}" ] then for i in ${provide} do virtuals_del "${i}" "${pcat}/${pname}" done fi fi # removes database entry if [ -d ${dbrecorddir} ] then rm -rf ${dbrecorddir} fi } # get the number of installed packages count_installed_pkgs() { local pcat local pname local pkg local i # very basic getops for i in $* do case $1 in --pcat|-c) shift; pcat="$1" ;; --pname|-n) shift; pname="$1" ;; esac shift done # sanity checks; abort if not given [ -z "${pcat}" ] && die "pkg_count() \$pcat not given." [ -z "${pname}" ] && die "pkg_count() \$pname not given." declare -i i=0 for pkg in $(get_uninstall_candidates --pcat ${pcat} --pname ${pname}) do (( i++ )) #echo "$i ${pkg}" done # return the value echo "${i}" } ################################################### # function compare_mtime # # compare_mtime $pcat/$PKGNAME /path/to/file # # # # returns: # # 0=delete me # # 1=keep me # # # # compares mtime of given files in packages # ################################################### compare_mtime() { local pfull="$1" local pathto="$2" local mtime local pcat local x mtime="$(stat -c %Y ${MROOT}${INSTALLDB}/${pfull}/.mtime)" # if $pathto is a symlink than compare linked binary if [ -L "${MROOT}${pathto}" ] then # readlink -f resolves full path of linked file x="$(readlink -f "${MROOT}${pathto}")" # abort if target does not exists # we keep safe here, theoretically the link can removed [ ! -e "${x}" ] && return 1 x=$(stat -c %Y "${x}") else x=$(stat -c %Y "${MROOT}${pathto}") fi [[ ${mtime} = ${x} ]] && return 0 # echo "keep me : ${pathto}" return 1 } ################################################### # function remove_symlinks # # remove_symlinks $PKGNAME # ################################################### remove_symlinks() { local pathto local posix local link local mtime local IFS local retval local pcat local pname local pver local pbuild local i local pfull IFS=$'\n' # very basic getops for i in $* do case $1 in --pcat|-c) shift; pcat="$1" ;; --pname|-n) shift; pname="$1" ;; --pver|-v) shift; pver="$1" ;; --pbuild|-b) shift; pbuild="$1" ;; esac shift done # sanity checks; abort if not given [ -z "${pcat}" ] && die "remove_symlinks() \$pcat not given." [ -z "${pname}" ] && die "remove_symlinks() \$pname not given." [ -z "${pver}" ] && die "remove_symlinks() \$pver not given." [ -z "${pbuild}" ] && die "remove_symlinks() \$pbuild not given." pfull="${pcat}/${pname}-${pver}-${pbuild}" # check needed global vars [ -z "${BUILDDIR}" ] && die "remove_symlinks() \$BUILDDIR not set." [ ! -f ${MROOT}${INSTALLDB}/${pfull}/.symlinks ] && die "remove_symlinks() .symlinks not found" # sets fieldseperator to "§" instead of " " IFS=§ while read pathto posix link mtime do [ -z "${pathto}" ] && continue if [ ! -L "${MROOT}${pathto}" ] then mqueryfeature "verbose" && \ echo -e "${COLRED}! exist${COLDEFAULT} === LINK: ${MROOT}${pathto}" continue fi # *no* ${MROOT}, will be set internal compare_mtime "${pfull}" "${pathto}" retval=$? # 0=delete me # # 1=keep me # case ${retval} in 0) mqueryfeature "verbose" && echo -e "\t<<< LINK: ${MROOT}${pathto}" rm "${MROOT}${pathto}" ;; 1) mqueryfeature "verbose" && \ echo -e "${COLRED}! mtime${COLDEFAULT} === LINK: ${MROOT}${pathto}" ;; esac done < ${MROOT}${INSTALLDB}/${pfull}/.symlinks # very important: unsetting the '§' fieldseperator IFS=$'\n' } ################################################### # function remove_files # # remove_files $PKGNAME # ################################################### remove_files() { local pathto local posix local user local group local mtime local md5sum local IFS local retval local pcat local pname local pver local pbuild local i local pfull IFS=$'\n' # very basic getops for i in $* do case $1 in --pcat|-c) shift; pcat="$1" ;; --pname|-n) shift; pname="$1" ;; --pver|-v) shift; pver="$1" ;; --pbuild|-b) shift; pbuild="$1" ;; esac shift done # sanity checks; abort if not given [ -z "${pcat}" ] && die "remove_files() \$pcat not given." [ -z "${pname}" ] && die "remove_files() \$pname not given." [ -z "${pver}" ] && die "remove_files() \$pver not given." [ -z "${pbuild}" ] && die "remove_files() \$pbuild not given." pfull="${pcat}/${pname}-${pver}-${pbuild}" # check needed global vars [ -z "${BUILDDIR}" ] && die "remove_files() \$BUILDDIR not set." [ ! -f ${MROOT}${INSTALLDB}/${pfull}/.files ] && die "remove_files() .files not found" # sets fieldseperator to "§" instead of " " IFS=§ while read pathto posix user group mtime md5sum do [ -z "${pathto}" ] && continue if [ ! -e "${MROOT}${pathto}" ] then mqueryfeature "verbose" && \ echo -e "${COLRED}! exist${COLDEFAULT} === FILE: ${MROOT}${pathto}" continue fi # *no* ${MROOT}, will be set internal compare_mtime "${pfull}" "${pathto}" retval=$? # 0=delete me # # 1=keep me # case ${retval} in 0) # check if the file is config_protected # ${MROOT} will automatically added if set !! is_config_protected "${pathto}" retval="$?" # 0 - not protected # # 1 - error # # 2 - protected # # 3 - protected but masked # # 4 - protected but ignored # case ${retval} in # file is not protected - delete it 0|3) mqueryfeature "verbose" && echo -e "\t<<< FILE: ${MROOT}${pathto}" rm "${MROOT}${pathto}" ;; # file is protected, do not delete 2) if mqueryfeature "verbose" then echo -en "${COLRED}" echo -n "! prot " echo -en "${COLDEFAULT}" echo " === FILE: ${MROOT}${pathto}" fi ;; # file is protected but ignored, delete the update/do nothing 4) if mqueryfeature "verbose" then echo -en "${COLRED}" echo -n "! ignr " echo -en "${COLDEFAULT}" echo " === FILE: ${MROOT}${pathto}" fi # simply do nothing here ;; esac ;; 1) mqueryfeature "verbose" && \ echo -e "${COLRED}! mtime${COLDEFAULT} === FILE: ${MROOT}${pathto}" ;; esac done < ${MROOT}${INSTALLDB}/${pfull}/.files # very important: unsetting the '§' fieldseperator IFS=$'\n' } ################################################### # function remove_blockdevices # # remove_blockdevices $PKGNAME # ################################################### remove_blockdevices() { local pathto local posix local user local group local IFS local pcat local pname local pver local pbuild local i local pfull IFS=$'\n' # very basic getops for i in $* do case $1 in --pcat|-c) shift; pcat="$1" ;; --pname|-n) shift; pname="$1" ;; --pver|-v) shift; pver="$1" ;; --pbuild|-b) shift; pbuild="$1" ;; esac shift done # sanity checks; abort if not given [ -z "${pcat}" ] && die "remove_blockdevices() \$pcat not given." [ -z "${pname}" ] && die "remove_blockdevices() \$pname not given." [ -z "${pver}" ] && die "remove_blockdevices() \$pver not given." [ -z "${pbuild}" ] && die "remove_blockdevices() \$pbuild not given." pfull="${pcat}/${pname}-${pver}-${pbuild}" # check needed global vars [ -z "${BUILDDIR}" ] && die "remove_blockdevices() \$BUILDDIR not set." [ ! -f ${MROOT}${INSTALLDB}/${pfull}/.pipes ] && die "remove_blockdevices() .pipes not found" # sets fieldseperator to "§" instead of " " IFS=§ while read pathto posix user group do [ -z "${pathto}" ] && continue mqueryfeature "verbose" && echo -e "\t<<< PIPE: ${MROOT}${pathto}" rm "${MROOT}${pathto}" done < ${MROOT}${INSTALLDB}/${pfull}/.pipes # very important: unsetting the '§' fieldseperator IFS=$'\n' } ################################################### # function remove_characterdevices # # remove_characterdevices $PKGNAME # ################################################### remove_characterdevices() { local pathto local posix local user local group local IFS local pcat local pname local pver local pbuild local i local pfull IFS=$'\n' # very basic getops for i in $* do case $1 in --pcat|-c) shift; pcat="$1" ;; --pname|-n) shift; pname="$1" ;; --pver|-v) shift; pver="$1" ;; --pbuild|-b) shift; pbuild="$1" ;; esac shift done # sanity checks; abort if not given [ -z "${pcat}" ] && die "remove_characterdevices() \$pcat not given." [ -z "${pname}" ] && die "remove_characterdevices() \$pname not given." [ -z "${pver}" ] && die "remove_characterdevices() \$pver not given." [ -z "${pbuild}" ] && die "remove_characterdevices() \$pbuild not given." pfull="${pcat}/${pname}-${pver}-${pbuild}" # check needed global vars [ -z "${BUILDDIR}" ] && die "remove_characterdevices() \$BUILDDIR not set." [ ! -f ${MROOT}${INSTALLDB}/${pfull}/.char ] && die "remove_characterdevices() .char not found" # sets fieldseperator to "§" instead of " " IFS=§ while read pathto posix user group do [ -z "${pathto}" ] && continue mqueryfeature "verbose" && echo -e "\t<<< CHAR: ${MROOT}${pathto}" rm "${MROOT}${pathto}" done < ${MROOT}${INSTALLDB}/${pfull}/.char # very important: unsetting the '§' fieldseperator IFS=$'\n' } ################################################### # function remove_fifos # # remove_fifos $PKGNAME # ################################################### remove_fifos() { local pathto local posix local user local group local IFS local pcat local pname local pver local pbuild local i local pfull IFS=$'\n' # very basic getops for i in $* do case $1 in --pcat|-c) shift; pcat="$1" ;; --pname|-n) shift; pname="$1" ;; --pver|-v) shift; pver="$1" ;; --pbuild|-b) shift; pbuild="$1" ;; esac shift done # sanity checks; abort if not given [ -z "${pcat}" ] && die "remove_fifos() \$pcat not given." [ -z "${pname}" ] && die "remove_fifos() \$pname not given." [ -z "${pver}" ] && die "remove_fifos() \$pver not given." [ -z "${pbuild}" ] && die "remove_fifos() \$pbuild not given." pfull="${pcat}/${pname}-${pver}-${pbuild}" # check needed global vars [ -z "${BUILDDIR}" ] && die "remove_fifos() \$BUILDDIR not set." # make it optional atm !! #[ ! -f ${MROOT}${INSTALLDB}/${pfull}/.fifo ] && die "remove_fifos() .fifo not found" [ ! -f ${MROOT}${INSTALLDB}/${pfull}/.fifo ] && return # sets fieldseperator to "§" instead of " " IFS=§ while read pathto posix user group do [ -z "${pathto}" ] && continue mqueryfeature "verbose" && echo -e "\t<<< FIFO: ${MROOT}${pathto}" rm "${MROOT}${pathto}" done < ${MROOT}${INSTALLDB}/${pfull}/.fifo # very important: unsetting the '§' fieldseperator IFS=$'\n' } ################################################### # function remove_direcories # # remove_direcories $PKGNAME # ################################################### remove_directories() { local pathto local posix local IFS local pcat local pname local pver local pbuild local i local pfull IFS=$'\n' # very basic getops for i in $* do case $1 in --pcat|-c) shift; pcat="$1" ;; --pname|-n) shift; pname="$1" ;; --pver|-v) shift; pver="$1" ;; --pbuild|-b) shift; pbuild="$1" ;; esac shift done # sanity checks; abort if not given [ -z "${pcat}" ] && die "remove_directories() \$pcat not given." [ -z "${pname}" ] && die "remove_directories() \$pname not given." [ -z "${pver}" ] && die "remove_directories() \$pver not given." [ -z "${pbuild}" ] && die "remove_directories() \$pbuild not given." pfull="${pcat}/${pname}-${pver}-${pbuild}" # check needed global vars [ -z "${BUILDDIR}" ] && die "remove_directories() \$BUILDDIR not set." [ ! -f ${MROOT}${INSTALLDB}/${pfull}/.char ] && die "remove_directories() .dirs not found" # sets fieldseperator to "§" instead of " " IFS=§ # reversed order is mandatory ! tac ${MROOT}${INSTALLDB}/${pfull}/.dirs | while read pathto posix do [ -z "${pathto}" ] && continue if [ ! -d "${MROOT}${pathto}" ] then mqueryfeature "verbose" && \ echo -e "${COLRED}! exist${COLDEFAULT} === DIR: ${MROOT}${pathto}" continue fi # exclude .keep directories if [ -f "${MROOT}${pathto}/.keep" ] then mqueryfeature "verbose" && \ echo -e "${COLRED}! .keep${COLDEFAULT} === DIR: ${MROOT}${pathto}" continue fi # monitors /etc/env.d -> env-rebuild [[ ${pathto} = /etc/env.d ]] && export MAGE_ENV_REBUILD=true # monitors /usr/share/info -> info-rebuild [[ ${pathto} = /usr/share/info ]] && export MAGE_INFO_REBUILD=true if rmdir "${MROOT}${pathto}" &> /dev/null then mqueryfeature "verbose" && echo -e "\t<<< DIR: ${MROOT}${pathto}" else mqueryfeature "verbose" && \ echo -e "${COLRED}! empty${COLDEFAULT} === DIR: ${MROOT}${pathto}" fi done # very important: unsetting the '§' fieldseperator IFS=$'\n' } ################################################### # function build_douninstall # # build_douninstall $PKGNAME # # NOTE: this is an wrapper to remove packages # ################################################### build_douninstall() { local pcat local pname local pver local pbuild local i # very basic getops for i in $* do case $1 in --pcat|-c) shift; pcat="$1" ;; --pname|-n) shift; pname="$1" ;; --pver|-v) shift; pver="$1" ;; --pbuild|-b) shift; pbuild="$1" ;; esac shift done # sanity checks; abort if not given [ -z "${pcat}" ] && die "build_douninstall() \$pcat not given." [ -z "${pname}" ] && die "build_douninstall() \$pname not given." [ -z "${pver}" ] && die "build_douninstall() \$pver not given." [ -z "${pbuild}" ] && die "build_douninstall() \$pbuild not given." # this is only a wrapper # NOTE: # !! we use § as field seperator !! # doing so prevent us to get errors by filenames with spaces for i in symlinks files blockdevices characterdevices directories fifos do remove_${i} \ --pcat "${pcat}" \ --pname "${pname}" \ --pver "${pver}" \ --pbuild "${pbuild}" \ || die "remove ${i} ${pcat}/${pname}-${pver}-${pbuild}" done } # convertmirrors [uri] convertmirrors() { local uri="$1" local scheme local mirror local mirrors local addon local real_uri local output # needs [[ -z ${MIRRORS} ]] && die "convertmirrors(): no mirrors defined!" [[ -z ${SOURCEFORGE_MIRRORS} ]] && die "convertmirrors(): no sourceforge mirrors defined!" [[ -z ${GNU_MIRRORS} ]] && die "convertmirrors(): no gnu mirrors defined!" [[ -z ${GNOME_MIRRORS} ]] && die "convertmirrors(): no gnome mirrors defined!" [[ -z ${KDE_MIRRORS} ]] && die "convertmirrors(): no kde mirrors defined!" # check known uri schemes case ${uri} in http://*|https://*|ftp://*|ftps://*) mirrors="" ;; mirror://*) mirrors="${MIRRORS}"; scheme="mirror://"; addon="/sources" ;; package://*) mirrors="${MIRRORS}"; scheme="package://"; addon="/${PACKAGES_SERVER_PATH}" ;; gnu://*) mirrors="${GNU_MIRRORS}"; scheme="gnu://" ;; sourceforge://*) mirrors="${SOURCEFORGE_MIRRORS}"; scheme="sourceforge://" ;; gnome://*) mirrors="${GNOME_MIRRORS}"; scheme="gnome://" ;; kde://*) mirrors="${KDE_MIRRORS}"; scheme="kde://" ;; *) die "convertmirror(): unsupported uri scheme in '${uri}'!" ;; esac if [[ ! -z ${mirrors} ]] then for mirror in ${mirrors} do # add a whitespace to the output [[ -z ${output} ]] || output+=" " output+="${mirror}${addon}/${uri/${scheme}/}" done else output="${uri}" fi echo "${output}" } mdownload() { local i local uri local real_uris local mirror local outputfile local outputdir local retval local wget_opts # very basic getops for i in $* do case $1 in --uri|-u) shift; uri="$1" ;; --dir|-d) shift; outputdir="$1" ;; esac shift done # sanity checks; abort if not given [[ -z ${uri} ]] && die "mdownload(): no uri given!" [[ -z ${outputdir} ]] && die "mdownload(): no dir given!" # convert mirrored uris to the real ones real_uris="$(convertmirrors ${uri})" # verbose or not mqueryfeature "!verbose" && wget_opts+=" --quiet" # filter wget options if busybox was found wget_opts+=" $(busybox_filter_wget_options ${WGET_FETCH_OPTIONS})" # create outputdir [[ ! -d ${outputdir} ]] && install -d "${outputdir}" for mirror in ${real_uris} do # get the name of the output file outputfile="${mirror##*/}" wget ${wget_opts} --output-document="${outputdir}/${outputfile}" "${mirror}" retval="$?" if [[ ${retval} = 0 ]] then break else continue fi done # return wget retval return "${retval}" } # fetch_packages /path/to/mage/file1 /path/to/mage/file2 fetch_packages() { local i local list="$@" local pkg local mirr local magefile local md5file local opt local count_current local count_total local wget_opts [ -z "${MIRRORS}" ] && die "You have no mirrors defined. Please edit your ${MAGERC}." # filter wget command if busybox was found wget_opts="$(busybox_filter_wget_options ${WGET_FETCH_OPTIONS})" # get count of total packages declare -i count_current=0 declare -i count_total=0 for i in ${list}; do (( count_total++ )); done for magefile in ${list} do pkg="$(get_value_from_magefile PKGNAME ${magefile}).${PKGSUFFIX}" pkgtype="$(get_value_from_magefile PKGTYPE ${magefile})" (( count_current++ )) xtitle "[ (${count_current}/${count_total}) Fetching ${pkg} ]" # abort on virtual pkg if [[ ${pkgtype} = virtual ]] then echo -ne " ${COLBLUE}---${COLDEFAULT}" echo " !fetch virtual (${count_current}/${count_total}): ${pkg/.${PKGSUFFIX}/} ... " continue fi # abort on sources pkg if [[ ${pkgtype} = sources ]] then echo -ne " ${COLBLUE}---${COLDEFAULT}" echo " !fetch sources (${count_current}/${count_total}): ${pkg/.${PKGSUFFIX}/} ... " continue fi # abort if already exist if [ -f ${PKGDIR}/${pkg} ] then echo -ne " ${COLBLUE}***${COLDEFAULT}" echo " fetch complete (${count_current}/${count_total}): ${pkg} ... " continue fi echo -ne " ${COLBLUE}***${COLDEFAULT}" echo -e " fetching (${count_current}/${count_total}): ${pkg} ... " mdownload --uri "package://${pkg}" --dir "${PKGDIR}" || die "Could not download ${pkg}" if [ ! -f ${PKGDIR}/${pkg} ] then die "Package '${pkg}' after download not found in '${PKGDIR}'" fi done # add a crlf for a better view if [ ${count_total} -gt 1 ]; then echo; fi } syncmage() { if [ -z "${RSYNC}" ] then die "You have no rsync-mirrors defined. Please edit your ${MAGERC}." fi local i for i in ${RSYNC} do rsync ${RSYNC_FETCH_OPTIONS} ${i} ${MAGEDIR} if [[ $? = 0 ]] then break else continue fi done # clean up backup files (foo~) find ${MAGEDIR} -name \*~ -exec rm '{}' ';' # check if a newer mage version is available is_newer_mage_version_available } syncmage_tarball() { local latest_tarball local latest_md5 local temp="$(mktemp -d)" local mirr mymirr local opt local tar_opts local wget_opts # try to get the md5 marked as latest on the server latest_md5="mage-latest.md5" # try to get the tarball marked as latest on the server latest_tarball="mage-latest.tar.bz2" # filter wget command if busybox was found wget_opts="$(busybox_filter_wget_options ${WGET_FETCH_OPTIONS})" for mirr in ${MIRRORS} do # path without distribution # (only for stable|testing|unstable and not DISTROTAG) case ${mirr##*/} in stable|testing|unstable) mymirr="${mirr%/*}";; *) mymirr="${mirr}";; esac echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo "fetching latest md5 from ${mymirr} ..." mqueryfeature "!verbose" && opt="--quiet" wget \ ${wget_opts} \ --directory-prefix=${temp} \ ${opt} ${mymirr}/rsync/tarballs/${latest_md5} echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo "fetching latest tarball from ${mymirr} ..." wget \ ${wget_opts} \ --directory-prefix=${temp} \ ${opt} ${mymirr}/rsync/tarballs/${latest_tarball} if [[ $? = 0 ]] then break else continue fi done if [[ -f ${temp}/${latest_tarball} ]] then # check md5 if [[ ! -f ${temp}/${latest_md5} ]] then die "md5 is missing ... aborting" else echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo -n "checking md5sum... " mchecksum --rundir "${temp}" --file "${latest_md5}" --method md5 || die "md5 for ${latest_tarball} failed" fi if [[ -d ${MAGEDIR} ]] then echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo "cleaning old mage-tree ${MAGEDIR}..." # honor mountpoints and empty dirs if mountpoint -q ${MAGEDIR} then if ! mcheckemptydir ${MAGEDIR} then find ${MAGEDIR} -mindepth 1 -maxdepth 1 | xarg --no-run-if-empty rm -r fi else rm -rf ${MAGEDIR} fi fi if need_busybox_support tar then tar_opts="xjf" else tar_opts="xjmf" fi echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo "updating mage-tree from tarball ..." # unpack in dirname of MAGEDIR, as the tarball has already the mage tar ${tar_opts} ${temp}/${latest_tarball} -C ${MAGEDIR%/*} || die "Unpacking tarball" if [[ -d ${temp} ]] then echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo "cleaning temp-files ..." rm -rf ${temp} fi # check if a newer mage version is available is_newer_mage_version_available else die "Could not fetch the latest tarball ... aborting" fi } cleanpkg() { if [ -d "${PKGDIR}" ] then echo -n "Removing downloaded packages... " rm -rf ${PKGDIR}/* echo "done." fi } xtitle() { if [[ ${TERM} = xterm ]] then echo -ne "\033]0;Mage: $1\007" fi return 0 } xtitleclean() { if [[ ${TERM} = xterm ]] then echo -ne "\033]0;\007" fi return 0 } # unused? # # # cuts full pathnames or versionized names down to basename # choppkgname() # { # #we want this only if full name was used # if [ -n "$(echo ${MAGENAME}|fgrep .mage)" ] # then # #cuts ARCH and PBUILD # #ARCH comes from ${MAGERC} # MAGENAME=$(echo ${MAGENAME} |sed -e "s:-${ARCH}$(print_distrotag)-r*.::g") # # #cuts version number # MAGENAME=$(basename ${MAGENAME%-*} .mage) # fi # } # get_categorie $PNAME, returns CATEGORIE # $1=pname # ret 0=ok, 1=not_found pname2pcat() { local pname="$1" local repo="$2" local pcat local categorie for pcat in ${MAGEDIR}/* do if [ -d ${pcat}/${pname} ] then categorie=$(basename ${pcat}) fi done echo "${categorie}" } # check_stable_package /path/to/foo.mage # returns 0=stable 1=unstable check_stable_package() { # first check if this magefile is not blacklisted blacklisted "$1" || return 1 local STATE STATE="$(get_value_from_magefile STATE "$1")" # state testing if [[ ${USE_TESTING} = true ]] || [[ ${MAGE_DISTRIBUTION} = testing ]] then case ${STATE} in testing|stable) return 0 ;; *) return 1 ;; esac fi # state unstable if [[ ${USE_UNSTABLE} = true ]] || [[ ${MAGE_DISTRIBUTION} = unstable ]] then case ${STATE} in unstable|testing|stable) return 0 ;; *) return 1 ;; esac fi # no use_state given = stable case ${STATE} in stable) return 0 ;; *) return 1 ;; esac } # get_highest_magefile ${PCAT} ${PNAME} # fake at moment returns only stable pkgs (must set to be one) # return $HIGHEST_MAGEFILE get_highest_magefile() { local HIGHEST_MAGEFILE local PCAT="$1" local PNAME="$2" local magefile # do not list the content of a directory, only the name (-d) for magefile in $(ls --format=single-column -v -d ${MAGEDIR}/${PCAT}/${PNAME}/* 2> /dev/null) do [[ -z ${magefile} ]] && continue # we exclude subdirs (for stuff like a md5sum dir) [[ -d ${magefile} ]] && continue if check_stable_package ${magefile} then HIGHEST_MAGEFILE=${magefile} #for debug only mqueryfeature "debug" && echo "HIGHEST_MAGEFILE=${HIGHEST_MAGEFILE}" fi done echo "${HIGHEST_MAGEFILE}" return 0 } ################################################### # function is_config_protected # # is_config_protected /path/to/file # # # # returns: # # 0 - not protected # # 1 - error # # 2 - protected # # 3 - protected but masked # # 4 - protected but ignored # # # ################################################### is_config_protected() { local EXPFILE local TEST local PROTECTED local IFS local i local x EXPFILE="${MROOT}$1" # file does not exist; it can be written [[ ! -e ${EXPFILE} ]] && return 0 # to be safe; it may be '§' IFS=' ' # check if config protected for i in ${CONFIG_PROTECT} do # only replace $i in the beginning of the variable TEST="${EXPFILE/#${MROOT}${i}/Protected}" if [[ ${TEST} != ${EXPFILE} ]] then # file is config proteced PROTECTED=TRUE # check if not masked for x in ${CONFIG_PROTECT_MASK} do TEST="${EXPFILE/#${MROOT}${x}/Protect_Masked}" if [[ ${TEST} != ${EXPFILE} ]] then PROTECTED=MASKED fi done # check if not ignored for x in ${CONFIG_PROTECT_IGNORE} do TEST="${EXPFILE/#${MROOT}${x}/Protect_Ignored}" if [[ ${TEST} != ${EXPFILE} ]] then PROTECTED=IGNORED fi done fi done unset IFS case ${PROTECTED} in TRUE) #echo "I'm protected" return 2 ;; MASKED) #echo "I'm protected, but masked - delete me" return 3 ;; IGNORED) #echo "I'm protected, but ignored - keep me, del update" return 4 ;; *) #echo "delete me" return 0 ;; esac } ################################################### # function count_protected_files # # count_protected_files /path/to/file # # # # note: prints number of protected files # # exp: 0012 # ################################################### count_protected_files() { local file="$1" local dirname="${file%/*}" local filename="${file##*/}" local count local output local i declare -i count=0 # check if there are already protected files for oldpretected in $(find ${dirname} -iname "._cfg????_${filename}" | sed -e "s:\(^.*/\)\(._cfg*_\)\(/.*$\):\1\2\3\%\2\%\3:" | sort -t'%' -k3 -k2 | cut -f1 -d'%') do count=$(echo ${oldpretected} | cut -d_ -f2 | sed -e "s:cfg::") done (( count ++ )) # fill output up with zeros for (( i=${#count}; i < 4; i++ )); do output="${output}0"; done output="${output}${count}" echo "${output}" } # call with # 'get_uninstall_candidates (--pcat cat --protected pcat/pfull) --pname PNAME' # returns /path/to/magefile(s) get_uninstall_candidates() { local search_pname local pkg local pcat local pname local pver local pbuild local list local pcatdir local protected local i # very basic getops for i in $* do case $1 in --pcat|-c) shift; pcatdir="$1" ;; --pname|-n) shift; search_pname="$1" ;; --protected|-p) shift; protected="$1" ;; esac shift done # it's not good to complain here about empty pnames; better to continue later anyway # # sanity checks; abort if not given # [ -z "${search_pname}" ] && die "get_uninstall_candidates() \$search_pname not given." # check needed global vars [ -z "${INSTALLDB}" ] && die "get_uninstall_candidates() \$INSTALLDB not set." # set pcatdir to '*' if empty [ -z "${pcatdir}" ] && pcatdir='*' for pkg in ${MROOT}${INSTALLDB}/${pcatdir}/* do # abort if not a dir [ ! -d ${pkg} ] && continue pname="$(magename2pname ${pkg})" if [[ ${search_pname} = ${pname} ]] then pcat="$(magename2pcat ${pkg} installdb)" pver="$(magename2pver ${pkg})" pbuild="$(magename2pbuild ${pkg})" # exclude proteced [[ ${protected} = ${pcat}/${pname}-${pver}-${pbuild} ]] && continue list="${list} ${pcat}/${pname}-${pver}-${pbuild}" fi done echo "${list}" } # reads virtualdb file #$1 = virtualname; $2 commands: showpkgs, showline #return 0 == installed -> shows installed pkg as well #return 1 == not installed virtuals_read() { local virtualname="$1" local command="$2" local virtline local line x i # parse file to get virtual_name line IFS=$'\n' for line in $(< ${MROOT}${VIRTUALDB_FILE}) do IFS=$' ' for x in ${line} do if [[ ${x} = ${virtualname} ]] then virtline="${line}" [[ ${command} = showline ]] && echo "${line}" fi done IFS=$'\n' done unset IFS # now read the packages linked to VIRTUAL_NAME and output them if [ -n "${virtline}" ] then if [[ ${command} = showpkgs ]] then declare -i x=0 for i in ${virtline} do if [ ${x} -ge 1 ] then echo "${i}" fi ((x++)) done fi return 0 fi return 1 } #add pkg to virtualdb # $1 == virtualname $2= pkgname # retvals: 0=ok,added; 1=error; 3=pkg already in virtual virtuals_add() { local virtualname="$1" local pkgname="$2" local oldline local line i local installed_file local OLDIFS if virtuals_read ${virtualname} then # make sure ${PKG_NAME} is *not* in ${VIRTUAL_NAME} already for i in $(virtuals_read ${virtualname} showpkgs) do if [[ ${i} = ${pkgname} ]] then echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo "${pkgname} already linked as ${virtualname} ..." #return 3 return 0 fi done echo -ne "${COLBLUE} *** ${COLDEFAULT}" echo "updating ${virtualname} entry with ${pkgname} ..." oldline="$(virtuals_read ${virtualname} showline)" # make a backup mv ${MROOT}${VIRTUALDB_FILE} ${MROOT}${VIRTUALDB_FILE}.old OLDIFS="${IFS}" IFS=$'\n' for line in $(< ${MROOT}${VIRTUALDB_FILE}.old) do # if the right line, append ${pkgname}, else do nothing if [[ ${line} = ${oldline} ]] then echo "${line} ${pkgname}" >> ${MROOT}${VIRTUALDB_FILE} else echo "${line}" >> ${MROOT}${VIRTUALDB_FILE} fi done # unset IFS IFS="${OLDIFS}" else echo -ne "${COLBLUE} >>> ${COLDEFAULT}" echo "register ${pkgname} as ${virtualname} ..." echo "${virtualname} ${pkgname}" >> ${MROOT}${VIRTUALDB_FILE} fi return 0 } #deletes pakages from virtual database #$1 virtualname; $2 pkgname virtuals_del() { local virtualname="$1" local pkgname="$2" local oldline local method local line i x local pkg_installed local OLDIFS # first check if exists if virtuals_read ${virtualname} then # get method -> delall or update and check if ${PKG_NAME} exists in ${VIRTUAL_NAME} declare -i x=0 for i in $(virtuals_read ${virtualname} showpkgs) do if [[ ${i} = ${pkgname} ]] then pkg_installed=true fi ((x++)) done # abort if not installed if [[ ${pkg_installed} != true ]] then echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo "${pkgname} does not exists in ${virtualname}." return 0 fi if [ ${x} -ge 2 ] then method=update else method=delall fi # get the complete line oldline="$(virtuals_read ${virtualname} showline)" # make a backup of the db mv ${VIRTUALDB_FILE} ${VIRTUALDB_FILE}.old # parse virtualdb OLDIFS="${IFS}" IFS=$'\n' for line in $(< ${VIRTUALDB_FILE}.old) do if [[ ${line} = ${oldline} ]] then #delall or update? case ${method} in update) echo -ne "${COLBLUE} *** ${COLDEFAULT}" echo "Unlinking ${pkgname} from ${virtualname} in virtual database ..." # del PKG_NAME from line echo "${line/ ${pkgname}/}" >> ${VIRTUALDB_FILE} ;; delall) echo -ne "${COLBLUE} <<< ${COLDEFAULT}" echo "Deleting ${virtualname} in virtual database ..." # continue; do not write anything continue ;; esac else echo "${line}" >> ${VIRTUALDB_FILE} fi done # unset IFS IFS="${OLDIFS}" else echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo "${virtualname} does not exists in virtual database." fi } # gets real pkgname from virtuals.default #$1=VIRTUAL_NAME; returns PKG_NAME default_virtualname_to_pkgname() { local VIRTUAL_NAME PKG_NAME db_virtualname db_pkgname VIRTUAL_NAME=$1 while read db_virtualname db_pkgname do if [ "${db_virtualname}" == "${VIRTUAL_NAME}" ] then PKG_NAME="${db_pkgname}" fi done << EOF $(< ${VIRTUALDB_DEFAULTS}) EOF if [ -n "${PKG_NAME}" ] then echo "${PKG_NAME}" fi } minclude() { local i if [[ -n $* ]] then for i in $* do mqueryfeature "debug" && \ echo "--- Including ${MAGEDIR}/include/${i}.minc" source ${MAGEDIR}/include/${i}.minc done mqueryfeature "debug" && echo fi } sminclude() { local i if [[ -n $* ]] then for i in $* do echo "--- Including ${SMAGESCRIPTSDIR}/include/${i}.sminc" source ${SMAGESCRIPTSDIR}/include/${i}.sminc done echo fi } # checks if an newer mage version is available is_newer_mage_version_available() { local newest_mage local installed_mage newest_mage="$(basename $(get_highest_magefile app-mage mage) .mage)" installed_mage="$(magequery -n mage | cut -d' ' -f5)" if [[ ${newest_mage} > ${installed_mage} ]] then echo echo -en ${COLRED}"An update for your packetmanager is available. "${COLDEFAULT} echo -e ${COLBLUE}"[ ${newest_mage} ]"${COLDEFAULT} echo "It is recommened to install this newer version" echo "or your current system installation may break." echo echo -en "Please update mage by running " echo -e ${COLGREEN}"'mage install mage'"${COLDEFAULT} echo fi } # returns pname from pkgname # pkgname2pname $PKGNAME pkgname2pname() { local pname pname="${1%-*-*-*}" echo "${pname}" } # returns pver from pkgname # pkgname2pver $PKGNAME pkgname2pver() { local i pver i="${1/$(pkgname2pname $1)-/}" pver="${i%-*-*}" echo "${pver}" } # returns pbuild from pkgname # pkgname2pbuild $PKGNAME pkgname2pbuild() { local pbuild pbuild="${1##*-}" echo "${pbuild}" } # returns parch from pkgname # pkgname2parch $PKGNAME pkgname2parch() { local i x parch i="${1%-*-*}-" x="${1%-*}" parch="${x/${i}/}" echo "${parch}" } # returns pname from magename # magename2pname /PATH/TO/MAGE/FILE magename2pname() { local i pname i="$(basename $1 .mage)" pname="${i%-*-*}" echo "${pname}" } # returns pver from magename # magename2pver /PATH/TO/MAGE/FILE magename2pver() { local i pver i="$(basename $1 .mage)" i="${i/$(magename2pname $1)-/}" pver="${i%-*}" echo "${pver}" } # returns pbuild from magename # magename2pbuild /PATH/TO/MAGE/FILE magename2pbuild() { local i pbuild i="$(basename $1 .mage)" pbuild="${i##*-}" echo "${pbuild}" } # returns pcat from magename # magename2pcat /PATH/TO/MAGE/FILE magename2pcat() { local i pcat if [[ ${2} = installdb ]] then # go 1 dir back i="${1%/*}" else # go 2 dirs back i="${1%/*/*}" fi # get basename pcat="${i##*/}" echo "${pcat}" } # returns pcat from DEPEND (without operand ! PCAT/PNAME-VERSION) # dep2pcat DEPEND dep2pcat() { local pcat pcat="${1%/*}" echo "${pcat}" } # returns pname from DEPEND (without operand ! PCAT/PNAME-VERSION) # $2=virtual is used to resolv VDEPEND from virtual packages # dep2pcat DEPEND (virtual) dep2pname() { local pname pname="${1##*/}" # cut version only if not virtual or it will cut the name if [[ $(dep2pcat $1) != virtual ]] && \ [[ $2 != virtual ]] then pname="${pname%-*}" fi echo "${pname}" } dep2highest_magefile() { local pcat local pname local magefile local installed_virtuals pcat="$(dep2pcat $1)" pname="$(dep2pname $1)" if [[ ${pcat} = virtual ]] then # first check if virtual is already installed installed_virtuals="$(virtuals_read ${pcat}/${pname} showpkgs)" if [ -n "${installed_virtuals}" ] then for vpkg in ${installed_virtuals} do realpkgname="${vpkg}" virtualpkgname="${pcat}/${pname}" pcat="$(dep2pcat ${realpkgname})" pname="$(dep2pname ${realpkgname} virtual)" done else # choose one from virtualdb defaults (virtuals.defaults) realpkgname="$(default_virtualname_to_pkgname ${pcat}/${pname})" virtualpkgname="${pcat}/${pname}" pcat="$(dep2pcat ${realpkgname})" pname="$(dep2pname ${realpkgname} virtual)" fi fi magefile="$(get_highest_magefile ${pcat} ${pname})" echo "${magefile}" } # is_installed ${PCAT}/${PNAME}-${PVER}-${PBUILD} is_installed() { local fullpkgname="$1" # return 0 if installed [ -d ${MROOT}${INSTALLDB}/${fullpkgname} ] && return 0 return 1 } install_packages() { local list="$@" local pkg local pcat local pname local pver local pbuild local total_pkgs local current_pkg local src_install local uninstall_list # check for --src-install if [[ $1 = --src-install ]] then # remove --src-install from list list=${list/--src-install/} # enable src-install src_install="--src-install" fi # reset MAGE_PROTECT_COUNTER declare -i MAGE_PROTECT_COUNTER=0 export MAGE_PROTECT_COUNTER # get count of total packages declare -i total_pkgs=0 declare -i current_pkg=0 for i in ${list}; do (( total_pkgs++ )); done echo if [[ -n ${MROOT} ]] then echo -ne ${COLRED} echo "!! installing in MROOT=${MROOT}" echo -ne ${COLDEFAULT} echo fi for pkg in ${list} do (( current_pkg++ )) pcat=$(magename2pcat ${pkg}) pname=$(magename2pname ${pkg}) pver=$(magename2pver ${pkg}) pbuild=$(magename2pbuild ${pkg}) mage_install \ --pcat ${pcat} \ --pname ${pname} \ --pver ${pver} \ --pbuild ${pbuild} \ --count-total ${total_pkgs} \ --count-current ${current_pkg} \ ${src_install} # check for allready installed packages and remove them # except the package we have installed uninstall_list="$(get_uninstall_candidates \ --pcat "${pcat}" \ --pname "${pname}" \ --protected ${pcat}/${pname}-${pver}-${pbuild})" # uninstall all packges in uninstall_list if not empty if [ -n "${uninstall_list}" ] then echo uninstall_packages ${uninstall_list} \ || die "install_packges() uninstalling not-needed." fi # crlf for better view in VERBOSE mode #if [[ ${VERBOSE} = on ]]; then echo; fi echo done #echo "DEBUG MAGE_PROTECT_COUNTER=${MAGE_PROTECT_COUNTER}" show_etc_update_mesg } # get_value_from_magefile VARIABLE # returns the content of this VAR get_value_from_magefile() { local var="$1" local magefile="$2" local value [[ -z ${var} ]] && return 1 [[ -z ${magefile} ]] && return 1 # local all possible vars of a mage file # to prevent bad issues local PKGNAME local STATE local DESCRIPTION local HOMEPAGE local DEPEND local SDEPEND local PROVIDE local PKGTYPE local MAGE_TARGETS local SPLIT_PACKAGE_BASE local preinstall local postinstall local preremove local postremove # sanity checks [ -f ${magefile} ] && source ${magefile} || \ die "get_value_from_magefile: ${magefile} not found." [ -z "${var}" ] && die "get_value_from_magefile: \$var not given." source ${magefile} eval value=\$$(echo ${var}) echo "${value}" # unset these functions unset -f preinstall unset -f postinstall unset -f preremove unset -f postremove } mage_install() { # local all possible vars of a mage file # to prevent bad issues local PKGNAME local STATE local DESCRIPTION local HOMEPAGE local DEPEND local SDEPEND local PROVIDE local PKGTYPE local preinstall local postinstall local preremove local postremove local pcat local pname local pver local pbuild local count_total local count_current local magefile local src_install local i # very basic getops for i in $* do case $1 in --pcat|-c) shift; pcat="$1" ;; --pname|-n) shift; pname="$1" ;; --pver|-v) shift; pver="$1" ;; --pbuild|-b) shift; pbuild="$1" ;; --count-total) shift; count_total="$1" ;; --count-current) shift; count_current="$1" ;; --src-install|-s) shift; src_install=true ;; esac shift done # sanity checks; abort if not given [ -z "${pcat}" ] && die "mage_install() \$pcat not given." [ -z "${pname}" ] && die "mage_install() \$pname not given." [ -z "${pver}" ] && die "mage_install() \$pver not given." [ -z "${pbuild}" ] && die "mage_install() \$pbuild not given." # check needed global vars [ -z "${MAGEDIR}" ] && die "mage_install() \$MAGEDIR not set." [ -z "${INSTALLDB}" ] && die "mage_install() \$INSTALLDB not set." [ -z "${BUILDDIR}" ] && die "mage_install() \$BUILDDIR not set." xtitle "[ (${count_current}/${count_total}) Installing ${pcat}/${pname}-${pver}-${pbuild} ]" echo -ne "${COLBLUE} >>> ${COLDEFAULT}" echo -n "installing (${count_current}/${count_total}): " echo -ne "${COLBLUE}${pcat}/${COLDEFAULT}" echo -e "${COLGREEN}${pname}-${pver}-${pbuild}${COLDEFAULT}" magefile="${MAGEDIR}/${pcat}/${pname}/${pname}-${pver}-${pbuild}.mage" source ${magefile} # abort on sources if no srcinstall if [[ ${PKGTYPE} = sources ]] && [[ ${src_install} != true ]] then echo echo -e "This Package is a Source Package." echo echo -e "Only 'srcinstall' works with this type of packages" echo -en "If you have done a srcinstall before, " echo -e "you will find the files in /usr/src." echo exit 1 fi ## preinstall scripts if [ -n "$(typeset -f preinstall)" ] then echo -e " ${COLBLUE}***${COLDEFAULT} running preinstall ... " preinstall unset preinstall fi if [[ ${src_install} = true ]] then local smage2file # check needed global vars [ -z "${SMAGESCRIPTSDIR}" ] && die "\$SMAGESCRIPTSDIR not set." [ -z "${SOURCEDIR}" ] && die "\$SOURCEDIR not set." [ -z "${BINDIR}" ] && die "\$BINDIR not set." # build the package first if [[ ${MAGEDEBUG} = on ]] then echo M:${pname} echo V:${pver} echo B:${pbuild} fi if [[ -n ${MAGE_TARGETS} ]] then # basic svn compat if [[ -d ${SMAGESCRIPTSDIR}/.svn ]] then for i in ${SMAGESCRIPTSDIR}/*/${pname/${MAGE_TARGETS}/}/${pname/${MAGE_TARGETS}/}-${pver}-${pbuild}.smage2 do smage2file="${i}" done else smage2file=${SMAGESCRIPTSDIR}/${pname/${MAGE_TARGETS}/}/${pname/${MAGE_TARGETS}/}-${pver}-${pbuild}.smage2 fi elif [[ -n ${SPLIT_PACKAGE_BASE} ]] then # basic svn compat if [[ -d ${SMAGESCRIPTSDIR}/.svn ]] then for i in ${SMAGESCRIPTSDIR}/*/${SPLIT_PACKAGE_BASE}/${SPLIT_PACKAGE_BASE}-${pver}-${pbuild}.smage2 do smage2file="${i}" done else smage2file=${SMAGESCRIPTSDIR}/${SPLIT_PACKAGE_BASE}/${SPLIT_PACKAGE_BASE}-${pver}-${pbuild}.smage2 fi else # basic svn compat if [[ -d ${SMAGESCRIPTSDIR}/.svn ]] then for i in ${SMAGESCRIPTSDIR}/*/${pname}/${pname}-${pver}-${pbuild}.smage2 do smage2file="${i}" done else smage2file=${SMAGESCRIPTSDIR}/${pname}/${pname}-${pver}-${pbuild}.smage2 fi fi if [ -f "${smage2file}" ] then echo -e " ${COLBLUE}***${COLDEFAULT} building package from source ... " smage2 ${smage2file} || die "compile failed" else echo echo "$(basename ${SMAGEFILE}) not found." echo "update your smage-tree and try it again." echo die fi fi if [[ ${PKGTYPE} != virtual ]] && \ [[ ${PKGTYPE} != sources ]] then echo -e " ${COLBLUE}***${COLDEFAULT} merging files into system ... " build_doinstall ${PKGNAME} fi ## postinstall scripts if [ -n "$(typeset -f postinstall)" ] then echo -e " ${COLBLUE}***${COLDEFAULT} running postinstall ... " postinstall unset postinstall fi # install a database entry install_database_entry \ --pcat "${pcat}" \ --pname "${pname}" \ --pver "${pver}" \ --pbuild "${pbuild}" \ --pkgname "${PKGNAME}" \ --pkgtype "${PKGTYPE}" \ || die "error in mage_install() running install_database_entry()." # remove the package dir now if [ -d ${BUILDDIR}/${PKGNAME} ] then rm -rf ${BUILDDIR}/${PKGNAME} fi # rebuilds toplevel info node if [[ ${MAGE_INFO_REBUILD} = true ]] then echo -ne "${COLBLUE} *** ${COLDEFAULT}" echo -n "rebuilding top-level info node ... " ${MLIBDIR}/mkinfodir ${MROOT}/usr/share/info \ > ${MROOT}/usr/share/info/dir && \ echo "done." || echo "failure." unset MAGE_INFO_REBUILD fi # rebuilds the enviroment with the content of /etc/env.d if [[ ${MAGE_ENV_REBUILD} = true ]] then echo -ne "${COLBLUE} *** ${COLDEFAULT}" echo -n "rebuilding environment ... " ${MLIBDIR}/env-rebuild.sh > /dev/null && \ echo "done." || echo "failure." unset MAGE_ENV_REBUILD fi xtitleclean echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo -n "package " # echo -ne "${COLBLUE}${pcat}/${COLDEFAULT}" # echo -ne "${COLGREEN}${pname}-${pver}-${pbuild}${COLDEFAULT} " echo "successfully installed." # unset these functions unset -f preinstall unset -f postinstall unset -f preremove unset -f postremove } md5sum_packages() { local list="$@" local magefile local pcat local pname local pkgname local pkgfile local pkgtype local count_current local count_total # get count of total packages declare -i count_current=0 declare -i count_total=0 for i in ${list}; do (( count_total++ )); done for magefile in ${list} do pcat=$(magename2pcat ${magefile}) pname=$(magename2pname ${magefile}) pkgname="$(get_value_from_magefile PKGNAME ${magefile})" md5file="${MAGEDIR}/${pcat}/${pname}/md5/${pkgname}.md5" pkgfile="$(get_value_from_magefile PKGNAME ${magefile}).${PKGSUFFIX}" pkgtype="$(get_value_from_magefile PKGTYPE ${magefile})" (( count_current++ )) xtitle "[ (${count_current}/${count_total}) MD5SUM: ${pkgfile} ]" # abort on virtual pkg if [[ ${pkgtype} = virtual ]] then echo -ne " ${COLBLUE}---${COLDEFAULT}" echo " !md5sum virtual (${count_current}/${count_total}): ${pkgfile/.${PKGSUFFIX}/} ... " continue fi # abort on sources pkg if [[ ${pkgtype} = sources ]] then echo -ne " ${COLBLUE}---${COLDEFAULT}" echo " !md5sum sources (${count_current}/${count_total}): ${pkgfile/.${PKGSUFFIX}/} ... " continue fi if [ -f "${md5file}" ] then echo -ne "${COLBLUE} *** ${COLDEFAULT}" echo -ne "checking md5sum (${count_current}/${count_total}): " mchecksum --rundir "${PKGDIR}" --file "${md5file}" --method md5 || die "md5 for ${pkgfile} failed" else echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo -e "!! no md5sum file found for ${pkgfile} :(" fi done # add a crlf for a better view if [ ${count_total} -gt 1 ]; then echo; fi } ## uninstall_packages ulist uninstall_packages() { local list="$@" local pcat local pname local pver local pbuild local can_pcat local can_pname local can_ver_list if [[ -n ${MROOT} ]] then echo -ne ${COLRED} echo "!! uninstalling from MROOT=${MROOT}" echo -ne ${COLDEFAULT} echo fi # generate a candidates list for pkg in ${list} do pcat=$(dep2pcat ${pkg}) pname=$(magename2pname ${pkg}) pver=$(magename2pver ${pkg}) pbuild=$(magename2pbuild ${pkg}) can_pcat="${pcat}" can_pname="${pname}" if [ -z "${can_ver_list}" ] then can_ver_list=" ${pver}-${pbuild}" else can_ver_list="${can_ver_list}, ${pver}-${pbuild}" fi done echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo "following candidate(s) will be removed:" echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo -ne "${COLBOLD}${can_pcat}/${can_pname}:${COLDEFAULT}" echo -e "${COLRED} ${can_ver_list} ${COLDEFAULT}" echo if [ ${MAGE_UNINSTALL_TIMEOUT} -gt 0 ] then echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo "( Press [CTRL+C] to abort )" echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo -n "Waiting ${MAGE_UNINSTALL_TIMEOUT} seconds ..." for ((i=MAGE_UNINSTALL_TIMEOUT; i >= 0; i--)) do echo -ne "${COLRED} ${i}${COLDEFAULT}" sleep 1 done echo echo fi for pkg in ${list} do pcat=$(dep2pcat ${pkg}) pname=$(magename2pname ${pkg}) pver=$(magename2pver ${pkg}) pbuild=$(magename2pbuild ${pkg}) mage_uninstall \ --pcat ${pcat} \ --pname ${pname} \ --pver ${pver} \ --pbuild ${pbuild} \ --count-total ${total_pkgs} \ --count-current ${current_pkg} \ ${src_install} # crlf for better view in VERBOSE mode #if [[ ${VERBOSE} = on ]]; then echo; fi echo done } mage_uninstall() { # local all possible vars of a mage file # to prevent bad issues local PKGNAME local STATE local DESCRIPTION local HOMEPAGE local DEPEND local SDEPEND local PROVIDE local PKGTYPE local preinstall local postinstall local preremove local postremove local pcat local pname local pver local pbuild local magefile local i # very basic getops for i in $* do case $1 in --pcat|-c) shift; pcat="$1" ;; --pname|-n) shift; pname="$1" ;; --pver|-v) shift; pver="$1" ;; --pbuild|-b) shift; pbuild="$1" ;; esac shift done # sanity checks; abort if not given [ -z "${pcat}" ] && die "mage_uninstall() \$pcat not given." [ -z "${pname}" ] && die "mage_uninstall() \$pname not given." [ -z "${pver}" ] && die "mage_uninstall() \$pver not given." [ -z "${pbuild}" ] && die "mage_uninstall() \$pbuild not given." # check needed global vars [ -z "${MAGEDIR}" ] && die "mage_uninstall() \$MAGEDIR not set." [ -z "${INSTALLDB}" ] && die "mage_uninstall() \$INSTALLDB not set." [ -z "${BUILDDIR}" ] && die "mage_uninstall() \$BUILDDIR not set." xtitle "[ (${count_current}/${count_total}) Removing ${pcat}/${pname}-${pver}-${pbuild} ]" echo -ne "${COLBLUE} <<< ${COLDEFAULT}" echo -n "removing: " echo -ne "${COLBLUE}${pcat}/${COLDEFAULT}" echo -e "${COLRED}${pname}-${pver}-${pbuild}${COLDEFAULT}" magefile="${MROOT}${INSTALLDB}/${pcat}/${pname}-${pver}-${pbuild}/${pname}-${pver}-${pbuild}.mage" source ${magefile} ## preremove scripts if [ -n "$(typeset -f preremove)" ] then echo -e " ${COLBLUE}***${COLDEFAULT} running preremove ... " preremove unset preremove fi # runs uninstall build_douninstall \ --pcat "${pcat}" \ --pname "${pname}" \ --pver "${pver}" \ --pbuild "${pbuild}" ## postremove scripts if [ -n "$(typeset -f postremove)" ] then echo -e " ${COLBLUE}***${COLDEFAULT} running postremove ... " postremove unset postremove fi # removes the database entry remove_database_entry \ --pcat "${pcat}" \ --pname "${pname}" \ --pver "${pver}" \ --pbuild "${pbuild}" \ || die "error in mage_uninstall() running remove_database_entry()." # rebuilds toplevel info node if [[ ${MAGE_INFO_REBUILD} = true ]] then echo -ne "${COLBLUE} *** ${COLDEFAULT}" echo -n "rebuilding top-level info node ... " ${MLIBDIR}/mkinfodir ${MROOT}/usr/share/info \ > ${MROOT}/usr/share/info/dir && \ echo "done." || echo "failure." unset MAGE_INFO_REBUILD fi # rebuilds the enviroment with the content of /etc/env.d if [[ ${MAGE_ENV_REBUILD} = true ]] then echo -ne "${COLBLUE} *** ${COLDEFAULT}" echo -n "rebuilding environment ... " ${MLIBDIR}/env-rebuild.sh > /dev/null && \ echo "done." || echo "failure." unset MAGE_ENV_REBUILD fi echo -ne "${COLBLUE} --- ${COLDEFAULT}" echo -n "package " # echo -ne "${COLBLUE}${pcat}/${COLDEFAULT}" # echo -ne "${COLGREEN}${pname}-${pver}-${pbuild}${COLDEFAULT} " echo "successfully removed." # unset these functions unset -f preinstall unset -f postinstall unset -f preremove unset -f postremove } show_etc_update_mesg() { [ ${MAGE_PROTECT_COUNTER} -eq 0 ] && return 0 echo echo -ne "${COLRED}" echo "Important:" echo -ne ${COLDEFAULT} echo "${MAGE_PROTECT_COUNTER} protected file(s) were installed." echo echo "Please run 'etc-update' to update your configuration files." echo } pkgsearch() { local string="$1" local result local pkg local pcat local pname local magefile local pver local pbuild local state local descriptiom local homepage local license local i local all_installed local ipver local ipbuild local latest_available local depsfull local sdepsfull local deps local sdeps local dep local sign # only names no versions result="$(find ${MAGEDIR} -mindepth 2 -maxdepth 2 -type d -name '*'${string}'*'| sed '/profiles/d' | sed '/includes/d')" #result="$(find ${MAGEDIR} -type f -name '*'${string}'*'.mage | sort)" # nothing found [[ -z ${result} ]] && die "No package found containing '${string}' in the name." for pkg in ${result} do # dirty, but does the job pcat="$(magename2pcat ${pkg}/foo)" pname="$(magename2pname ${pkg}-foo-foo)" # get highest version available magefile=$(get_highest_magefile ${pcat} ${pname}) if [[ ! -z ${magefile} ]] then # now get all needed infos to print a nice output pver="$(magename2pver ${magefile})" pbuild="$(magename2pbuild ${magefile})" state="$(get_value_from_magefile STATE ${magefile})" description="$(get_value_from_magefile DESCRIPTION ${magefile})" homepage="$(get_value_from_magefile HOMEPAGE ${magefile})" license="$(get_value_from_magefile LICENSE ${magefile})" # all installed for i in $(get_uninstall_candidates --pname ${pname} --pcat ${pcat}) do ipver="$(magename2pver ${i})" ipbuild="$(magename2pbuild ${i})" if [[ -z ${all_installed} ]] then all_installed="${ipver}-${ipbuild}" else all_installed="${all_installed} ${ipver}-${ipbuild}" fi done [[ -z ${all_installed} ]] && all_installed="none" case ${state} in stable) state=${COLGREEN}"[s] ";; testing) state=${COLYELLOW}"[t] ";; unstable) state=${COLRED}"[u] ";; old) state=${COLGRAY}"[o] ";; esac latest_available="${pver}-${pbuild}" else # package is masked state="${COLRED}[m] " latest_available="${COLRED}masked for this distribution.${COLDEFAULT}" fi depsfull="$(get_value_from_magefile DEPEND ${magefile})" sdepsfull="$(get_value_from_magefile SDEPEND ${magefile})" while read sign dep do case ${dep} in "") continue;; esac deps="${deps} $(basename ${dep%-*})" done << EOF ${depsfull} EOF while read sign dep do case ${dep} in "") continue;; esac sdeps="${sdeps} $(basename ${dep%-*})" done << EOF ${sdepsfull} EOF echo -e "${state}${pcat}/${pname}"${COLDEFAULT} echo -e " Latest available: ${latest_available}" echo " Installed versions: ${all_installed}" echo " Description: ${description}" echo " Homepage: ${homepage}" if [[ ! -z ${license} ]] then echo " License: ${license}" fi echo " Depends: ${deps}" echo " SDepends: ${sdeps}" echo unset pcat unset pname unset magefile unset pver unset pbuild unset state unset descriptiom unset homepage unset all_installed unset ipver unset ipbuild unset depsfull unset sdepsfull unset deps unset sdeps unset dep unset sign done } export_inherits() { local include="$1" shift while [ "$1" ] do local functions="$1" # sanity checks [ -z "${include}" ] && die "export_inherits(): \$include not given." [ -z "${functions}" ] && die "export_inherits(): \$functions not given." eval "${functions}() { ${include}_${functions} ; }" # debug mqueryfeature "debug" && typeset -f "${functions}" shift done } mlibdir() { local libdir=lib [[ ${ARCH} = x86_64 ]] && libdir=lib64 echo "${libdir}" } ## blacklisted ${magefile} blacklisted() { [[ -z ${MAGE_DISTRIBUTION} ]] && local MAGE_DISTRIBUTION=stable # compat [[ ${USE_UNSTABLE} = true ]] && local MAGE_DISTRIBUTION=unstable [[ ${USE_TESTING} = true ]] && local MAGE_DISTRIBUTION=testing # support both types for the moment if [[ -f /etc/mage-profile/package.blacklist-${ARCH}-${MAGE_DISTRIBUTION} ]] then local EXCLUDED="/etc/mage-profile/package.blacklist-${ARCH}-${MAGE_DISTRIBUTION}" else local EXCLUDED="/etc/mage-profile/package.blacklist-${ARCH}" fi # return 0 if the list not exist; nothin is masked [[ ! -f ${EXCLUDED} ]] && return 0 local MAGEFILE="$1" local PCAT="$(magename2pcat ${MAGEFILE})" local PNAME="$(magename2pname ${MAGEFILE})" local PVER="$(magename2pver ${MAGEFILE})" local PBUILD="$(magename2pbuild ${MAGEFILE})" local EXPCAT EXPNAME EXPVER EXPBUILD while read EXPCAT EXPNAME EXPVER EXPBUILD do # ignore spaces and comments case "${EXPCAT}" in \#*|"") continue ;; esac # exclude full pver if [[ -n ${PCAT} ]] && [[ -n ${PNAME} ]] && [[ -n ${EXPCAT} ]] && [[ -n ${EXPNAME} ]] && [[ -n ${PVER} ]] && [[ -n ${PBUILD} ]] && [[ -n ${EXPVER} ]] && [[ -n ${EXPBUILD} ]] then [[ ${EXPCAT}/${EXPNAME}-${EXPVER}-${EXPBUILD} = ${PCAT}/${PNAME}-${PVER}-${PBUILD} ]] && return 1 fi # exclude pcat/pname only if [[ -n ${PCAT} ]] && [[ -n ${PNAME} ]] && [[ -n ${EXPCAT} ]] && [[ -n ${EXPNAME} ]] && [[ -z ${EXPVER} ]] && [[ -z ${EXPBUILD} ]] then [[ ${EXPCAT}/${EXPNAME} = ${PCAT}/${PNAME} ]] && return 1 fi done << EOF $( cat ${EXCLUDED}; echo) EOF return 0 } # need_busybox_support ${cmd} # return 0 (no error = needs busybox support) or return 1 (error = no busybox support required) need_busybox_support() { local cmd cmd="$1" if [[ -x /bin/busybox ]] then if [[ $(readlink $(which ${cmd})) = /bin/busybox ]] then # needs busybox support return 0 fi fi # no busybox return 1 } # busybox_filter_wget_options ${wget_opts} busybox_filter_wget_options() { local opts="$@" local i local fixed_opts if need_busybox_support wget then for i in ${opts} do # show only the allowed ones case ${i} in -c|--continue) fixed_opts+=" -c" ;; -s|--spider) fixed_opts+=" -s" ;; -q|--quiet) fixed_opts+=" -q" ;; -O|--output-document) shift; fixed_opts+=" -O $1" ;; --header) shift; fixed_opts+=" --header $1" ;; -Y|--proxy) shift; fixed_opts+=" -Y $1" ;; -P) shift; fixed_opts+=" -P $1" ;; --no-check-certificate) fixed_opts+=" --no-check-certificate ${i}" ;; -U|--user-agent) shift; fixed_opts+=" -U ${i}" ;; # simply drop all other opts *) continue ;; esac done echo "${fixed_opts}" else echo "${opts}" fi } have_root_privileges() { local retval if [[ $(id -u) = 0 ]] then retval=0 else retval=1 fi return ${retval} } known_mage_feature() { local feature="$1" local retval case "${feature}" in autosvc|!autosvc) retval=0 ;; buildlog|!buildlog) retval=0 ;; ccache|!ccache) retval=0 ;; check|!check) retval=0 ;; compressdoc|!compressdoc) retval=0 ;; debug|!debug) retval=0 ;; distcc|!distcc) retval=0 ;; kernelsrcunpack|!kernelsrcunpack) retval=0 ;; libtool|!libtool) retval=0 ;; linuxsymlink|!linuxsymlink) retval=0 ;; pkgbuild|!pkgbuild) retval=0 ;; pkgdistrotag|!pkgdistrotag) retval=0 ;; purge|!purge) retval=0 ;; qalint|!qalint) retval=0 ;; regentree|!regentree) retval=0 ;; resume|!resume) retval=0 ;; srcpkgbuild|!srcpkgbuild) retval=0 ;; srcpkgtarball|!srcpkgtarball) retval=0 ;; static|!static) retval=0 ;; stepbystep|!stepbystep) retval=0 ;; strip|!strip) retval=0 ;; verbose|!verbose) retval=0 ;; *) retval=1 ;; esac return "${retval}" } load_mage_features() { for i in ${MAGE_FEATURES_GLOBAL[*]} ${MAGE_FEATURES[*]} do FVERBOSE=off msetfeature ${i} done } msetfeature() { local feature local count local i local found for feature in $@ do found=0 count="${#MAGE_FEATURES_CURRENT[*]}" if ! known_mage_feature "${feature}" then [[ ${FVERBOSE} = off ]] || echo -e "${COLRED}Unknown feature '${feature}', ignoring it${COLDEFAULT}" return 3 fi for ((i=0; i