+++ /dev/null
-#!@PERL@
-
-#
-# cnid_maint: A script to maintain the consistency of CNID databases.
-#
-# $Id: cnid_maint.in,v 1.15 2003-02-17 02:32:45 jmarcus Exp $
-#
-
-use strict;
-use Getopt::Std;
-use vars qw(
- $APPLE_VOLUMES_FILE
- $STOP_CMD
- $START_CMD
- $PS_CMD
- $GREP
- $DB_STAT
- $DB_RECOVER
- $DB_VERIFY
- $VERSION
- $START_NETATALK
- $LOCK_FILE
- $HOLDING_LOCK
-);
-
-## Edit ME
-$STOP_CMD = '/usr/local/etc/rc.d/netatalk.sh stop';
-$START_CMD = '/usr/local/etc/rc.d/netatalk.sh start';
-
-# This ps command needs to output the following fields in the following order:
-# USER,PID,PPID,COMMAND
-# Below is the example of a BSD ps. A SYSV example is:
-# /bin/ps -eflouid,pid,ppid,comm
-$PS_CMD = '@PS@ -axouser,pid,ppid,command';
-$DB_STAT = '@BDB_BIN@/db_stat';
-$DB_RECOVER = '@BDB_BIN@/db_recover';
-$DB_VERIFY = '@BDB_BIN@/db_verify';
-$APPLE_VOLUMES_FILE = '@PKGCONFDIR@/AppleVolumes.default';
-## End edit section
-
-$VERSION = '1.0';
-$GREP = '@GREP@';
-$START_NETATALK = 0;
-$LOCK_FILE = tmpdir() . '/cnid_maint.LOCK';
-$HOLDING_LOCK = 0;
-
-sub LOCK_SH { 1 }
-sub LOCK_EX { 2 }
-sub LOCK_NB { 4 }
-sub LOCK_UN { 8 }
-
-my $opts = {};
-my $extra_safe = 0;
-my $do_verify = 0;
-my $remove_logs = 0;
-
-getopts('hsvVl', $opts);
-
-if ($opts->{'v'}) {
- version();
- exit(0);
-}
-if ($opts->{'h'}) {
- help();
- exit(0);
-}
-if ($opts->{'s'}) {
- $extra_safe = 1;
-}
-if ($opts->{'V'}) {
- $do_verify = 1;
-}
-if ($opts->{'l'}) {
- $remove_logs = 1;
-}
-
-if ($< != 0) {
- die "You must be root to run this script.\n";
-}
-
-print "Beginning run of CNID DB Maintanence script at "
- . scalar(localtime) . ".\n\n";
-
-if (-f $LOCK_FILE) {
- error(1, "Lock file $LOCK_FILE exists.");
- end();
-}
-
-unless (open(LOCK, ">" . $LOCK_FILE)) {
- error(2, "Unable to create $LOCK_FILE: $!");
-}
-flock(LOCK, LOCK_EX);
-$HOLDING_LOCK = 1;
-
-# Check to see if the AppleVolumes.default file exists. We will use this file
-# to get a list of database environments to recover. We will ignore users'
-# home directories since that could be a monumental under taking.
-if (!-f $APPLE_VOLUMES_FILE) {
- error(2, "Unable to locate $APPLE_VOLUMES_FILE");
-}
-
-# Use ps to get a list of running afpds. We will track all afpd PIDs that are
-# running as root.
-unless (open(PS, $PS_CMD . " | $GREP afpd | $GREP -v grep |")) {
- error(2, "Unable to open a pipe to ps: $!");
-}
-
-my $children = 0;
-my $processes = 0;
-while (<PS>) {
- chomp;
- $processes++;
- my ($user, $pid, $ppid, $command) = split (/\s+/);
- if (($user eq "root" && $ppid != 1) || ($user ne "root")) {
- $children++;
- }
-}
-
-close(PS);
-
-if ($children) {
-
- # We have some children. We cannot run recovery.
- error(1,
- "Clients are still connected. Database recovery will not be run at this time."
- );
- end();
-}
-
-if ($processes) {
-
- # Shutdown the running afpds.
- $START_NETATALK = 1;
- error(0, "Shutting down afpd process...");
- error(2, "Failed to shutdown afpd")
- if system($STOP_CMD . ">/dev/null 2>&1");
-}
-
-# Now, we parse AppleVolumes.default to get a list of volumes to run recovery
-# on.
-unless (open(VOLS, $APPLE_VOLUMES_FILE)) {
- error(2, "Unable to open $APPLE_VOLUMES_FILE: $!");
-}
-flock(VOLS, LOCK_SH);
-
-my @paths = ();
-while (<VOLS>) {
- s/#.*//;
- s/^\s+//;
- s/\s+$//;
- next unless length;
- my ($path, @options) = split (/\s+/, $_);
- next if ($path =~ /^~/);
- my $option = "";
- foreach $option (@options) {
-
- # We need to check for the dbpath option on each volume. If
- # that option is present, we should use its path instead of
- # the actual volume path.
- if ($option =~ /^dbpath:/) {
- push @paths, $';
- } else {
- push @paths, $path;
- }
- }
-}
-
-close(VOLS);
-
-my $path = "";
-foreach $path (@paths) {
- my $dbpath = $path . "/.AppleDB";
- if (!-d $dbpath) {
- error(1, "Database environment $dbpath does not exist");
- next;
- }
- if ($extra_safe) {
- error(0,
- "Checking database environment $dbpath for open connections..."
- );
- unless (open(STAT, $DB_STAT . " -h $dbpath -e |")) {
- error(1, "Failed to open a pipe to $DB_STAT: $!");
- next;
- }
-
- # Now, check each DB environment for any open connections
- # (db_stat calls them as references). If a volume has no
- # references, we can do recovery on it. Only check this option
- # if the user wants to play things extra safe.
- my $connections = 0;
- while (<STAT>) {
- chomp;
- s/\s//g;
- if (/References\.$/) {
- $connections = $`;
- last;
- }
- }
-
- close(STAT);
-
- # Print out two different skip messages. This is just for
- # anality.
- if ($connections == 1) {
- error(1,
- "Skipping $dbpath since it has one active connection"
- );
- next;
- }
-
- if ($connections > 0) {
- error(1,
- "Skipping $dbpath since it has $connections active connections"
- );
- next;
- }
- }
-
- # Run the db_recover command on the environment.
- error(0, "Running db_recover on $dbpath");
- if (system($DB_RECOVER . " -h $dbpath >/dev/null 2>&1")) {
- error(1, "Failed to run db_recover on $dbpath");
- next;
- }
-
- if ($do_verify) {
- error(0, "Verifying $dbpath/cnid.db");
- if (system($DB_VERIFY . " -q -h $dbpath cnid.db")) {
- error(1, "Verification of $dbpath/cnid.db failed");
- next;
- }
-
- error(0, "Verifying $dbpath/devino.db");
- if (system($DB_VERIFY . " -q -h $dbpath devino.db")) {
- error(1, "Verification of $dbpath/devino.db failed");
- next;
- }
-
- error(0, "Verifying $dbpath/didname.db");
- if (system($DB_VERIFY . " -q -h $dbpath didname.db")) {
- error(1, "Verification of $dbpath/didname.db failed");
- next;
- }
- if (-f "$dbpath/mangle.db") {
- error(0, "Verifying $dbpath/mangle.db");
- if (system($DB_VERIFY . " -q -h $dbpath mangle.db")) {
- error(1,
- "Verification of $dbpath/mangle.db failed"
- );
- next;
- }
- }
- }
-
- if ($remove_logs) {
-
- # Remove the log files if told to do so.
- unless (opendir(DIR, $dbpath)) {
- error(1, "Failed to open $dbpath for browsing: $!");
- next;
- }
-
- my $file = "";
- while (defined($file = readdir(DIR))) {
- if ($file =~ /^log\.\d+$/) {
- error(0, "Removing $dbpath/$file");
- unless (unlink($dbpath . "/" . $file)) {
- error(1,
- "Failed to remove $dbpath/$file: $!"
- );
- next;
- }
- }
- }
-
- closedir(DIR);
- }
-
-}
-
-end();
-
-sub tmpdir {
- my $tmpdir;
-
- foreach ($ENV{TMPDIR}, "/tmp") {
- next unless defined && -d && -w _;
- $tmpdir = $_;
- last;
- }
- $tmpdir = '' unless defined $tmpdir;
- return $tmpdir;
-}
-
-sub error {
- my ($code, $msg) = @_;
-
- my $err_types = {
- 0 => "INFO",
- 1 => "WARNING",
- 2 => "ERROR",
- };
-
- print $err_types->{$code} . ": " . $msg . "\n";
-
- end() if ($code == 2);
-}
-
-sub end {
- if ($START_NETATALK) {
- error(0, "Restarting Netatalk");
- if (system($START_CMD . " >/dev/null 2>&1")) {
- print "ERROR: Failed to restart Netatalk\n";
- }
- }
- if ($HOLDING_LOCK) {
- close(LOCK);
- unlink($LOCK_FILE);
- }
- print "\nRun of CNID DB Maintenance script ended at "
- . scalar(localtime) . ".\n";
- exit(0);
-}
-
-sub version {
- print "$0 version $VERSION\n";
-}
-
-sub help {
- print "usage: $0 [-hlsvV]\n";
- print "\t-h view this message\n";
- print "\t-l remove transaction logs after running recovery\n";
- print
- "\t-s be extra safe in verifying there are no open DB connections\n";
- print "\t-v print version and exit\n";
- print
- "\t-V run a verification on all database files after recovery\n";
-}
+++ /dev/null
-#!@PERL@
-#
-# $Id: apple_cleanup.in,v 1.1 2009-04-22 07:44:10 franklahm Exp $
-#
-# apple_cleanup
-# Copyright (C) 2001 Heath Kehoe <hakehoe@avalon.net>
-#
-# 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.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-
-require 5;
-use Getopt::Std;
-
-sub usage {
- print STDERR <<EOF;
-Usage: $0 [-r] [-v] directory [directory ...]
-
-Scans each directory and:
- 1) removes orphaned .AppleDouble files (from <directory>/.AppleDouble)
- 2) fixes permissions on .AppleDouble files to match corresponding data file (minus x bits)
- 3) fixes owner/group of .AppleDouble files to match corresponding data file (root only)
-
-Options:
- -r Recursively check all subdirectories of each directory
- -R Like -r but follows symbolic links to directories (warning: no loop-checking is done)
- -p Preview: no deletions or changes are actually made
- -v Verbose
-EOF
- exit 1;
-}
-
-$isroot = ($> == 0);
-
-sub S_ISDIR {
- my($mode) = @_;
- return (($mode & 0170000) == 0040000);
-}
-sub S_ISREG {
- my($mode) = @_;
- return (($mode & 0170000) == 0100000);
-}
-sub S_ISLNK {
- my($mode) = @_;
- return (($mode & 0170000) == 0120000);
-}
-
-
-sub do_dir {
- my($dir) = @_;
- my($f, $havead, @dirlist, $mode, $uid, $gid, $fn);
- my(%dm, %du, %dg);
-
- print STDERR "Scanning $dir ...\n" if($opt_v);
-
- $havead = -d "$dir/.AppleDouble";
-
- # there's nothing more to do if we're not recursive and there's no .AppleDouble
- return if(!$havead && !$opt_r);
-
- opendir DIR, $dir or do {
- warn "Can't opendir $dir: $!\n";
- return;
- };
- while(defined($f = readdir DIR)) {
- next if($f eq ".");
- next if($f eq "..");
- next if($f eq ".AppleDouble");
- next if($f eq ".AppleDesktop");
-
- (undef, undef, $mode, undef, $uid, $gid) = lstat "$dir/$f";
- next if(!defined($mode));
-
- if(S_ISLNK($mode)) {
- (undef, undef, $mode, undef, $uid, $gid) = stat "$dir/$f";
- next if(!defined($mode));
- next if(S_ISDIR($mode) && !$opt_R);
- }
- if(S_ISDIR($mode)) {
- push @dirlist, $f if($opt_r);
- } elsif(S_ISREG($mode)) {
- if($havead) {
- $dm{$f} = $mode & 0666;
- $du{$f} = $uid;
- $dg{$f} = $gid;
- }
- } else {
- warn "Ignoring special file: $dir/$f\n";
- }
- }
- closedir DIR;
-
- if($havead) {
- if(opendir DIR, "$dir/.AppleDouble") {
- while(defined($f = readdir DIR)) {
- next if($f eq ".");
- next if($f eq "..");
- next if($f eq ".Parent");
-
- $fn = "$dir/.AppleDouble/$f";
- (undef, undef, $mode, undef, $uid, $gid) = stat $fn;
- next if(!defined($mode));
-
- if(S_ISDIR($mode)) {
- warn "Found subdirectory $f in $dir/.AppleDouble\n";
- next;
- }
- unless(exists $dm{$f}) {
- print STDERR "Deleting $fn ...\n" if($opt_v);
- if($opt_p) {
- print "rm '$fn'\n";
- } else {
- unlink "$fn" or warn "Can't unlink $fn: $!\n";
- }
- next;
- }
- $mode = $mode & 07777;
- if($mode != $dm{$f}) {
- printf STDERR "Changing permissions from %o to %o on $fn\n", $mode, $dm{$f} if($opt_v);
- if($opt_p) {
- printf "chmod %o '$fn'\n", $dm{$f};
- } else {
- chmod $dm{$f}, $fn or warn "Can't chmod $fn: $!\n";
- }
- }
- if($isroot && ($uid != $du{$f} || $gid != $dg{$f})) {
- print STDERR "Changing owner from $uid:$gid to $du{$f}:$dg{$f} on $fn\n" if($opt_v);
- if($opt_p) {
- print "chown $du{$f}:$dg{$f} '$fn'\n";
- } else {
- chown $du{$f}, $dg{$f}, $fn or warn "Can't chown $fn: $!\n";
- }
- }
- }
- closedir DIR;
- } else {
- warn "Can't opendir $dir/.AppleDouble: $!\n";
- }
- }
-
- if($opt_r) {
- foreach $f ( @dirlist ) {
- do_dir("$dir/$f");
- }
- }
-}
-
-usage unless(getopts 'prRv');
-usage if(@ARGV == 0);
-
-if($opt_R) {
- $opt_r = 1;
-}
-
-foreach $d ( @ARGV ) {
- do_dir $d;
-}
-