Article 344 of alt.sources: Path: lightnin!rwsys!utacfd.uta.edu!news.oc.com!mercury.unt.edu!cs.utexas.edu!wupost!uunet!mcsun!uknet!pavo.csi.cam.ac.uk!nntp-serv.cam.ac.uk!tdw From: tdw@uk.ac.cam.cl (Tim Wilson) Newsgroups: alt.sources #Subject: Another stat program (perl script) Message-ID: Date: 5 Oct 92 12:43:26 GMT Sender: news@infodev.cam.ac.uk (USENET news) Organization: University of Cambridge Computer Laboratory, UK Lines: 307 Nntp-Posting-Host: ramsey.cl.cam.ac.uk Here's another stat command. Use the -l flag to examine symbolic links (instead of the linked-to file). This version of stat one has two output formats. The default is human-readable, eg $ stat stat stat device 0x5526 inode 23068 0x5a1c mode -r-xr-xr-x 0100555 nlink 1 owner tdw group private rdev -1 size 6707 atime Mon Oct 5 12:31:57 1992 mtime Mon Oct 5 11:53:48 1992 ctime Mon Oct 5 11:53:48 1992 blksize 8192 blocks 14 but there is also a numeric output format that is useful for forther processing, eg $ stat -n stat stat 0x5526 0x5a1c 0100555 1 1007 19 0xffffffff 6707 718284717 718282428 718282428 8192 14 The fields are: device inode mode nlink uid gid rdev size {a,m,c}time blocksize blocks. I hope someone finds this useful. If you have any comments or suggestions, please let me know. Tim -- Tim Wilson tdw@cl.cam.ac.uk University of Cambridge Computer Laboratory, UK --- CUT HERE ----------------------------------------------------------------- # /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'stat' <<'END_OF_FILE' X#!/usr/bin/perl X# X# Last edited: Mon Oct 5 11:48:02 1992 by Tim Wilson X# $Id: stat,v 1.1 1992/10/05 10:53:13 tdw Exp $ X# X# Stat(2) files and print results. X# X# Usage: stat [-?] [-l] [-n] [-h] [--] files... X# X# -l: use lstat(2) instead of stat(2) X# -n: print output in numeric format (instead of readable format) X# -h: if in numeric format, also print header line X# -?: print help message X# --: remaining arguments are file names X# X###################################################################### X# X# Copyright (C) 1992 T D Wilson. All rights reserved. X# X# Permission to copy without fee all or part of this material is X# granted provided that the copies are not made or distributed for X# direct commercial advantage, the copyright notice and the title and X# date appear, and notice is given that copying is by permission of X# the author. To copy otherwise, or to republish, requires specific X# permission. X# X# T D Wilson makes no representations about the suitability of this X# software for any purpose. It is provided "as is" without express or X# implied warranty. X# X###################################################################### X# X# Modification summary: X# 5 Oct 1992 Tim Wilson Altered comments; posted to X# alt.sources. Revision 1.1. X# 11 Jul 1991 Tim Wilson Created. X# X# Tim Wilson, University of Cambridge Computer Laboratory, UK. X# tdw@cl.cam.ac.uk X# X Xsub usage { X die "Usage: $progname [-l] [-n] [-h] [--] files...\n"; X} X Xsub Lstat { X ($st_dev,$st_ino,$st_mode,$st_nlink,$st_uid,$st_gid,$st_rdev,$st_size, X $st_atime,$st_mtime,$st_ctime,$st_blksize,$st_blocks) = lstat(shift(@_)); X} X Xrequire "stat.pl"; Xrequire "ctime.pl"; X X###################################################################### X# X# p_perm -- Return part permissions symbolically X# X# perm: Permissions. Only the low three bits are significant X# extra: Extra bit to be encoded with execute (suid, sgid, sticky) X# c: Character to be used instead of `x' (`s' or `t') X# X# Returns -- three character string X# X# Side effects -- Output X# X###################################################################### X Xsub p_perm { X local ($perm,$extra,$c) = @_; X local ($lower,$upper) = ($c, $c); X local ($result); X $lower =~ tr/ST/st/; # Guaranteed lower case `s' or `t' X $upper =~ tr/st/ST/; # Guaranteed upper case `S' or `T' X X $result = ($perm & 04) ? "r" : "-"; X $result .= ($perm & 02) ? "w" : "-"; X # Want 2D array; do index arithmetic ourselves X $result .= ("-", "x", $upper, $lower)[!!$extra * 2 + ($perm & 01)]; X} X X X###################################################################### X# X# p_mode -- Return symbolic $st_mode (and/or memorized stat structure) X# X# Arguments are global variables. Ahem! X# X# Returns -- ten character string X# X# Side effects -- Output X# X###################################################################### X Xsub p_mode { X local ($result); X # First letter according to type of file X TYPE: { X -p _ && do {$result = "p"; last TYPE;}; X -c _ && do {$result = "c"; last TYPE;}; X -d _ && do {$result = "d"; last TYPE;}; X -b _ && do {$result = "b"; last TYPE;}; X -l $file && do {$result = "l"; last TYPE;};# lstat problems X -f _ && do {$result = "-"; last TYPE;}; X -S _ && do {$result = "s"; last TYPE;}; X warn ("unknown type of file, mode %#o\n", $st_mode); X $result = "?"; X } X X $result .= &p_perm ($st_mode >> 6, -u _, "s"); # User X $result .= &p_perm ($st_mode >> 3, -g _, "s"); # Group X $result .= &p_perm ($st_mode >> 0, -k _, "t"); # Others X} X X X###################################################################### X# X# uid, gid -- Convert numeric uid, gid to symbolic X# X# arg: numeric id X# X# Returns -- Name associated with id if found, else number X# X# Side effects -- Accesses /etc/passwd or replacement X# X###################################################################### X Xsub uid { X local ($uid) = @_; X local ($name) = getpwuid ($uid); X X defined ($name) ? return $name : return $uid; X} X Xsub gid { X local ($gid) = @_; X local ($name) = getgrgid ($gid); X X defined ($name) ? return $name : return $gid; X} X X X###################################################################### X# X# verbstat -- Print $st_* variable (and/or remembered stat structure) X# in multiline verbose format X# X# Arguments are global variables. Ahem! X# X# Returns -- nothing X# X# Side effects -- Output X# X###################################################################### X Xsub verbstat { X local ($atime, $mtime, $ctime) X = (&ctime ($st_atime), &ctime ($st_mtime), &ctime ($st_ctime)); X local ($mode) = &p_mode; X X printf ("%s\n", $file); X printf ("\tdevice\t\t%#x\n", $st_dev); X printf ("\tinode\t\t%d\t\t%#x\n", $st_ino, $st_ino); X printf ("\tmode\t\t%s\t%#o\n", &p_mode, $st_mode); X printf ("\tnlink\t\t%d\n", $st_nlink); X printf ("\towner\t\t%s\n", &uid ($st_uid)); X printf ("\tgroup\t\t%s\n", &gid ($st_gid)); X printf ("\trdev\t\t%d\n", $st_rdev); X printf ("\tsize\t\t%d\n", $st_size); X chop ($atime); X chop ($mtime); X chop ($ctime); X printf ("\tatime\t\t%s\n\tmtime\t\t%s\n\tctime\t\t%s\n", X $atime, $mtime, $ctime); X printf ("\tblksize\t\t%d\n", $st_blksize); X printf ("\tblocks\t\t%d\n", $st_blocks); X} X X X###################################################################### X# Main program X###################################################################### X X$_ = $0; X$progname = m|.*/([^/]+)| ? $1 : $_; X X X$opt_lstat = 0; # If true use lstat not stat X$opt_header = 0; # Add header line X$opt_numeric = 0; # One-line numeric format X X# No switch clustering with this simple parser X XSWITCH: Xwhile ($_ = shift) { X /^-\?/ && &usage; # stat -? ... gives usage X /^--$/ && last SWITCH; # -- terminates switches X /^-l$/ && ($opt_lstat = 1, next SWITCH); X /^-h$/ && ($opt_header = 1, next SWITCH); X /^-n$/ && ($opt_numeric = 1, next SWITCH); X X unshift (ARGV, $_); # We are looking at the first file X last SWITCH; X} X X($#ARGV < $[) && &usage; # Must have at least one arg X X X# Print out header if requested and numeric format X X$opt_numeric && $opt_header && print "dev ino mode nlink uid gid rdev size atime mtime ctime blksize blocks\n"; X X X# Stat remaining args and print result X Xforeach $file (@ARGV) { X if ($opt_lstat) { X &Lstat ($file); X } else { X &Stat ($file); X } X X if (defined ($st_dev)) { X if ($opt_numeric) { X # fn dev ino md nl ud gd rdv siz atm mtm ctm bks nbk X printf "%s %#x %#x %#o %d %d %d %#x %ld %ld %ld %ld %d %d\n", X $file, X $st_dev, $st_ino, $st_mode, $st_nlink, X $st_uid, $st_gid, X $st_rdev, $st_size, X $st_atime, $st_mtime, $st_ctime, X $st_blksize, $st_blocks; X } else { X &verbstat; X } X } else { X $opt_lstat ? X warn $file, ": Can't lstat\n" : X warn $file, ": Can't stat\n"; X } X} X X# End of stat END_OF_FILE if test 6707 -ne `wc -c <'stat'`; then echo shar: \"'stat'\" unpacked with wrong size! fi chmod +x 'stat' # end of 'stat' fi echo shar: End of shell archive. exit 0 -- Tim Wilson tdw@cl.cam.ac.uk University of Cambridge Computer Laboratory, UK