diff --git a/Makefile b/Makefile index 930569e..69a437c 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ sed-compat-bashlt4 = -e 'sx\$${\([a-zA-Z_]*\),,}x\$$(tr A-Z a-z <<<\$${\1})xg' \ PROGRAMS_C=beeversion beesep beecut beeuniq beesort beegetopt -PROGRAMS_SHELL=bee beesh +PROGRAMS_SHELL=bee beesh beefind PROGRAMS_PERL=beefind.pl HELPER_BEE_SHELL=bee-init bee-check bee-remove bee-install bee-list bee-query bee-download bee-update diff --git a/src/beefind.sh.in b/src/beefind.sh.in new file mode 100644 index 0000000..9854067 --- /dev/null +++ b/src/beefind.sh.in @@ -0,0 +1,269 @@ +#!/bin/bash +# +# beefind - scan directory and print files and metadata +# +# Copyright (C) 2009-2012 +# Tobias Dreyer +# Marius Tolzmann +# and other bee developers +# +# This file is part of bee. +# +# bee is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +BEE_VERSION="@BEE_VERSION@" + +: ${BEE_LIBEXECDIR:=@LIBEXECDIR@} +: ${BEE_BINDIR:=@BINDIR@} + +. ${BEE_LIBEXECDIR}/bee/beelib.config.sh + +: ${BEEVERSION:=${BEE_BINDIR}/beeversion} +: ${BEESEP=${BEE_BINDIR}/beesep} + +function usage() { + cat <<-EOF + beefind v${BEE_VERSION} 2009-2012 + by Tobias Dreyer and Marius Tolzmann <{dreyer,tolzmann}@molgen.mpg.de> + Max Planck Institute for Molecular Genetics Berlin Dahlem + + Usage: beefind [options] + + Options: + -c | --cutroot strip from displayed files + -e | --exclude ignore files matching + -s | --skiplist ignore files matching pattern described in + + -o | --output output is redirected into instead of + -d | --dump-files read and just display files; must contain + beefind output + + -h | --help display this help + + EOF +} + +function dump_files() { + local infile=${1} + + if [ ! -r "${infile}" ] ; then + print_warning "cannot read file '${infile}'" + exit 1 + fi + + for line in $(cat ${infile}) ; do + eval $(${BEESEP} ${line}) + + echo ${file%//*} + done +} + +function get_md5() { + local file=${1} + + if [ -L "${file}" ] ; then + md5='link' + elif [ -d "${file}" ] ; then + md5='directory' + elif [ -f "${file}" ] ; then + md5=$(md5sum ${file}) + md5=${md5%% *} + if [ "$?" != 0 -o -z "${md5}" ] ; then + print_warning "failed to create md5 sum for ${file}" + md5='#MD5ERROR#' + fi + elif [ -p "${file}" ] ; then + md5='pipe' + elif [ -S "${file}" ] ; then + md5='socket' + elif [ -b "${file}" ] ; then + md5='block' + elif [ -c "${file}" ] ; then + md5='char' + elif [ -S "${file}" ] ; then + md5='socket' + else + md5='#MD5UNKNOWN#' + fi + + echo ${md5} +} + +function bee_find() { + local options=$(${BEE_BINDIR}/beegetopt --name beefind \ + --option exclude/e= \ + --option skiplist/s= \ + -- "${@}") + + if [ $? != 0 ] ; then + usage + exit 1 + fi + + eval set -- "${options}" + + declare -a OPT_EXCLUDE + declare -a OPT_SKIPLSIT + + while true ; do + case "${1}" in + --exclude) + OPT_EXCLUDE=( ${OPT_EXCLUDE:+${OPT_EXCLUDE[@]}} "${2}" ) + shift 2 + ;; + --skiplist) + OPT_SKIPLIST=( ${OPT_SKIPLIST:+${OPT_SKIPLIST[@]}} "${2}" ) + shift 2 + ;; + --) + shift + break + ;; + esac + done + + if [ -z "${1}" ] ; then + print_warning "no directory to scan specified" + exit 1 + fi + + find ${1} -mindepth 1 | \ + grep \ + --extended-regexp \ + --invert-match \ + --file=<(if [ "${#OPT_SKIPLIST[@]}" -gt 0 ] ; then + grep --invert-match --regexp="^ *$" ${OPT_SKIPLIST[@]} + fi) \ + --file=<(for p in ${OPT_EXCLUDE[@]} ; do + echo ${p} + done) +} + +function do_beefind() { + local options=$(${BEE_BINDIR}/beegetopt --name beefind \ + --option cutroot/c= \ + -- "${@}") + + if [ $? != 0 ] ; then + usage + exit 1 + fi + + eval set -- "${options}" + + declare OPT_CUTROOT= + + while true ; do + case "${1}" in + --cutroot) + OPT_CUTROOT="${2}" + shift 2 + ;; + --) + shift + break + ;; + esac + done + + for f in $(cat <(bee_find ${@})) ; do + md5=$(get_md5 ${f}) + + data=( $(stat -c "%05a %h %u %g %s %Y" ${f}) ) + if [ "$?" != 0 -o -z "${data}" ] ; then + print_warning "can't stat ${f}" + exit 1 + fi + + echo -n "md5=${md5}:" + echo -n "omode=${data[0]}:" + echo -n "nlink=${data[1]}:" + echo -n "uid=${data[2]}:" + echo -n "gid=${data[3]}:" + echo -n "size=${data[4]}:" + echo -n "mtime=${data[5]}:" + + filename=${f} + if [ -n "${OPT_CUTROOT}" ] ; then + filename=${f#${OPT_CUTROOT}} + fi + echo -n "file=${filename}" + + if [ "${md5}" = "link" ] ; then + echo -n "//$(readlink ${f})" + fi + + echo "" + done +} + +############################################################################### +############################################################################### +############################################################################### + +options=$(${BEE_BINDIR}/beegetopt --name beefind \ + --option output/o= \ + --option dump-files/d= \ + --option help/h \ + -- "${@}") + +if [ $? != 0 ] ; then + usage + exit 1 +fi + +eval set -- "${options}" + +declare OPT_OUTPUT= +declare OPT_DUMPFILES= + +while true ; do + case "${1}" in + --output) + OPT_OUTPUT="${2}" + shift 2 + ;; + --dump-files) + OPT_DUMPFILES="${2}" + shift 2 + ;; + --help) + usage + exit 0 + ;; + --) + shift + break + ;; + esac +done + +if [ -n "${OPT_OUTPUT}" ] ; then + if ! exec 1>${OPT_OUTPUT} ; then + print_warning "can't write to ${OPT_OUTPUT}" + exit 1 + fi +fi + +if [ -n "${OPT_DUMPFILES}" ] ; then + if [ ! -r "${OPT_DUMPFILES}" ] ; then + print_warning "cannot read file '${OPT_DUMPFILES}'" + exit 1 + fi + + dump_files ${OPT_DUMPFILES} + exit 0 +fi + +do_beefind ${@}