diff --git a/mycp/mycp b/mycp/mycp index e901635..d971977 100755 --- a/mycp/mycp +++ b/mycp/mycp @@ -3,28 +3,101 @@ # $Id$ # $Source$ +# +# Copyright (c) 2003 Ward Wouts +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + + use strict; +use Sys::Hostname; use Getopt::Std; use File::Basename; use File::Copy; +use Cwd; +use Cwd 'abs_path'; +use vars qw( +$hostname +$cvspath +$editor +$cpcmd +$cvscmd +$mkdircmd +$sudocmd +); + +$hostname = hostname(); +#my $cvspath = "$ENV{HOME}/worktrees/systems/$hostname"; +$editor = "vi"; +$cpcmd = "/bin/cp"; +$cvscmd = "/usr/bin/cvs"; +$mkdircmd = "/bin/mkdir"; +$sudocmd = "/usr/bin/sudo"; + +&readconfig; -my $editor = "vi"; my %option = (); -getopts("eh", \%option); +&cmdline; -if ( $option{h} ) { &help; } -if ( scalar(@ARGV) == 0 ) { &help; } +if ( $cvspath ) { + &checkcvspath; -foreach ( @ARGV ) { - &backup($_); - if ( $option{e} ) { - if ( exists $ENV{'EDITOR'} ) { - $editor = $ENV{'EDITOR'}; + foreach ( @ARGV ) { + if ( -f $_ ) { + &incvs($_); # check if file exists in cvs else make it so + unless (&cmptocvs($_)) { # compare file to cvs + print "$_ not in sync with cvs version\n"; + print "please fix this\n"; + print "press enter to continue\n"; + my $line = <>; + next; + } + if ( $option{e} ) { + &edit($_); # edit file + unless (&cmptocvs($_)) { # if changed... then: + &cvsupdate($_); # copy file to cvs & check in into cvs + # copy file back; don't change permissions + } + } + } else { + print "$_ is not a file, skipping. Press enter to continue.\n"; + my $enter = <>; + } + } +} else { + foreach ( @ARGV ) { + &backup($_); + if ( $option{e} ) { + &edit; } - system("$editor $_"); } } +sub cmdline { + getopts("eh", \%option); + + if ( $option{h} ) { &help; } + if ( scalar(@ARGV) == 0 ) { &help; } +} + +sub readconfig { + if ( -f "$ENV{HOME}/.mycprc" && -r "$ENV{HOME}/.mycprc" ) { + do "$ENV{HOME}/.mycprc" or die "Couldn't parse $ENV{HOME}/.mycprc\n"; + } elsif ( -f "/etc/mycp" && -r "/etc/mycp" ) { + do "/etc/mycp" or die "Couldn't parse /etc/mycp\n"; + } +} sub backup($) { my $file = shift; @@ -37,8 +110,22 @@ sub backup($) { @timestamp = localtime($stat[9]); $timestamp[5] += 1900; if ( length($timestamp[3]) < 2 ) { $timestamp[3] = "0$timestamp[3]"; } + +# +# ouderwetse moron style +# sane style introduceren +# + $sfx = "$timestamp[3]$months[$timestamp[4]]$timestamp[5]"; - unless ( -d "$dir/OLD" ) { mkdir "$dir/OLD", 0777 or die "Couldn't create $dir/OLD: $!\n"; } + + print "Creating \"$dir/OLD\" directory\n"; + unless ( -d "$dir/OLD" ) { + if ( -w $dir ) { + mkdir "$dir/OLD", 0777 or die "Couldn't create $dir/OLD: $!\n"; + } else { + system("$sudocmd mkdir " . &escape("$dir/OLD")); + } + } $backup = "$dir/OLD/$base.$sfx"; if ( -e $backup && ! &cmp($file, $backup) ) { @@ -49,13 +136,123 @@ sub backup($) { $backup = "$backup-$n"; } - copy("$file", "$backup") or die "Couldn't copy $file to $backup: $!\n"; + if ( -w $file || -w &fullpath($file) ) { + copy("$file", "$backup") or die "Couldn't copy $file to $backup: $!\n"; + } else { + system("$sudocmd $cpcmd " . &escape($file) . " " . &escape($backup)); + } } else { die "No such file: $file\n"; } } +sub incvs($) { + my $file = shift; + my $path = &fullpath($file); + if ( -f "$cvspath/$path/" . basename($file) ) { + return 1; + } else { + &cvsadd($file); + &checkin($file); + } +} + +sub edit($) { + if ( exists $ENV{'EDITOR'} ) { + $editor = $ENV{'EDITOR'}; + } + if ( -w $_ ) { + system("$editor " . &escape($_)); + } else { + system("$sudocmd $editor ". &escape($_)); + } +} + +sub checkcvspath($) { + unless ( -d $cvspath ) { + print "$cvspath is not a directory. Set up cvs environment first.\n"; + exit; + } +} + +sub cvsadd($) { + my $file = shift; + my $cwd = cwd; + my $path = &fullpath($file); + $path =~ s|^\/||; + my $checkpath = $cvspath; + my $parent = $cvspath; + print "PATH: $path\n"; + foreach my $i (split '/', $path) { + $checkpath .= "/$i"; + if ( -d $checkpath ) { + print "$i issa dir\n"; + } elsif ( -e $checkpath ) { + print "$i is not a dir, PROBLEM. Fix this by hand.\n"; + exit; + } else { + print "making $checkpath\n"; + mkdir $checkpath; + print "cd $parent\n"; + chdir $parent; + system("$cvscmd add " . &escape($i)); + } + $parent = $checkpath; + } + print "FILE: $file\n"; + print "PATH: $checkpath\n"; + copy($file, $checkpath) || die "error copying file to cvstree: $!\n"; + chdir $checkpath; + system("$cvscmd add " . &escape(basename($file))); + chdir $cwd; +} + +sub cvsupdate($) { + my $file = shift; + ©tocvs($file); + &checkin($file); + ©fromcvs($file); +} + +sub copytocvs($) { + my $file = shift; + my $cwd = cwd; + my $path = "$cvspath/" . &fullpath($file); + copy($file, $path); + chdir($path); + system("$cvscmd ci " . &escape(basename($file))); + chdir $cwd; +} + +sub checkin($) { + my $file = shift; + my $cwd = cwd; + my $path = &fullpath($file); + chdir "$cvspath/$path"; + system("$cvscmd ci " . &escape(basename($file))); + chdir $cwd; +} + +sub copyfromcvs($) { + my $file = shift; + my $path = &fullpath($file); + my $fullname = "$path/" . basename($file); + if ( -w $fullname) { + copy("$cvspath/$fullname", $fullname); + } else { + system("$sudocmd $cpcmd " . &escape("$cvspath/$fullname") . " " . &escape($fullname)); + } + # also check file permissions +} + +sub cmptocvs($) { + my $file = shift; + my $path = &fullpath($file); + my $fullname = "$path/" . basename($file); + return &cmp("$cvspath/$fullname", $fullname); +} + sub cmp($$) { my $source = shift; my $target = shift; @@ -68,6 +265,39 @@ sub cmp($$) { $tf eq $sf; } +sub askyn($) { + my $question = shift; + while (1) { + print "$question [y/n]? "; + my $line = <>; + if ( $line =~ /^y$/ ) { + return 1; + } elsif ( $line =~ /^n$/ ) { + return 0; + } + } +} + +sub escape($) { + my $string = shift; + $string =~ s/([ \&\;\`\'\\\"\|\*\?\~\<\>\^\(\)\[\]\{\}\$\010\013\020\011])/\\${1}/g; + return $string; +} + +sub fullpath($) { + my $file = shift; + my $path = dirname($file); + if ( $path =~ /^\// ) { + return $path; + } elsif ( $path =~ /^\.$/ ) { + return cwd; + } else { + $path = cwd . "/" . dirname($file); + $path = abs_path($path); + return $path; + } +} + sub help { print <