Archive for October, 2009

how much time you got?

October 23rd, 2009

One of the most important currencies of today is time. Of course, people have always been trading in time, paying people to do things for them that they were either too lazy, or "too important", to do. But in today's world time has gone as far as to replace money in the daily rhetoric of many people. I wonder if people in the past spent as much time complaining about not having enough time as it's common to do today. We have more freedoms and opportunities than ever, there's just no time to enjoy them all.

The biggest complaint among people today, once they stop complaining about lack of money, is lack of time. There is a strange kind of contempt for people who have time.
- Look at this cool thing these guys did.
- Yeah they really have a lot of time on their hands (those rich bastards!)

Strangely enough, there are also those who have a sense of pride about *not* having time. They just love fake-complaining to you about how busy they are. Well who decided you have to be so busy? Oh, I know, *you* did. Here, I have the solution for you. Ditch _everything_ that you're doing right now and you'll have more time than you ever dreamed of.

Being busy is also the standard way to lie to yourself when rejecting people. "Oh dear, I'd love to come to your whatever, but I'm just so darn busy". No, you just decided that you'd rather do something else. *I* know what it means, and you might as well just have told me that you weren't interested instead of telling yourself that you're a caring person who never lets anyone down. Because that's just plain obnoxious.

Now, what people seem to forget is that unlike money, time is very much your own choice. You don't choose to be born into a wealthy family, but you can easily choose to be rich on time. Here's a simple test: do you have a tv? Unplug it. You just won hours upon hours of time and it didn't cost you a dime! (Unless of course tv is what you most want to use your time for, but then you shouldn't complain about lack of time, you should revel in all the tv time you have!)

findpkgs: Find packages for application

October 14th, 2009

Every distribution has a package manager and a whole lot of work goes into maintaining packages and correctly resolving their dependencies. This is a descriptive kind of dependency tracking.

The other day I had the idea of using a more "evidence based" method. Given a linked binary, you can find out what libraries it uses with ldd. (This, however, will not account for any dynamic linking that happens during runtime.) More interestingly, perhaps, given a running process, you can figure out which files it using to run. There is lsof, and if not, /proc/pid/maps has that information too.

Such a list of files can then be fed to the package manager to find the packages which own them.

For instance, which package owns init (on an Ubuntu system)?

$ findpkgs 1
upstart

What's needed to run ls (on a Gentoo system)?

$ findpkgs ls
sys-apps/acl
sys-apps/attr
sys-apps/coreutils
sys-libs/glibc

What about a Python application like iotop?

$ findpkgs `pgrep iotop`
dev-lang/python
dev-libs/openssl
sys-libs/glibc
sys-libs/ncurses
sys-libs/zlib

The query-package-manager-for-owner-of-file tries to figure out which package manager is used on the system in this order:

  1. paludis
  2. qfile
  3. equery
  4. dpkg
  5. rpm

To be honest I'm not really sure how useful this is, I just put it together since I figured out it could be done. It *can* answer the question: which packages are required to run this application? (Or to be more precise: to achieve this specific runtime state of the application.) So if you write an app, send it to a friend and he can't make it run, you could use findpkgs to get a list of them he needs to install (provided he's on the same distro and all that).

# Author: Martin Matusiak <numerodix@gmail.com>
# Licensed under the GNU Public License, version 3
#
# <desc> Find packages by binary or process pid </desc>
#
# <usage>
# source this file in bash, then run `findpkgs`
# </usage>


function _findpkgfor() {
	local file="$1";shift;

	if which paludis &>/dev/null; then
		paludis -o "$file" 2>/dev/null | grep '::installed' \
			| sed "s/::installed//g" | tr -d ' '
	elif which qfile &>/dev/null; then
		qfile "$file" 2>/dev/null | awk '{print $1}'
	elif which equery &>/dev/null; then
		equery belongs "$file" 2>/dev/null | awk '{print $1}'
	elif which dpkg &>/dev/null; then
		dpkg -S "$file" 2>/dev/null | awk '{print $1}' | tr -d ':'
	elif which rpm &>/dev/null; then
		rpm -qf "$file" 2>/dev/null | grep -v "not owned"
	else
		echo "No known package manager found"
	fi
}

function findpkgs() {
	local arg="$1";shift;

	if [ ! "$arg" ]; then
		echo "Usage:  findpkgs [ pid | /path/to/binary ]"
		return
	fi

	local pid=
	local arg_new=
	local bin=
	if echo "$arg" | grep "^[0-9]*$" &>/dev/null; then
		pid="$arg"
	else
		arg_new=$(which "$arg" 2>/dev/null)
		[ "$arg_new" ] && arg="$arg_new"
		if ! echo "$arg" | grep '^/' &>/dev/null; then
			echo "Can't find absolute path (or not a binary) for: $arg" >&2
			return
		fi
		arg=$(readlink -f "$arg")
		if ! file "$arg" | grep 'ELF' &>/dev/null; then
			echo "Not a binary: $arg" >&2
			return
		fi
		bin="$arg"
	fi


	local fst=
	local fst_new=
	local files=
	if [ "$pid" ]; then
		fst=$(ps aux \
					| sed "s/^[^ ]* *//g" \
					| grep "^$pid " \
					| awk '{print $10}' \
					| tr -d ':')
		fst_new=$(which "$fst" 2>/dev/null)
		[ "$fst_new" ] && fst="$fst_new"
		if ! echo "$fst" | grep '^/' &>/dev/null; then
			echo "Can't find absolute path for: $fst" >&2
			unset fst
		fi

		if $(which lsof &>/dev/null); then
			files=$(lsof \
						| sed "s/^[^ ]* *//g" \
						| grep "^$pid " \
						| awk '{print $8}' \
						| grep '^/' \
						| sort \
						| uniq)
		else
			files=$(cat "/proc/$pid/maps" \
						| awk '{print $6}' \
						| grep '^/' \
						| sort \
						| uniq)
		fi

		files="$fst $files"
		for file in `echo $files`; do
			_findpkgfor "$file"
		done | sort | uniq

	elif [ "$bin" ]; then
		files=$(ldd "$bin" \
					| awk '{print $3}' \
					| grep '^/' \
					| sort \
					| uniq)
		files="$bin $files"
		for file in `echo $files`; do
			_findpkgfor "$file"
		done | sort | uniq
	fi
}