cvs commit: hints installwatch.txt

timothy at linuxfromscratch.org timothy at linuxfromscratch.org
Fri Jul 26 18:08:45 PDT 2002


timothy     02/07/26 18:08:45

  Modified:    .        installwatch.txt
  Log:
  Updates by author.
  
  Revision  Changes    Path
  1.5       +88 -130   hints/installwatch.txt
  
  Index: installwatch.txt
  ===================================================================
  RCS file: /home/cvsroot/hints/installwatch.txt,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- installwatch.txt	15 Jun 2002 21:43:41 -0000	1.4
  +++ installwatch.txt	27 Jul 2002 01:08:45 -0000	1.5
  @@ -12,6 +12,9 @@
   Changelog
   ---------
   
  +Revision 1.10  2002/07/27 01:06:27  feztaa
  +Updated nuke script to version 1.11
  +
   Revision 1.9  2002/06/15 18:03:12  feztaa
   Updated nuke script to version 1.9
   
  @@ -69,13 +72,12 @@
   In an attempt to make this easier to read, all "code blocks" that you should
   execute on the commandline start and end with "##--CODE--##". Feel free to copy
   that onto the commandline along with the code itself, it won't hurt anything.
  -Also, for quoted text (the output of a program, for example), each line is
  -prefixed with four spaces.
  +Quoted text, such as the output of a program, is prefixed with four spaces.
   
   Also, if you're trying to use this during the early stages of Chapter 6 in the
   LFS book, it will fail miserably for you. The reason is that installwatch needs
   programs to be dynamically linked for it to work; in Chapter 6, all of your
  -programs are statically linked. installwatch *might* work for you near the end
  +programs are statically linked. Installwatch *might* work for you near the end
   of chapter 6 when most of the static stuff is gone, but I advise not using it
   until chapter 6 is finished and you're installing other stuff. I've yet to find
   a program that wouldn't install properly with installwatch, just as long as
  @@ -134,35 +136,50 @@
   files that it mentions. This, of course, is used only when you've decided that
   you want to uninstall that program ;)
   
  -Create the script by running this at the command prompt as root:
  +You can download it from http://members.shaw.ca/feztaa/projects/nuke, or you
  +can execute the following commands (it's long) to create the script.  If you
  +download it, be sure to save it to /usr/sbin/nuke, and give it 755 (rwxr-wr-w)
  +permissions. If you don't want to download it, run the this at the command
  +promp as root:
   
   ##--CODE--##
   cat <<"EOF" >/usr/sbin/nuke
   #!/usr/bin/env perl
  -# Version: 1.9 2002/06/15 17:56:37
   # Author: Robert Park <feztaa at shaw.ca>
   # License: GNU General Public License
   
  -# Die if the user isn't root.
  +# Revision 1.11  2002/07/27 00:45:39  feztaa
  +# Major overhaul; reduced LOC and increased efficiency all around.
  +#
  +# Revision 1.10  2002/07/26 19:41:00  feztaa
  +# Incorporated fixes from Zenith Lau <zenithlau at sniic.com>, fixing
  +# issues with symlinks.
  +
  +use strict;
  +
   die "You must be root!\n" unless ($< == 0);
   
  -# Easily underline a string of text
  +# Used for sorting the list of files; symlinks first,
  +# everything else is by length, longest first.
  +sub symlength
  +{
  +  (-l $a) ? -1 : (-l $b) ? 1 : length $b <=> length $a
  +}
  +
  +# Underline a string by appending with with a newline and hyphens
   sub underline
   {
     my $str = join("", @_);
     my $chomp = 1;
   
  -  while (chomp $str)
  -  {
  -    $chomp++;
  -  }
  +  $chomp++ while (chomp $str);
   
     return "$str\n" . ("-" x length $str) . ("\n" x $chomp);
   }
   
  -# Return a list with proper commification ("one two three" becomes "one, two,
  -# and three")
  -sub commify_series
  +# Take an array, and return a string that's been properly commified, 
  +# ie ("one", "two", "three") becomes "one, two, and three".
  +sub commify
   {
     (@_ == 0) ? ''                                      :
     (@_ == 1) ? $_[0]                                   :
  @@ -170,136 +187,89 @@
                 join(", ", @_[0 .. ($#_-1)], "and $_[-1]");
   }
   
  -foreach $arg (@ARGV)
  +my $report;
  +my @args;
  +
  +foreach my $arg (@ARGV)
   {
  -  if ($arg eq "-r")
  -  {
  -    $report = 1;
  -  }
  -  else
  -  {
  -    push @args, $arg;
  -  }
  +  ($arg eq "-r") ? $report = 1 : push @args, $arg;
   }
   
  -foreach $arg (@args)
  +# Process all the logfiles
  +foreach my $arg (@args)
   {
  -  # Incase some doofus gives us an absolute path
  -  $arg =~ s/^.*\///g;
  +  $arg =~ s#^.*/##g;
     chomp $arg;
   
  -  # Get paths
  -  $install = "/var/install/" . $arg;
  -  $uninstall = "/var/uninstall/" . $arg;
  +  my $install = "/var/install/" . $arg;
  +  my $uninstall = "/var/uninstall/" . $arg;
   
  -  # Skip bad ones
     unless (-f $install)
     {
       print "Can't find $arg\n";
       next;
     }
  -  
  +
     print "Uninstalling $arg ... " unless ($report);
  -  
  +
     open "INSTALL", "<$install" or die "$!\n";
   
  -  # Reset some variables/hashes
  -  %files = ();
  -  %directories = ();
  -  $error=0;
  -  
  +  my %files;
  +  my %directories;
  +  my $error = 0;
  +
     while (<INSTALL>)
     {
  -    # Get all the data into the @fields array
       chomp;
  -    @fields = split;
  +    my @fields = split;
  +
       my $action = $fields[1];
  -    my $file = $fields[2];
  -    my $status = $fields[-1];
  +    my $file = $action eq "symlink" ? $fields[3] : $fields[2];
   
  -    # If a file wasn't successfully created, don't bother
  -    # marking it for deletion; this prevents the script
  -    # from trying to delete /usr or something
  -    if ($status eq "#success")
  +    # Don't delete stuff that wasn't created properly; 
  +    # prevents deletion of /usr or similar.
  +    if ($fields[-1] eq "#success")
       {
  -      # Keep track of what action was done on what file/directory.
  -      push @{ $files{$file} }, $action if (-f $file or -l $file);
  -      push @{ $directories{$file} }, $action if (-d $file);
  +      push @{ $files{$file} }, $action if (-f $file or -l $file or -d $file);
       }
     }
   
  -  # Don't delete anything, just report what the logfile has to say
     if ($report)
     {
  -    # Print an underlined header
  -    print underline("Actions taken on files from $arg\n");
  -    
  -    # Print all the files, and the actions taken on the files
  -    foreach $file (sort { length $b <=> length $a } keys %files)
  -    {
  -      print "$file:  ", commify_series(@{$files{$file}}), "\n";
  -    }
  -    
  -    # Print an underlined header
  -    print "\n", underline("Actions taken on directories from $arg\n");
  -    
  -    # Print all the directories, and the actions taken on them
  -    foreach $dir (sort { length $b <=> length $a } keys %directories)
  +    # Reporting mode, don't delete anything.
  +    print underline("Files/Directories installed by $arg\n");
  +
  +    foreach my $file (sort symlength keys %files)
       {
  -      print "$dir:  ", commify_series(@{$directories{$dir}}), "\n";
  +      print "$file:  ", commify (@{ $files{$file} }), "\n";
       }
  -    
  -    print "\n";
     }
  -
  -  # Remove all the files referenced in the logfile
     else
     {
  -    # Open the uninstall logfile so we can output our stuff
  +    # Not reporting mode, delete stuff.
       open "UNINSTALL", ">$uninstall" or die "$!\n";
  -    
  -    # divert output to the 'UNINSTALL' filehandle
  +
       select UNINSTALL;
  -    
  -    print underline("Removed Files\n");
  -    
  -    # Remove files
  -    foreach $file (sort keys %files)
  -    {
  -      if (grep /open/, @{ $files{$file} })
  -      {
  -        $! = "";
  -        print $file;
  -        unlink $file;
  -        if ($!)
  -        {
  -          print " -- $!";
  -          $error++;
  -        }
  -        print "\n";
  -      }
  -    }
   
  -    print "\n", underline("Removed Directories\n");
  -    
  -    # Remove directories
  -    foreach $dir (sort { length $b <=> length $a } keys %directories)
  +    print underline("Removed Files/Directories");
  +
  +    foreach my $file (sort symlength keys %files)
       {
  -      if (grep /mkdir/, @{ $directories{$dir} })
  +      if (grep /open|symlink|mkdir/, @{ $files{$file} })
         {
           $! = "";
  -        print $dir;
  -        rmdir $dir;
  +
  +        print "\n$file";
  +        (-d $file) ? rmdir "$file" : unlink "$file";
  +
           if ($!)
           {
             print " -- $!";
             $error++;
           }
  -        print "\n";
         }
       }
   
  -    # Close the files and divert output back to STDOUT
       close "INSTALL";
       close "UNINSTALL";
       select STDOUT;
  @@ -311,7 +281,7 @@
       }
       else
       { 
  -      unlink $install; # Don't need the install logfile anymore
  +      unlink $install;
         print "successful.\n"; 
       }
     }
  @@ -320,33 +290,27 @@
   chmod 755 /usr/sbin/nuke
   ##--CODE--##
   
  -This script looks kind of long and complicated, but it is relatively simple; It
  -examines the logfile and keeps track of all the files and directories that were
  -created during the install process, then it removes all the files, and then it
  -removes all the directories.
  +This script examines the logfile and keeps track of all the files and
  +directories that were created during the install process, then it removes them.
   
   It will also create a log of what it uninstalled. This logfile will be located
   in /var/uninstall and will have the same name as the original logfile in
   /var/install. This new logfile will look something like this:
   
  -    Removed Files
  -    -------------
  +    Removed Files/Directories
  +    -------------------------
       
  -    /path/to/file
  -    /path/to/another/file
       /different/path/to/file -- Permission denied
  -    
  -    Removed Directories
  -    -------------------
  -    
  -    /path/to
  -    /path/to/another
  +    /path/to/another/file
       /different/path/to -- Directory not empty
  +    /path/to/another
  +    /path/to/file
  +    /path/to
   
  -In this case, we see that /different/path/to/file could not be removed due to
  -permission problems, and /different/path/to could not be removed because it was
  -not empty ('file' was still there). The other files and directories were
  -deleted properly.
  +In this case, /different/path/to/file could not be removed due to permission
  +problems, and /different/path/to could not be removed because it was not empty
  +('file' was still there). The other files and directories were deleted
  +properly.
   
   5. Next, you need to know how to use installwatch when you're compiling your
   software. Without this part, you'd have no logfiles in /var/install, and the
  @@ -421,17 +385,11 @@
   
   This will produce output something like this:
   
  -    Actions taken on files from foobar-1.0
  -    --------------------------------------
  -    
  -    /usr/share/foobar/manual.html:  open and chmod
  -    /usr/share/man/man1/foobar.1:  open and chmod
  -    /usr/bin/foobar:  open and chmod
  -    
  -    Actions taken on directories from foobar-1.0
  -    --------------------------------------------
  +    Files/Directories installed by foobar-1.0
  +    -----------------------------------------
       
  -    /usr/share/foobar:  mkdir
  +    /usr/bin/foobar:  open, chown, and chmod
  +    /etc/foobarrc:  open, chown, and chmod
   
   The End
   -------
  @@ -439,5 +397,5 @@
   Congratulations! You now have an extremely easy method of removing software
   that was compiled from source!
   
  -If you encounter any problems (did I screw up? It's possible!), please let me
  -know. I want to make this as good as it can possibly be ;)
  +If you encounter any problems, please let me know. I want to make this as good
  +as it can possibly be ;)
  
  
  
-- 
Unsubscribe: send email to listar at linuxfromscratch.org
and put 'unsubscribe hints' in the subject header of the message



More information about the hints mailing list