#!/bin/sh # This is CCat - the Crafty Cat. It's like cat, but more sneaky. # It's sneaky because it'll recognize compressed data, and decompress it. # Hopefully while behaving otherwise completely identical to cat. # Copyright (C) 2009, Robert Russell - http://administra.tion.ca/ # This program 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 . ############################################################################## # The list of files that we should ccat. CCAT_FILES="" # The arguments we received, which we'll happily pass to real cat. CCAT_ARGS="" # The magic words we expect to find in Real Cat, but not in this script! CAT_MAGIC="Concatenate FILE(s)," CAT_MAGIC="$CAT_MAGIC or standard input," CAT_MAGIC="$CAT_MAGIC to standard output." ############################################################################## # First, verify that we have a reasonable cat to work with. Someone might # have aliased THIS ungodly machination to cat, and we'll have to adjust # for that. for KITTEN in `which cat` /usr/local/bin/cat /usr/bin/cat /bin/cat ; do if [ -x "$KITTEN" ] ; then strings $KITTEN | grep "$CAT_MAGIC" >/dev/null if [ $? -eq 0 ] ; then CAT="$KITTEN" break fi fi done ############################################################################## # If dog is available, we should use it instead of cat, maybe? # FIXME ############################################################################## # Next up, we should parse our arguments. Anything that's a file, we want to # pre-process and decompress. And we can't use getopts, since we want to be # compatible with unknown options for a future improved cat. Get on that, # RMS, impress us. NO_MOAR_ARGS=1 for CATNIP in $* ; do # Note: The -- and sed is needed or -n will go to echo instead of cat echo "-- $CATNIP" | sed 's/^-- //' | grep "^-" > /dev/null if [ $? -gt 0 ] ; then # If $CATNIP does not start with - is filename if [ -r "$CATNIP" ] ; then CCAT_FILES="$CCAT_FILES $CATNIP" else echo "$0 Error: Cannot read $CATNIP" > /dev/stderr fi else if [ "$CATNIP" == "--help" ] ; then echo "This is the help message" elif [ "$CATNIP" == "-" ] ; then # If $CATNIP is just - then we add /dev/stdin to files. # Warning: http://linux.derkeiler.com/Mailing-Lists/Kernel/2008-03/msg06733.html CCAT_FILES="$CCAT_FILES /dev/stdin" elif [ "$CATNIP" == "--" ] ; then # If $CATNIP is -- we stop looking for - NO_MOAR_ARGS=0 else # Otherwise, $CATNIP just starts with - and is argument if [ $NO_MOAR_ARGS ] ; then CCAT_FILES="$CCAT_FILES $CATNIP" else CCAT_ARGS="$CCAT_ARGS $CATNIP" fi fi fi done ############################################################################## # Hrm. I suppose that if we have no files to ccat, that would imply stdin. # I should handle that with a simple $CAT $CCAT_ARGS and exit. [ -z "$CCAT_FILES" ] && CCAT_FILES="/dev/stdin" ############################################################################## # Now, we'll loop through our fileish arguments, fileify them, and cat them. # If we can't read them, that's our error to handle. for TARGET in $CCAT_FILES ; do TARGET_TYPE=`file -L -b -- $TARGET | sed 's/,.*//g'` if [ "$TARGET_TYPE" == "gzip compressed data" ] ; then gzip -cd -- $TARGET | $CAT $CCAT_ARGS elif [ "$TARGET_TYPE" == "bzip2 compressed data" ] ; then bzip2 -cd -- $TARGET | $CAT $CCAT_ARGS else $CAT $CCAT_ARGS -- $TARGET fi done