#!/bin/sh # # Script to clean binary files. # # JPackage Project # # $Id: clean-binary-files,v 1.1 2006/09/19 19:39:37 fnasser Exp $ # Import java functions [ -r "/usr/share/java-utils/java-functions" ] \ && . "/usr/share/java-utils/java-functions" || exit 1 # Prints help message usage() { cat >&2 << EOF_USAGE Usage: $0 {[-f {-, instructions_file}], [-e exclusion_file] [-l]} [-a archive_file] [-d custom_jar_map] [-n] [-p] [-s] Options: -f - The instructions file, specifying which files to keep and which to remove -e - The exclusions file, specifying special binary files that are to be preserved, or non-binary files that are to be removed. -l - Only list instructions (to put in instructions file), do not delete anything. -a - Archive file on which actions will be performed, as opposed to current directory -d - A custom jar map file (has priority over the generic one). -n - No symlinks (i.e. only clean jars, don't run build-jar-repository afterwards) -p - Preserve original file names (-p to build-jar-repository) -s - Silent mode. Won't output commands during cleanup EOF_USAGE exit 2 } [ "$1" = "--help" ] && usage [ "$#" = 0 ] && usage set_javacmd || exit 3 check_java_env || exit 4 set_jvm_dirs || exit 5 # Directory in which script was invoked _WORKING_DIR=`pwd` # Default jar map _JAR_MAP_FILE="/usr/share/java-utils/jarname-jpp-map" # Variables used for comparing file lists _TEMP_COMPARISON_FILE=/tmp/_temp_comparison_file.$$ _KEEP_REMOVE_FILELIST=/tmp/_kr_file.$$ _ON_DISK_FILELIST=/tmp/_fnlist_file.$$ _FILELIST_DIFF=/tmp/_filelist_diff_file.$$ rm -f $_KEEP_REMOVE_FILELIST $_ON_DISK_FILELIST $_FILELIST_DIFF # Temporary instructions file _TEMP_INSTRUCTIONS_FILE=/tmp/_temp_instruction_file.$$ # Directory where archive is extracted, if we are working with one _ARCHIVE_EXTRACTION_DIR=/tmp/_cbr_archive_dir.$$ # MODE can be list, list_and_delete, or delete _MODE="list_and_delete" # Run-time variables _ARCHIVE_FILE="" _INSTRUCTIONS_FILE="" _EXCEPTIONS_FILE="" _KEEP_LIST="" _PRESERVE_BINARY_NAMES=0 _REMOVE_LIST="" _SILENT_MODE=0 _CREATE_SYMLINKS=1 _CUSTOM_JAR_MAP_FILE="" # Adds to the appropriate (keep/remove) list add_to_keep_or_remove_list() { if [ $1 = "keep" ]; then shift if [ -z "$_KEEP_LIST" ]; then _KEEP_LIST=$* else _KEEP_LIST=${_KEEP_LIST}"|"$* fi else shift if [ -z "$_REMOVE_LIST" ]; then _REMOVE_LIST=$* else _REMOVE_LIST=${_REMOVE_LIST}"|"$* fi fi } # Function to check against exclusion generate the # keep/remove command check_and_generate_command() { _old_ifs=$IFS IFS='|' echo $1 | grep -E "\\.jar$" >& /dev/null if [ $? -eq 0 ]; then # Check if the item is in the exclusion list _exclude=0 for excluded in $_KEEP_LIST; do if [ "$1" = "$excluded" ]; then _exclude=1 break fi done if [ $_exclude -eq 0 ]; then output_command "remove $1" else output_command "keep $1" fi fi IFS=$_old_ifs } # Function to delete files delete_and_replace_file() { rm -f "$1" print "rm -f \"$1\"" # Now find the appropriate jar in the map, and output the # build-jar-repository command execute_bjr_command $1 } # Ensures that the file exists ensure_exclusion_files_exist() { rm -f $_ON_DISK_FILELIST touch $_ON_DISK_FILELIST # Generate a list of binary files on disk _filter="\\.jar$" if [ ! "$_KEEP_LIST" = "" ]; then _filter="$_filter|$_KEEP_LIST" fi if [ ! "$_REMOVE_LIST" = "" ]; then _filter="$_filter|$_REMOVE_LIST" fi find . | sed -e s:^./::g | grep -E "$_filter" | sort -u > $_ON_DISK_FILELIST _old_ifs=$IFS IFS='|' for filename in $_KEEP_LIST; do grep ^$filename $_ON_DISK_FILELIST >& /dev/null if [ $? -gt 0 ]; then echo "Cannot find file $filename from exclusions list. Aborting." rm -f $_ON_DISK_FILELIST IFS=$_old_ifs exit 7 fi done for filename in $_REMOVE_LIST; do grep ^$filename $_ON_DISK_FILELIST >& /dev/null if [ $? -gt 0 ]; then echo "Cannot find file $filename from exclusions list. Aborting." rm -f $_ON_DISK_FILELIST IFS=$_old_ifs exit 7 fi done rm -f $_ON_DISK_FILELIST IFS=$_old_ifs } # Ensures that files in kee/remove list exist on disk, and vice-versa ensure_files_exist() { rm -f $_TEMP_COMPARISON_FILE touch $_TEMP_COMPARISON_FILE _old_ifs=$IFS IFS='|' for filename in $_REMOVE_LIST; do echo $filename >> $_TEMP_COMPARISON_FILE done for filename in $_KEEP_LIST; do echo $filename >> $_TEMP_COMPARISON_FILE done IFS=$_old_ifs sort -u --output=$_KEEP_REMOVE_FILELIST $_TEMP_COMPARISON_FILE rm -f $_TEMP_COMPARISON_FILE # We have a list of keep/remove items. Now generate a list of # binary files on disk _filter="\\.jar$" if [ ! "$_KEEP_LIST" = "" ]; then _filter="$_filter|$_KEEP_LIST" fi if [ ! "$_REMOVE_LIST" = "" ]; then _filter="$_filter|$_REMOVE_LIST" fi find . | sed -e s:^./::g | grep -E "$_filter" | sort -u > $_ON_DISK_FILELIST # Now compare the two diff -c $_KEEP_REMOVE_FILELIST $_ON_DISK_FILELIST > $_FILELIST_DIFF rm -f $_KEEP_REMOVE_FILELIST $_ON_DISK_FILELIST if [ -s $_FILELIST_DIFF ]; then echo "ERROR: Extraneous files were found." echo "" echo "Files in keep/remove list, but not on disk/archive:" cat $_FILELIST_DIFF | grep "^- " | sed -e s:"^- "::g echo "" echo "Binary files in on disk/archive, but not in keep/remove list:" cat $_FILELIST_DIFF | grep "^+ " | sed -e s:"^+ "::g echo "" echo "Indistinguishable files:" cat $_FILELIST_DIFF | grep "^\! " | sed -e s:"^\! "::g rm -f $_FILELIST_DIFF exit 7 fi rm -f $_FILELIST_DIFF } # Executes the build-jar-repository command execute_bjr_command() { if [ $_CREATE_SYMLINKS -eq 0 ]; then return 0; fi echo $1 | grep -E "\\.jar$" >& /dev/null if [ ! $? -eq 0 ]; then return 0 fi # Strip version and extention. e.g. abc-2.1-api-1.0.4.jar -> abc-2.1-api _jar_filename=`basename $1` _search_name=`basename $1` _search_name=`echo $_search_name | sed -r -e s/-[[:digit:].]*\\\.jar//g | sed -r -e s/\\\.jar$//g` _mapped_jar_name="" _final_name="" # Search in custom jar map first if [ ! "$_CUSTOM_JAR_MAP_FILE" = "" ] && [ -f $_CUSTOM_JAR_MAP_FILE ]; then # echo "grep -E \"^$_search_name.jar \" $_CUSTOM_JAR_MAP_FILE | awk '{print $2}'" _mapped_jar_name=`grep -E "^$_search_name\\.jar " $_CUSTOM_JAR_MAP_FILE | awk '{print $2}'` if [ "$_mapped_jar_name" = "" ]; then _mapped_jar_name=`grep -E "^$_jar_filename " $_CUSTOM_JAR_MAP_FILE | awk '{print $2}'` fi fi # Search in global jar map ONLY IF things were not found in the custom map if [ -f $_JAR_MAP_FILE ] && [ "$_mapped_jar_name" = "" ]; then # echo "grep -E \"^$_search_name.jar \" $_JAR_MAP_FILE | awk '{print $2}'" _mapped_jar_name=`grep -E "^$_search_name\\.jar " $_JAR_MAP_FILE | awk '{print $2}'` fi if [ "$_mapped_jar_name" = "" ]; then _final_name=$_search_name else _final_name=$_mapped_jar_name fi _preserve_name_flag="" if [ $_PRESERVE_BINARY_NAMES = 1 ]; then _preserve_name_flag="-p" fi _target_dir=`dirname $1` _old_ifs=$IFS IFS=' ' for jppname in $_final_name; do print "build-jar-repository -s $_preserve_name_flag $_target_dir $jppname" build-jar-repository -s $_preserve_name_flag $_target_dir $jppname done IFS=$_old_ifs } # Outputs command to either STDOUT, or to a temp file, depending on what is required output_command() { if [ $_MODE = "list" ]; then echo $* elif [ $_MODE = "list_and_delete" ]; then echo $* >> $_TEMP_INSTRUCTIONS_FILE fi } # Outputs to STDOUT (depending on whether or not we are in silent mode) print() { if [ $_SILENT_MODE -eq 0 ]; then echo $* fi } ## BEGIN EXECUTION # Get the command line options and set up appropriate parameters while [ $# -gt 0 ] ; do case "$1" in -e) # Exclusion list (LIST MODE) if [ ! -f $2 ] ; then echo "$0: ERROR: Could not find exclusions file!" exit 6; fi while read line; do echo $line | grep ^% >& /dev/null if [ $? -eq 0 ] || [ "$line" = "" ]; then continue fi _type=`echo $line | awk '{print $1}'` _value=`echo $line | awk '{ printf "%s", $2; for (i = 3; i <= NF; i=i+1) printf " %s", $i }'` if [ $_type = "keep" ]; then if [ -z "$_KEEP_LIST" ]; then _KEEP_LIST=$_value else _KEEP_LIST=${_KEEP_LIST}"|"$_value fi else if [ -z "$_REMOVE_LIST" ]; then _REMOVE_LIST=$_value else _REMOVE_LIST=${_REMOVE_LIST}"|"$_value fi fi done < $2 if [ ! "$_MODE" = "list" ]; then # If program had previously crashed, the temp file could be there. Remove it rm -f $_TEMP_INSTRUCTIONS_FILE _MODE="list_and_delete" fi if [ ! "$_INSTRUCTIONS_FILE" = "" ]; then echo "ERROR: -e and -f are mutually exclusive options" exit 6 fi _EXCEPTIONS_FILE=$2 shift ;; -f) # Instruction file (DELETE MODE) if [ $2 == "-" ]; then while read command; do _type=`echo $command | awk '{print $1}'` _value=`echo $command | awk '{ printf "%s", $2; for (i = 3; i <= NF; i=i+1) printf " %s", $i }'` add_to_keep_or_remove_list $_type $_value done else if [ ! -f $2 ] ; then echo "$0: ERROR: Could not find instructions file!" exit 6; fi while read line; do echo $line | grep ^% >& /dev/null if [ $? -eq 0 ] || [ "$line" = "" ]; then continue fi _type=`echo $line | awk '{print $1}'` _value=`echo $line | awk '{ printf "%s", $2; for (i = 3; i <= NF; i=i+1) printf " %s", $i }'` add_to_keep_or_remove_list $_type $_value done < $2 _INSTRUCTIONS_FILE=$2 fi if [ "$_MODE" = "list" ]; then echo "ERROR: -f and -l are mutually exclusive options" exit 6 fi if [ ! "$_EXCEPTIONS_FILE" = "" ]; then echo "ERROR: -e and -f are mutually exclusive options" exit 6 fi _MODE=delete shift ;; -l) if [ "$_MODE" = "delete" ]; then echo "ERROR: -f and -l are mutually exclusive options" exit 6 fi _MODE=list ;; -a) _ARCHIVE_FILE=$2 shift ;; -d) _CUSTOM_JAR_MAP_FILE=$2 shift ;; -n) _CREATE_SYMLINKS=0 ;; -p) _PRESERVE_BINARY_NAMES=1 ;; -s) _SILENT_MODE=1 ;; *) echo "ERROR: Unknown argument $1" exit 6 ;; esac shift done # Are basic arguments given? if [ -z "$_EXCEPTIONS_FILE" ] && [ -z "$_INSTRUCTIONS_FILE" ]; then echo "ERROR: One of -f or -e is required!" exit 6 fi # Now, carry out the actions # If we are dealing with an archive file, we need to extract things somewhere, and do our actions in there if [ ! -z $_ARCHIVE_FILE ]; then rm -rf $_ARCHIVE_EXTRACTION_DIR mkdir -p $_ARCHIVE_EXTRACTION_DIR pushd $_ARCHIVE_EXTRACTION_DIR >& /dev/null tar xf $_WORKING_DIR/`basename $_ARCHIVE_FILE` fi # If in delete mode, we need to clean up the binary files if [ $_MODE = "delete" ]; then # First, ensure that files in keep/remove lists exist on disk, and vice-versa ensure_files_exist _old_ifs=$IFS IFS='|' for filename in $_REMOVE_LIST; do delete_and_replace_file $filename done IFS=$_old_ifs else # Else, in list mode, we list the actions that will go into the instructions file # Ensure that files in both lists exist ensure_exclusion_files_exist # Generate a list of files, and subsequently, the commands _old_ifs=$IFS IFS=' ' for filename in `find . | grep .jar$ | sed -e s:^./::g`; do check_and_generate_command $filename done IFS=$_old_ifs # Add all of the "remove" commands from the exclusion list _old_ifs=$IFS IFS='|' for filename in $_REMOVE_LIST; do output_command "remove $filename" done; IFS=$_old_ifs if [ $_MODE = "list_and_delete" ]; then _instructions_file_flag="-f" _instructions_file="$_TEMP_INSTRUCTIONS_FILE" _silent_mode_flag="" if [ $_SILENT_MODE = 1 ]; then _silent_mode_flag="-s" fi _preserve_names_flag="" if [ $_PRESERVE_BINARY_NAMES = 1 ]; then _preserve_names_flag="-p" fi _no_symlinks_flag="" if [ $_CREATE_SYMLINKS = 0 ]; then _no_symlinks_flag="-n" fi _custom_map_flag="" _custom_map="" if [ ! "$_CUSTOM_JAR_MAP_FILE" = "" ]; then _custom_map_flag="-d" _custom_map="$_CUSTOM_JAR_MAP_FILE" fi #echo "$0 $_instructions_file_flag $_instructions_file $_preserve_names_flag $_silent_mode_flag $_no_symlinks_flag $_custom_map_flag $_custom_map" #$0 $_instructions_file_flag $_instructions_file $_preserve_names_flag $_silent_mode_flag $_no_symlinks_flag $_custom_map_flag $_custom_map clean-binary-files $_instructions_file_flag $_instructions_file $_preserve_names_flag $_silent_mode_flag $_no_symlinks_flag $_custom_map_flag $_custom_map rm -f $_TEMP_INSTRUCTIONS_FILE fi fi if [ ! -z $_ARCHIVE_FILE ]; then _archive_basename=`basename $_ARCHIVE_FILE` _arch_name=${_archive_basename%%.*} _arch_ext=${_archive_basename#*.} _compression_flag="" echo $_ARCHIVE_FILE | grep gz$ >& /dev/null if [ $? -eq 0 ]; then _compression_flag=z fi echo $_ARCHIVE_FILE | grep bz2$ >& /dev/null if [ $? -eq 0 ]; then _compression_flag=f fi tar cf$_compression_flag $_WORKING_DIR/$_arch_name-clean.$_arch_ext * popd >& /dev/null rm -rf $_ARCHIVE_EXTRACTION_DIR fi