#!/bin/bash # a lightning fast search script for the portage tree # (C) 2003 Marius Mauch source /etc/make.conf # to get PORTDIR and PORTDIR_OVERLAY SEARCH_DB=/var/cache/edb/fastsearch_db # the name of the database file PROG_NAME=$(basename $0) # the name of this script for use in help messages # set the following to default if not set in make.conf [ -z "${PORTDIR}" ] && PORTDIR="/usr/portage" [ -z "${PORTDIR_OVERLAY}" ] && PORTDIR_OVERLAY="/usr/local/portage" # print a usage message print_help() { echo "Usage:" echo "${PROG_NAME} -h | --help | -u | --update | " echo -e "\t-h | --help: print this usage message" echo -e "\t-u | --update: (re-)create the search database" echo -e "\t-i | --info: show some information about the database" echo "mode-option is one of:" echo -e "\t-d | --description: search in descriptions" echo -e "\t-n | --name: search in package names" echo -e "\t-l | --long-desc: search in long descriptions" echo -e "\t-a | --all: search in all fields" echo 'pattern is a grep regular expression to search for (^ and $ might not work as expected)' echo "grep-option is one or more options for grep to manipulate the search" } # imports the names and descriptions of all packages in the given directory # into the database. # # $1: directory to import import_category() { if [ -d "${1}" ]; then echo " reading category ${1} ..." for P in "${1}"/*; do EBUILD=$(ls -v ${P}/*.ebuild 2> /dev/null | tail -1) if [ ${EBUILD} ]; then # get only the variable assignment and strip the quotes, # might cause problems if the description itself contains quotes DESCRIPTION=$(grep DESCRIPTION\= ${EBUILD} | cut -d\= -f 2 | cut -d\" -f 2) printf "%-30s%s\n" "${P}::" "${DESCRIPTION}" >> "${SEARCH_DB}.new" else echo " No ebuilds for package ${P}, skipping" fi done else # some categories might have entries in the categories file # but no corresponding directory caused by RSYNC_EXCLUDE or other # user modifications echo " No directory for category ${1}, skipping" fi } # the main script starts here case "$1" in -h | --help) print_help exit 0 ;; -n | --name) MODE=SEARCH FIELD=NAME ;; -d | --description) MODE=SEARCH FIELD=DESC ;; -a | --all) MODE=SEARCH FIELD=ALL ;; -l | --long) # reserved for future versions echo "not implemented yet" exit 3 ;; -u | --update) MODE=UPDATE ;; -i | --info) MODE=INFO ;; -*) echo "I don't know this option: $1" print_help exit 1 ;; *) if [ -z "${1}" ]; then echo "I need at least one option" print_help exit 1 else echo "No mode option given, assuming name search" MODE=SEARCH FIELD=NAME set - "${1}" "${1}" # set $2=$1 fi ;; esac if [ "${MODE}" == "SEARCH" -a -z "$2" ]; then echo "I need a pattern to search for" print_help exit 1 fi if [ "${MODE}" == "INFO" ]; then echo -n "Database was last updated on: " stat "${SEARCH_DB}" 2> /dev/null | grep -i modify | cut -b 9-27 echo -n "Database size: " du -sh "${SEARCH_DB}" 2> /dev/null | cut -f 1 echo -n "Number of indexed packages: " wc -l "${SEARCH_DB}" 2> /dev/null | tr -c -d [:digit:] echo echo -n "Last emerge sync was on: " stat "${PORTDIR}/metadata" 2> /dev/null | grep -i modify | cut -b 9-27 fi if [ "${MODE}" == "UPDATE" ]; then [ -d $(dirname "${SEARCH_DB}") ] || mkdir -p $(dirname "${SEARCH_DB}") echo "Updating database ..." rm -f "${SEARCH_DB}.new" echo "importing packages from ${PORTDIR} ..." cd "${PORTDIR}" for C in $(grep -v packages profiles/categories); do import_category "${C}" done if [ -d "${PORTDIR_OVERLAY}" ]; then echo "importing packages from ${PORTDIR_OVERLAY} ..." cd "${PORTDIR_OVERLAY}" for C in *; do import_category "${C}" done fi mv -f "${SEARCH_DB}.new" "${SEARCH_DB}" echo "Finished updating" exit fi if [ ! -f "${SEARCH_DB}" ]; then echo "no search database found, you should create it with \"${PROG_NAME} --update\"" echo "see \"${PROG_NAME} --help\" for a description of all options" exit 2 fi PATTERN=$2 shift shift GREP_OPTIONS="${GREP_OPTIONS} $*" case "${FIELD}" in NAME) grep ${GREP_OPTIONS} "${PATTERN/^//}.*::" "${SEARCH_DB}" ;; DESC) grep ${GREP_OPTIONS} "::.*${PATTERN}" "${SEARCH_DB}" ;; ALL) grep ${GREP_OPTIONS} "${PATTERN}" "${SEARCH_DB}" ;; esac [ "$?" != "0" ] && echo "no matching entries found"