1*0Sstevel@tonic-gate;# $RCSfile: validate.pl,v $$Revision: 4.1 $$Date: 92/08/07 18:24:19 $ 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gate;# The validate routine takes a single multiline string consisting of 4*0Sstevel@tonic-gate;# lines containing a filename plus a file test to try on it. (The 5*0Sstevel@tonic-gate;# file test may also be a 'cd', causing subsequent relative filenames 6*0Sstevel@tonic-gate;# to be interpreted relative to that directory.) After the file test 7*0Sstevel@tonic-gate;# you may put '|| die' to make it a fatal error if the file test fails. 8*0Sstevel@tonic-gate;# The default is '|| warn'. The file test may optionally have a ! prepended 9*0Sstevel@tonic-gate;# to test for the opposite condition. If you do a cd and then list some 10*0Sstevel@tonic-gate;# relative filenames, you may want to indent them slightly for readability. 11*0Sstevel@tonic-gate;# If you supply your own "die" or "warn" message, you can use $file to 12*0Sstevel@tonic-gate;# interpolate the filename. 13*0Sstevel@tonic-gate 14*0Sstevel@tonic-gate;# Filetests may be bunched: -rwx tests for all of -r, -w and -x. 15*0Sstevel@tonic-gate;# Only the first failed test of the bunch will produce a warning. 16*0Sstevel@tonic-gate 17*0Sstevel@tonic-gate;# The routine returns the number of warnings issued. 18*0Sstevel@tonic-gate 19*0Sstevel@tonic-gate;# Usage: 20*0Sstevel@tonic-gate;# require "validate.pl"; 21*0Sstevel@tonic-gate;# $warnings += do validate(' 22*0Sstevel@tonic-gate;# /vmunix -e || die 23*0Sstevel@tonic-gate;# /boot -e || die 24*0Sstevel@tonic-gate;# /bin cd 25*0Sstevel@tonic-gate;# csh -ex 26*0Sstevel@tonic-gate;# csh !-ug 27*0Sstevel@tonic-gate;# sh -ex 28*0Sstevel@tonic-gate;# sh !-ug 29*0Sstevel@tonic-gate;# /usr -d || warn "What happened to $file?\n" 30*0Sstevel@tonic-gate;# '); 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gatesub validate { 33*0Sstevel@tonic-gate local($file,$test,$warnings,$oldwarnings); 34*0Sstevel@tonic-gate foreach $check (split(/\n/,$_[0])) { 35*0Sstevel@tonic-gate next if $check =~ /^#/; 36*0Sstevel@tonic-gate next if $check =~ /^$/; 37*0Sstevel@tonic-gate ($file,$test) = split(' ',$check,2); 38*0Sstevel@tonic-gate if ($test =~ s/^(!?-)(\w{2,}\b)/$1Z/) { 39*0Sstevel@tonic-gate $testlist = $2; 40*0Sstevel@tonic-gate @testlist = split(//,$testlist); 41*0Sstevel@tonic-gate } 42*0Sstevel@tonic-gate else { 43*0Sstevel@tonic-gate @testlist = ('Z'); 44*0Sstevel@tonic-gate } 45*0Sstevel@tonic-gate $oldwarnings = $warnings; 46*0Sstevel@tonic-gate foreach $one (@testlist) { 47*0Sstevel@tonic-gate $this = $test; 48*0Sstevel@tonic-gate $this =~ s/(-\w\b)/$1 \$file/g; 49*0Sstevel@tonic-gate $this =~ s/-Z/-$one/; 50*0Sstevel@tonic-gate $this .= ' || warn' unless $this =~ /\|\|/; 51*0Sstevel@tonic-gate $this =~ s/^(.*\S)\s*\|\|\s*(die|warn)$/$1 || do valmess('$2','$1')/; 52*0Sstevel@tonic-gate $this =~ s/\bcd\b/chdir (\$cwd = \$file)/g; 53*0Sstevel@tonic-gate eval $this; 54*0Sstevel@tonic-gate last if $warnings > $oldwarnings; 55*0Sstevel@tonic-gate } 56*0Sstevel@tonic-gate } 57*0Sstevel@tonic-gate $warnings; 58*0Sstevel@tonic-gate} 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gatesub valmess { 61*0Sstevel@tonic-gate local($disposition,$this) = @_; 62*0Sstevel@tonic-gate $file = $cwd . '/' . $file unless $file =~ m|^/|; 63*0Sstevel@tonic-gate if ($this =~ /^(!?)-(\w)\s+\$file\s*$/) { 64*0Sstevel@tonic-gate $neg = $1; 65*0Sstevel@tonic-gate $tmp = $2; 66*0Sstevel@tonic-gate $tmp eq 'r' && ($mess = "$file is not readable by uid $>."); 67*0Sstevel@tonic-gate $tmp eq 'w' && ($mess = "$file is not writable by uid $>."); 68*0Sstevel@tonic-gate $tmp eq 'x' && ($mess = "$file is not executable by uid $>."); 69*0Sstevel@tonic-gate $tmp eq 'o' && ($mess = "$file is not owned by uid $>."); 70*0Sstevel@tonic-gate $tmp eq 'R' && ($mess = "$file is not readable by you."); 71*0Sstevel@tonic-gate $tmp eq 'W' && ($mess = "$file is not writable by you."); 72*0Sstevel@tonic-gate $tmp eq 'X' && ($mess = "$file is not executable by you."); 73*0Sstevel@tonic-gate $tmp eq 'O' && ($mess = "$file is not owned by you."); 74*0Sstevel@tonic-gate $tmp eq 'e' && ($mess = "$file does not exist."); 75*0Sstevel@tonic-gate $tmp eq 'z' && ($mess = "$file does not have zero size."); 76*0Sstevel@tonic-gate $tmp eq 's' && ($mess = "$file does not have non-zero size."); 77*0Sstevel@tonic-gate $tmp eq 'f' && ($mess = "$file is not a plain file."); 78*0Sstevel@tonic-gate $tmp eq 'd' && ($mess = "$file is not a directory."); 79*0Sstevel@tonic-gate $tmp eq 'l' && ($mess = "$file is not a symbolic link."); 80*0Sstevel@tonic-gate $tmp eq 'p' && ($mess = "$file is not a named pipe (FIFO)."); 81*0Sstevel@tonic-gate $tmp eq 'S' && ($mess = "$file is not a socket."); 82*0Sstevel@tonic-gate $tmp eq 'b' && ($mess = "$file is not a block special file."); 83*0Sstevel@tonic-gate $tmp eq 'c' && ($mess = "$file is not a character special file."); 84*0Sstevel@tonic-gate $tmp eq 'u' && ($mess = "$file does not have the setuid bit set."); 85*0Sstevel@tonic-gate $tmp eq 'g' && ($mess = "$file does not have the setgid bit set."); 86*0Sstevel@tonic-gate $tmp eq 'k' && ($mess = "$file does not have the sticky bit set."); 87*0Sstevel@tonic-gate $tmp eq 'T' && ($mess = "$file is not a text file."); 88*0Sstevel@tonic-gate $tmp eq 'B' && ($mess = "$file is not a binary file."); 89*0Sstevel@tonic-gate if ($neg eq '!') { 90*0Sstevel@tonic-gate $mess =~ s/ is not / should not be / || 91*0Sstevel@tonic-gate $mess =~ s/ does not / should not / || 92*0Sstevel@tonic-gate $mess =~ s/ not / /; 93*0Sstevel@tonic-gate } 94*0Sstevel@tonic-gate print STDERR $mess,"\n"; 95*0Sstevel@tonic-gate } 96*0Sstevel@tonic-gate else { 97*0Sstevel@tonic-gate $this =~ s/\$file/'$file'/g; 98*0Sstevel@tonic-gate print STDERR "Can't do $this.\n"; 99*0Sstevel@tonic-gate } 100*0Sstevel@tonic-gate if ($disposition eq 'die') { exit 1; } 101*0Sstevel@tonic-gate ++$warnings; 102*0Sstevel@tonic-gate} 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate1; 105