#!/usr/bin/perl
# Copyright (c) 1996-2002 SuSE Linux AG, Nuernberg, Germany.
# All rights reserved.
#
# Author: Reinhold Sojer <feedback@suse.de>, 1996
#         Burchard Steinbild <feedback@suse.de>, 1996
#
# /usr/bin/chkstat
#
# usage: chkstat [-set] file-list
#

sub get_type {
    $S_IFLNK  = 0120000;    # symbolic link
    $S_IFREG  = 0100000;    # regular file
    $S_IFDIR  = 0040000;    # directory
    $S_IFCHAR = 0020000;    # character device
    $S_IFBLK  = 0060000;    # block device
    $S_IFFIFO = 0010000;    # fifo
    $S_IFSOCK = 0140000;    # socket
    $S_IFMT   = 0170000;    # type of file

    if (($_[0] & $S_IFMT) == $S_IFLNK) { $S_m = $_[0] - $S_IFLNK; }
    elsif (($_[0] & $S_IFMT) == $S_IFREG) { $S_m = $_[0] - $S_IFREG; }
    elsif (($_[0] & $S_IFMT) == $S_IFDIR) { $S_m = $_[0] - $S_IFDIR; }
    elsif (($_[0] & $S_IFMT) == $S_IFCHAR) { $S_m = $_[0] - $S_IFCHAR; }
    elsif (($_[0] & $S_IFMT) == $S_IFBLK) { $S_m = $_[0] - $S_IFBLK; }
    elsif (($_[0] & $S_IFMT) == $S_IFFIFO) { $S_m = $_[0] - $S_IFFIFO; }
    elsif (($_[0] & $S_IFMT) == $S_IFSOCK) { $S_m = $_[0] - $S_IFSOCK; }
    $S_m;
}

if (($ARGV[0] eq "-set") && ($#ARGV == 1)) {
    $warn = 0; 
    $list = $ARGV[1];
} elsif ($#ARGV == 0) {
    $warn = 1; 
    $list = $ARGV[0];
} else {
    die "usage: chkstat [-set] file-list\n";
}

$told=0;

open (LIST, $list) || die "chkstat: cannot open $list\n";
while (<LIST>) {

    # set values of the line.
    ($test_file, $perm, $mod) = (split (/\s+/))[0,1,2];
    ($owner, $group) = split (/\./, $perm);


    if ( -e "$test_file" && ! -l "$test_file" ) {
        
        $is_wrong = 0;

        # retrieve mode, uid, gid from actual file;
        @file_stat = stat ($test_file);
        $uid = (getpwnam ($owner)) [2] ;
        $gid = (getgrnam ($group)) [2];

        if ( ($uid != @file_stat[4]) || ($gid != @file_stat[5]) ) {
            $is_wrong = 1 ;
            if ($warn == 0) {
                unless (chown ($uid, $gid, $test_file)) {
                    die "ERROR:  $test_file to ownership $owner.$group failed.\n ";
                }
            }
        }
        @file_stat = stat ($test_file) if ($is_wrong == 1);
        $lmod = &get_type (@file_stat[2]);
        if (oct($mod) != $lmod) {
            $is_wrong = 1 ;
            if ($warn == 0) {
                unless (chmod (oct($mod), $test_file)) {
                    die "ERROR:  $test_file to permission $mod failed.\n ";
                }
            }
        }

       if ($is_wrong == 1) {
           if ($told == 0) {
               $told = 1;
               print "Checking permissions and ownerships - using $list...\n";
           }
           if ($warn == 0) {
               print "setting $test_file to $owner.$group $mod.\n";
           } else {
               print "$test_file should be $owner.$group $mod.\n";
           }
       }
    }
}
close (LIST);
