#!/bin/bash
################################################################################
#
# bak2disc - backup to disc volumes while maintaining original data structure
# Copyright (C) 2005-2006 dorphell <dorphell [AT] gmail [DOT] com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
################################################################################
#--------------------------------------------------------------------
# PUBLIC CONSTANTS [Default Parameters]
#--------------------------------------------------------------------
## Dir used for meta-data (a few MBs of ASCII files) ##
TMP_DIR="${TEMP:-/tmp/bak2disc}"
mkdir -p $TMP_DIR
## Disc type (valid types: CD74, CD80, DVD5, DVD9, DLT7, LTO2, LTO3) ##
MEDIA_TYPE="DVD5"
## Space allocated for index metadata (MiB)##
INDEX_SIZE=4
## mkisofs options used by growisofs ##
MKISOFS_OPTS=" -r -J "
## Limit for the volume-filling search in the element array ##
SEARCH_RANGE=150
Label="Volume"
#--------------------------------------------------------------------
# PRIVATE CONSTANTS [Do not Modify]
#--------------------------------------------------------------------
VERSION="0.7-tpb"
PROG_NAME="bak2disc"
GB=1073741824 # 1024^3
MB=1048576 # 1024^2
## ANSI Color modifiers ##
C_BOLD="\e[1m" # Bold
C_NORM="\e[m\e[0;39m" # Normal
C_BLUE="\e[1;34m" # Blue
C_RED="\e[1;31m" # Red
## Only use newlines for field separation ##
IFS=$'\n'
## Error Messages ##
ErrorMsgs=(
"00: No error"
"01: Unknown error"
"02: Program \'\$2\' not in \\\$PATH"
"03: Working directory \'\$2\' already exists"
"04: Permission denied or file/directory does not exist: \$2"
"05: File[s] too big, choose a higher-capacity disc or suppress oversized file[s]"
"06: Temporary directory \'\$2\' exists"
"07: Could not create temporary directory \'\$2\'"
"08: User reported failed burn for disc volume \$2, --resume to try again"
"09: Option \'\$2\' requires an argument"
"10: Invalid option: \$2"
"11: Previous session metadata not found. Incorrect --temp parameter?"
"12: No options given, what do you want to do?"
"13: No \'--include\' files/directories defined"
"14: Disc \$2 index larger than allocated space, increase --index size"
"15: Please provide a single valid operating mode"
"16: Unknown disc type \'\$2\'. Valid types: cD74, CD80, DVD5, DVD9, DLT7, LTO2, LTO3"
"17: SIGINT caught"
"18: Invalid --speed argument, value must be an integer"
"19: mkisofs is really genisoimage which will not work")
#--------------------------------------------------------------------
# FUNCTIONS
#--------------------------------------------------------------------
Help() {
cat << EOF
$PROG_NAME v$VERSION (c) 2006 dorphell
Usage: $PROG_NAME <mode> [options]
Backup to disc volumes while maintaining original data structure
Informative flags:
-h, --help Print help screen
-v, --version Print version information
Operating mode flags: (one required)
-f, --fresh Start a new backup session
-n, --noburn Generate backup volume information but don't burn to disc
-r, --resume Resume the burn phase of a previous backup session (relies
on original metadata)
-w, --wipe Clean up temporary directory and exit
Accessibility flags:
-j, --eject Open drive tray for disc loading/unloading and skip the
verification prompt.
-l, --exlarge Automatically exclude files too large for backup media
-c, --nocolor Turn off all text color/highlighting
Configuration options: (every option requires an argument)
-i, --include Colon-separated file/directory paths to include (multiple
definitions and bash globbing wildcards are also vallid)
-e, --exclude File/directory paths to exclude (same syntax as --include)
-t, --temp Temporary directory [default: $TMP_DIR]
-o, --mkisofs Burning options passed onto mkisofs/growisofs
[default: $MKISOFS_OPTS]
-m, --mtype Disc type (CD74, CD80, DVD5, DVD9, DLT7, LTO2, LTO3) [default: $MEDIA_TYPE]
-x, --index Space allocated for index metadata out of disc capacity
[default: $INDEX_SIZE]
-g, --range Number of files/directories to poll when filling slack
space on volumes [default: $SEARCH_RANGE]
-s, --speed Speed factor of the writing process (integer value)
[default: Maximum supported by the drive]
--label Label the .iso and volume name
Examples:
$PROG_NAME --fresh --include "/etc:/mnt/HD*:/opt" -d /dev/hdc --mtype DVD5
$PROG_NAME -n -i /usr -i /var -e /var/log --temp /tmp --range 10 -m DVD5
$PROG_NAME --resume --temp /var/tmp
GNUtar:
gtar cf <tape> -T $TMP_DIR/Volume_1
EOF
}
Version() {
echo "$PROG_NAME $VERSION"
}
## ErrorExit "int error_code" "string reference_name" ##
ErrorExit() {
echo -ne "$C_BLUE" >&2
echo -ne ">> "
echo -ne "$C_RED" >&2
eval echo -n "ERROR ${ErrorMsgs[$1]}"
echo -ne "$C_NORM" >&2
echo
exit $1
}
## PrintBold "string message" ##
PrintBold() {
echo -ne "$C_BOLD" >&2
echo -ne "$1"
echo -ne "$C_NORM" >&2
}
## PrintStatus "string message" ##
PrintStatus() {
echo -ne "$C_BLUE" >&2
echo -ne ">>"
echo -ne "$C_NORM$C_BOLD " >&2
echo -ne "$1"
echo -ne "$C_NORM" >&2
echo
}
## YesNo "string question" "boolean default" [y/n] ##
YesNo() {
OPTIONS="[y/n]"
[ "$2" == "y" ] && OPTIONS="[Y/n] "
[ "$2" == "n" ] && OPTIONS="[y/N] "
PrintBold "$1 $OPTIONS"
IFS=$' \t\n' read ANSWER
[ ! "$ANSWER" ] && [ "$2" ] && ANSWER="$2"
while [ "$ANSWER" != 'y' ] && [ "$ANSWER" != 'n' ] && [ "$ANSWER" != 'Y' ] && [ "$ANSWER" != 'N' ]; do
PrintBold "Invalid response, please answer 'y' or 'n': "
IFS=$' \t\n' read ANSWER
done
[[ "$ANSWER" == 'y' || "$ANSWER" == 'Y' ]] && return 0 || return 1
}
## CheckPath "string program_name" ##
CheckPath() {
while [ "$1" ]; do
! type "$1" &>/dev/null && ErrorExit 2 "$1"
shift
done
}
## ParseArgs "string args" (e.g. "$@") ##
ParseArgs() {
while [ "$1" ]; do
## Informative flags ##
case "$1" in
-h|--help)
Help; exit ;;
-v|--version)
Version; exit ;;
## Operating modes flags ##
-f|--fresh)
FRESH=1; shift ;;
-r|--resume)
RESUME=1; shift ;;
-n|--noburn)
NOBURN=1; shift ;;
-w|--wipe)
WIPE=1; shift ;;
## Accessibility flags ##
-j|--eject)
CheckPath 'eject'
EJECT=1; shift ;;
-l|--exlarge)
AUTO_EXCLUDE=1; shift ;;
-c|--nocolor)
NOCOLOR=1; shift ;;
## Configuration options ##
-i|--include)
[ ! "$2" ] && ErrorExit 9 "$1"
INCLUDE="$INCLUDE:$2"; shift 2;;
-e|--exclude)
[ ! "$2" ] && ErrorExit 9 "$1"
EXCLUDE="$EXCLUDE:$2"; shift 2;;
-o|--mkisofs)
[ ! "$2" ] && ErrorExit 9 "$1"
MKISOFS_OPTS="$2"; shift 2;;
-m|--mtype)
[ ! "$2" ] && ErrorExit 9 "$1"
MEDIA_TYPE="$2"; shift 2;;
-x|--index)
[ ! "$2" ] && ErrorExit 9 "$1"
INDEX_SIZE="$2"; shift 2;;
-t|--temp)
[ ! "$2" ] && ErrorExit 9 "$1"
TMP_DIR="$2"; shift 2;;
-g|--range)
[ ! "$2" ] && ErrorExit 9 "$1"
SEARCH_RANGE="$2"; shift 2;;
-s|--speed)
[ ! "$2" ] && ErrorExit 9 "$1"
[ "${2##*[^0-9]*}" ] || ErrorExit 18
SPEED="-speed=$2"; shift 2;;
--label)
[ ! "$2" ] && ErrorExit 9 "$1"
Label="$2"; shift 2;;
*)
Help; ErrorExit 10 "$1";;
esac
done
}
## SetMediaSize "string preset" (e.g. SetMediaSize "dvd9") ##
SetMediaSize() {
MEDIA_TYPE="$(echo $1| tr a-z A-Z)"
case "$MEDIA_TYPE" in
CD74) MEDIA_SIZE=650 ;;
CD80) MEDIA_SIZE=703 ;;
DVD5) MEDIA_SIZE=4482 ;;
DVD9) MEDIA_SIZE=8144 ;;
DLT7) MEDIA_SIZE=30000 ;;
LTO2) MEDIA_SIZE=190000 ;;
LTO2c) MEDIA_SIZE=323000 ;;
LTO3) MEDIA_SIZE=390000;;
LTO3c) MEDIA_SIZE=663000;;
*) Help;
ErrorExit 16 "$1" ;;
esac
let "MEDIA_SIZE-=INDEX_SIZE"
}
## ValidatePath "string path" "string output_variable" ##
## If path is readable, return its proper pathname; else error + exit ##
ValidatePath() {
[ ! -r "$1" ] && CleanUp && ErrorExit 4 "$1"
[ "$1" == '/' ] && return
eval "$2=\"$(echo "$1"| sed 's|/\+|/|g;s|/$||')\""
}
## GetList "string du_output_syntax" (e.g. "1234 <TAB> /path/to/dir") ##
## Returns a list of files/dirs that are less than media size ##
GetList() {
## Set Size and Name ##
VARS=(${1//$'\t'/$'\n'})
Size=${VARS[0]}
Name=${VARS[1]}
if [ $Size -gt $((MEDIA_SIZE*MB)) ] && [ -d "$Name" ]; then
for x in $($DU -ba --max-depth=1 "$Name"| gawk -F '\t' '$2 != "'$Name'" {print}'); do
GetList "$x"
done
else
printf "%s\t%s\n" "$Name" "$Size"
fi
}
## Burn disc volumes defined in TMP_DIR ##
BurnVolumes() {
NumOfDiscs=$(head -n 1 "$TMP_DIR/summary" 2>/dev/null| gawk '{print $8}')
MEDIA_TYPE=$(head -n 1 "$TMP_DIR/summary" 2>/dev/null| gawk '{print $9}')
## Check if metadata exists ##
[ ! $NumOfDiscs ] && ErrorExit 11
## If --resume, reprint distribution summary ##
if [ $RESUME ]; then
PrintStatus "Resuming burn session..."
while read line; do
vol=$(echo $line| gawk '$1 == "Disc" {printf "%i\n", $2}')
[ ${line:0:1} == " " ] && echo "$line" && continue
[ ${line:0:1} == "I" ] && PrintStatus "$line" && continue
[ -z $vol ] && PrintBold "$line\n" && continue
[ -e "$TMP_DIR/Volume_$vol" ] && PrintBold "$line\n" || echo "$line [Done]"
done < "$TMP_DIR/summary"
echo
fi
## Make ISO files
# for (( DISC_NUM=1; DISC_NUM<=$NumOfDiscs; DISC_NUM++ )); do
DISC_NUM=1
while [ $DISC_NUM -le $NumOfDiscs ]; do
## Volume already burned ##
[ ! -e "$TMP_DIR/Volume_$DISC_NUM" ] && continue
## Burn the volume ##
ALL_MKISOFS_OPTS="$MKISOFS_OPTS -quiet -V ${Label}-${DISC_NUM}_of_$NumOfDiscs -graft-points -exclude-list $EXC_LIST -path-list $TMP_DIR/Volume_$DISC_NUM -o ${Label}_$DISC_NUM.iso"
IFS=$' \n';
echo "mkisofs $ALL_MKISOFS_OPTS"
mkisofs $ALL_MKISOFS_OPTS
IFS=$'\n'
## Volume successfully burned, delete volume metadata ##
rm "$TMP_DIR/Volume_$DISC_NUM" "$TMP_DIR/volume_${DISC_NUM}_of_${NumOfDiscs}"
DISC_NUM=$(expr $DISC_NUM + 1)
done
## Backup complete, wipe out metadata ##
PrintStatus "All $NumOfDiscs backup volumes burned."
CleanUp
}
## CleanUp (removes "$TMP_DIR" entirely) ##
CleanUp() {
PrintStatus "Cleaning up temporary data"
rm -rf "$TMP_DIR"
}
Terminate() {
echo
ErrorExit 17
}
#--------------------------------------------------------------------
# SCRIPT START
#--------------------------------------------------------------------
## Capture ^C exit code ##
trap Terminate SIGINT
## Check if utilities are in $PATH ##
# Solaris /bin/du won't work. Look for GNU du named gdu
[ -f $(which gdu) ] && DU=$(which gdu) || DU=$(which du)
[ $(uname -s) == "SunOS" -a $(basename $DU) != "gdu" ] && ErrorExit 2 "gdu"
CheckPath 'gawk' 'sed' 'printf' 'sort' "$DU" 'stat' 'comm' 'mkisofs'
mkisofs --version | grep -s genisoimage > /dev/null
[ $? -eq 0 ] && echo "mkisofs is really genisoimage which will not work"
## Parse command-line arguments ##
[ -z "$1" ] && Help && ErrorExit 12
ParseArgs "$@"
ValidatePath "$TMP_DIR" "TMP_DIR"
TMP_DIR="$TMP_DIR/$PROG_NAME-$USER"
FILE_LIST="$TMP_DIR/include"
EXC_LIST="$TMP_DIR/exclude"
SetMediaSize "$MEDIA_TYPE"
[ $NOCOLOR ] && unset C_BOLD C_NORM C_BLUE C_RED
## No operating modes defined, error ##
[ $((FRESH+NOBURN+RESUME+WIPE)) -ne 1 ] && Help && ErrorExit 15
## If --resume specified, just burn using preexisting metadata ##
[ $RESUME ] && BurnVolumes && exit
## Delete any garbage/leftovers and start fresh ##
[ $WIPE ] && CleanUp && exit
## Check for leftovers, if not clean, ask what to do ##
if [ -e "$TMP_DIR" ]; then
! YesNo "Leftover metadata detected; DELETE and start fresh?" "n" && PrintBold "Nothing dnoe... exiting\n" && exit
CleanUp
fi
## Check/Ask for required variables ##
[ ! "$INCLUDE" ] && Help && ErrorExit 13
PrintBold "$C_RED-------------------------------------------------------------------$C_NORM\n"
PrintBold " Do not modify included files until they have been written to disc\n"
PrintBold " Excessive growth may cause volume to overflow disc capacity\n"
PrintBold "$C_RED-------------------------------------------------------------------$C_NORM\n"
## Start a fresh backup now ##
mkdir -p "$TMP_DIR" || ErrorExit 7 "$TMP_DIR"
## Convert path lists to arrays ##
INCLUDE=(${INCLUDE//:/$'\n'})
EXCLUDE=(${EXCLUDE//:/$'\n'})
## Validate all dir/file paths ##
x=0
while [ $x -lt ${#INCLUDE[@]} ]; do ValidatePath "${INCLUDE[$x]}" "INCLUDE[$x]"; x=$(expr $x + 1); done
x=0
while [ $x -lt ${#EXCLUDE[@]} ]; do ValidatePath "${EXCLUDE[$x]}" "EXCLUDE[$x]"; x=$(expr $x + 1); done
## Remove all dupes ##
for x in "${INCLUDE[@]}"; do INCLUDE=($(echo "${INCLUDE[*]}"| sed "\|^$x/|d"| sort -u)); done
for x in "${EXCLUDE[@]}"; do EXCLUDE=($(echo "${EXCLUDE[*]}"| sed "\|^$x/|d"| sort -u)); done
## Generate element filelist from INCLUDE paths ##
for x in "${INCLUDE[@]}"; do
GetList "$($DU -bs "$x")"
done| sort > "$FILE_LIST"
## Remove excluded items from filelist ##
if [ "${EXCLUDE[*]}" ]; then
for item in $($DU -bs "${EXCLUDE[@]}"); do
item=(${item//$'\t'/$'\n'})
Size=${item[0]}
Name=${item[1]}
## *Exact* match ##
Exists=$(gawk -F '\t' '$1 == "'$Name'" || $1 ~ "'$Name'/" {print $1}' "$FILE_LIST")
if [ "$Exists" ]; then
for x in $Exists; do sed "\|^$x\t.*|d" -i "$FILE_LIST"; done
else
Parent=""
while [ ! "$Parent" ] && [ "$Name" ]; do
Name="${Name%/*}"
Parent=$(gawk -F '\t' '$1 == "'$Name'" {print}' "$FILE_LIST")
done
Parent=(${Parent//$'\t'/$'\n'})
PName=${Parent[0]}
PSize=${Parent[1]}
NewSize=$((PSize-Size))
sed "s|\(^$PName\)\t\(.*$\)|\1\t$NewSize|" -i "$FILE_LIST"
fi
done
fi
## Initialize element array ##
ELEMENTS=($(cat "$FILE_LIST"))
## Fill content elements into disc volumes ##
Current=0; Count=0; CountRange=0; declare -i Size; LastElement=${#ELEMENTS[@]}
while [ "${ELEMENTS[*]}" ]; do
line=(${ELEMENTS[$Count]//$'\t'/$'\n'})
Name="${line[0]}" # File name
Size="${line[1]}" # File size
if [ $Size -gt $((MEDIA_SIZE*MB)) ]; then # file bigger than disc capacity
AEXCLUDE[${#AEXCLUDE[@]}]="$Name" # add file to auto-exclude list
# unset ELEMENTS[$Count] Name
unset ELEMENTS[$Count]
unset Name
fi
if [ ! $Name ] && [ $Count -ne $CountRange ]; then # skip null elements
:
elif [ $CountRange -ne 0 ] && [ $Count -eq $CountRange ]; then # end of search range, volume filled
CountRange=0
let "Count=KeepCount-1" # go to 1st element that didn't fit
let "Current++"
# echo "$Current"
# echo "$((VolSizes[$Current]+Size)) $((MEDIA_SIZE*MB))"
elif [ $((VolSizes[$Current]+Size)) -lt $((MEDIA_SIZE*MB)) ]; then
VolSizes[$Current]=$((${VolSizes[$Current]}+$Size))
VolNames[$Current]="${VolNames[$Current]}$Name\n"
unset ELEMENTS[$Count]
else # element too big for current vol
if [ $CountRange -eq 0 ]; then # remember element position
KeepCount=$Count
let "CountRange=Count+SEARCH_RANGE"
if [ $CountRange -gt $LastElement ]; then # don't set range outside the array!
CountRange=$LastElement
fi
fi
fi
let "Count++"
done
## Ask if big files should be auto-excluded ##
if [ "$AEXCLUDE" ]; then
if [ ! $AUTO_EXCLUDE ]; then
for x in "${AEXCLUDE[@]}"; do echo "| $x"; done
YesNo "+ The preceding file[s] will not fit on a $MEDIA_TYPE disc, exclude and continue?" "y" || ErrorExit 5
echo
fi
EXCLUDE=("${EXCLUDE[@]}" "${AEXCLUDE[@]}")
fi
## Account for excluded files in distribution summary ##
find "${EXCLUDE[@]}" ! -type d 2>/dev/null| sort > "$EXC_LIST"
## Generate index and filelists ##
x=0;
while [ $x -lt ${#VolNames[@]} ]; do
BurnName="Volume_$((x+1))" # e.g. Volume_1
IndexName="volume_$((x+1))_of_${#VolNames[@]}" # e.g. volume_1_of_16
## Generate mkisofs graft-points formated filelist ##
echo -e "${VolNames[$x]}"| gawk -F '\n' '$1 {printf "data%s=%s\n", $1, $1}' > "$TMP_DIR/$BurnName"
## Generate volume reference index ##
VolFiles[$x]=$(comm -23 <(find $(echo -e "${VolNames[$x]}") ! -type d 2>/dev/null| sort) "$EXC_LIST")
echo "${VolFiles[$x]}" > "$TMP_DIR/$IndexName"
## Generate master catalog ##
echo "### $IndexName ###" >> "$TMP_DIR/catalog.idx"
echo -e "${VolFiles[$x]}\n"| sed 's|^/|'$((x+1))': /|' >> "$TMP_DIR/catalog.idx"
## Append reference index and master catalog to mkisofs input filelist ##
#echo "$IndexName=$TMP_DIR/$IndexName" >> "$TMP_DIR/$BurnName"
echo "catalog.idx=$TMP_DIR/catalog.idx" >> "$TMP_DIR/$BurnName"
x=$(expr $x + 1 )
done
## Generate mkisofs exclude list file ##
echo "${EXCLUDE[*]}" > "$EXC_LIST"
TotalSize=$(echo "${VolSizes[*]}"| gawk '{sum+=$1} END {printf "%.2f", (sum/'$GB') }')
Index_Size=$(stat -c %s "$TMP_DIR/catalog.idx" 2>/dev/null)
TotalFiles=$(echo "${VolFiles[*]}"| grep -c "[^\n]")
NumOfDiscs=${#VolNames[@]}
## Overall backup summary ##
SUM_TOTALS=$(printf "Summary: %s files (%s GiB) divided into %s %s disc volumes" "$TotalFiles" "$TotalSize" "$NumOfDiscs" "$MEDIA_TYPE")
SUM_INC=$(for x in "${INCLUDE[@]}"; do echo " $x"; done)
SUM_EXC=$(for x in "${EXCLUDE[@]}"; do echo " $x"; done)
PrintBold "$SUM_TOTALS\n"; echo -e "$SUM_TOTALS" > "$TMP_DIR/summary"
PrintStatus "Items Included:" && echo "$SUM_INC" && echo -e "Items Included:\n$SUM_INC" >> "$TMP_DIR/summary"
[ $EXCLUDE ] && PrintStatus "Items Excluded:" && echo "$SUM_EXC" && echo -e "Items Excluded:\n$SUM_EXC" >> "$TMP_DIR/summary"
## Disc volume distribution summary ##
x=0
while [ $x -lt $NumOfDiscs ]; do
DISC_NUM=$((x+1))
DISC_FILES=$(echo "${VolFiles[$x]}"| grep -c "[^\n]")
VIDX_SIZE=$(stat -c %s "$TMP_DIR/volume_${DISC_NUM}_of_${NumOfDiscs}")
DISC_SIZE=$(echo "${VolSizes[$x]}" $Index_Size $VIDX_SIZE $MB| gawk '{printf "%f", ($1+$2+$3)/$4 }')
DISC_FREE=$(echo $MEDIA_SIZE $INDEX_SIZE $DISC_SIZE| gawk '{printf "%i", $1+$2-$3}')
PRINT_DIST="$PRINT_DIST$(printf "Disc %3d: %5d files -> %8.2f MiB, %4i MiB free" "$DISC_NUM" "$DISC_FILES" "$DISC_SIZE" "$DISC_FREE")\n"
[ $DISC_FREE -lt 1 ] && ErrorExit 14 $DISC_NUM
x=$(expr $x + 1 )
done; PrintBold $PRINT_DIST
## Save distribution summary ##
echo -ne $PRINT_DIST >> "$TMP_DIR/summary"
## If --noburn specified, exit now ##
[ $NOBURN ] && PrintStatus "Backup metadata generated." && exit
## Ask whether to burn now or leave metadata for later ##
YesNo "\nBegin burn sequence now?" "y" && BurnVolumes
#--------------------------------------------------------------------
# SCRIPT END
#--------------------------------------------------------------------
Wednesday, July 29, 2009
Archiving a tree to DVD with bak2disc
bak2disc by dorphell is a script to create DVDs of a directory tree, preserving the structure. It will create an index file on the DVD so you can find which DVD the files are on.
I modified the script to create .iso files. You can also feed the file lists created to tar. So I modified the script to create lists contining X GB of data. I feed that to tar and can tar files to a DLT, SDLT, LTO, etc tape.
I sent an email and didn't get a reply. I'll try to get a version up somewhere.
I modified the script to create .iso files. You can also feed the file lists created to tar. So I modified the script to create lists contining X GB of data. I feed that to tar and can tar files to a DLT, SDLT, LTO, etc tape.
I sent an email and didn't get a reply. I'll try to get a version up somewhere.
Wednesday, June 11, 2008
Micro Irrigation
Article showing typical layout
HOWTO install a system
From Colorado State
RainBird automation
Tutorials
Irrigo systems - nice picture
Drip Works - end user vendor
Toro Micro Irrigation
HOWTO install a system
From Colorado State
RainBird automation
Tutorials
Irrigo systems - nice picture
Drip Works - end user vendor
Toro Micro Irrigation
Wednesday, June 4, 2008
Gardening
Just a few quick sites
Getting rid of weeds from http://www.thisgardenisillegal.com
Composting
http://myfolia.com/ is a garden tracking journal
According to http://www.garden.org, We are Zone 6a. And they have a nice plant zone finder.
Oh My!! GardenMon
Getting rid of weeds from http://www.thisgardenisillegal.com
Composting
http://myfolia.com/ is a garden tracking journal
According to http://www.garden.org, We are Zone 6a. And they have a nice plant zone finder.
Oh My!! GardenMon
Friday, February 8, 2008
Unsolicited phone calls
From Slashdot:
Here is an effective (though laborious) way to deal with that.
1. Register on National Do-Not-Call list.
2. Wait 3 month beginning period.
3. Get caller ID.
4. Wait for another call.
5. Be pleasant to the person, if you can order something cheap, say $10, do it.
6. Get their address and phone number as you place the order.
7. Photograph the Caller ID display as evidence.
8. Take good notes including date, time, person talked to, company name, as more evidence.
9. Copy the bill you receive for $10 as conclusive evidence of marketing intent.
10. Go to your county courthouse, lodge a small claim for $500 for a telemarketing violation.
11. Send them proper notice they are being sued.
12. Since they are often out of state, they won't show and you get default judgment.
13. If they do show, you have proof of listing, notice, call, and call purpose.
14. For bonus dollars, ($500 per item) look into whether they have,
train to, practice and publish upon demand the required company calling
policies.
15. Profit!!!
Powered by ScribeFire.
Sunday, February 3, 2008
Podcasting with an M-Audio Microtrack
Think of the MT (Microtrack) as you would a cassette recorder. Don't worry about listening. That's for later on the computer. The MT is to capture the sound. Much you'd use a camera to take lots of pictures of an event. You'll select relevant photos for your presentation, possibly editing and cleaning them up. You might change the order of the photos to better fit your presentation.
Make sure the battery is charged up.
Use the electret microphone on the wire, not the T mic. This lets you put the microphone near the sound.
On one side of the MT (microtrack) is a L/M/H switch. Put it on M for Microphone.
Put the microphone in its jack.
Press record to start recording. Do a test recording to check sound levels.
On the screen you'll see 2 bars, labeled L and R, for Left and Right.
The levels are the sensitivity of the sound. You want to adjust the level or sensitivity of the microphone so you get all the sound but not so sensitive that the sound is distorted.
Too low a level & the mic will not pickup (hear) any sound. Too high a level and there will be too much static and distortion. You might be able to hear someone's heartbeat ;-)
You want to adjust the levels so they are near the right side, but not hitting the end. Read your script while doing this until the levels are adjusted.
Hit record again to stop the recording. The MT will display "Writing" as it saves the recording as an MP3 file.
I'd suggest keeping a list of what you record:
Now that you've recorded, bring the MT over to the computer. Plug the USB cable into the MT and the computer.
The MT will appear as a disk called "MICRODRIVE" with all your recordings named file001.mp3, file002.mp3, etc. There is one for each time you pressed rec to start & then rec to end. Your log will help you figure out which is which.
They might not start number 001, but they will be numbered sequentially.
Create a folder in your My Documents folder and copy the files from the MICRODRIVE into it. Do not erase them from the MICRODRIVE yet. These are your originals. Some people make a CD of them so they have a read only copy.
Now you have your sound files to edit. MT supplies Audacity which is a good choice. You can copy it from the CD or download it off the internet.
I've never used Audacity, but basically it lets you edit your sound files. You can filter it to change the sound if your original recording wasn't optimal. Mostly, you'll be cutting out dead air and splicing snippets into place. You might find splicing the 1st half of take #2 with the 2nd half of take #3 to be the best choice. The better your original, the less to do latter.
Make sure the battery is charged up.
Use the electret microphone on the wire, not the T mic. This lets you put the microphone near the sound.
On one side of the MT (microtrack) is a L/M/H switch. Put it on M for Microphone.
Put the microphone in its jack.
Press record to start recording. Do a test recording to check sound levels.
On the screen you'll see 2 bars, labeled L and R, for Left and Right.
The levels are the sensitivity of the sound. You want to adjust the level or sensitivity of the microphone so you get all the sound but not so sensitive that the sound is distorted.
Too low a level & the mic will not pickup (hear) any sound. Too high a level and there will be too much static and distortion. You might be able to hear someone's heartbeat ;-)
You want to adjust the levels so they are near the right side, but not hitting the end. Read your script while doing this until the levels are adjusted.
Hit record again to stop the recording. The MT will display "Writing" as it saves the recording as an MP3 file.
I'd suggest keeping a list of what you record:
- Sound check
- Script take #1
- Script take #2
- recording of speech to students
Now that you've recorded, bring the MT over to the computer. Plug the USB cable into the MT and the computer.
The MT will appear as a disk called "MICRODRIVE" with all your recordings named file001.mp3, file002.mp3, etc. There is one for each time you pressed rec to start & then rec to end. Your log will help you figure out which is which.
They might not start number 001, but they will be numbered sequentially.
Create a folder in your My Documents folder and copy the files from the MICRODRIVE into it. Do not erase them from the MICRODRIVE yet. These are your originals. Some people make a CD of them so they have a read only copy.
Now you have your sound files to edit. MT supplies Audacity which is a good choice. You can copy it from the CD or download it off the internet.
I've never used Audacity, but basically it lets you edit your sound files. You can filter it to change the sound if your original recording wasn't optimal. Mostly, you'll be cutting out dead air and splicing snippets into place. You might find splicing the 1st half of take #2 with the 2nd half of take #3 to be the best choice. The better your original, the less to do latter.
Tuesday, January 15, 2008
Friday, December 28, 2007
Thursday, December 27, 2007
TiVo
Tivo Desktop
Running on Windows. Grabs the shows to a local VM disk. It won't save to a mapped drive. Lame.
VideoReDo
Converts the .TiVo to an mpg that the TiVo can view. Also strips commercials. Costs about $30. Windows.
TVAP
Watches the local VM disk for new shows. It then runs VideoReDo on the shows and saves them to the file server. It creates a text file with the show metadata in it. Windows.
pyTiVo
Publishes the shows on the file server for the TiVo to view again.
Runs on the file server (Solaris) but could be anything that can run python and ffmpeg (mplayer?). Unix, MacOSX, Windows. Uses the show metadata from TVAP.
Apparently pyTivo doesn't like "-" in the name of a share. Anything I tried to transfer from such a share would pause after 10 seconds and eventually kill the transfer. Removing the "-" from the sharename fixes it.
pyTivo has a version that will create a share for every subfolder you have. It works well.
Encoding and Ripping
Lifehacker Top 10: Top 10 Free Video Rippers, Encoders, and Converters
Running on Windows. Grabs the shows to a local VM disk. It won't save to a mapped drive. Lame.
VideoReDo
Converts the .TiVo to an mpg that the TiVo can view. Also strips commercials. Costs about $30. Windows.
TVAP
Watches the local VM disk for new shows. It then runs VideoReDo on the shows and saves them to the file server. It creates a text file with the show metadata in it. Windows.
pyTiVo
Publishes the shows on the file server for the TiVo to view again.
Runs on the file server (Solaris) but could be anything that can run python and ffmpeg (mplayer?). Unix, MacOSX, Windows. Uses the show metadata from TVAP.
Apparently pyTivo doesn't like "-" in the name of a share. Anything I tried to transfer from such a share would pause after 10 seconds and eventually kill the transfer. Removing the "-" from the sharename fixes it.
pyTivo has a version that will create a share for every subfolder you have. It works well.
Encoding and Ripping
Lifehacker Top 10: Top 10 Free Video Rippers, Encoders, and Converters
Organizing blogs
I've been reading a number of blogs about organizing, GTD (Getting Things Done) and dealing with clutter. Here's a list of links:
Unclutterer - and dealing with paper clutter
Declutter an area from Good housekeeping
43 Folders deals with GTD and is a source of the hipster PDA (paper based)
Lifehacker has tips on GTD and changing your life habits
Zen Habit's simplification of GTD Nice graphic of flow
Resources for Decluttering your home from http://zenhabits.net
WWLD? No. 2: Keeping Connected | 43 Folders
WWLD? No. 3: Organizing your environment | 43 Folders
WWLD? No. 4: Living Your Life | 43 Folders
Unclutterer - and dealing with paper clutter
Declutter an area from Good housekeeping
43 Folders deals with GTD and is a source of the hipster PDA (paper based)
Lifehacker has tips on GTD and changing your life habits
Zen Habit's simplification of GTD Nice graphic of flow
Resources for Decluttering your home from http://zenhabits.net
WWLD? No. 2: Keeping Connected | 43 Folders
WWLD? No. 3: Organizing your environment | 43 Folders
WWLD? No. 4: Living Your Life | 43 Folders
Powered by ScribeFire.
Wednesday, December 5, 2007
Sysadmin
Brendan Gregg has a ton of Solaris tools and stuff that works elsewhere. Portping can substitute where pings are not returned but another service is.
Clonezilla is a ghost clone
How to Make a Network Cable
Clonezilla is a ghost clone
How to Make a Network Cable
Friday, October 26, 2007
Macintosh software
More SCSI issues
I got another card with an LSI 53c895. It should be supported by the glm driver in 64 bit solaris. *sigh* Nope.
So now, I've got the Adaptec 2940au in the Linux box. It's seen but not the tape drive. I have a 2940U2 card to try also.
When did SCSI get difficult?
So now, I've got the Adaptec 2940au in the Linux box. It's seen but not the tape drive. I have a 2940U2 card to try also.
When did SCSI get difficult?
Friday, October 19, 2007
Solaris 10 x86 SCSI cards
I just got a cast off DLT 7000 drive to put in my Solaris x86 box. I've had SCSI on most of my systems dating back to a 286 with an Adaptec 1542b card. I ran Minix and DOS at the time with a Syquest 88MB drive. I often used that drive on Macintosh at a nearby college to download from simtel20.
Later I got a 486 and a 2GB 4mm DAT drive. I used the same card. The syquest and DAT worked with versions of tar for MacOS 7, SunOS 4.x, OS/2, DOS and Linux. Back when my drives were < 500MB, 2GB was quite large.
Along the way, I picked up other SCSI adapters; they were new or salvaged. I have a Symbios 53c825, an Adaptec 2940u, a Compaq Ultra 2. I thought they'd work great in my AMD dual core Solaris box.
*sigh*. The Symbios uses the ncrs driver which is 32 bit only. The 2940 uses the adp which is only 32bit. The Compaq uses the cadp which is also only 32 bit. They will work in Linux and probably MacOSX. I've found some stuff on the net about the adp and cadp drivers having issues and the glm driver for LSI chips is in house. The glm driver is the only one of the lot to be 64 bits.
So, for Solaris, I need a new card. The best bet I think is an LSI (ne symbios) card that uses the glm driver. The 53c825 isn't supported by glm, but many older/newer ones are. Sun used LSI chips. Some of the LSI cards are much cheaper then the Adaptec (the adp320 driver will work) I would need to get. I'm getting one on eBay at 1/3 the price of the Adaptecs that would work. More information later.
I could run backups on my Linux box, but I want to have the drive local to the disks, etc. Gigabit is about 60 MB/s and the drive is 8 (5?) MB/s so there's no lack of bandwidth, but all the data is on the Solaris file server.
Later I got a 486 and a 2GB 4mm DAT drive. I used the same card. The syquest and DAT worked with versions of tar for MacOS 7, SunOS 4.x, OS/2, DOS and Linux. Back when my drives were < 500MB, 2GB was quite large.
Along the way, I picked up other SCSI adapters; they were new or salvaged. I have a Symbios 53c825, an Adaptec 2940u, a Compaq Ultra 2. I thought they'd work great in my AMD dual core Solaris box.
*sigh*. The Symbios uses the ncrs driver which is 32 bit only. The 2940 uses the adp which is only 32bit. The Compaq uses the cadp which is also only 32 bit. They will work in Linux and probably MacOSX. I've found some stuff on the net about the adp and cadp drivers having issues and the glm driver for LSI chips is in house. The glm driver is the only one of the lot to be 64 bits.
So, for Solaris, I need a new card. The best bet I think is an LSI (ne symbios) card that uses the glm driver. The 53c825 isn't supported by glm, but many older/newer ones are. Sun used LSI chips. Some of the LSI cards are much cheaper then the Adaptec (the adp320 driver will work) I would need to get. I'm getting one on eBay at 1/3 the price of the Adaptecs that would work. More information later.
I could run backups on my Linux box, but I want to have the drive local to the disks, etc. Gigabit is about 60 MB/s and the drive is 8 (5?) MB/s so there's no lack of bandwidth, but all the data is on the Solaris file server.
Tuesday, September 11, 2007
Today's links
DVD Flick - DVD Authoring w/ chapterising
Libra - Personal media inventory w/ lending. Barcode reading via webcam, cuecat
ZFS quick guide.
Automatic ZFS snapshotting - Not quite Netapp, but better then anything else out there IMO
Libra - Personal media inventory w/ lending. Barcode reading via webcam, cuecat
ZFS quick guide.
Automatic ZFS snapshotting - Not quite Netapp, but better then anything else out there IMO
Friday, September 7, 2007
Podcasting links
A friend of my wife is interested in starting podcasting so I googled some links.
She has a Macintosh so I'm focusing on Mac tools
O'Reilly Digital Media Article - a good site for all digital media
Audacity is a good audio editor. It's cross platform and open source too. Free.
Engadget has a HOWTO that mentions free tools for receiving and creating
A Linux setup for Recording Video - many of the tools are available for MacOSX
From about.com - more info
iLounge is a cool iPod site with a Beginner's Guide
Most of these articles mention Free/Open Source software. You don't need to buy software to podcast. You can get by with a microphone, a computer, free software and maybe a webcam. Better microphones and a digital camcorder are obvious upgrades.
There might be Legal issues. This is the Creative Commons take on it. It's based on EFF's Guide. The EFF is all about protecting your legal rights in digital media. Since you're publishing, you care about Intellectual Property (IP) and Copyright. Lawrence Lessig is worth paying attention to.
I'd focus on creating the content, the audio MP3. I'd leave distribution to one of the podcasting sites. The about.com link has some sites.
She has a Macintosh so I'm focusing on Mac tools
O'Reilly Digital Media Article - a good site for all digital media
Audacity is a good audio editor. It's cross platform and open source too. Free.
Engadget has a HOWTO that mentions free tools for receiving and creating
A Linux setup for Recording Video - many of the tools are available for MacOSX
From about.com - more info
iLounge is a cool iPod site with a Beginner's Guide
Most of these articles mention Free/Open Source software. You don't need to buy software to podcast. You can get by with a microphone, a computer, free software and maybe a webcam. Better microphones and a digital camcorder are obvious upgrades.
There might be Legal issues. This is the Creative Commons take on it. It's based on EFF's Guide. The EFF is all about protecting your legal rights in digital media. Since you're publishing, you care about Intellectual Property (IP) and Copyright. Lawrence Lessig is worth paying attention to.
I'd focus on creating the content, the audio MP3. I'd leave distribution to one of the podcasting sites. The about.com link has some sites.
Fly Fusion Pen
My wife & I got a Fly Fusion pen to try. You write on special paper and the pen records your writing.
You can hook it up to a USB cable and import the drawing & writing. Output is an image or OCR will transform the text into a document.
In addition, the pen had a speaker and headphone jack to play music and give feedback for other functions. There is a music playing app: You draw a keyboard and can then play it with the pen. It will translate spanish writing to english speaking or vice versa. A calculator.
Your lettering needs to be block style like elementry school. I have pretty bad handwriting and decent block lettering. The OCR works well for me.
It's targeted at kids for homework and the applications are geared that way. For note taking, I think it's good for business use too. It's less obtrusive in a meeting then a laptop or especially a table computer. It's quicker then using a Palm. It captures drawings better then both. At $70 plus $8 per notebook, it's a nobrainer.
You can hook it up to a USB cable and import the drawing & writing. Output is an image or OCR will transform the text into a document.
In addition, the pen had a speaker and headphone jack to play music and give feedback for other functions. There is a music playing app: You draw a keyboard and can then play it with the pen. It will translate spanish writing to english speaking or vice versa. A calculator.
Your lettering needs to be block style like elementry school. I have pretty bad handwriting and decent block lettering. The OCR works well for me.
It's targeted at kids for homework and the applications are geared that way. For note taking, I think it's good for business use too. It's less obtrusive in a meeting then a laptop or especially a table computer. It's quicker then using a Palm. It captures drawings better then both. At $70 plus $8 per notebook, it's a nobrainer.
Wednesday, September 5, 2007
pyTivo issues
Apparently pyTivo doesn't like "-" in the name of a share. Anything I tried to transfer from such a share would pause after 10 seconds and eventually kill the transfer. Removing the "-" from the sharename fixes it.
Subscribe to:
Posts (Atom)
