1 message in net.sourceforge.lists.courier-users[courier-users] courier-fix
FromSent OnAttachments
Brian GrossmanSep 14, 2001 12:59 am.Other
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:[courier-users] courier-fixActions...
From:Brian Grossman (bri@SoftHome.net)
Date:Sep 14, 2001 12:59:40 am
List:net.sourceforge.lists.courier-users
Attachments:
courier-fix - 2k

Attached is "courier-fix". It reconciles the filenames and inode numbers in a courier mail queue.

Courier-fix is useful if you move a queue to another disk; say a disk is dying and you cpio the queue to another disk before the disk dies completely. If you neglect the reconcile step, you can get overwritten control and data files.

This is the first version. Please audit it before using it. It seemed to work for me, but your mileage may vary.

Sam, I encourage you to audit it and include it in your distribution. You may modify it however you please.

Others, please retain the author and revision history lines, but otherwise do with it as you please.

Usage: # ./courier-fix /usr/courier > /j # chmod +x /j # /j # rm -f /j

Brian

#!/usr/bin/perl -w

# Author: Brian Grossman <bri@SoftHome.net> # 13 Sep 2001 birth

my $top = shift; while( $top =~ m,/$, ) { chop $top } $top .= '/var';

my $pwd = `pwd`; chomp $pwd;

$top = "$pwd/$top" if $top =~ m/^\./ ;

chdir($top) || die "chdir $top";

print "#!/bin/sh\n"; print "cd $top || exit 1\n";

sub splitname { my $ofname = shift; my $dirname = $ofname; $dirname =~ s,/[^/]+$,,; my $basename = $ofname; $basename =~ s,^$dirname/,,; my $letter = substr($basename, 0, 1); my $sufx = $basename; $sufx =~ s,^.\d+,,; my $old_i = $basename; $old_i =~ s/^.(\d+).*$/$1/; return { Dirname => $dirname, Letter => $letter, Sufx => $sufx, OldInode => $old_i, }; }

sub mkname { my $r = shift; my $i = shift; return "$r->{Dirname}/$r->{Letter}$i$r->{Sufx}"; }

print "echo adjusting filenames in tmp and msgs\n"; print STDERR "find tmp msgs ...\n"; my %inode; # old inode -> new inode my %msgs; # old name -> breakout my %oino_ofname; open(IN, "find tmp msgs -name C\* | "); while(<IN>) { chomp; my $ofname = $_; my $file = splitname($ofname); my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat($ofname); $file->{NewInode} = $ino; my $oino = $file->{OldInode} ; $inode{$oino} = $ino; # cache even the unchanging ones $msgs{$ofname} = $file; $oino_ofname{$oino} = $ofname; } close IN;

for my $ofname (keys %msgs) { my $oino = $msgs{$ofname}{OldInode}; my $ino = $msgs{$ofname}{NewInode}; next if $oino == $ino; print "mv $ofname " . mkname($msgs{$ofname}, $ino) . "\n"; }

print "echo adjusting filenames and links in msgq\n"; print STDERR "find msgq ...\n"; open(IN, "find msgq -name C\* | "); while(<IN>) { chomp; my $ofname = $_; my $file = splitname($ofname); my $oino = $file->{OldInode} ; my $nino = $inode{$oino}; if(!defined $nino) { # doesn't exist in msgs, so invalid or unrecoverable print STDERR "deleting stray control file $ofname\n"; print "echo deleting stray control file $ofname\n"; print "rm $ofname\n"; next; } my $newname = mkname($file, $nino); my $realname = mkname($msgs{$oino_ofname{$oino}}, $nino); my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat($ofname); if($ino == $nino) { # link survived cpio print "mv $ofname $newname\n" if $ofname ne $newname; } else { print STDERR "reestablishing link to $realname\n"; print "echo reestablishing link to $realname\n"; print "rm $ofname\n"; print "ln $realname $newname\n"; } } close IN;