#!/bin/bash
#
# Preprocessor for 'less'. Used when this environment variable is set:
# LESSOPEN="|lesspipe %s"

# TODO: handle compressed files better

[[ -n ${LESSDEBUG} ]] && set -x

trap 'exit 0' PIPE

guesscompress() {
	case "$1" in
		*.gz|*.z)   echo "gunzip -c" ;;
		*.bz2|*.bz) echo "bunzip2 -c" ;;
		*.lz)       echo "lzip -dc" ;;
		*.lzma)     echo "unlzma -c" ;;
		*.lzo)      echo "lzop -dc" ;;
		*.xz)       echo "xzdec" ;;
		*)          echo "cat" ;;
	esac
}

lesspipe_file() {
	local out=$(file -L -- "$1")
	local suffix
	case ${out} in
		*" 7-zip archive"*) suffix="7z";;
		*" ar archive"*)    suffix="a";;
		*" CAB-Installer"*) suffix="cab";;
		*" cpio archive"*)  suffix="cpio";;
		*" ELF "*)          suffix="elf";;
		*" LHa"*archive*)   suffix="lha";;
		*" troff "*)        suffix="man";;
		*" script text"*)   suffix="sh";;
		*" shared object"*) suffix="so";;
		*" tar archive"*)   suffix="tar";;
		*" Zip archive"*)   suffix="zip";;
		*": data")          hexdump -C -- "$1"; return 0;;
		*)                  return 1;;
	esac
	lesspipe "$1" ".${suffix}"
	return 0
}

lesspipe() {
	local match=$2
	[[ -z ${match} ]] && match=$1

	local DECOMPRESSOR=$(guesscompress "${match}")

	# User filters
	if [[ -x ~/.lessfilter ]] ; then
		~/.lessfilter "$1" && exit 0
	fi

	local ignore
	for ignore in ${LESSIGNORE} ; do
		[[ ${match} == *.${ignore} ]] && exit 0
	done

	# Handle non-regular file types.
	if [[ -d $1 ]] ; then
		ls -alF -- "$1"
		return
	elif [[ ! -f $1 ]] ; then
		stat "$1"
		return
	fi

	case "${match}" in

	### Doc files ###
	*.[0-9n]|*.man|\
	*.[0-9n].bz2|*.man.bz2|\
	*.[0-9n].gz|*.man.gz|\
	*.[0-9n].lzma|*.man.lzma|\
	*.[0-9n].xz|*.man.xz|\
	*.[0-9][a-z].gz|*.[0-9][a-z].gz)
		local out=$(${DECOMPRESSOR} -- "$1" | file -)
		case ${out} in
			*troff*)
				# Need to make sure we pass path to man or it will try
				# to locate "$1" in the man search paths
				if [[ $1 == /* ]] ; then
					man -- "$1"
				else
					man -- "./$1"
				fi
				;;
			*text*)
				${DECOMPRESSOR} -- "$1"
				;;
			*)
				# We could have matched a library (libc.so.6), so let
				# `file` figure out what the hell this thing is
				lesspipe_file "$1"
				;;
		esac
		;;
	*.dvi)      dvi2tty "$1" ;;
	*.ps)       ps2ascii "$1" || pstotext "$1" ;;
	*.pdf)      pdftotext "$1" - || ps2ascii "$1" || pstotext "$1" ;;
	*.doc)      antiword "$1" || catdoc "$1" ;;
	*.rtf)      unrtf --nopict --text "$1" ;;
	*.conf|*.txt|*.log) ;; # force less to work on these directly #150256

	### URLs ###
	ftp://*|http://*|*.htm|*.html)
		for b in links2 links lynx ; do
			${b} -dump "$1" && exit 0
		done
		html2text -style pretty "$1"
		;;

	### Tar files ###
	*.tar|\
	*.tar.bz2|*.tar.bz|*.tar.gz|*.tar.z|\
	*.tar.lz|*.tar.tlz|\
	*.tar.lzma|*.tar.xz)
		${DECOMPRESSOR} -- "$1" | tar tvvf -;;
	*.tbz2|*.tbz|*.tgz|*.tlz|*.txz)
		lesspipe "$1" "$1".tar.${1##*.t} ;;

	### Misc archives ###
	*.bz2|\
	*.gz|*.z|\
	*.lz|\
	*.lzma|*.xz)  ${DECOMPRESSOR} -- "$1" ;;
	*.rpm)        rpm -qpivl --changelog -- "$1" || rpm2tar -O "$1" | tar tvvf -;;
	*.cpi|*.cpio) cpio -itv < "$1" ;;
	*.ace)        unace l "$1" ;;
	*.arc)        arc v "$1" ;;
	*.arj)        unarj l -- "$1" ;;
	*.cab)        cabextract -l -- "$1" ;;
	*.lha|*.lzh)  lha v "$1" ;;
	*.zoo)        zoo -list "$1" || unzoo -l "$1" ;;
	*.7z|*.exe)   7z l -- "$1" || 7za l -- "$1" || 7zr l -- "$1" ;;
	*.a)          ar tv "$1" ;;
	*.elf)        readelf -a -W -- "$1" ;;
	*.so)         readelf -h -d -s -W -- "$1" ;;
	*.mo|*.gmo)   msgunfmt -- "$1" ;;

	*.rar|.r[0-9][0-9])  unrar l -- "$1" ;;

	*.jar|*.war|*.ear|*.xpi|*.zip)
		unzip -v "$1" || miniunzip -l "$1" || miniunz -l "$1" || zipinfo -v "$1"
		;;

	*.deb|*.udeb)
		if type -P dpkg > /dev/null ; then
			dpkg --info "$1"
			dpkg --contents "$1"
		else
			ar tv "$1"
			ar p "$1" data.tar.gz | tar tzvvf -
		fi
		;;

	### Filesystems ###
	*.squashfs)   unsquashfs -s "$1" && unsquashfs -ll "$1" ;;

	### Media ###
	*.bmp|*.gif|*.jpeg|*.jpg|*.ico|*.pcd|*.pcx|*.png|*.ppm|*.tga|*.tiff|*.tif|*.webp)
		identify -verbose -- "$1" || file -L -- "$1"
		;;
	*.asf|*.avi|*.mov|*.mp4|*.mpeg|*.mpg|*.qt|*.ram|*.rm|*.webm|*.wmv)
		midentify "$1" || file -L -- "$1"
		;;
	*.mp3)        mp3info "$1" || id3info "$1" ;;
	*.ogg)        ogginfo "$1" ;;
	*.flac)       metaflac --list "$1" ;;
	*.torrent)    torrentinfo "$1" || torrentinfo-console "$1" || ctorrent -x "$1" ;;
	*.bin|*.cue|*.raw)
		# not all .bin/.raw files are cd images #285507
		# fall back to lesspipe_file if .cue doesn't exist, or if
		# cd-info failed to parse things sanely
		[[ -e ${1%.*}.cue ]] \
			&& cd-info --no-header --no-device-info "$1" \
			|| lesspipe_file "$1"
		;;
	*.iso)
		iso_info=$(isoinfo -d -i "$1")
		echo "${iso_info}"
		# Joliet output overrides Rock Ridge, so prefer the better Rock
		case ${iso_info} in
			*$'\n'"Rock Ridge"*) iso_opts="-R";;
			*$'\n'"Joliet"*)     iso_opts="-J";;
			*)                   iso_opts="";;
		esac
		isoinfo -l ${iso_opts} -i "$1"
		;;

	### Encryption stuff ###
	*.crl) openssl crl -hash -text -noout -in "$1" ;;
	*.csr) openssl req -text -noout -in "$1" ;;
	*.crt|*.pem) openssl x509 -hash -text -noout -in "$1" ;;

# May not be such a good idea :)
#	### Device nodes ###
#	/dev/[hs]d[a-z]*)
#		fdisk -l "${1:0:8}"
#		[[ $1 == *hd* ]] && hdparm -I "${1:0:8}"
#		;;

	### Everything else ###
	*)
		case $(( recur++ )) in
			# Maybe we didn't match due to case issues ...
			0) lesspipe "$1" "$(echo $1 | LC_ALL=C tr '[:upper:]' '[:lower:]')" ;;

			# Maybe we didn't match because the file is named weird ...
			1) lesspipe_file "$1" ;;
		esac

		# So no matches from above ... finally fall back to an external
		# coloring package.  No matching here so we don't have to worry
		# about keeping in sync with random packages.  Any coloring tool
		# you use should not output errors about unsupported files to
		# stdout.  If it does, it's your problem.

		# Allow people to flip color off if they dont want it
		case ${LESSCOLOR} in
			always)                   LESSCOLOR=2;;
			[yY][eE][sS]|[yY]|1|true) LESSCOLOR=1;;
			[nN][oO]|[nN]|0|false)    LESSCOLOR=0;;
			*)                        LESSCOLOR=0;; # default to no color #188835
		esac
		if [[ ${LESSCOLOR} != "0" ]] && [[ -n ${LESSCOLORIZER=code2color} ]] ; then
			# 2: Only colorize if user forces it ...
			# 1: ... or we know less will handle raw codes -- this will
			#    not detect -seiRM, so set LESSCOLORIZER yourself
			if [[ ${LESSCOLOR} == "2" ]] || [[ " ${LESS} " == *" -"[rR]" "* ]] ; then
				LESSQUIET=true ${LESSCOLORIZER} "$1"
			fi
		fi

		# Nothing left to do but let less deal
		exit 0
		;;
	esac
}

if [[ -z $1 ]] ; then
	echo "Usage: lesspipe <file>"
elif [[ $1 == "-V" || $1 == "--version" ]] ; then
	cat <<-EOF
		lesspipe (git)
		Copyright 2001-2016 Gentoo Foundation
		Mike Frysinger <vapier@gentoo.org>
		     (with plenty of ideas stolen from other projects/distros)

	EOF
	less -V
elif [[ $1 == "-h" || $1 == "--help" ]] ; then
	cat <<-EOF
		lesspipe: preprocess files before sending them to less

		Usage: lesspipe <file>

		lesspipe specific settings:
		  LESSCOLOR env     - toggle colorizing of output (no/yes/always; default: no)
		  LESSCOLORIZER env - program used to colorize output (default: code2color)
		  LESSIGNORE        - list of extensions to ignore (don't do anything fancy)

		You can create per-user filters as well by creating the executable file:
		  ~/.lessfilter
		One argument is passed to it: the file to display.  The script should exit 0
		to indicate it handled the file, or non-zero to tell lesspipe to handle it.

		To use lesspipe, simply add to your environment:
		  export LESSOPEN="|lesspipe %s"

		Run 'less --help' or 'man less' for more info.
	EOF
else
	recur=0
	[[ -n ${LESSDEBUG} ]] \
		&& lesspipe "$1" \
		|| lesspipe "$1" 2> /dev/null
fi
