Date: Sat, 06 Jan 2001 09:35:01 -0500 From: "Bryan J. Smith" <b.j.smith@ieee.org> To: david2000la@yahoo.com Cc: david@nns.ne.jp, freebsd-questions@freebsd.org Subject: RE: How about a free TCSH shell to backup to CDR? -- WAS: CDR Backup Copies of Software for Windows Message-ID: <3A572D15.8B3B7F0F@ieee.org> References: <FOEAIBOAIENFHIPHDDFBOEOICKAA.david@nns.ne.jp>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------96831CFD466F3AD9AB8F1BC0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit RE: How about a free TCSH shell to backup to CDR? -- WAS: CDR Backup Copies of Software for Windows CDR Software wrote: > Hello. I am selling CDR backup copies of software for Windows. > I charge only $10/CD and I have a huge collection including all > of the very latest programs. If you are interested, please > e-mail me and I'll send you a list. Hi David (assuming you have not masqueraded your E-mail as someone else)! Appreciate the SPAM! This is a FreeBSD (UNIX) list and we do not believe in piracy. Futhermore, our software is free and we have no use for pirated Windows software which won't run on our computers. Now if you are intersted in backup software to CDRs, I wrote this free TCSH shell script (attached) that let's you backup to CD (including per-file compression). I cover the features of the script below ... --- I recently (2000Dec15) created this script after a long user group discussion on backups, file integrity and recovery of corrupted backups, etc... For example, while Tar is quite recoverable when corrupted (where the corrupted section only affects files in that section), a compressed tarball is not (the whole archive becomes unrecoverable). Likewise, PKZip has this same issue. We even had one user who was so new to UNIX, he PKZiped his files and then burned that to a CD (talk about putting your data at risk, let alone it would be a pain to restore!). Since ISO9660 is an archive format in itself, you don't need to put it in a Tar, Cpio or even PKZip archive format. You just need to get the files in the ISO9660 master ISO file. Now we want to maximize storage, so we want to compress files individually. And we want to minimize temporary space, so we want to compress as we copy to the temporary area where we will master our CDs from. The end result is a burnable ISO9660 CD (with RockRidge & Joliet extensions + Apple/Mac if you use mkhybrid) that is filled with files that can be directly accessed as normal, with the exception that they are compressed for maximum capacity. I currently backup almost 2GB into a 650MB CD using this utility. I wanted a nice complement for CD backup that I have in afio for tape backup. It works on Linux, Solaris, FreeBSD and even Cygwin (for NT systems). Hope everyone enjoy's this Tcsh script. Review of features: - Per file compression! - Uses GZip by default - User selectable (see CONSTANTS) - Individually selectable for text and non-text (since GZip is faster/better for text, BZip2 better, although slower for most non-text) - Minimizes disk usage by compressing as it finds files -- but doesn't compress the existing files -- it compresses them in the temporary archive space - Identification of pre-compressed files (so it doesn't waste time recompressing) in 2 ways: - Via "file" string (catches anything compressed with Compress/Gzip/BZip2, including Dia and files not easily identifyable) - Via filename "extension" - Both are extensible (see CONSTANTS) - Takes one or more relative and/or absolute paths - You can mix'n match relative and absolute paths - Builds a hierarchy with the directory name in root (unlike stock mkisofs/mkhybrid, where the source directory is stripped -- I hate that!) - Can take the current directory (via ".") as a parameter - It checks _all_parameters_ to make sure they are _valid_ relative/absolute directories (yet another "niceity" over stock mkisofs/mkhybrid) - Does not cross filesystem boundaries (for obvious sanity reasons) - Symlinks are copied as symlinks and special files are copied over as special files (i.e. no issues/worries about dealing with them) - Supports both mkisofs (UNIX/Windows) and mkhybrid (+Mac) - If "iso_mac" set (see VARIABLES), myhybrid is used - Can specify alternative, mkisofs/mkhybrid compatible binary (see CONSTANTS) - Can also reset UNIX permissions so all files are world readable (default is to preserve UID, GID and bits -- see VARIABLES) - You can set both the output and temporary directories (see VARIABLES) - Great for setting an output path to a Samba shared directory where you can copy the .iso file over to your Windows system with a CD burner (and pull up CD Creator and tell it to burn a CD from an .iso image) - Does not assume binaries are in path, or are set. - You can override just about any binary location in CONSTANTS. - Only need tcsh and which, it either finds, or you can set, anything else - Minimal console clutter (nice simple ticks when archiving), but maximum logging to files Limitations (currently): - Parameters must be directories - A file cannot be a command-line parameter - But you can still send "." for the current directory - Parameters cannot have spaces in name - Only the actually parameters passed on the command-line - Spaces in their subdirectories and filenames are fine - Again, only what you pass on the command-line cannot have spaces (not even if you use "" or \ -- it's an internal variable issue I haven't accomodated yet), but any dirs/files under them are fine - Symlinks are blindly copied over, two issues: - It does not check that it points to anything useful in the CD image (especilly for absolute paths) [ I will probably never address this, no one does ] - Even if it points to a relative path that is on the CD, if that file is now compressed, it will not point to the new filename [ I'll probably fix this soon ] - Cannot have both a file and a compressed file in the same directory - Otherwise, only the first file will get copied and used (e.g., if file and file.gz both exist, only the first one seen by find will get backed up) -- TheBS -- Bryan "TheBS" Smith, Engineer CONTACT INFO *********************************************************** Chat: thebs413 @ AOL/MSN/Yahoo (see http://Everybuddy.com) Email: mailto:thebs@smithconcepts.com,thebs@theseus.com --------------96831CFD466F3AD9AB8F1BC0 Content-Type: text/plain; charset=us-ascii; name="back2cd.tcsh" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="back2cd.tcsh" #!/bin/tcsh -f # # back2cd.tcsh # $Id: back2cd.tcsh,v 1.4 2000/12/15 16:12:48 bjsmith Exp $ # # Make a CD-R ISO9660 Backup CD Image with UNIX/Windows/Mac extensions # compressing individual files in the image for maximum capacity. # # Written by Bryan "TheBS" Smith (mailto:b.j.smith@ieee.org) # Licensed under the GNU Public License (GPL) version 2.1 # All rights reserved to the Free Software Foundation ########################################################## # VARIABLES ########################################################## # Directories #========================================================= # Temporary Directory (need upto 700MB + biggest, uncompressed file) #--------------------------------------------------------- set iso_tmp=/tmp # ISO Output Directory (need upto 700MB) #--------------------------------------------------------- set iso_dir=/home # Extensions/Options #========================================================= # Set iso_mac to use Mac long filenames (requires Mkhybrid) #--------------------------------------------------------- #DISABLED#set iso_mac=set # Set iso_rrr to reset UNIX permissions (so all files are readable by everyone) #--------------------------------------------------------- #DISABLED#set iso_rrr=set # Information (for ISO9660 namespace) #========================================================= # Publisher #--------------------------------------------------------- set iso_pub="my name, company, address, phone" # Preparer #--------------------------------------------------------- set iso_pre="`whoami`@`uname -n`" ########################################################## # CONSTANTS ########################################################## # Binaries #========================================================= # Mkisofs/Mkhybrid (defaults to mkisofs in path, mkhybrid if "iso_mac" set) #--------------------------------------------------------- #OPTION#set bin_mkiso=/usr/bin/mkisofs #OPTION#set bin_mkiso=/usr/bin/mkhybrid # Compression for text files (defaults to GZip in path) #--------------------------------------------------------- #OPTION#set bin_cmptxt=/usr/gzip #OPTION#set bin_cmptxt=/usr/bin/bzip2 # Compression for non-text files (defaults to GZip in path) #--------------------------------------------------------- #OPTION#set bin_cmpbin=/usr/bin/gzip #OPTION#set bin_cmpbin=/usr/bin/bzip2 # Other Binaries (defaults to binary in path) #--------------------------------------------------------- #OPTION#set bin_cpio=/bin/cpio #OPTION#set bin_find=/usr/bin/find #OPTION#set bin_file=/usr/bin/file #OPTION#set bin_grep=/bin/grep #OPTION#set bin_mkdir=/bin/mkdir #OPTION#set bin_rm=/bin/rm # Files that should NOT be compressed #========================================================= # Strings reported by "file" (catches files compressed by Compress, GZip, BZip2, compressed XML apps) #--------------------------------------------------------- set noc_typ="compress" # By filename extension #--------------------------------------------------------- set noc_ext="arc lha lhz pak rpm zip zoo" ########################################################## # SCRIPT ########################################################## # Help #========================================================= if ( $# < 2 || $1 == "--help" || $1 == "-?" || $1 == "-h" || $1 == "-H" ) then echo "" echo "Syntax:" echo " back2cd <label> <dir> [<dir>...]" echo "" echo "Purpose:" echo " Create a 'ready-to-burn' backup ISO9660 image, including" echo " individually compressed files for maximum capacity while" echo " preserving data integrity and ease of access." echo "" echo "Where:" echo " <label> is the ISO volume label and output filename" echo " (withOUT the .iso extension -- NO SPACES)" echo " <dir> is the relative or absolute path to directories" echo " (you can specify one or more paths -- use '.' to pick" echo " the files/subdirectories in the current directory)" echo "" echo "The LOG of the archive process will be '${iso_dir}/<label>_arc.log'" echo "The LOG of the CD mastering will be '${iso_dir}/<label>_iso.log'" echo "The ISO file created will be '${iso_dir}/<label>.iso'" echo "" exit 0 endif # Verify an ISO image with the same name does NOT already exist #========================================================= set iso_label=$1 if ( -e ${iso_dir}/${iso_label}.iso ) then echo "" echo "ERROR: ISO Image '${iso_dir}/${iso_label}.iso' ALREADY EXISTS!" echo "Please pick another output label/filename." echo "" exit 1 endif # Find binaries and/or verify binaries exists (NOTE: long and mundane, but neccessary) #========================================================= # Mkisofs/Mkhybrid Binary #--------------------------------------------------------- if ( $?bin_mkiso ) then if ( ! -e ${bin_mkiso} ) then echo "" echo "ERROR: Binary '${bin_mkiso}' NOT found!" echo "Please correct in script's CONSTANTS section" echo "" exit 1 endif else if ( $?iso_mac ) then unalias mkhybrid set bin_mkiso=`which mkhybrid` if ( ! $?bin_mkiso ) then echo "" echo "ERROR: Cannot locate 'mkhybrid' binary" echo "Apple long filename option set which requires 'mkhybrid'" echo "Please set full path in script's CONSTANTS section" echo "OR disabled Apple long filename option" echo "(i.e. uses 'mkisofs' instead)" echo "" exit 1 endif else unalias mkisofs set bin_mkiso=`which mkisofs` if ( ! $?bin_mkiso ) then echo "" echo "ERROR: Cannot locate 'mkisofs' binary" echo "Please set full path to binary in script's CONSTANTS section" echo "" exit 1 endif endif endif # Compression Binaries #--------------------------------------------------------- if ( $?bin_cmptxt ) then if ( ! -e ${bin_cmptxt} ) then echo "" echo "ERROR: Binary '${bin_cmptxt}' NOT found!" echo "Please correct in script's CONSTANTS section" echo "" exit 1 endif else unalias gzip set bin_cmptxt=`which gzip` if ( ! $?bin_cmptxt ) then echo "" echo "ERROR: Cannot locate 'gzip' binary" echo "Please set full path to binary in script's CONSTANTS section" echo "" exit 1 endif endif if ( $?bin_cmpbin ) then if ( ! -e ${bin_cmpbin} ) then echo "" echo "ERROR: Binary '${bin_cmpbin}' NOT found!" echo "Please correct in script's CONSTANTS section" echo "" exit 1 endif else unalias gzip set bin_cmpbin=`which gzip` if ( ! $?bin_cmpbin ) then echo "" echo "ERROR: Cannot locate 'gzip' binary" echo "Please set full path to binary in script's CONSTANTS section" echo "" exit 1 endif endif # Other binaries #--------------------------------------------------------- if ( $?bin_cpio ) then if ( ! -e ${bin_cpio} ) then echo "" echo "ERROR: Binary '${bin_cpio}' NOT found!" echo "Please correct in script's CONSTANTS section" echo "" exit 1 endif else unalias cpio set bin_cpio=`which cpio` if ( ! $?bin_cpio ) then echo "" echo "ERROR: Cannot locate 'cpio' binary" echo "Please set full path to binary in script's CONSTANTS section" echo "" exit 1 endif endif if ( $?bin_file ) then if ( ! -e ${bin_file} ) then echo "" echo "ERROR: Binary '${bin_file}' NOT found!" echo "Please correct in script's CONSTANTS section" echo "" exit 1 endif else unalias file set bin_file=`which file` if ( ! $?bin_file ) then echo "" echo "ERROR: Cannot locate 'file' binary" echo "Please set full path to binary in script's CONSTANTS section" echo "" exit 1 endif endif if ( $?bin_find ) then if ( ! -e ${bin_find} ) then echo "" echo "ERROR: Binary '${bin_find}' NOT found!" echo "Please correct in script's CONSTANTS section" echo "" exit 1 endif else unalias find set bin_find=`which find` if ( ! $?bin_find ) then echo "" echo "ERROR: Cannot locate 'find' binary" echo "Please set full path to binary in script's CONSTANTS section" echo "" exit 1 endif endif if ( $?bin_grep ) then if ( ! -e ${bin_grep} ) then echo "" echo "ERROR: Binary '${bin_grep}' NOT found!" echo "Please correct in script's CONSTANTS section" echo "" exit 1 endif else unalias grep set bin_grep=`which grep` if ( ! $?bin_grep ) then echo "" echo "ERROR: Cannot locate 'grep' binary" echo "Please set full path to binary in script's CONSTANTS section" echo "" exit 1 endif endif if ( $?bin_mkdir ) then if ( ! -e ${bin_mkdir} ) then echo "" echo "ERROR: Binary '${bin_mkdir}' NOT found!" echo "Please correct in script's CONSTANTS section" echo "" exit 1 endif else unalias mkdir set bin_mkdir=`which mkdir` if ( ! $?bin_mkdir ) then echo "" echo "ERROR: Cannot locate 'mkdir' binary" echo "Please set full path to binary in script's CONSTANTS section" echo "" exit 1 endif endif if ( $?bin_rm ) then if ( ! -e ${bin_rm} ) then echo "" echo "ERROR: Binary '${bin_rm}' NOT found!" echo "Please correct in script's CONSTANTS section" echo "" exit 1 endif else unalias rm set bin_rm=`which rm` if ( ! $?bin_rm ) then echo "" echo "ERROR: Cannot locate 'rm' binary" echo "Please set full path to binary in script's CONSTANTS section" echo "" exit 1 endif endif # Verify target paths actual exist #========================================================= shift set path_start=`pwd` foreach path_param ( $* ) if ( ! -d "${path_param}" ) then echo "" echo "ERROR: Path '${path_param}'" echo "is NOT a valid relative or absolute path to a directory." echo "" exit 1 endif end # Create temporary archive hierarchy #========================================================= # Begin Log #--------------------------------------------------------- set arc_log = ${iso_dir}/${iso_label}_arc.log echo "" > ${arc_log} echo "${arc_log}" >> ${arc_log} echo "`date`" >> ${arc_log} echo "" >> ${arc_log} echo " ISO Label: ${iso_label}" >> ${arc_log} echo " Image to Create: ${iso_dir}/${iso_label}.iso" >> ${arc_log} echo " Mastering Binary: ${bin_mkiso}" >> ${arc_log} echo "" >> ${arc_log} echo " Dir Launched In: ${path_start}" >> ${arc_log} echo " Dirs to Archive: $*" >> ${arc_log} echo " Archiving Temporary Dir: ${iso_tmp}/${iso_label}" >> ${arc_log} echo "" >> ${arc_log} echo " Text Compression Binary: ${bin_cmptxt}" >> ${arc_log} echo " Non-Text Compression Binary: ${bin_cmpbin}" >> ${arc_log} echo "Skip Compress 'file' Strings: ${noc_typ}" >> ${arc_log} echo " Skip Compress Filename Exts: ${noc_ext}" >> ${arc_log} echo "" >> ${arc_log} echo " Other Binary Paths: ${bin_cpio} ${bin_find} ${bin_file} ${bin_grep} ${bin_mkdir} ${bin_rm}" >> ${arc_log} echo "" >> ${arc_log} # Clear out any directory from a previous attempt #--------------------------------------------------------- if ( -e "${iso_tmp}/${iso_label}" ) then echo "Previous temporary archiving directory '${iso_tmp}/${iso_label}' already exists!" >> ${arc_log} echo " Deleting ..." >> ${arc_log} echo "" >> ${arc_log} ${bin_rm} -fr {$iso_tmp}/${iso_label} endif # Create new hierarchy #--------------------------------------------------------- echo "Creating temporary backup hierarchy" >> ${arc_log} echo " mkdir ${iso_tmp}/${iso_label}" >> ${arc_log} ${bin_mkdir} "${iso_tmp}/${iso_label}" foreach path_param ( $* ) echo " mkdir ${iso_tmp}/${iso_label}/${path_param}" >> ${arc_log} echo "${path_param}" | ${bin_cpio} -pmdv ${iso_tmp}/${iso_label} >&! /dev/null end echo "" >> ${arc_log} # Make compressed versions of parameter trees #========================================================= echo "" echo -n "Phase 1: Archiving " foreach path_param ( $* ) echo "" >> ${arc_log} echo "***********************************************************" >> ${arc_log} echo "* Archiving '${path_param}'" >> ${arc_log} echo "***********************************************************" >> ${arc_log} echo "" >> ${arc_log} cd ${path_start} cd ${path_param} foreach file_curr ( `${bin_find} . -mount -print` ) # First off, blindly copy file/dir to temporary iso archiving area #--------------------------------------------------------- echo -n "." if ( -d "${file_curr}" ) then set path_curdir=${file_curr} echo "Creating/Analyzing directory '${path_param}/${path_curdir}'" >> ${arc_log} echo "${file_curr}" | ${bin_cpio} -pmdv ${iso_tmp}/${iso_label}/${path_param} >&! /dev/null goto skip_proc endif if ( -l "${file_curr}" ) then echo " ${path_param}/${path_curdir} is a symlink, blindy copying (may be broken if referencing a, now, compressed file)" >> ${arc_log} echo "${file_curr}" | ${bin_cpio} -pmdv ${iso_tmp}/${iso_label}/${path_param} >&! /dev/null goto skip_proc endif echo "${file_curr}" | ${bin_cpio} -pmdv ${iso_tmp}/${iso_label}/${path_param} >&! /dev/null # If file is plain file #--------------------------------------------------------- if ( -f "${file_curr}" ) then # Check file type for known compressed file types #--------------------------------------------------------- foreach file_typ ( ${noc_typ} ) if ( `file ${file_curr} | ${bin_grep} -i "${file_typ}"` != "" ) then echo " ${path_param}/${file_curr} is known to be a '${file_typ}' file type -- NO compression" >> ${arc_log} goto skip_proc endif end # Check filename extension known compressed filename extensions #--------------------------------------------------------- foreach file_ext ( ${noc_ext} ) if ( `echo "${file_curr}" | ${bin_grep} -i "\.${file_ext}"` != "" ) then echo " ${path_param}/${file_curr} has a filename extension of '.${file_ext}' -- NO compression" >> ${arc_log} goto skip_proc endif end # Check for text or non-text content, compress with program as designated #--------------------------------------------------------- if ( `file ${file_curr} | ${bin_grep} -i "text"` != "" ) then echo " ${path_param}/${file_curr} is of a known text type, compressing with '${bin_cmptxt}'" >> ${arc_log} ${bin_cmptxt} ${iso_tmp}/${iso_label}/${path_param}/${file_curr} else echo " ${path_param}/${file_curr} is of a non-text type, compressing with '${bin_cmpbin}'" >> ${arc_log} ${bin_cmpbin} ${iso_tmp}/${iso_label}/${path_param}/${file_curr} endif # Otherwise, leave alone (compressed files, directories, symlinks, etc...) # (NOTE: symlinks get broken if they point to a plain file that is subsequently compressed) #--------------------------------------------------------- skip_proc: endif end end echo "" echo "" >> ${arc_log} echo "***********************************************************" >> ${arc_log} echo "* Archiving process complete" >> ${arc_log} echo "***********************************************************" >> ${arc_log} echo "" >> ${arc_log} # Finally make the freak'n ISO image! #========================================================= # Resolve ISO options #--------------------------------------------------------- if ( $?iso_mac ) then set iso_macset="-apple" else set iso_macset="" endif if ( $?iso_rrr ) then set iso_rrrset="-r" else set iso_rrrset="" endif # Master ISO image #--------------------------------------------------------- echo "" echo "Phase 2: Mastering (no progress marks)" echo "" >> ${arc_log} echo "Making ISO file '${iso_dir}/${iso_label}.iso'" >> ${arc_log} echo "" >> ${arc_log} echo "Running command (from ${iso_tmp}/${iso_label}): ${bin_mkiso} -A ${iso_label} -J -log-file ${iso_dir}/${iso_label}_iso.log -o ${iso_dir}/${iso_label}.iso -P '${iso_pub}' -p '${iso_pre}' -R ${iso_rrrset} -V ${iso_label} -v ${iso_macset} ." >> ${arc_log} echo "" >> ${arc_log} cd ${iso_tmp}/${iso_label} ${bin_mkiso} -A ${iso_label} -J -log-file ${iso_dir}/${iso_label}_iso.log -o ${iso_dir}/${iso_label}.iso -P "${iso_pub}" -p "${iso_pre}" -R ${iso_rrrset} -V ${iso_label} -v ${iso_macset} . # Trap errors #-------------------------------------------------------- if ( $status ) then echo "" echo "ERROR in CD creation." echo "See LOG file '${iso_dir}/${iso_label}.log' for details." echo "" exit 1 endif # Remove temporary archive directory (if successful) #-------------------------------------------------------- ${bin_rm} -fr {$iso_tmp}/${iso_label} echo "" echo "PROCESS COMPLETE" echo "" echo "The LOG of the archive process is '${iso_dir}/${iso_label}_arc.log'" echo " The LOG of the CD mastering is '${iso_dir}/${iso_label}_iso.log'" echo " The ISO file created is '${iso_dir}/${iso_label}.iso'" echo "" exit 0 --------------96831CFD466F3AD9AB8F1BC0-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3A572D15.8B3B7F0F>