Created
January 4, 2010 11:39
-
-
Save jetztgradnet/268474 to your computer and use it in GitHub Desktop.
inspect jar and war files, Grails applications and plugins
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# needs bash >= 3.2 for regex | |
jarfile= | |
file= | |
fileList= | |
verbose=0 | |
extract=0 | |
list=0 | |
listFilter= | |
manifestHeaders= | |
# check whether zipinfo is available | |
which zipinfo >/dev/null 2>&1 | |
zipInfoAvailable=$? | |
ALL_HEADERS="--all--" | |
options="hHvxXoawmISMWjJrgGcCpPlLdD:" | |
function usage() { | |
echo "jinspect [-$options] jarfile [filename ...]" | |
cat <<EOU | |
Options: | |
-h show help | |
-v be more verbose | |
-X save specified files (including path) to the current directory instead of printing them | |
-l list war contents; specify again to include more information | |
-x list xml files | |
-o list properties files | |
-c list class files | |
-j list java files | |
-J list jsp files | |
-S list js files | |
-g list groovy files | |
-G list gsp files | |
-H list html files | |
-C list css files | |
-I list image files | |
-L list files in lib directory | |
-M list files in META-INF directory | |
-W list files in WEB-INF directory | |
-a show WEB-INF/applicationContext.xml | |
-w show WEB-INF/web.xml | |
-r show WEB-INF/grails.xml | |
-m show META-INF/MANIFEST.MF | |
-p show plugin.xml | |
-P show *GrailsPlugin.groovy | |
-d show manifest headers in nicely formatted way; implies -m | |
-D <name> display named manifest header; can be used multiple times, implies -m | |
EOU | |
} | |
function addFilter() { | |
local expr=$1 | |
if [ "$list" -eq 0 ]; then | |
list=$((list + 1)) | |
fi | |
if [ -n "$listFilter" ]; then | |
listFilter="$listFilter|$expr" | |
else | |
listFilter="$expr" | |
fi | |
} | |
function addFile() { | |
local file=$1 | |
# skip duplicates | |
for existingFile in $fileList; do | |
if [ "$file" = "$existingFile" ]; then | |
return 1 | |
fi | |
done | |
if [ -n "$fileList" ]; then | |
fileList="$fileList $file" | |
else | |
fileList="$file" | |
fi | |
} | |
function addManifestHeader() { | |
local header="$1" | |
if [ -n "$manifestHeaders" ]; then | |
manifestHeaders="$manifestHeaders $header" | |
else | |
manifestHeaders="$header" | |
fi | |
addFile "META-INF/MANIFEST.MF" | |
} | |
function displayManifestHeader() { | |
awk ' BEGIN { ORS=""; indent=" "; headerCount=0 }; { | |
pos=index($0, ":") | |
if (pos > 0) { | |
# split name from contents | |
name=substr($0, 1, pos - 1) | |
contents=substr($0, pos + 1, length($0)) | |
# remove leading and trailing whitespace | |
sub(/^[ \t]+/, "", contents) | |
sub(/[ \t]+$/, "", contents) | |
# header name | |
if (headerCount > 0) { | |
print "\n" | |
} | |
print name "\n" | |
headerCount++ | |
# iterate over contents, which is separated by ',' | |
# NOTE: some quoted parts may contain ',' as well, e.g. in version range | |
inQuotes=0 | |
newPart=1 | |
# for each character | |
count = split(contents, parts, "") | |
for (p=1; p <= count; p++) { | |
# new part | |
if (newPart > 0) { | |
newPart=0 | |
print indent | |
} | |
# quote character | |
if (parts[p] == "\"") { | |
if (inQuotes > 0) { | |
inQuotes=0 | |
} | |
else { | |
inQuotes=1 | |
} | |
print parts[p] | |
} | |
# comma, which is a spearator, when not within quotes | |
else if (parts[p] == ",") { | |
if (inQuotes) { | |
print parts[p] | |
} | |
else { | |
print "\n" | |
newPart=1 | |
} | |
} | |
# any other character | |
else { | |
print parts[p] | |
} | |
} | |
} | |
else { | |
print $0 | |
} | |
}; END { print "\n" }' | |
} | |
function showManifestHeaders() { | |
local jarfile=$1 | |
shift | |
# extract MANIFEST.MF, remove \r and rejoin wrapped lines | |
local manifestHeaders=` | |
unzip -p "$jarfile" "META-INF/MANIFEST.MF" | tr -d '\r' | | |
awk ' | |
BEGIN { ORS="" } | |
/^[^ ]/{ | |
if ( NR > 1) { | |
print "\n" | |
} | |
# remove trailing whitespace | |
sub(/[ \t]+$/, "", $0) | |
print $0 | |
} | |
/^[ ]/{ | |
# remove leading whitespace | |
sub(/^[ \t]+/, "", $0) | |
print $0 | |
} | |
END { print "\n"; }'` | |
# print wanted headers | |
for header in $@; do | |
if [ "$header" = "$ALL_HEADERS" ]; then | |
echo "$manifestHeaders" | displayManifestHeader | |
else | |
echo "$manifestHeaders" | grep "$header" | displayManifestHeader | |
fi | |
done | |
} | |
# parse options | |
while getopts "$options" OPT $@; do | |
case "$OPT" in | |
h) usage; exit 0 ;; | |
v) verbose=$((verbose + 1));; | |
l) list=$((list + 1));; | |
x) addFilter '\.xml';; | |
X) extract=1;; | |
o) addFilter '\.properties';; | |
c) addFilter '\.class';; | |
C) addFilter '\.css';; | |
j) addFilter '\.java';; | |
J) addFilter '\.jsp';; | |
S) addFilter '\.js';; | |
g) addFilter '\.groovy';; | |
G) addFilter '\.gsp';; | |
H) addFilter '\.html';; | |
I) addFilter '\.jpg'; addFilter '\.png'; addFilter '\.gif'; addFilter '\.ico'; addFilter '\.bmp';; | |
M) addFilter 'META-INF/';; | |
W) addFilter 'WEB-INF/';; | |
L) addFilter 'lib/';; | |
m) addFile "META-INF/MANIFEST.MF";; | |
a) addFile "WEB-INF/applicationContext.xml";; | |
w) addFile "WEB-INF/web.xml";; | |
r) addFile "WEB-INF/grails.xml";; | |
p) addFile "*plugin.xml";; | |
P) addFile "*GrailsPlugin.groovy";; | |
d) addManifestHeader "$ALL_HEADERS";; | |
D) addManifestHeader "$OPTARG";; | |
esac | |
done | |
optind=$OPTIND | |
unset OPTIND | |
if [ "$optind" -gt 0 ]; then | |
# remove options | |
shift $((optind - 1)) | |
fi | |
jarfile="$1" | |
if [ ! -e "$jarfile" ]; then | |
echo >&2 "no such file: $jarfile" | |
exit 1 | |
fi | |
shift | |
for file in "$@"; do | |
addFile "$file" | |
done | |
if [ -n "$2" ]; then | |
# use file name provided on command line | |
file=$2 | |
fi | |
if [ -n "$fileList" ]; then | |
index=0 | |
if [ "$verbose" -gt 0 ]; then | |
echo "=== extracting $fileList from $jarfile" | |
fi | |
for file in $fileList; do | |
if [ "$verbose" -gt 0 ]; then | |
if [ "$index" -gt 0 ]; then | |
echo "" | |
fi | |
echo "=== $jarfile:$file" | |
fi | |
if [ "$extract" -gt 0 ]; then | |
unzip "$jarfile" "$file" | |
elif [[ "$file" =~ \.xml$ ]]; then | |
# xml file, prettify | |
unzip -p "$jarfile" "$file" | xmllint --format --recover --nowarning - | |
elif [ "$file" = "META-INF/MANIFEST.MF" -a -n "$manifestHeaders" ]; then | |
showManifestHeaders "$jarfile" $manifestHeaders | |
else | |
unzip -p "$jarfile" "$file" | |
fi | |
index=$((index + 1)) | |
done | |
else | |
# no file specified, list contents | |
if [ "$list" -eq 0 ]; then | |
list=$((list + 1)) | |
fi | |
fi | |
if [ "$list" -gt 0 ]; then | |
if [ "$verbose" -gt 0 ]; then | |
if [ -n "$listFilter" ]; then | |
# remove regex escapes | |
displayFilter=`echo "$listFilter" | sed 's/\\\\//g'` | |
echo "=== listing contents of $jarfile: $displayFilter" | |
else | |
echo "=== listing contents of $jarfile" | |
fi | |
fi | |
listing= | |
# use unzip -l if long listing is wanted or zip info is not available | |
if [ "$list" -gt 1 -o "$zipInfoAvailable" -gt 0 ]; then | |
listing=`unzip -l "$jarfile"` | |
else | |
listing=`zipinfo -1 "$jarfile"` | |
fi | |
if [ -n "$listing" ]; then | |
if [ -n "$listFilter" ]; then | |
echo "$listing" | grep -E $listFilter | |
else | |
echo "$listing" | |
fi | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment