# -*-eselect-*- vim: ft=eselect # Copyright 2005-2012 Gentoo Foundation # Distributed under the terms of the GNU GPL version 2 or later inherit config multilib package-manager DESCRIPTION="Manage environment variables set in /etc/env.d/" MAINTAINER="eselect@gentoo.org" # Classes of env-vars SPACE_CLASS="CONFIG_PROTECT CONFIG_PROTECT_MASK" PATH_CLASS="ADA_INCLUDE_PATH ADA_OBJECTS_PATH CLASSPATH INFODIR INFOPATH KDEDIRS LDPATH MANPATH PATH PKG_CONFIG_PATH PRELINK_PATH PRELINK_PATH_MASK PYTHONPATH ROOTPATH" # Recognized file formats: MIME_WHITELIST="text/plain text/x-makefile" # Configuration files ENVPROFILE="${EROOT}/etc/profile.env" LDCONFIG="${EROOT}/etc/ld.so.conf" PRELINK="${EROOT}/etc/prelink.conf" # Keep all stored LDPATHS ESELECT_LDPATH=( ) # is_envd_file() # Return successfuly when file can be sourced. is_envfile() { local mime envfile=${1} # Make sure it is a file and no backup file [[ -f ${envfile} ]] || return 1 [[ -n ${envfile##*~} ]] || return 1 [[ ${envfile##*.} != bak ]] || return 1 mime=$(POSIXLY_CORRECT=1 file -i "${envfile}" \ | cut -d ' ' -f 2 | sed -e 's/;$//') if ! has ${mime} ${MIME_WHITELIST}; then echo "Skipping non-text file ${envfile}." return 1 fi return 0 } # update_envvar_classes() # Update the contents of *_CLASS based on env,d files. update_envvar_classes() { local -a envfiles local value envfiles=( "${EROOT}"/etc/env.d/* ) for envfile in "${envfiles[@]}"; do is_envfile "${envfile}" || continue value=$(load_config "${envfile}" COLON_SEPARATED) for x in ${value}; do has ${x} ${PATH_CLASS} || PATH_CLASS="${PATH_CLASS} ${x}" done value=$(load_config "${envfile}" SPACE_SEPARATED) for x in ${value}; do has ${x} ${SPACE_CLASS} || SPACE_CLASS="${SPACE_CLASS} ${x}" done done } # create_profile_env() # Create profile.env file create_profile_env() { local -a envfiles local vars store items tmpprofile ifs_save envfiles=( "${EROOT}"/etc/env.d/* ) # Blank the file first! tmpprofile=$(mktemp "${ROOT}/tmp/profile.XXXXXX") [[ $? -eq 0 ]] || die "Couldn't create temporary file!" # Gather ye classes while ye may! update_envvar_classes # Parse all files in env.d for envfile in "${envfiles[@]}"; do is_envfile "${envfile}" || continue # Which vars are to be loaded? # TODO: Change to bash magic? vars=$(LC_ALL=C sed \ -e 's/^\s*//' \ -e 's/^export\s\+//' \ -e '/^[[:alpha:]_]\w*=/!d' \ -e 's/=.*//' \ "${envfile}") for var in ${vars}; do if [[ ${var} = LDPATH ]]; then # Don't store LDPATH in profile.env continue elif has ${var} ${PATH_CLASS}; then # Colon separated store=$(load_config "${tmpprofile}" ${var}) if [[ -z ${store} ]]; then store=$(load_config "${envfile}" ${var}) else items=$(load_config "${envfile}" ${var}) ifs_save=${IFS-$' \t\n'} IFS=":" for item in ${items}; do has ${item} ${store} \ || store="${store}${store:+:}${item}" done IFS=${ifs_save} fi elif has ${var} ${SPACE_CLASS}; then # Space separated store=$(load_config "${tmpprofile}" ${var}) if [[ -z ${store} ]]; then store=$(load_config "${envfile}" ${var}) else items=$(load_config "${envfile}" ${var}) for item in ${items}; do has ${item} ${store} \ || store="${store}${store:+ }${item}" done fi else # Ok, just a non-cumulative var. store=$(load_config "${envfile}" ${var}) fi store_config "${tmpprofile}" ${var} "${store}" done has LDPATH ${vars} || continue # Store LDPATH for later processing items=$(load_config "${envfile}" LDPATH) ifs_save=${IFS-$' \t\n'} IFS=":" items=( ${items} ) IFS=${ifs_save} for item in "${items[@]}"; do has "${item}" "${ESELECT_LDPATH[@]}" \ || ESELECT_LDPATH=( "${ESELECT_LDPATH[@]}" "${item}" ) done done # Move new file onto old one chmod a+r "${tmpprofile}" mv "${tmpprofile}" "$(canonicalise "${ENVPROFILE}")" \ || die "Couldn't move ${tmpprofile} to ${ENVPROFILE}!\n Original profile.env remains unchanged." } # create_ld_so_conf() # Create ld.so.conf file based upon gathered LDPATHs create_ld_so_conf() { [[ -z ${ESELECT_LDPATH[@]} ]] \ && die -q "No LDPATHs found in ${EROOT}/etc/env.d/*" local str str="# ld.so.conf autogenerated by eselect\n" str="${str}# Make all changes to /etc/env.d files\n" for x in "${ESELECT_LDPATH[@]}"; do str="${str}${x}\n" done echo -n -e "${str}" >"$(canonicalise "${LDCONFIG}")" } # create_prelink_conf() # Create prelink.conf file based upon existing profile.env create_prelink_conf() { [[ -z ${ESELECT_LDPATH[@]} ]] \ && die -q "No LDPATHs found in ${EROOT}/etc/env.d/*" local path prelink_path prelink_mask str x ifs_save str="# prelink.conf autogenerated by eselect\n" str="${str}# Make all changes to /etc/env.d files\n" # Add default items for x in /bin /sbin /usr/bin /usr/sbin; do str="${str}-l ${EPREFIX}${x}\n" done for x in $(list_libdirs); do [[ -e ${EROOT}/${x} ]] && str="${str}-l ${EPREFIX}/${x}\n" [[ -e ${EROOT}/usr/${x} ]] && str="${str}-l ${EPREFIX}/usr/${x}\n" done path=$(load_config "${ENVPROFILE}" PATH) prelink_path=$(load_config "${ENVPROFILE}" PRELINK_PATH) prelink_mask=$(load_config "${ENVPROFILE}" PRELINK_PATH_MASK) ifs_save=${IFS-$' \t\n'} IFS=":" for x in ${path} ${prelink_path} "${ESELECT_LDPATH[@]}"; do has ${x} ${prelink_mask} && continue [[ -z ${x##*/} ]] || x="${x}/" str="${str}-h ${x}\n" done for x in ${prelink_mask}; do str="${str}-b ${x}\n" done IFS=${ifs_save} echo -n -e "${str}" >"$(canonicalise "${PRELINK}")" } # update_ldcache() # Update ld.so.cache using ldconfig update_ldcache() { case $(uname -s) in Linux | *GNU | *gnu) echo "Regenerating ${ROOT}/etc/ld.so.cache..." ( cd / ldconfig -X ${1} -r "${ROOT:-/}" ) ;; FreeBSD | DragonFly) echo "Regenerating ${ROOT}/var/run/ld-elf.so.hints..." ( cd / ldconfig -elf -i -f "${ROOT:-/}var/run/ld-elf.so.hints" \ "${ROOT:-/}etc/ld.so.conf" ) ;; esac } ### update action describe_update() { echo "Collect environment variables from all scripts in /etc/env.d/" } describe_update_parameters() { echo "" } describe_update_options() { echo "noldconfig : Do not alter the ld.so cache or configuration." } do_update() { local ldconfig=1 while [[ $# -gt 0 ]]; do case ${1##--} in makelinks) # option is ignored, only for backwards compatibility ;; noldconfig|no-ldconfig) ldconfig=0 ;; *) die -q "Unknown option '${1}'" ;; esac shift done # Test for sufficient permissions if [[ -e ${ENVPROFILE} ]]; then [[ -w ${ENVPROFILE} ]] || die -q "You need to be root!" else touch "${ENVPROFILE}" || die -q "You need to be root!" fi # Use the package manager's env-update command if available, # otherwise (if 127 was returned) fall back to shell implementation env_update ${ldconfig} && return [[ $? -eq 127 ]] || die -q "env-update failed" # Create configuration files create_profile_env if [[ ${ldconfig} -ne 0 ]]; then create_ld_so_conf [[ -e ${EROOT}/usr/sbin/prelink ]] && create_prelink_conf update_ldcache fi # fix up ${ENVPROFILE} cp "${ENVPROFILE}" "${ENVPROFILE/.env/.csh}" sed -i -e "s/^\(.*\)=\"\(.*\)\"/export \1='\2'/" \ "$(canonicalise "${ENVPROFILE}")" sed -i -e "s/^\(.*\)=\"\(.*\)\"/setenv \1 '\2'/" \ "$(canonicalise "${ENVPROFILE/.env/.csh}")" }