#!/bin/bash ## ############################################################# ## Spliting up subdirectories for archiving ## ## Usage: ## split_for_dvd_burn.bash [switches] arg ## ## Frozen Versions: ## ## Relies on: (see help description) ## ## ############################################################# ## $Id: split_for_dvd_burn.bash,v 1.12 2005/05/06 05:59:53 oli Exp $ ## ############################################################# ## @TABLE OF CONTENTS: [TOCD: 20:55 05 May 2005] ## ## [0.1] ELEMENTAR SETUP ## [1] AUX FUNCTIONS ## [1.1] BIN PACKING ## [2] MAIN ## [2.1] READ OPTIONS ## [2.2] DERIVED VALUES ## [2.3] SANITY CHECK ## [2.4] REQUIRED SUB-SCRIPTS and UNIX FUNCTIONS ## [2.5] SPAM ## [3] PROCESSING ## [3.1] INIT ## [3.2] CHECK FEASIBILITY ## [3.3] DISTRIBUTE ## [3.4] CREATE LINKS ## [4] EMACS VARIABLES ## ############################################################# ## @FILE: split_for_dvd_burn.bash ## @PLACE: Linux Homestation ## @FORMAT: Bash Script ## @AUTHOR: M. Oliver M'o'ller ## @BEGUN: Sat Jan 15 17:13:35 2005 ## @VERSION: $Revision: 1.12 $ Thu May 5 22:46:30 2005 ## ############################################################# ## SHELL=/bin/bash ## ############################################### ## [0.1] ELEMENTAR SETUP ## ############################################### ## Shell settings INFILE=""; VERBOSE=false; QUIET=false; MAX_MB_PER_DIR=4400 ; DIR_PREFIX=dvd_ ; OFFSET=0; TMPFILE_ALL_FILES=/tmp/tmp.split_for_dvd_burn.bash.all_files.$$ TMPFILE_ALL_DIRS=/tmp/tmp.split_for_dvd_burn.bash.all_dirs.$$ OPTION_ONLYSHOW=false; OPTION_NEWER_DATE=""; NEWER_DATE_DATE=""; HERE=`dirname $0`; ME=`basename $0`; COPY_FILES=true; BIN_PACK=false; SOURCE_DIR=$PWD; TARGET_DIR=/root/Burn ; ## ---------------------------------------------------- VERSION_NUMBER=$(echo "$Revision: 1.12 $" | cut -d':' -f2 | cut -d'$' -f1); VERSION_DATE="Thu May 5 22:46:30 2005" ; VERSION="${VERSION_NUMBER} [${VERSION_DATE}]"; declare -a dir_array[1000]; declare -a size_array[1000]; ## needed for bin packing declare -a dist_dir[100000]; declare -a size_dir[100000]; declare -a name_dir[100000]; declare -a aux_dist_dir[100000]; # assignment dir -> disc N_DIR=0; COUNT=0; ## ################################################################### ## [1] AUX FUNCTIONS ## ################################################################### function print_usage { echo "${ME} (${VERSION})" 1>&2; echo "" 1>&2; echo "usage: ${ME} [OPTIONS] " 1>&2; echo "options: --help -h : print help" 1>&2; echo " --verbose -v : verbose on" 1>&2; echo " --size -m N : set max disc size to N MB (default: ${MAX_MB_PER_DIR})" 1>&2; echo " --source-dir -s D : root directory of data (default: .)" 1>&2; echo " --target-dir -t D : directory to create symlinks in (default: ${TARGET_DIR})" 1>&2; echo " --newer-date -d T : only those newer that date T (e.g. T=\"2005-01-01\")" 1>&2; echo " --only-show -n : do not create directories, only show" 1>&2; echo " --prefix -p X : use string X as directory prefix (default: ${DIR_PREFIX})" 1>&2; echo " --offset -o N : skip first N DVDs in counting (default: 0)" 1>&2; echo " --no-files -x : do not create copies of files found in source-dir" 1>&2; echo " --bin-pack -b : dont use alpabetic order, but pack optimally" 1>&2; echo " --version : print version" 1>&2; } function print_help { print_usage; echo ""; echo "description:"; echo " This script generates a segmented copy of a directory tree, starting" ; echo " at source-dir (default: .):"; echo " /${DIR_PREFIX}01/ "; echo " /${DIR_PREFIX}02/ "; echo " ... "; echo " For all sub-directories of . symbolic links are generated that are distributed" ; echo " alphabetically (unless option -b is selected), such that no segment ${DIR_PREFIX}NN "; echo " exceeds a given size limit (option -m, default: ${MAX_MB_PER_DIR} MB)"; echo " All files in . are copied to each segment (unless option -x is selected)."; echo " "; echo " Since the copies mainly consist of symbolic links, they will not use up much "; echo " disc space. Make sure that your burn application is set to FOLLOW these symbolic"; echo " links. E.g, in k3b, select burn option 'advanced/follow symbolic link'"; echo " A file OVERVIEW.txt summarizes the distribution of sub-directories to segments."; echo " "; echo " This works well for a large number of sub-directories, each of moderate size."; echo " Warning: The bin packing algorithm is very slow!"; echo " "; echo "relies on: array sed "; echo ""; echo "author: M. Oliver M'o'ller "; exit 1; } function remove_tempfiles { if [ -f ${TMPFILE_ALL_DIRS} ]; then rm ${TMPFILE_ALL_DIRS}; fi; if [ -f ${TMPFILE_ALL_FILES} ]; then rm ${TMPFILE_ALL_FILES}; fi; } function abort { ## -- clear the temp files -- echo "$0: ERROR: $1" 1>&2; remove_tempfiles; echo "** $0 aborted." 1>&2; exit 1; } function abort_on_error { ## -- clear the temp files -- if [ $1 -ne 0 ]; then abort "$@"; fi } function confirm() { echo -n "$@ (y/N)? " >&2 read CONFIRM_QUERY_ANSWER case $CONFIRM_QUERY_ANSWER in y ) echo true;; Y ) echo true;; yes ) echo true;; YES ) echo true;; * ) echo false;; esac } function get_last { local RESULT=""; for f in "$@"; do RESULT=$f; echo "----- $f"; done; echo ${RESULT} } ## total number of KB function du_total_from_filelist { if [ ! -f "$1" ]; then abort 1 "du_total_from_filelist: no such file '$1'" fi; du -c -k $(cat ${1} ) \ | grep -e "[0-9]*[ \t]*total$" \ | sed 's/[^0-9].*$//g'; } ## total number of KB function du_total_from_dir { if [ ! -d "$1" ]; then abort 1 "du_total_from_filelist: no such dir '$1'" fi; du -c -k ${1} \ | grep -e "[0-9]*[ \t]*total$" \ | sed 's/[^0-9].*$//g'; } function get_dir { ## -- get abs path to directory that is $1-relative to script local RESULT; pushd $(dirname $0) >/dev/null 2>/dev/null ; if [ -z "$1" ]; then export RESULT=$PWD; else cd $1; abort_on_error $? "Failed to change to dir $PWD + $1 "; export RESULT=$PWD; fi; popd >/dev/null 2>/dev/null ; echo ${RESULT}; } function abs_dir { ## -- get abs path to directory that is $1-relative to pwd local RESULT; if [ -z "$1" ]; then export RESULT=$PWD; else cd $1; abort_on_error $? "Failed to change to dir $PWD + $1 "; export RESULT=$PWD; fi; echo ${RESULT}; } function get_version_number_of_script { ## 0.00: nonexistent! PROG=$(which $1 2>/dev/null); if [ ! -z "${PROG}" ] && [ -x "${PROG}" ]; then $PROG --version 2>/dev/null |sed -e "s/@//g" |sed -e "s/\\./@/1" | sed -e "s/[^0123456789@]//g" | sed -e "s/@/./g" ; else echo "0.00"; fi } function compute_minus { ## minus, scaled (used for comparison of floats) echo "10000000.0*(($1)-($2))" | bc -l | cut -d'.' -f 1; } function blurt { ## output some text, if ${VERBOSE} is true if ${VERBOSE}; then echo "$@"; fi; } function set_noswitch_arguments { if [ -z ${INFILE} ]; then INFILE=$1; else abort "surplus argument: $1"; fi } function clear_file { if [ -z "$1" ]; then echo "INTERNAL ERROR: clear_file called without argument"; exit 99; fi; rm -f $1; touch $1; abort_on_error $? "failed to write to file $1"; } ## -- other aux functions: function add_link_to_next_dir { ## $1: directory to add if [ ! -d "$1" ]; then abort 1 "du_total_from_filelist: no such dir '$1'" fi; if [ $((${CURRENT_SUM} + $(du_total_from_dir $1))) -ge ${MAX_KB_PER_DIR} ]; then export N_DIR=$((${N_DIR}+1)); export CURRENT_SUM=$((${DU_FILES} + $(du_total_from_dir $1))); dir_array[${N_DIR}]="$1"; size_array[${N_DIR}]="${CURRENT_SUM}"; else export CURRENT_SUM=$((${CURRENT_SUM} + $(du_total_from_dir $1))); dir_array[${N_DIR}]="${dir_array[${N_DIR}]} $1"; size_array[${N_DIR}]="${CURRENT_SUM}"; fi; } function aux_create_overview { ## $1: file name to create local COUNT=1; echo "" > ${1}; abort_on_error $? "cannot write to file $1"; echo "** ********************************************" >> $1 ; echo "** TOTAL NUMBER OF DISCS: ${N_DIR} : $((${OFFSET}+1)) - $((${OFFSET}+${N_DIR})) " >> $1 ; echo "** ********************************************" >> $1 ; echo "" >> $1 ; while [ ${COUNT} -le ${N_DIR} ]; do echo "++ DISC $((${COUNT}+${OFFSET})) [$((${size_array[${COUNT}]} / 1024)) MB] +++++++++++++++++++++++++++++++" >> $1 ; for f in ${dir_array[${COUNT}]}; do echo " $f" >> $1 ; done; echo "" >> $1 ; COUNT=$((${COUNT}+1)); done; } function show_all { local TMP_OVERVIEW=/tmp/tmp.split_for_dvd_burn.bash.overview.$$ ; aux_create_overview ${TMP_OVERVIEW}; cat ${TMP_OVERVIEW}; rm ${TMP_OVERVIEW}; } function create_overview { aux_create_overview ${FILENAME_OVERVIEW}; } ## ################################################################### ## [1.1] BIN PACKING ## ################################################################### # NOTE: # The bin packing problem (assignment of N objects of differen size to a # minimal number K of containers of fixed size S) is NP-Complete. For large or # mean instances of this problem, every known algorithm will run in # superpolynomial time. # A bash script is certainly not your choice of language to solve these # instances. # # The algorithm used here is rather simple (spell: stupid), but complete. # The idea is that we start with a theoretically possible K, and # systematically try all combinations for feasibility (i.e. no container # overflows). # If no such solution exists, K is incremented. # As soon as a feasible solution for the current K is found, the algorithms # stops. # Determine whether a combination is feasible # $1: N_DIRS function is_feasible { local RESULT=true; local DIR=1; local DISC; local VALUE; # echo "? is_feasible ${aux_dist_dir[1]} ${aux_dist_dir[2]} ${aux_dist_dir[3]} ..." >&2 ; DISC=1; while [ ${DISC} -le ${BEST_NUMBER_OF_DISCS} ]; do size_array[${DISC}]=${DU_FILES}; DISC=$((${DISC}+1)); done; while ${RESULT} && [ ${DIR} -le ${1} ] ; do DISC=aux_dist_dir[${DIR}]; VALUE=$((${size_array[${DISC}]} + ${size_dir[${DIR}]})); if [ ${VALUE} -le ${MAX_KB_PER_DIR} ]; then size_array[${DISC}]=${VALUE}; else RESULT=false; fi; DIR=$((${DIR}+1)); done echo ${RESULT}; } function bin_pack { local N_DIRS=0; local DIR; local DISC; local POS; local FINISH; echo "## USING BIN-PACKING: stopping when an minimal assignment is found"; echo "## !! WARNING !! This may run a LONG time..."; echo ""; ## -- initial best assigment is the alpabetic one -------------------------- size_array[1]=${DU_FILES}; DISC=1; for f in $(cat ${TMPFILE_ALL_DIRS}); do N_DIRS=$((1+${N_DIRS})); size_dir[${N_DIRS}]=$(du_total_from_dir $f); name_dir[${N_DIRS}]=$f; aux_dist_dir[${N_DIRS}]=1; if [ $((${size_array[${DISC}]} + ${size_dir[${N_DIRS}]})) -gt ${MAX_KB_PER_DIR} ]; then DISC=$((${DISC}+1)); size_array[${DISC}]=${DU_FILES}; fi dist_dir[${N_DIRS}]=${DISC}; size_array[${DISC}]=$((${size_array[${DISC}]}+${size_dir[${N_DIRS}]})); done; BEST_NUMBER_OF_DISCS=${DISC}; if ! ${QUIET}; then echo "## current best number of discs: ${BEST_NUMBER_OF_DISCS}"; echo "## theoretically possible min number of discs: ${MIN_NUMBER_OF_DISCS}"; fi; ## -- Compute a minimal assignment ----------------------------------------- while [ ${BEST_NUMBER_OF_DISCS} -gt ${MIN_NUMBER_OF_DISCS} ]; do if $(is_feasible ${N_DIRS}); then if [ ${MIN_NUMBER_OF_DISCS} -lt ${BEST_NUMBER_OF_DISCS} ]; then BEST_NUMBER_OF_DISCS=${MIN_NUMBER_OF_DISCS}; DIR=1; while [ ${DIR} -le ${N_DIRS} ]; do dist_dir[${DIR}]=${aux_dist_dir[${DIR}]}; DIR=$((${DIR}+1)); done; fi fi; ## -- count up ---------------------------------------- POS=1; FINISHED=false; while ! ${FINISHED} && [ ${POS} -le ${N_DIRS} ] ; do VALUE=$((1+${aux_dist_dir[${POS}]})); if [ ${VALUE} -le ${MIN_NUMBER_OF_DISCS} ]; then aux_dist_dir[${POS}]=${VALUE}; #echo "increment pos ${POS} to ${VALUE}" >&2 ; #echo "${aux_dist_dir[${POS}]} " >&2 ; FINISHED=true; else aux_dist_dir[${POS}]=1; POS=$((${POS}+1)); fi done if [ ${POS} -gt ${N_DIRS} ]; then ## OVERFLOW export MIN_NUMBER_OF_DISCS=$((${MIN_NUMBER_OF_DISCS}+1)); if ! ${QUIET}; then echo "## theoretically possible min number of discs: ${MIN_NUMBER_OF_DISCS}"; fi; DIR=1; while [ ${DIR} -le ${N_DIRS} ]; do aux_dist_dir[${N_DIRS}]=1; DIR=$((${DIR}+1)); done; else if ${VERBOSE}; then : #echo "Counted up to ${aux_dist_dir[1]} ${aux_dist_dir[2]} ${aux_dist_dir[3]} ..." >&2 ; fi; fi; done; ## -- Create this assignment ----------------------------------------------- DISC=1; while [ ${DISC} -le ${BEST_NUMBER_OF_DISCS} ]; do dir_array[${DISC}]=""; size_array[${DISC}]=${DU_FILES}; DISC=$((${DISC}+1)); done; DIR=1; while [ ${DIR} -le ${N_DIRS} ]; do DISC=${dist_dir[${DIR}]}; dir_array[${DISC}]="${dir_array[${DISC}]} ${name_dir[${DIR}]}"; size_array[${DISC}]=$((${size_array[${DISC}]} + ${size_dir[${DIR}]})); DIR=$((${DIR}+1)); done; ## -- show assignment ------------------------------------------------------ if ${VERBOSE}; then echo "## Minimal assignment found: "; DIR=1; while [ ${DIR} -le ${N_DIRS} ]; do echo "${DIR} : ${name_dir[${DIR}]} (${size_dir[${DIR}]} KB) -> disc ${dist_dir[${DIR}]}"; DIR=$((${DIR}+1)); done fi; ## -- set number of discs -------------------------------------------------- export N_DIR=${BEST_NUMBER_OF_DISCS}; } ## ################################################################### ## [2] MAIN ## ################################################################### ## ############################################### ## [2.1] READ OPTIONS ## ############################################### AWAIT=""; for switch in $@; do case $AWAIT in -m ) AWAIT=""; export MAX_MB_PER_DIR=$switch;; -p ) AWAIT=""; export DIR_PREFIX=$switch;; -d ) AWAIT=""; export NEWER_DATE_DATE=$(echo $switch | sed 's/#/ /g');; -o ) AWAIT=""; export OFFSET=$switch;; -s ) AWAIT=""; export SOURCE_DIR=$(abs_dir $switch);; -t ) AWAIT=""; export TARGET_DIR=$(abs_dir $switch);; * ) case $switch in --help ) print_help;; -help ) print_help;; -h ) print_help;; --verbose ) VERBOSE=true;; -v ) VERBOSE=true;; -q ) QUIET=true;; --only-show ) OPTION_ONLYSHOW=true;; -n ) OPTION_ONLYSHOW=true;; --size ) AWAIT="-m";; -m ) AWAIT="-m";; --prefix ) AWAIT="-p";; -p ) AWAIT="-p";; --newer-date ) AWAIT="-d";; -d ) AWAIT="-d";; -o ) AWAIT="-o";; --offset ) AWAIT="-o";; --source-dir ) AWAIT="-s";; -s ) AWAIT="-s";; --target-dir ) AWAIT="-t";; -t ) AWAIT="-t";; --no-files ) COPY_FILES=false;; -x ) COPY_FILES=false;; --bin-pack ) BIN_PACK=true;; -b ) BIN_PACK=true;; --version ) echo "Version: $VERSION";exit 0;; -* ) echo "Unknown switch: $switch";print_usage;exit 1;; * ) set_noswitch_arguments $switch;; esac esac done; ## ############################################### ## [2.2] DERIVED VALUES ## ############################################### export MAX_KB_PER_DIR=$((1024 * ${MAX_MB_PER_DIR})); ## ############################################### ## [2.3] SANITY CHECK ## ############################################### if [ ! -d ${SOURCE_DIR} ]; then echo "$0: source directory ${SOURCE_DIR} does not exist." 1>&2; print_usage; exit 1; fi if [ ! -d ${TARGET_DIR} ]; then echo "$0: target directory ${TARGET_DIR} does not exist." 1>&2; print_usage; exit 1; fi FILENAME_OVERVIEW=${TARGET_DIR}/OVERVIEW.txt; if [ ! -z "${NEWER_DATE_DATE}" ]; then COMPUTED_MINUTES=$(echo \($(date +%s) - \ $(date --date "${NEWER_DATE_DATE}" +%s) \) / 60 | bc); OPTION_NEWER_DATE="-mmin -${COMPUTED_MINUTES}"; if [ ${COMPUTED_MINUTES} -lt 0 ]; then echo "ERROR: selected date \"${NEWER_DATE_DATE}\" is in the future."; exit 1; fi fi; ## ############################################### ## [2.4] REQUIRED SUB-SCRIPTS and UNIX FUNCTIONS ## ############################################### #SCRIPT_VERSION=$(get_version_number_of_script fig2eps); #if [ $(compute_minus $SCRIPT_VERSION 1.0) -lt 0 ]; then # echo "$0: Need SCRIPT 1.0 or higher. " 1>&2; # echo "Sorry. " 1>&2; # exit 1; #fi; ## ############################################### ## [2.5] SPAM ## ############################################### if $VERBOSE; then echo "----------------------------------------------------------------------"; echo "SOURCE_DIR: ${SOURCE_DIR}" ; echo "TARGET_DIR: ${TARGET_DIR}" ; echo "MAX_MB_PER_DIR: ${MAX_MB_PER_DIR}" ; echo "MAX_KB_PER_DIR: ${MAX_KB_PER_DIR}" ; echo "DIR_PREFIX: ${DIR_PREFIX}" ; echo "OPTION_ONLYSHOW: ${OPTION_ONLYSHOW}" ; echo "NEWER_DATE_DATE: ${NEWER_DATE_DATE}" ; echo "OPTION_NEWER_DATE: ${OPTION_NEWER_DATE}" ; echo "OFFSET: ${OFFSET}" ; echo "QUIET: ${QUIET}" ; echo "COPY_FILES: ${COPY_FILES}" ; echo "BIN_PACK: ${BIN_PACK}" ; echo "VERBOSE: ${VERBOSE}" ; echo "VERSION: ${VERSION}" ; echo "----------------------------------------------------------------------"; fi; ## ################################################################### ## [3] PROCESSING ## ################################################################### ## ############################################### ## [3.1] INIT ## ############################################### echo "## ls -l ${TARGET_DIR} -------------------------------- "; ls -l ${TARGET_DIR} ; echo "## END OF ls -l ${TARGET_DIR} -------------------------------- "; if $(confirm "clean up target dir: ${TARGET_DIR} "); then rm -rf ${TARGET_DIR}/*; fi; clear_file ${TMPFILE_ALL_FILES} ; clear_file ${TMPFILE_ALL_DIRS} ; if ${COPY_FILES}; then find ${SOURCE_DIR}/ -name "*" -type f -maxdepth 1 > ${TMPFILE_ALL_FILES}; fi; find ${SOURCE_DIR}/* -name "*" -type d -maxdepth 0 ${OPTION_NEWER_DATE} > ${TMPFILE_ALL_DIRS}; if [ -S ${TMPFILE_ALL_DIRS} ]; then echo "ERROR: no directories found."; exit 1; fi; export DU_FILES=0; if [ -S ${TMPFILE_ALL_FILES} ]; then export DU_FILES=$(du -c -k $(cat ${TMPFILE_ALL_FILES} ) \ | grep -e "[0-9]*[ \t]*total$" \ | sed 's/[^0-9].*$//g'); fi; DU_DIRS=$(du_total_from_filelist ${TMPFILE_ALL_DIRS}); if ! ${QUIET}; then echo "## ALL FILES (${DU_FILES} KB -> $((${DU_FILES} /1024)) MB):"; cat ${TMPFILE_ALL_FILES} echo ""; echo "## ALL DIRS (${DU_DIRS} KB -> $((${DU_DIRS}/1024)) MB):"; cat ${TMPFILE_ALL_DIRS} echo ""; fi; ## ############################################### ## [3.2] CHECK FEASIBILITY ## ############################################### export TOTAL_KB_TO_BURN=0; for f in $(cat ${TMPFILE_ALL_DIRS}); do THIS_DIR_KB=$(du_total_from_dir $f); export TOTAL_KB_TO_BURN=$((${TOTAL_KB_TO_BURN}+${THIS_DIR_KB})); if [ $((${DU_FILES}+${THIS_DIR_KB})) -ge ${MAX_KB_PER_DIR} ]; then echo "ERROR: cannot keep size limit of ${MAX_KB_PER_DIR} KB." echo " Follwing directory is too big:"; echo " $f ($(du_total_from_dir $f) KB)"; echo " (together with ${DU_FILES} KB of commonly copied files)"; exit 1; fi; done; ## ############################################### ## [3.3] DISTRIBUTE ## ############################################### export DISC_SPACE=$((${MAX_KB_PER_DIR}-${DU_FILES})); export MIN_NUMBER_OF_DISCS=$((${TOTAL_KB_TO_BURN} / ${DISC_SPACE})); if [ 0 -ne $((${TOTAL_KB_TO_BURN} % ${DISC_SPACE})) ]; then export MIN_NUMBER_OF_DISCS=$((${MIN_NUMBER_OF_DISCS}+1)); fi if ! ${QUIET}; then echo "## ${TOTAL_KB_TO_BURN} KB vs DISC SPACE ${DISC_SPACE} KB "; echo "## The minimal number of required discs is at least ${MIN_NUMBER_OF_DISCS}"; fi; if ${BIN_PACK}; then bin_pack ; else if ! ${QUIET}; then echo "## DISTRIBUTING ${TOTAL_KB_TO_BURN} KB ALPHABETICALLY "; fi CURRENT_SUM=${MAX_KB_PER_DIR}; for f in $(cat ${TMPFILE_ALL_DIRS}); do add_link_to_next_dir $f; done; fi; if ${VERBOSE} || ${OPTION_ONLYSHOW}; then show_all; fi; ## ############################################### ## [3.4] CREATE LINKS ## ############################################### if ! ${OPTION_ONLYSHOW}; then create_overview; COUNT=1; while [ ${COUNT} -le ${N_DIR} ]; do blurt "## CREATING DISC $((${COUNT}+${OFFSET}))"; CURRENT_DIR=${TARGET_DIR}/${DIR_PREFIX}$(printf "%02d" $((${COUNT}+${OFFSET}))); mkdir ${CURRENT_DIR}; abort_on_error $? "Creation of ${CURRENT_DIR} FAILED"; if [ -S ${TMPFILE_ALL_FILES} ]; then cp $(cat ${TMPFILE_ALL_FILES}) ${CURRENT_DIR}/ ; fi; cp ${FILENAME_OVERVIEW} ${CURRENT_DIR}/ ; for d in ${dir_array[${COUNT}]}; do ln -s $d ${CURRENT_DIR} ; abort_on_error $? "FAILED to create symbolic link to $d" ; done; COUNT=$((${COUNT}+1)); done; fi; ## ---------------------------------------------------- remove_tempfiles; if ! ${QUIET} && ! ${OPTION_ONLYSHOW}; then echo ""; echo "** -----------------------------------------------------------------------"; echo "** READY TO BURN ${N_DIR} SUB-DIRECTORIES OF ${TARGET_DIR}"; echo "** NOTE: Make sure that your burn program follow the symbolic links." echo "** e.g, in k3b, select burn option 'advanced/follow symbolic link'"; echo "** -----------------------------------------------------------------------"; echo ""; fi; exit 0; ## --- OK ------------------------------------- ## ################################################################### ## [4] EMACS VARIABLES ## ################################################################### ### Local Variables: *** ### mode: lisp *** ### eval: (defun update-global-date () (let ((pos (point-marker))) (goto-char (point-min)) (if (search-forward-regexp "^VERSION_DATE=" (point-max) t) (progn (kill-line) (insert (format "\"%s\" ;" (current-time-string))) (basic-save-buffer) (message "** Version Date Updated."))) (goto-char pos))) *** ### eval: (defun new-global-hh-insert-disclaimer () (interactive) (insert-disclaimer) (update-global-date) (shell-script-mode)(font-lock-mode) (local-set-key [f4] #'new-global-hh-insert-disclaimer)) *** ### eval: (progn (shell-script-mode)(font-lock-mode) (local-set-key [f4] #'new-global-hh-insert-disclaimer)) *** ### comment-column:0 *** ### comment-start: "### " *** ### comment-end:"***" *** ### End: ***