#!/bin/bash source ScriptFunctions Import File Import GoboLinux Import Log Import OptionParser Import PostInstall ### Options ################################################################### scriptDescription="Install GoboLinux packages." scriptCredits="Released under the GNU GPL." helpOnNoArguments=yes scriptUsage="|" scriptExample="Gimp--2.0.5.tar.gz" scriptNotes="Default behavior for --same is 'cancel', for --old is 'keep'. Notice that 'remove' may be dangerous for important system packages as it can leave the system in an inconsistent state during installation." Add_Option_Boolean "b" "batch" "Do not ask for confirmation." Add_Option_Boolean "" "use-contrib" "Look in contrib store as well." Add_Option_Boolean "D" "no-dependencies" "Do not try to fullfit dependencies." Add_Option_Boolean "I" "no-install" "Do not install, only locate and fetch the package. Automatically enables '--keep'" Add_Option_Boolean "S" "no-symlink" "Do not create symbolic links in ${goboLinks}, just fetch and unpack the package." Add_Option_Boolean "k" "keep" "Do not remove downloaded packages." Add_Option_Entry "s" "same" "What to do when unpackaging over the same version, 'keep', 'remove', 'ask' or 'cancel'." "ask" Add_Option_Entry "o" "old" "What to do with a previously existing version of a package if found, 'keep', 'remove', 'ask' or 'cancel'." "keep" Add_Option_Entry "u" "unmanaged" "Defines what to do with unmanaged files "\ "from package. Options available are \"ask\", \"install\" and \"skip\"." "ask" Add_Option_Boolean "C" "no-sign-check" "Do not check the signature." Add_Option_Boolean "U" "no-updatesettings" "Do not update settings for the package" Add_Option_Boolean "W" "no-web" "Do not check remote site for packages, and bypass fetching of archives." Parse_Options "$@" if [ -z "$ROOTLESS_GOBOLINUX" ] && ! $sudo_validate then Ask "You are trying to install $(Arg 1) as normal user without privileges.\n\ Should a rootless environment be set up instead?" && { CreateRootlessEnvironment && . ~/Programs/Rootless/Current/bin/StartRootless } fi ### Operation ################################################################# if [ "$goboInstall" = "" ] then export goboInstall="$goboPrograms" fi unmanaged="--unmanaged $(Entry unmanaged)" Boolean "batch" && batch="--batch" Boolean "keep" && keep="--keep" Boolean "no-symlink" && nosymlink="--no-symlink" Boolean "no-install" && noinstall="--no-install" && keep="--keep" Boolean "use-contrib"&& contrib=",contrib_package" && usecontrib="--use-contrib" Boolean "no-sign-check" && nosigncheck="--no-sign-check" Is_Writable "${goboPrograms}" || Verify_Superuser Is_Writable "${goboInstall}" || Verify_Superuser # if $1 is an url: # 1 - Download; # 2 - Call InstallPackage on local file; # 3 - Remove local file (if not '--keep'). if Is_URL "$(Arg 1)" then url=$(Arg 1) filename=$(basename ${url}) #rm -f ${goboTemp}/`basename $1` Log_Normal "Downloading package to ${goboTemp}/${filename}." wget -c "${url}" -O "${goboTemp}/${filename}" || Die "Error downloading package." if [ "${keep}" ] then . "`Find_Conf GetAvailable.conf`" || Die "Couldn't read GetAvailable.conf" [ -d "${defaultLocalPackagesPaths[0]}" ] || mkdir -p "${defaultLocalPackagesPaths[0]}" Log_Normal "Moving package to ${defaultLocalPackagesPaths[0]}/${filename}." if mv "${goboTemp}/${filename}" "${defaultLocalPackagesPaths[0]}/${filename}" then InstallPackage ${unmanaged} ${usecontrib} ${noinstall} ${nosymlink} ${nosigncheck} ${keep} ${batch} "${defaultLocalPackagesPaths[0]}/${filename}" else Log_Error "Could not move package." InstallPackage ${unmanaged} ${usecontrib} ${noinstall} ${nosymlink} ${nosigncheck} ${keep} ${batch} "${goboTemp}/${filename}" fi else InstallPackage ${unmanaged} ${usecontrib} ${noinstall} ${nosymlink} ${nosigncheck} ${keep} ${batch} "${goboTemp}/${filename}" Log_Normal "Removing downloaded package ${goboTemp}/${filename}." rm -f -- "${goboTemp}/${filename}" fi exit 0 fi # if $1 is not a existing file nor a existing directory: # 1 - Try to find a package matching the exact version, or try to find any package for that program; # 2 - Calls InstallPackage passing the found url, or abort. function check_glibc_version_against_running_kernel_version() { glibc_version=$1 if [ -z "$glibc_version" ] || [ $(echo ${glibc_version} | sed 's/\([0-9]*\)\.\([0-9]\).*/\1\2/') -gt 24 ] && [ $(echo $(uname -r) | sed -e 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1\2\3/') -lt 2620 ] then Log_Error "You are trying to install a version of Glibc that requires a running kernel of version 2.6.20 or later." Die "Either it is not installed or you have not rebooted after you installed it. Please fix before trying install Glibc again." fi } if [ ! -e "$(Arg 1)" ] then # checking if there is not a '/' in $1 if ! { echo "$(Arg 1)" | Quiet grep "/" ;} then name="$(Arg 1)" version="$(Arg 2)" [ "$(Downcase ${name})" = "glibc" ] && check_glibc_version_against_running_kernel_version "${version}" Log_Normal "Locating a binary package for" ${name} ${version} "..." noweb=`Forward_Boolean_Entry "no-web"` pkgType="-t local_package,official_package${contrib}" if [ ${version} ] then found=`FindPackage $noweb $pkgType ${name} ${version}` if [ "${found}" ] then Log_Normal "Found package for ${name} ${version}: ${found}" InstallPackage ${unmanaged} ${usecontrib} ${noinstall} ${nosymlink} ${nosigncheck} ${keep} ${batch} "${found}" else Die_With $errorNotFound "Package for ${name} ${version} not found." fi else found=$(FindPackage $noweb $pkgType ${name}) if [ "${found}" ] then [ ! "$batch" ] && Ask_Continue "Installing ${found}" InstallPackage ${unmanaged} ${usecontrib} ${noinstall} ${nosymlink} ${nosigncheck} ${keep} ${batch} "${found}" else Die_With $errorNotFound "Package for ${name} not found." fi fi exit 0 else Die "$(Arg 1) is not an existing file or directory." fi fi if [ "${noinstall}" ] then Log_Normal "Skipping instalation of $(Arg 1)." exit 0 fi if [ -d "$(Arg 1)" ] # $1 is a directory then dir=$(Arg 1) if [ -L "${dir}/../Current" ] then packagedir=`readlink -f "${dir}"` elif [ -L "${dir}/Current" ] then packagedir=`readlink -f "${dir}/Current"` else Die "${dir} does not seem to be a valid GoboLinux package." fi basedir=`echo "$packagedir" | sed 's/\(.*\)\/\([^\/].*\)\/\([^\/].*\)/\1/'` if [ "$basedir" == "${goboPrograms}" ] then Die "Source and destination directory are the same ($packagedir)" fi packagename=`Get_Token "$packagedir" "/" "-2"` packageversion=`Get_Token "$packagedir" "/" "-1"` packagearch="i686" # General assumption packagetype="directory" else # $1 is a file filename="$(Arg 1)" if ! { echo "${filename}" | grep -- "--" &> /dev/null ;} then Die "${filename} does not seem to be a valid GoboLinux package." fi # Removing all possible extensions... noext=`basename "${filename}"` for extension in ".gz" ".bz2" ".zip" ".tgz" ".tbz" ".tar" do noext=`basename "$noext" "$extension"` done packagename=`Get_Token "$noext" "--" "0"` packageversionrevision=`Get_Token "$noext" "--" "1"` packageversion=`String_Version $packageversionrevision` packagerevision=`String_Revision $packageversionrevision` if echo "$noext" | Quiet grep ".*--.*--.*" then packagearch=`Get_Token "$noext" "--" "2"` else packagearch="i686" # All old packages are i686 fi packagetype="file" packageversion=`echo $packageversion | sed 's/-PersonalBackup//'` archive=`readlink -f "${filename}"` fi unset sameversion existingpackage=`ls "${goboPrograms}" | grep -i "^$packagename$"` [ "$existingpackage" ] && { Is_Entry "old" "cancel" && Pass_Away "An old version of $packagename already exists." Is_Entry "old" "remove" && doremove=yes Is_Entry "old" "ask" && { Log_Terse "Another version of this package already exists." doremove=yes doask=yes } if [ -e "${goboPrograms}/$existingpackage/$packageversion" ] then Is_Entry "same" "cancel" && Pass_Away "Attempting to install $packagename over same version." Is_Entry "same" "remove" && doremove=yes Is_Entry "same" "ask" && { Log_Question "An installation of this same version already exists." doremove=yes doask=yes } fi } function try_remove() { [ "$doremove" = "yes" ] && { [ "$doask" = "yes" ] && { Ask_Option "Remove existing? [R]emove/[k]eep/[c]ancel" "R" '[ -n "$REPLY" -a -z "$(echo $REPLY | sed -r -e "s/((R|r)|(K|k)|(C|c))//")" ]' echo [ "$REPLY" = "C" -o "$REPLY" = "c" ] && exit 1 [ "$REPLY" = "K" -o "$REPLY" = "k" ] && return } rm -rf -- "${goboPrograms}/$existingpackage/$packageversion" } } try_remove Log_Normal "Installing $packagename, version $packageversion." if [ "$goboInstall" != "$goboPrograms" ] then if ! Is_Directory "${goboPrograms}/$packagename/$packageversion" then Make_Directory "${goboInstall}/$packagename/$packageversion" Make_Directory "${goboPrograms}/$packagename" ln -nsf "${goboInstall}/$packagename/$packageversion" "${goboPrograms}/$packagename/$packageversion" fi fi if [ "$packagetype" = "directory" ] then if [ ! -d "${goboPrograms}/$packagename" ] then mkdir "${goboPrograms}/$packagename" fi cp -ra "$packagedir" "${goboPrograms}/$packagename" else # XXX should use aunpack if Is_Extension "bz2" "$archive" then taroption="jxvpf" else taroption="zxvpf" fi Log_Normal "Uncompressing to ${goboPrograms}..." Verbose tar "$taroption" "$archive" -C "${goboPrograms}" fi # Checking correct revision if [ -f "${goboPrograms}/$packagename/$packageversion/Resources/Revision" ] then [ "$(cat ${goboPrograms}/$packagename/$packageversion/Resources/Revision 2>/dev/null)" != "$packagerevision" ] && Die "Package spoofing detected. Package revision for tarball ($packagerevision) does not match the package revision ($(cat ${goboPrograms}/$packagename/$packageversion/Resources/Revision 2>/dev/null))" elif [ -n "$packagerevision" ] then Log_Terse "No Revision file exists in ${goboPrograms}/$packagename/$packageversion/Resources. Cannot validate package revision." fi if [ -n "${nosigncheck}" ] then Log_Normal "Skipping package's signature verification." package_verified="true" else verify_opts="--quiet" package_verified="false" Boolean "verbose" && verify_opts="--verbose" Boolean "no-web" && verify_opts="${verify_opts} --no-web" VerifyProgram $verify_opts "$packagename" "$packageversion" result="$?" if [ $result -eq 0 ] then Log_Normal "Package Signature Verified" package_verified="true" elif [ $result -eq 2 ] then Log_Question "GnuPG not installed. Unable to verify signature" Ask_Continue "Continue install?" elif [ $result -eq 4 ] || [ $result -eq 5 ] then Log_Question "No signature. Unable to verify package" Ask_Continue "Continue install?" elif [ $result -eq 6 ] then Log_Question "Package signed with unknown signature. Unable to verify package" Ask_Continue "Continue install?" elif [ $result -eq 7 ] then Log_Question "Package file hash generate with incompatible version of Scripts. Unable to verify package" Ask_Continue "Continue install?" elif [ $result -eq 3 ] then Log_Error "Invalid signature. FileHash could not be verified." Log_Error "Suspect package in ${goboPrograms}/$packagename/$packageversion" exit 1 elif [ $result -eq 1 ] then Log_Error "Invalid FileHash. Package has been modified" Log_Error "Suspect package in ${goboPrograms}/$packagename/$packageversion" exit 1 fi fi # Hack for updating Glibc if [ -z "$ROOTLESS_GOBOLINUX" ] then glibcinstalledversion=`Get_Version Glibc Current` glibcrequiredversion=`grep -w Glibc "${goboPrograms}/$packagename/$packageversion/Resources/BuildInformation" 2> /dev/null | cut -f2 -d' '` if [ -n "$glibcrequiredversion" -a "`GuessLatest $glibcrequiredversion $glibcinstalledversion`" != "$glibcinstalledversion" ] then Log_Question "Installed package was built using a newer Glibc ($glibcrequiredversion)." Ask "Install an updated Glibc?" && InstallPackage Glibc fi fi cd "${goboPrograms}/$packagename" #Backward compatibility: if [ -d "$packageversion/Wrappers" ] then Log_Normal "Moving \"Wrappers\" directory inside \"Resources\"" [ -d "$packageversion/Resources" ] || mkdir "$packageversion/Resources" mv "$packageversion/Wrappers" "$packageversion/Resources" fi if [ -d "$packageversion/Defaults" ] then Log_Normal "Moving \"Defaults\" directory inside \"Resources\"" [ -d "$packageversion/Resources" ] || mkdir "$packageversion/Resources" mv "$packageversion/Defaults" "$packageversion/Resources/" fi Quiet cd - if [ "$packagename" = "Scripts" ] then cd "${goboPrograms}/$packagename/$packageversion" make --silent cd "${goboPrograms}/$packagename/$packageversion/bin" PATH=$PWD:$PATH ./SymlinkProgram Scripts "$packageversion" Quiet cd - exit 0 fi # Hack for updating Glibc if [ "$packagename" != "Glibc" ] then Boolean "no-updatesettings" || UpdateSettings "$packagename" "$packageversion" fi Boolean "no-symlink" || SymlinkProgram ${unmanaged} "$packagename" "$packageversion" [ "$package_verified" = "true" ] && Run_PostInstall "$packagename" "$packageversion" "" "" if ! Boolean "no-dependencies" then if ! Boolean "no-dependencies" && ! Boolean "no-build" then Log_Normal "Checking dependencies..." set -o pipefail selecteddeps=$(CheckDependencies --types=local_package,official_package${contrib} --mode=missing \ --quiet-progress "$packagename" "$packageversion" \ "installed" "${goboPrograms}/$packagename/$packageversion" | awk '{ print $4 }') || Die "Aborted." set +o pipefail for d_url in $selecteddeps do InstallPackage --no-dependencies ${unmanaged} ${usecontrib} ${noinstall} ${nosymlink} ${nosigncheck} ${keep} ${batch} $d_url || { ret=$? exit $ret } done fi # Dependencies --check --keep-going --higher-or-missing-only ${batch} --execute "$0 $keep" "$packagename" "$packageversion" fi Log_Verbose "Done." if [ "$existingpackage" ] then if [ "$existingpackage" != "$packagename" ] then Log_Verbose "The capitalization of the package name has changed" Log_Verbose "from '$existingpackage' to '$packagename'." fi fi