#!/usr/bin/perl # # @program cdcat # @version 0.3 # @author LittleDragon # # @license # 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. # $program_name='cdcat'; $version_major=0; $version_minor=3; # Default settings $device="/dev/cdrom"; # The default device name $mount_point="/mnt/cdrom"; # The default device's mount point $directory="/var/lib/cdcat"; # The directory where the text files will reside $ls="/bin/ls"; $sed="/bin/sed"; $grep="/bin/grep"; $find="/usr/bin/find"; $isoinfo="/usr/bin/isoinfo"; $fstab="/etc/fstab"; $colors=1; # Use colors $show_related=1; # Show related entries for the -d option $err="Error"; $cat="Catalogued"; $del="Erased"; $ce="\033[m"; $cer="\033[1;31m"; # Error color $cok="\033[1;32m"; # OK color $cn="\033[1;37m"; # Neutral color $cfind="\033[0;36m"; # Find: match color $ccd="\033[0;32m"; # Find: CD name color $csep="\033[1;30m"; # Find: separator color $cerr="${cer}${err}:${ce}"; $ccat="${cok}${cat}:${ce}"; $cdel="${cok}${del}:${ce}"; $tsep=":"; # Find: separator my @qq; @qq[1]="a"; # Read settings from config files. for("/etc/cdcat.conf", "$ENV{HOME}/.cdcatrc") { open(CONF, "<$_"); for() { ${$1}=$2 if(/^[\s\t]*([^#]+?)[\s\t]*=[\s\t]*(.+?)$/) } close(CONF); } # Program sub error { print STDERR "$cerr $_[0]\n" } sub check_mount { if($<>0) { # $mtab=qx{cat /etc/mtab|$grep $mount_point|wc -l}; # if($mtab=~/^\s*0/) { # error("You must be root or $device must be mounted."); # exit; # } } } $def_dev=$device; sub color_switch { if(!$colors) { $cok=$cfind=$ccd=$csep=$ce=""; $cerr="$err:"; $ccat="$cat:"; $cdel="$del:"; } } if(@ARGV!="") { for(@ARGV) { $argv.=$_." " }; if($argv=~/(-V|--version)/) { print("$program_name $version_major.$version_minor\n"); exit(0); } if($argv=~/(-c|--no-colors)/) { $colors=0; color_switch } if($argv=~/(-q|--quiet)/) { $quiet=1 } if($argv=~/(-d|--device) *(.+?) /) { $device=$mount_point=""; $device=$2; @mp=qx{cat $fstab}; for(@mp) { if(/${device}[ \t]/) { s/${device}[ \t]+(.+?)[ \t].*$/$1/; if(length($_)>0) { $mount_point=$_ } } } } if($argv=~/(-m|--mount-point) *(.+?) /) { $mount_point=$2 } chomp($device); chomp($mount_point); if(!length($device)>0 || !length($mount_point)>0) { error("Device or mount point not specified."); exit; } if($argv=~/(-l|--list)/) { @list_files=qx{ls -1 $directory 2>/dev/null|sort}; $list_counter=0; if(@list_files) { for(@list_files) { chomp; $list_counter++; s/^(.*)?:.*$/$1/; print("$list_counter) $_\n"); } } else { error("Catalog empty."); } exit; } if($argv=~/(-b|--browse) *(.+?) /) { $browse_number=$2-1; @list_files=qx{ls -1 $directory 2>/dev/null|sort}; if(@list_files) { @list_cat=qx{cat $directory/$list_files[$browse_number]}; for(@list_cat) { chomp; s/^\///; print("$_\n") } } else { error("Catalog empty."); } exit; } if($argv=~/-a/ || $argv=~/--append/) { # Append check_mount; $append=1; $append_label=$argv; $append_label=~s/^.*(-a|--append) *(.*?) .*$/$2/; } elsif($argv=~/-r/ || $argv=~/--rename/) { # Rename check_mount; $rename=1; $rename_label=$argv; $rename_label=~s/^.*(-r|--rename) *(.*?) .*$/$2/; } elsif($argv=~/-e/ || $argv=~/--erase/) { # Delete $delete=1; $delete_match=$argv; $delete_match=~s/^.*(-e|--erase) *(.*?) .*$/$2/; } elsif($argv=~/-f/ || $argv=~/--find/) { # Find $grep_string=$argv; $grep_string=~s/^.*(-f|--find) *(.*$)/$2/; if($grep_string=~/^(\s*-[^ ]+\s*)+ ([^-].+?) -(.*) $/g) { # (-f <-options >) (-cdcat_options) # Separate arguments from grep arguments and from grep quote. # Magic formula: ^(\s*-[^ ]+\s*)+ ([^-].+?) -(.*) $ $grep_quote=$2; $grep_args=$grep_string; $grep_args=~s/^(.*)$grep_quote.*/$1/; $grep_string="$grep_args \"$grep_quote\""; $argv=~s/$grep_args//g; $argv=~s/$grep_quote//g; $argv=~s/-f//g; $grep_string=~s/ $//g; } else { $grep_string=~s/ $//g; } @find_strings=qx{$grep $grep_string $directory/*}; $grep_pattern=$grep_string; $grep_pattern=~s/^ *//g; $grep_pattern=~s/-[a-zA-Z0-9]+//g; $grep_pattern=~s/^ *//g; $grep_pattern=~s/\"//g; for(@find_strings) { chomp; s/$directory\///g; s/^(.+?):.+?:\/(.*)$/$ccd$1$csep$tsep$ce$2/g; s/($grep_pattern)/$cfind$1$ce/gi; print("$_\n"); } exit; } elsif($argv=~/-(C|-compress) *(.+?)\b/) { my $tmp_compression = $1; if($tmp_compression =~ /^gzip$/i || $tmp_compression =~ /^bzip2$/) { $compress = $tmp_compression; } else { $compress = "none"; } } elsif($argv=~/(-h|--help)/) { $prog_name=$0; $prog_name=~s/^.*\/(.+)$/$1/g; print("Usage: $prog_name [OPTION]\n"); print("Example: $prog_name -f -i source\n"); print("\n"); print("[OPTION] can be:\n"); print(" -a, --append [text] Append \"_[text]\" at the end of the catalog entry name, when creating a new entry. -b, --browse Browse CD . -c, --no-colors Disable colors. -d, --device Specify a different device. The default is $def_dev. -e, --erase [number|a] Delete the current CD entry from the catalog, or the [number] similar to current entry. If \"a\" is specified instead of a number, then all the similar entries are deleted. -f, --find [options] Search all the catalog entries and return the file names matching . Also, most grep options can be specified as [options]. -h, --help Show this help screen. -l, --list Show the list of all catalogued CDs. -m, --mount-point Specify a different mount point for the current device. -q, --quiet Only show errors. -r, --rename Rename the catalog entry to . -V, --version Outputs version information and exits. "); exit; } } $escaped_mp=$mount_point; $escaped_mp=~s/\//\\\//gi; @iso=qx{$isoinfo -d -i $device 2>&1}; for(@iso) { if(/volume id: (.*)$/i) { $label=$1 } if(/volume size is: (.*)$/i) { $volume=$1 } if(/isoinfo: (.*)$/i) { error("$1"); exit } } $label=~s/\s/_/gi; $label=~s/[\/\\]/_/gi; if($append) { $label.="_".$append_label } elsif($rename) { $label=$rename_label } if($delete) { if($delete_match && $delete_match=~/^a$/) { @delete_strings=qx{find $directory -type f}; if(@delete_strings) { $delete_count=-1; for(@delete_strings) { $delete_count++; $delete_string=$delete_strings[$delete_count]; chomp($delete_string); if(qx{[ -e "$delete_string" ] && echo 1 || echo 0}==1) { qx{rm -fr $delete_string}; $delete_current=$delete_string; $delete_current=~s/$directory\///; $delete_current=~s/^(.*):.*$/$1/; if(!$quiet) { print("$cdel $delete_current\n") } } } } else { error("No entries found."); } exit; } if($delete_match && $delete_match=~/^(\d+)$/) { $delete_match--; @list_files=qx{ls -1 $directory 2>/dev/null|sort}; if(@list_files) { if ($list_files[$delete_match]) { qx{rm -fR $directory/$list_files[$delete_match]}; if(!$quiet) { print("$cdel $list_files[$delete_match]") } } else { error("Entry not found"); } } else { error("Catalog empty."); } exit; } else { error("Please use an index number or \"a\" to erase all "); exit;} } if(qx{[ -e "$directory/$label:$volume" ] && echo 1 || echo 0}==1) { error("The CD was most probably already catalogued."); exit; } else { $fname="$directory/$label:$volume" } @files=qx{ mount $mount_point 2>&1|| mount $device $mount_point 2>&1| $grep -vi "already mounted"| $grep -vi "write-protected"| $sed 's/mount: \\(.*\\)\$/$cerr \\1/gi'; $find $mount_point| $sed 's/$escaped_mp//gi'; umount $mount_point 2>&1 }; check_mount; $counter=0; undef($first_line); for(@files) { chomp; if(!defined($first_line)) { $first_line=1 } else { $files[$counter]=$_; $counter++; } } open(F, ">$fname"); for(@files) { print F "$_\n" } close(F); if(!$quiet) { print("$ccat $label\n") }