#!/bin/bash moddir="" zipdir="" pkgcnt=0 usage() { echo "Usage: $0 -m moddir [-z zipdir]" >&2 echo " $0 -h|-?" >&2 echo " -m moddir The source directory containing sub-directories mods.d and modules" >&2 echo " If the moddir is not properly set up, it is an error." >&2 echo " -z zipdir The destination directory for the zipped modules [default: /tmp/zip]" >&2 echo " If the zipdir does not exist it is created." >&2 echo " -h|-? This usage statement" >&2 } package_module() { local conf=$1 local modName="" local dataPath="" local count=0 if [ ! -f $conf ] ; then echo "$Error: $conf does not exist" >&2 return fi if [ ! -r $conf ] ; then echo "Error: $conf is not readable" >&2 return fi # Read the conf for the section [NAME] and DataPath while read line do # Remove trailing \r from windows created files line=${line%$'\015'} # Check for the [NAME] # Use a regular expression to grab what is inside the [ ] if [[ $line =~ ^\[(.*)\]$ ]] then (( count++ )) modName=${BASH_REMATCH[1]} fi # If it is DataPath grab what follows the = sign if [[ $line =~ DataPath=(.*) ]] then (( count++ )) # Save off the match dataPath=${BASH_REMATCH[1]} # The dataPath of some modules has a prefix for filenames as the last element if [[ ! -d "$dataPath" ]] then # Since it is a prefix, remove the last element # so that it becomes a directory dataPath=${dataPath%/*} fi # If the path ends in a / then remove it dataPath=${dataPath%/} # If the path starts with ./ then remove it dataPath=${dataPath#./} fi # Quit processing the file once everything needed # has been seen if (( count == 2 )) then break fi done < $conf if [[ ! -d "$dataPath" ]] then echo "Error in $conf: $dataPath is not a directory" >&2 # should we rename the conf? return fi # create the zip if one of the following is true # - it doesn't exist # - some part is newer than the existing zip # - the conf is newer than the existing zip if [[ ! -f $zipdir/$modName.zip || -n $(find $dataPath -type f -cnewer $zipdir/$modName.zip) || $zipdir/$modName.zip -ot $conf ]] then (( pkgcnt++ )) # the name of the zipped file FINAL_ZIP=$zipdir/$modName.zip # Zip to a temp file so that current zip stays valid TMP_ZIP=$zipdir/tmp-$modName.zip echo zip -q -r $TMP_ZIP $conf $dataPath zip -q -r $TMP_ZIP $conf $dataPath # As long as the source and destination are on the same partition the move will be atomic # Note: Those that have the file prior to the move will still get it mv $TMP_ZIP $FINAL_ZIP fi } cache_confs() { if (( pkgccnt == 0 )) then return fi # the name of the cache file FINAL_CACHE=mods.d.tar.gz # tar.gz to a temp file so that current cache stays valid TMP_CACHE=tmp-$FINAL_CACHE tar czvf $TMP_CACHE mods.d/*.conf # As long as the source and destination are on the same partition the move will be atomic # Note: Those that have the file prior to the move will still get it mv $TMP_CACHE $FINAL_CACHE } # A POSIX variable OPTIND=1 # Reset in case getopts has been used previously in the shell. while getopts "h?z:m:" opt do case "$opt" in m) moddir=$OPTARG ;; z) zipdir=$OPTARG ;; h|\?) usage exit 0 ;; esac done shift $((OPTIND-1)) if (( $# != 0 )) then echo "Error: extra parameters: $@" usage exit 1 fi if [[ -z $moddir ]] then echo "Invalid -m has an empty argument" >&2 usage exit 1 fi # if -z parameter was not specified then set zipdir to the default [[ -z $zipdir ]] && zipdir=/tmp/zip [[ -d $zipdir ]] || mkdir $zipdir if [[ ! -d "$moddir" ]] then echo "Error: $moddir does not exist" >&2 usage exit 1 fi # Work in the moddir cd $moddir if [[ ! -d "mods.d" ]] then echo "Error: $moddir/mods.d does not exist" >&2 usage exit 1 fi if [[ ! -d "modules" ]] then echo "Error: $moddir/modules does not exist" >&2 usage exit 1 fi for modconf in mods.d/*.conf do package_module $modconf done if (( pkgcnt > 0 )) then cache_confs fi exit 0