You are not logged in.

#1 2009-09-19 00:39:13

ConnorBehan
Package Maintainer (PM)
From: Long Island NY
Registered: 2007-07-05
Posts: 1,359
Website

Slow and insecure but feature-rich pacman wrapper in bash

This project of mine started because I want to compile my packages in a way that lets me delete gnome apps. Here's the problem: I see that evince depends on gnome-keyring, gnome-keyring depends on gconf and alltray depends on gconf. This leads me to think that if I recompile evince to not use gnome-keyring and recompile alltray to not use gconf, I can delete gconf.

NO!

I have to recompile evince to not use gconf as well because little do I know from pacman's dependency handling... gconf is a direct (but second level) dependency of evince as it's compiled as well.

This is a pretty standard problem. It's the reason why debian dependency lists are so damn long. I don't want Arch to move to a system like that... well sort of. Here's what I did. I made a script that acts just like pacman but when you tell it to download and install a package, it tells pacman to only download that package into a separate cache, then it extracts the package, finds all dynamic executables in the package, uses ldd to determine their library dependencies, uses pacman -Qo to find packages that own these dependencies (and caches them in a file so they can be looked up more quickly in the future), applies some other enhancements that should be visible in the script, then adds the new dependencies to the depends array and makes sure that none are duplicated. It also formats the array so that it goes (original clean dependency list) kernel26 (new list). That way it can parse queries as well so -Qi will omit all the dependencies after kernel26 and the Required By section while -Qii shows everything. This is the perfect compromise for me. Not sure if it will be for you.

Other things it does:

* Checks if AUR packages need updating (but doesn't update them)
* Takes out docs and gconf schemas
* Cleans up man pages so there's no /usr/man and just /usr/share/man/man*
* Convers /usr/share/man/locale/man1/whatever.1.gz to /usr/share/man/man1/whatever-locale.1.gz
* Converts info pages to man pages with info2man and puts them in man9
* Gzips all man pages
* Allows replacing packages with -U
* Package specific stuff like disabling the firefox error console.

Regretably I had to make it play around with the md5sums. This essentially makes them useless but if I don't do this reinstalling a package that is in the main cache because this script put it there fails due to corruption. So you might want to get rid of this "feature" and probably the firefox / uvesafb /gstreamer / info2man stuff but this is cool so tell me what you think of it.

#!/bin/bash

function aur_check {
    STARTDIR=`pwd`
    cd /var/cache/pacman
    for r in `pacman -Qmq`; do
        wget "http://aur.archlinux.org/packages/$r/$r/PKGBUILD" >/dev/null 2>&1
        if [ $? -eq 0 ]; then
            LOCAL_VERSION_REL=`'pacman' -Q $r | awk '{print $2}'`
            LOCAL_VERSION=`echo $LOCAL_VERSION_REL| sed -e 's/-.*//g'`
            REMOTE_VERSION=`cat PKGBUILD | grep -E '^pkgver=' | sed -e 's/pkgver=//g' | sed -e 's/[ ]*//g'`
            REMOTE_REL=`cat PKGBUILD | grep -E '^pkgrel=' | sed -e 's/pkgrel=//g'`
            if [[ "$LOCAL_VERSION" < "$REMOTE_VERSION" ]]; then
                printf "warning: $r: ignoring package upgrade ($LOCAL_VERSION_REL => ${REMOTE_VERSION}-${REMOTE_REL})\n"
            fi
        rm PKGBUILD
        fi
    done
    cd $STARTDIR
}

function sync_check {
    STARTDIR=`pwd`
    cd /var/cache/pacman
    IGNORED_PACKAGES=`cat /etc/pacman.conf | grep -E '^IgnorePkg' | sed -e 's/IgnorePkg[ ]*=[ ]*//g'`
    for s in $IGNORED_PACKAGES; do
        REMOTE_VERSION_STRING=`'pacman' -Si $s 2>/dev/null | grep -E '^Version'`
        if [ $? -eq 0 ]; then
            REMOTE_VERSION_REL=`echo $REMOTE_VERSION_STRING | awk '{print $3}'`
            LOCAL_VERSION_STRING=`'pacman' -Q $s 2>/dev/null`
            if [ $? -eq 0 ]; then
                LOCAL_VERSION_REL=`echo $LOCAL_VERSION_STRING | awk '{print $2}'`
                printf "warning: $s: ignoring package upgrade ($LOCAL_VERSION_REL => $REMOTE_VERSION_REL)\n"
            fi
        fi
    done
    cd $STARTDIR
}

function remove_crap {
    # No docs or schemas.
    rm -rf 2>/dev/null ./usr/share/doc
    rm -rf 2>/dev/null ./usr/share/gtk-doc
    rm -rf 2>/dev/null ./etc/gconf
    # Please delete this file. It is not necessary for linking the library.
    find . -name "*.la" -exec rm {} \;
    # Only one man directory please.
    if [ -d ./usr/man ]; then
        if [ ! -d ./usr/share ]; then
            mkdir ./usr/share
        fi
        mv ./usr/man ./usr/share/man
    fi
    if [ -d ./usr/share/man ]; then
        cd ./usr/share/man
        ls | grep 'cat' | xargs rm -rf
        if [ -d ./man ]; then
            mv ./man/* .
            rm -rf ./man
        fi
        # Imposes what I consider to be a better naming convention for some reason.
        for t in `ls`; do
            if [ $t != 'man0' ] && [ $t != 'man1' ] && [ $t != 'man2' ] && [ $t != 'man3' ] && [ $t != 'man4' ] && [ $t != 'man5' ] && [ $t != 'man6' ] && [ $t != 'man7' ] && [ $t != 'man8' ] && [ $t != 'man9' ] && [ $t != 'mann' ] && [ $t != 'manm' ]; then
                cd $t
                for u in `ls`; do
                    cd $u
                    for v in `ls`; do
                        SECOND_LAST_EXTENSION=`echo $v | sed -e 's/\.gz$//g' | rev | sed -e 's/\..*//g' | rev`
                        PREFIX=`echo $v | sed -e 's/\.gz$//g' | sed -e "s/\.${SECOND_LAST_EXTENSION}//g"`
                        SUFFIX=`echo $v | sed -e "s/$PREFIX//g"`
                        if [ ! -h $v ]; then    
                            install -D $v ../../${u}/${PREFIX}-${t}${SUFFIX}
                        else
                            TARGET=`readlink $v`
                            TARGET_SECOND_LAST_EXTENSION=`echo $TARGET | sed -e 's/\.gz$//g' | rev | sed -e 's/\..*//g' | rev`
                            TARGET_PREFIX=`echo $TARGET | sed -e 's/\.gz$//g' | sed -e "s/\.${TARGET_SECOND_LAST_EXTENSION}//g"`
                            TARGET_SUFFIX=`echo $TARGET | sed -e "s/${TARGET_PREFIX}//g"`
                            install -d ../../${u}
                            ln -s ${TARGET_PREFIX}-${t}${TARGET_SUFFIX} ../../${u}/${PREFIX}-${t}${SUFFIX}
                        fi
                    done
                    cd ..
                done
                cd ..
                rm -rf $t
            fi
        done
        # Now that it is nicely organized we can gzip everything and add symlinks.
        for x in `ls`; do
            cd $x
            for y in `ls`; do
                echo $y | grep -q -E '\.gz$'
                if [ $? -ne 0 ]; then
                    gzip $y >/dev/null 2>&1
                    SECOND_LAST_EXTENSION=`echo $y | rev | sed -e 's/\..*//g' | rev`
                    PREFIX=`echo $y | sed -e "s/\.${SECOND_LAST_EXTENSION}//g"`
                    NEW_NAME=`echo $PREFIX | sed -e 's/\./-/g'`
                    if [ $NEW_NAME != $PREFIX ]; then
                        ln -s ${y}.gz ${NEW_NAME}.${SECOND_LAST_EXTENSION}.gz
                    fi
                else
                    SECOND_LAST_EXTENSION=`echo $y | sed -e 's/\.gz$//g' | rev | sed -e 's/\..*//g' | rev`
                    PREFIX=`echo $y | sed -e 's/\.gz//g' | sed -e "s/\.${SECOND_LAST_EXTENSION}//g"`
                    NEW_NAME=`echo $PREFIX | sed -e 's/\./-/g'`
                    if [ $NEW_NAME != $PREFIX ]; then
                        ln -s ${y} ${NEW_NAME}.${SECOND_LAST_EXTENSION}.gz
                    fi
                fi
            done
            cd ..
        done
        cd ../../..
    fi
    # Converts info pages to man pages in the man9 directory
    if [ -d ./usr/share/info ]; then
        if [ -d ./usr/share/man ]; then
            mkdir ./usr/share/man/man9
        else
            mkdir ./usr/share/man
            mkdir ./usr/share/man/man9
        fi
        cd ./usr/share/info
        for z in `ls`; do
            echo $z | grep -q -E '\.gz$'
            if [ $? -eq 0 ]; then
                NAME=`echo $z | sed -e 's/\.gz$//g'`
                NEWNAME=`echo $NAME | sed -e 's/\./-/g'`
                gunzip $z
                info2man $NAME > ../man/man9/${NEWNAME}
                gzip ../man/man9/${NEWNAME} >/dev/null 2>&1
            else
                NEWNAME=`echo $z | sed -e 's/\./-/g'`
                info2man $z > ../man/man9/${NEWNAME}
                gzip ../man/man9/${NEWNAME} >/dev/null 2>&1
            fi
        done
        cd ../../..
        rm -rf ./usr/share/info
    fi
}

function install_with_u {
    ULTIMATE_ANSWER="y"
    # Checks if there are package conflicts
    CONFLICTS=`cat .PKGINFO | grep 'conflict = ' | awk '{print $3}'`
    ACTUAL_CONFLICTS=""
    for p in $CONFLICTS; do
        VERSION_CHECK=0
        CONFLICTING_PACKAGE=`echo $p | sed -r 's/(>|=|<).*//g'`
        # Checks if these conflicts actually affect packages on the system
        'pacman' -Q $CONFLICTING_PACKAGE >/dev/null 2>&1
        if [ $? -eq 0 ]; then
            AFFECTED=1
            if [ ${#p} -gt ${#CONFLICTING_PACKAGE} ]; then
                AFFECTED=0
                # If a version is specified, finds it out and sees if we're affected
                CONFLICTING_VERSION_STRING=${p:${#CONFLICTING_PACKAGE}:${#p}-${#CONFLICTING_PACKAGE}}
                RELATION=${CONFLICTING_VERSION_STRING:1:2}
                if [ "$RELATION" = "=" ]; then
                    RELATION=${CONFLICTING_VERSION_STRING:0:1}${RELATION}
                    CONFLICTING_VERSION=${CONFLICTING_VERSION_STRING:2:${#CONFLICTING_VERSION_STRING}-2}
                else
                    RELATION=${CONFLICTING_VERSION_STRING:0:1}
                    CONFLICTING_VERSION=${CONFLICTING_VERSION_STRING:1:${#CONFLICTING_VERSION_STRING}-1}
                fi
                ACTUAL_VERSION=`pacman -Q $CONFLICTING_PACKAGE | awk '{print $2}'`
                if [ "$RELATION" = ">" ]; then
                    if [[ "$ACTUAL_VERSION" > "$CONFLICTING_VERSION" ]]; then
                        AFFECTED=1
                    fi
                elif [ "$RELATION" = "<" ]; then
                    if [[ "$ACTUAL_VERSION" < "$CONFLICTING_VERSION" ]]; then
                        AFFECTED=1
                    fi
                elif [ "$RELATION" = ">=" ]; then
                    if [ "$ACTUAL_VERSION" >= "$CONFLICTING_VERSION" ]; then
                        AFFECTED=1
                    fi
                elif [ "$RELATION" = "<=" ]; then
                    if [ "$ACTUAL_VERSION" <= "$CONFLICTING_VERSION" ]; then
                        AFFECTED=1
                    fi
                else
                    if [ "$ACTUAL_VERSION" = "$CONFLICTING_VERSION" ]; then
                        AFFECTED=1
                    fi
                fi
            fi
            if [ $AFFECTED -ne 0 ]; then
                ACTUAL_CONFLICTS="$ACTUAL_CONFLICTS $CONFLICTING_PACKAGE"
                printf ":: ${1} conflicts with ${CONFLICTING_PACKAGE}. Remove ${CONFLICTING_PACKAGE}? [Y/n] "
                read ANSWER
                if [ $ANSWER != "Y" ] && [ $ANSWER != "y" ]; then
                    ULTIMATE_ANSWER="n"
                    break
                fi
            fi
        fi
    done
    if [ $ULTIMATE_ANSWER = "y" ]; then
        for q in $ACTUAL_CONFLICTS; do
            'pacman' -Rd ${q}
        done
        return 0
    fi
    return 1
}

function get_deps {
    PACKAGE_NAME=`cat .PKGINFO | grep 'pkgname = ' | sed -e 's/pkgname = //g'`
    
    # Does a few package specific things
    if [ $PACKAGE_NAME = "kernel26" ]; then
        ln -s /etc/uvesafb.conf /etc/uvesafb
    elif [ $PACKAGE_NAME = "firefox" ]; then
        cd ./usr/lib
        FIREFOX_DIR=`ls | grep 'firefox'`
        if [ $? -eq 0 ]; then
            cd $FIREFOX_DIR/chrome
            jar -xf ./browser.jar
            rm ./browser.jar
            sed -i -e '/console.xul/s/^/\/\//g' ./content/browser/browser.js
            jar -cf browser.jar content
            rm -r content
            cd ../..
        fi
        cd ../..
    elif [ $PACKAGE_NAME = "gstreamer0.10-good-plugins" ]; then
        rm ./usr/lib/gstreamer0.10/libgstesd.so
    fi
    
    POSSIBLE_LIBS=`find . -type f | grep -E '(\.so\.|\.so$)'`
    POSSIBLE_BINS=`find . -type f | grep -v 'PKGINFO' | grep -v -E '\/.*\.[a-zA-Z0-9]+$' | grep -v 'LICENSE'`
    POSSIBLE_ELFS="$POSSIBLE_LIBS $POSSIBLE_BINS"
    DEPS=""

    # Makes a list of all the direct dependencies
    for i in $POSSIBLE_ELFS; do
        #echo "SCANNING: $i"
        ldd $i >/dev/null 2>&1
        if [ $? -eq 0 ]; then
            # Caches the shared libraries in a file to make it easier for everything else to look them up
            DIRNAME=`dirname ${i:1:${#i}}`
            echo "$i" | grep -q ".so"
            if [ $? -eq 0 ]; then
                if [ "$DIRNAME" = "/lib" ] || [ "$DIRNAME" = "/usr/lib" ]; then
                    grep -q "${i:1:${#i}} $PACKAGE_NAME" /var/cache/pacman/quicklookup
                    # If this package's library assigned to this package was not found...
                    if [ $? -ne 0 ]; then
                        grep -q "${i:1:${#i}}" /var/cache/pacman/quicklookup
                        # It may have been assigned to another package so we change that
                        if [ $? -eq 0 ]; then
                            sed -i -e "/${i:1:${#i}}/d" /var/cache/pacman/quicklookup
                        fi
                        # Otherwise we just assign it to this package
                        echo "${i:1:${#i}} $PACKAGE_NAME" >> /var/cache/pacman/quicklookup
                    fi
                fi
            fi
            # Figures out what packages own the library dependencies
            POSSIBLE_DEPS=`ldd $i 2>/dev/null | grep '=> ' | grep -v '=>  ' | sed -e 's/.* => //g' | sed -e 's/ (.*//g'`
            for j in $POSSIBLE_DEPS; do
                DIRNAME=`dirname $j`
                if [ "$DIRNAME" = "/lib" ] || [ "$DIRNAME" = "/usr/lib" ]; then
                    OWNER=`grep "$j" /var/cache/pacman/quicklookup`
                    # The owner of the dep is either already in the quicklookup file
                    if [ $? -eq 0 ]; then
                        OWNER=`echo $OWNER | awk '{print $2}'`
                        DEPS="$DEPS $OWNER"
                    else
                        # Or it's part of the current package
                        BASENAME=`basename $j`
                        find . -name ${BASENAME} | grep -q "${BASENAME}"
                        if [ $? -eq 0 ]; then
                            echo "$j $PACKAGE_NAME" >> /var/cache/pacman/quicklookup
                        else
                            # Or we figure out its owner with pacman and put it in the quicklookup file
                            OWNER=`'pacman' -Qoq $j 2>/dev/null`
                            if [ $? -eq 0 ]; then
                                echo "$j $OWNER" >> /var/cache/pacman/quicklookup
                                DEPS="$DEPS $OWNER"
                            fi
                        fi
                    fi
                fi
            done
        fi
    done

    # Sticks a "kernel26" between the old dependencies and the new dependencies
    CURRENT_DEPS=`cat .PKGINFO | grep -E '^depend = ' | sed -e 's/depend = //g'`
    DEPS="$CURRENT_DEPS kernel26a $DEPS"

    # Puts them into the PKGINFO file so that all depend lines are contiguous
    grep -q -E '^depend = ' .PKGINFO
    if [ $? -eq 0 ]; then
        FIRST_DEPEND_LINE_NUMBER=`grep -n -E '^depend = ' .PKGINFO | head -1 | sed -e 's/:.*//g'`
        LAST_DEPEND_LINE_NUMBER=`grep -n -E '^depend = ' .PKGINFO | tail -1 | sed -e 's/:.*//g'`
        LAST_LINE_NUMBER=`wc -l .PKGINFO | awk '{print $1}'`
        (( DIFFERENCE=$LAST_LINE_NUMBER-$LAST_DEPEND_LINE_NUMBER ))
        cat .PKGINFO | tail -${DIFFERENCE} > .PKGINFO-3
        touch .PKGINFO-2
        (( FIRST_DEPEND_LINE_NUMBER-- ))
        cat .PKGINFO | head -${FIRST_DEPEND_LINE_NUMBER} > .PKGINFO-1
    else
        cp .PKGINFO .PKGINFO-1
        touch .PKGINFO-2
        touch .PKGINFO-3
    fi
    for k in $DEPS; do
        echo "depend = $k" >> .PKGINFO-2
    done
    # This is all so we don't get mesa and mesa=7.5 in the same dep array
    cat .PKGINFO-2 | awk '{print $3}' | sed -r 's/(>=|>|=|<|<=)/ \1/g' > .RAW-DEPS
    cat .RAW-DEPS | awk '{print $1}' > .COL-1
    cat .RAW-DEPS | awk '{print $2}' > .COL-2
    # Got this from sed1line.txt... it removes duplicate lines
    sed -i -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P' .COL-1
    paste --delimiter="" .COL-1 .COL-2 > .RAW-DEPS
    sed -i -e "/${PACKAGE_NAME}/d" .RAW-DEPS
    sed -i -e 's/kernel26a/kernel26/g' .RAW-DEPS
    sed -e 's/^/depend = /g' .RAW-DEPS > .PKGINFO-2
    sed -i -e "/depend =[ ]*$/d" .PKGINFO-2
    cat .PKGINFO-1 .PKGINFO-2 .PKGINFO-3 > .PKGINFO
    rm .PKGINFO-1 .PKGINFO-2 .PKGINFO-3 .RAW-DEPS .COL-1 .COL-2
}

function do_install {
    STARTDIR=`pwd`
    cd /var/cache/pacman/tmp
    for l in `ls -tr`; do
        TEMP_DIR=`echo $l | sed -r 's/(-i686|-x86_64|-any|)\.pkg\.tar\.gz//g'`
        # Extracts the package and makes the necessary modifications to it
        mkdir $TEMP_DIR
        mv $l $TEMP_DIR
        cd $TEMP_DIR
        tar -xf $l >/dev/null 2>&1
        rm $l
        remove_crap
        get_deps
        # Retars the package and installs it
        if [ -e .INSTALL ]; then
            tar -cf $l .INSTALL .PKGINFO * >/dev/null 2>&1
        else
            tar -cf $l .PKGINFO * >/dev/null 2>&1
        fi
        # Installs it and puts it in the cache
        install_with_u $l
        if [ $? -eq 0 ]; then
            'pacman' -Udf $l
        else
            mv $l ../../pkg
            cd ..
            rm -r $TEMP_DIR
            break;
        fi
        mv $l ../../pkg
        cd ..
        rm -r $TEMP_DIR
    done
    cd $STARTDIR
}

function get_answer {
    read ANSWER
    echo $ANSWER > /var/cache/pacman/answer
    echo $ANSWER
}

if [ "$1" = "-Syu" ]; then
    sync_check
    aur_check
    'pacman' --cachedir /var/cache/pacman/tmp -Syuw
    do_install
elif [ "$1" = "-Su" ]; then
    sync_check
    aur_check
    'pacman' --cachedir /var/cache/pacman/tmp -Suw
    do_install
elif [ "$1" = "-S" ]; then
    shift
    PACKAGE_ARRAY=""
    # If something we're installing is in the cache... move it to the temporary cache
    for n in $@; do
        if [ ${n:0:1} != "-" ]; then
            NUM_MATCHES=`ls -1 /var/cache/pacman/pkg | grep -E "^${n}-" | wc -l`
            for o in `seq 1 $NUM_MATCHES`; do
                POSSIBLE_MATCH=`ls /var/cache/pacman/pkg | grep -E "^${n}-" -m${o} | tail -1`
                HYPHENS=`echo $POSSIBLE_MATCH | sed -e "s/${n}//g" | grep -o "-" | wc -l`
                if [ $HYPHENS -le 3 ]; then
                    mv /var/cache/pacman/pkg/${POSSIBLE_MATCH} /var/cache/pacman/tmp
                    # Changes the stored md5sum temporarily - I don't know a better way to do this
                    TEMP_DIR=`echo ${POSSIBLE_MATCH} | sed -r 's/(-i686|-x86_64|-any|)\.pkg\.tar\.gz//g'`
                    find /var/lib/pacman/sync -name $TEMP_DIR | grep -q $TEMP_DIR
                    if [ $? -eq 0 ]; then
                        MD5SUM=`md5sum /var/cache/pacman/tmp/${POSSIBLE_MATCH} | awk '{print $1}'`
                        REPOS=`find /var/lib/pacman/sync -name $TEMP_DIR | sed -e 's/\// /g' | awk '{print $5}'`
                        sed -i '/%MD5SUM%/G' /var/lib/pacman/sync/$REPOS/$TEMP_DIR/desc
                        MD5_LINE_NUMBER=`grep -n '%MD5SUM%' /var/lib/pacman/sync/$REPOS/$TEMP_DIR/desc | sed -e 's/:.*//g'`
                        (( MD5_LINE_NUMBER++ ))
                        sed -i -e "${MD5_LINE_NUMBER}s/.*/${MD5SUM}/" /var/lib/pacman/sync/$REPOS/$TEMP_DIR/desc
                        PACKAGE_ARRAY="${PACKAGE_ARRAY} ${REPOS}/${TEMP_DIR}"
                    fi
                    break;
                fi
            done
        fi
    done
    # Pacman is run and then a function reads a y or an n from stdin and passes it to pacman's stdin
    get_answer | 'pacman' --cachedir /var/cache/pacman/tmp -Sw $@
    # The function also saves it in a file so we know whether to proceed or cancel because pacman was cancelled
    LETTER=`cat /var/cache/pacman/answer`
    if [ "$LETTER" != "y" ] || [ "$LETTER" != "Y" ]; then
        do_install
    else
        # If anything got moved to the temporary cache for this it is sent back to the main one
        FILES_IN_CACHE=`ls /var/cache/pacman/tmp | wc -l`
        if [ $FILES_IN_CACHE -ne 0 ]; then
            mv /var/cache/pacman/tmp/* /var/cache/pacman/pkg
        fi
    fi
    # Changes all the md5sums back
    for w in $PACKAGE_ARRAY; do
        MD5_LINE_NUMBER=`grep -n '%MD5SUM%' /var/lib/pacman/sync/$w/desc | sed -e 's/:.*//g'`
        (( MD5_LINE_NUMBER++ ))
        sed -i -e "${MD5_LINE_NUMBER}d" /var/lib/pacman/sync/$w/desc
    done
elif [ "$1" = "-U" ]; then
    STARTDIR=`pwd`
    TEMP_DIR=`echo $2 | sed -r 's/(-i686|-x86_64|-any|)\.pkg\.tar\.gz//g'`
    mkdir /var/cache/pacman/$TEMP_DIR
    cp "$2" /var/cache/pacman/$TEMP_DIR
    cd /var/cache/pacman/$TEMP_DIR
    tar -xf $2 >/dev/null 2>&1
    rm $2
    get_deps
    # Retars the package and installs it
    if [ -e .INSTALL ]; then
        tar -cf $2 .INSTALL .PKGINFO * >/dev/null 2>&1
    else
        tar -cf $2 .PKGINFO * >/dev/null 2>&1
    fi
    install_with_u $2
    if [ $? -eq 0 ]; then
        'pacman' -U $2
    fi
    cd ..
    rm -r $TEMP_DIR
    cd $STARTDIR
elif [ "$1" = "-Qi" ] || [ "$1" = "-Qii" ]; then
    INITIAL_ARG=$1
    shift
    if [ "$INITIAL_ARG" = "-Qi" ]; then
        'pacman' -Qi $@ > /var/cache/pacman/tempquery
    else
        'pacman' -Qii $@ > /var/cache/pacman/tempquery
    fi
    if [ $? -ne 0 ] || [ ! -e /var/cache/pacman/tempquery ]; then
        exit 1
    fi
    
    # Filters out all deps after kernel26 for a regular query
    # Filters out all deps before kernel26 for a verbose query
    if [ $? -eq 0 ]; then
        START_LINE_NUMBER=`cat /var/cache/pacman/tempquery | grep -n 'Depends On' | sed -e 's/:.*//g'`
        LINE_NUMBER=$START_LINE_NUMBER
        (( LINE_NUMBER=$LINE_NUMBER+1 ))
        cat /var/cache/pacman/tempquery | head -${LINE_NUMBER} | tail -1 | grep ':'>/dev/null 2>&1
        while [ $? -ne 0 ]; do
            (( LINE_NUMBER=$LINE_NUMBER+1 ))
            cat /var/cache/pacman/tempquery | head -${LINE_NUMBER} | tail -1 | grep ':'>/dev/null 2>&1
        done
        (( END_LINE_NUMBER=$LINE_NUMBER-1 ))
        (( DIFFERENCE=$LINE_NUMBER-$START_LINE_NUMBER ))
        OLD_DEP_LIST=`cat /var/cache/pacman/tempquery | head -${END_LINE_NUMBER} | tail -${DIFFERENCE} | sed -e 's/.* : //g' | sed -e 's/                 //g'`

        for k in $OLD_DEP_LIST; do
            if [ "$INITIAL_ARG" = "-Qi" ]; then
                if [ "$k" != "kernel26" ]; then
                    NEW_DEP_LIST="$NEW_DEP_LIST $k"
                else
                    break
                fi
            else
                if [ "$k" != "kernel26" ]; then
                    NEW_DEP_LIST="$NEW_DEP_LIST $k"
                fi
            fi
        done
    fi
    
    # Removes the old deps array and replaces it with the new one
    sed -i -e "${START_LINE_NUMBER},${END_LINE_NUMBER}d" /var/cache/pacman/tempquery
    (( START_LINE_NUMBER=$START_LINE_NUMBER-1 ))
    END_LINE_NUMBER=`wc -l /var/cache/pacman/tempquery | awk '{print $1}'`
    (( DIFFERENCE=$END_LINE_NUMBER-$START_LINE_NUMBER ))
    cat /var/cache/pacman/tempquery | head -${START_LINE_NUMBER} > /var/cache/pacman/tempquery-1
    cat /var/cache/pacman/tempquery | tail -${DIFFERENCE} > /var/cache/pacman/tempquery-3
    CURRENT_LINE=""
    CURRENT_LINE_NUMBER=1
    for m in $NEW_DEP_LIST; do
        if (( ${#CURRENT_LINE}+${#m}+1<=63 )); then
            CURRENT_LINE="$CURRENT_LINE $m"
        else
            if [ $CURRENT_LINE_NUMBER -eq 1 ]; then
                printf "Depends On     :$CURRENT_LINE\n" >> /var/cache/pacman/tempquery-2
            else
                printf "\t\t$CURRENT_LINE\n" >> /var/cache/pacman/tempquery-2
            fi
            CURRENT_LINE=" $m"
            CURRENT_LINE_NUMBER=0
        fi
    done
    if [ $CURRENT_LINE_NUMBER -eq 1 ]; then
        printf "Depends On     :$CURRENT_LINE\n" >> /var/cache/pacman/tempquery-2
    else
        printf "\t\t$CURRENT_LINE\n" >> /var/cache/pacman/tempquery-2
    fi
    cat /var/cache/pacman/tempquery-1 /var/cache/pacman/tempquery-2 /var/cache/pacman/tempquery-3 > /var/cache/pacman/tempquery
    
    # Removes the requirements array for a regular query
    if [ "$INITIAL_ARG" = "-Qi" ]; then
        START_LINE_NUMBER=`cat /var/cache/pacman/tempquery | grep -n 'Required By' | sed -e 's/:.*//g'`
        LINE_NUMBER=$START_LINE_NUMBER
        (( LINE_NUMBER=$LINE_NUMBER+1 ))
        cat /var/cache/pacman/tempquery | head -${LINE_NUMBER} | tail -1 | grep ':'>/dev/null 2>&1
        while [ $? -ne 0 ]; do
            (( LINE_NUMBER++ ))
            cat /var/cache/pacman/tempquery | head -${LINE_NUMBER} | tail -1 | grep ':'>/dev/null 2>&1
        done
        (( END_LINE_NUMBER=$LINE_NUMBER-1 ))
        sed -i -e "${START_LINE_NUMBER},${END_LINE_NUMBER}d" /var/cache/pacman/tempquery
    fi
    
    cat /var/cache/pacman/tempquery
    rm /var/cache/pacman/tempquery /var/cache/pacman/tempquery-1 /var/cache/pacman/tempquery-2 /var/cache/pacman/tempquery-3
elif [ "$1" = "-Scc" ]; then
    LINE_NUMBER=0
    for z in `cat /var/cache/pacman/quicklookup | awk '{print $1}'`; do
        (( LINE_NUMBER++ ))
        if [ ! -e $z ]; then
            sed -i -e "${LINE_NUMBER}d" /var/cache/pacman/quicklookup
            (( LINE_NUMBER-- ))
        fi
    done
    'pacman' -Scc
else
    'pacman' $@
fi

Last edited by ConnorBehan (2009-09-19 00:42:48)


6EA3 F3F3 B908 2632 A9CB E931 D53A 0445 B47A 0DAB
Great things come in tar.xz packages.

Offline

Board footer

Powered by FluxBB