#!/usr/bin/env bash # # ------------------------------------------------------------------ # made by sputnick in da FreAkY lApPy lAb (c) 2009 # gilles.quenot gmail com # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # (see http://www.gnu.org/licenses/gpl.html). # ------------------------------------------------------------------ # ,,_ # o" )@ # '''' # ------------------------------------------------------------------ # # vim:ts=4:sw=4 # This script is coded to resolv dependencies for "yum" and "apt" packages managers. # There's no GUI interface, I think that's the most reliable instead of guessing anything. # It's not 100% reliable, but you could send me your feedback to improve it. # This script is based on autodeb from Lorenzo J. Lucchini. # Tested on a Debian Lenny and a Centos. # ------------------------------------------------------------------------------------- # https://wiki.edubuntu.org/AutoDeb sample : # Contrary to AutoApt, AutoDeb does not just install every file that 'configure' # happens to peek at. Instead, it lets 'configure' run and fail, at which point # it installs only the last package that 'configure' required, and repeats the process. # ------------------------------------------------------------------------------------- # TODO # - finir d'implementer archlinux ( pkgfile --update ) shopt -s nullglob Dp() { tput setaf ${1:?} tput bold if (($1 == 1)); then echo -e "$2" >&2 tput sgr0 else echo -e "$2" tput sgr0 fi if [[ $3 == [[:digit:]] ]]; then exit $3 else return 0 fi } Help() { Dp 2 "Usage : $0 command [args]" 0 } AutoAptUpdate(){ [[ -e ~/.autoAptTimeStamp ]] || touch -t 200000000000.00 ~/.autoAptTimeStamp DateNowInSecFromEpoch=$(( $(date +%s) - $(stat -c '%Y' ~/.autoAptTimeStamp) )) if (( DateNowInSecFromEpoch > 172800 )); then Dp 2 "On met a jour la base auto-apt, elle a plus de 2 jours..." ( /usr/bin/auto-apt update && /usr/bin/auto-apt updatedb && /usr/bin/auto-apt update-local ) && :> ~/.autoAptTimeStamp clear fi } if [[ -f /etc/redhat-release ]]; then case $(< /etc/redhat-release) in CentOS*) pm=yum PmInstall(){ yum -y install $@; } FindPackageForFile(){ Package=$(yum provides \*$1 | tail -1 | sed -r 's/[[:space:]].*//' | grep -v "^No[[:space:]]*") } ;; Red*) if [[ -x /usr/bin/yum ]]; then pm=yum PmInstall(){ yum install $@; } elif [[ -x /usr/sbin/up2date ]]; then Dp 1 "Sorry, this distro isn't compliant for the moment..." 1 fi ;; esac elif [[ -f /etc/debian_version && -x /usr/bin/apt-get ]]; then pm=apt-get DateNowInSecFromEpoch=$(( $(date +%s) - $(stat -c '%Y' /var/cache/apt/pkgcache.bin) )) if (( DateNowInSecFromEpoch > 172800 )); then apt-get update clear fi PmInstall(){ apt-get install -qq $@; } FindPackageForFile(){ dpkg -l | grep -q $1 && return Package=$(auto-apt check $1 | sed 's@.*/@@') } AutoAptUpdate elif [[ -f /etc/pacman.conf ]]; then pm=yaourt PmInstall(){ yaourt -S $@; } FindPackageForFile(){ pacman -Q | grep -q $1 && return Package=$(pkgfile -s $1) } else Dp 1 "Sorry, this distro isn't compliant for the moment..." 1 fi [[ $1 ]] || Help [[ -f /tmp/blacklist ]] || :> /tmp/blacklist Dp 2 "${pm:?} detected..." /usr/bin/strace -f -F -q -e trace=file,exit_group -e signal=none "$@" 2> >(grep 'ENOENT\|exit\|pkg\-config' > /tmp/trace) MainStatCalls=$(tac /tmp/trace | grep -v '\[' | grep stat | head -200 | grep -Eo '"(NONE)?/[^"[:space:]]+"') ForkStatCalls=$(tac /tmp/trace | grep '\[' | grep stat | head -200 | grep -Eo '"(NONE)?/[^"[:space:]]+"') MainMiscCalls=$(tac /tmp/trace | grep -v '\[' | grep -v stat | head -200 | grep -Eo '"(NONE)?/[^"[:space:]]+"') ForkMiscCalls=$(tac /tmp/trace | grep '\[' | grep -v stat | head -200 | grep -Eo '"(NONE)?/[^"[:space:]]+"') PkgConfigCalls=$(tac /tmp/trace | grep 'exec' | grep 'pkg-config' | grep -o '"[^-/",][^/", ]\+[" ]' | sed 's/[" ]$/.pc"/g') FileList=$(echo "$PkgConfigCalls $MainStatCalls $ForkStatCalls $MainMiscCalls $ForkMiscCalls" | \ grep -v 'bin/cat"\|bin/rm"\|bin/sort"\|bin/gsed"\|bin/mv"\|bin/awk"\|bin/sed"\|bin/cut"' | sed 's:"::g; s:NONE::g') for File in $FileList; do grep -q "$File" /tmp/blacklist && continue grep -q '^/tmp\|^/home\|^/root|^/usr/local' <<< "$File" && continue Dp 3 "Searching package for ${File}..." FindPackageForFile $File if [[ $Package && $Package == [[:alnum:]]* ]]; then Dp 2 "I've found : \n$Package\nPress a key or \"s\" to skip this file or ^C to quit..." read -n1 -s if [[ $REPLY == [Ss] ]]; then continue 2 else PmInstall $Package exit $? fi else echo $File >> /tmp/blacklist fi done