import NetBSD stat
This commit is contained in:
parent
832f7f99fd
commit
49cab1c73c
11 changed files with 1730 additions and 511 deletions
|
@ -25,7 +25,7 @@ SUBDIR= aal add_route adduser advent arp ash at autil awk \
|
|||
ramdisk rarpd rawspeed rcp rdate readall readclock \
|
||||
readfs reboot remsync rev rget rlogin rlogind rmdir \
|
||||
rotate rsh rshd sed service setup shar size \
|
||||
sleep slip sort spell split srccrc stat strings ackstrip \
|
||||
sleep slip sort spell split srccrc strings ackstrip \
|
||||
stty su sum svclog swapfs swifi sync synctree sysenv \
|
||||
syslogd tail talk talkd tar tcpd tcpdp tcpstat tee telnet \
|
||||
telnetd term termcap tget time tinyhalt top touch tr \
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
PROG= stat
|
||||
MAN=
|
||||
|
||||
LINKS+= ${BINDIR}/stat ${BINDIR}/readlink
|
||||
LINKS+= ${BINDIR}/stat ${BINDIR}/fstat
|
||||
LINKS+= ${BINDIR}/stat ${BINDIR}/lstat
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,389 +0,0 @@
|
|||
/* stat.c Feb 1987 - main, printit, statit
|
||||
*
|
||||
* stat - a program to perform what the stat(2) call does.
|
||||
*
|
||||
* usage: stat [-] [-all] -<field> [-<field> ...] [file1 file2 file3 ...]
|
||||
*
|
||||
* where <field> is one of the struct stat fields without the leading "st_".
|
||||
* The three times can be printed out as human times by requesting
|
||||
* -Ctime instead of -ctime (upper case 1st letter).
|
||||
* - means take the file names from stdin.
|
||||
* -0.. means fd0..
|
||||
* no files means all fds.
|
||||
*
|
||||
* output: if only one field is specified, that fields' contents are printed.
|
||||
* if more than one field is specified, the output is
|
||||
* file filed1: f1val, field2: f2val, etc
|
||||
*
|
||||
* written: Larry McVoy, (mcvoy@rsch.wisc.edu)
|
||||
*/
|
||||
|
||||
# define ALLDEF /* Make -all default. (kjb) */
|
||||
|
||||
# include <sys/types.h>
|
||||
# include <errno.h>
|
||||
# include <limits.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
# include <string.h>
|
||||
# include <time.h>
|
||||
# include <sys/stat.h>
|
||||
# define addr(x) ((void*) &sbuf.x)
|
||||
# define size(x) sizeof(sbuf.x)
|
||||
# define equal(s, t) (strcmp(s, t) == 0)
|
||||
# ifndef PATH_MAX
|
||||
# define PATH_MAX 1024
|
||||
# endif
|
||||
# undef LS_ADDS_SPACE /* AT&T Unix PC, ls prints "file[* /]" */
|
||||
/* This makes stat fail. */
|
||||
|
||||
# ifndef _MINIX /* All but Minix have u_* and st_blocks */
|
||||
# define BSD
|
||||
# endif
|
||||
|
||||
# ifndef S_IREAD
|
||||
# define S_IREAD S_IRUSR
|
||||
# define S_IWRITE S_IWUSR
|
||||
# define S_IEXEC S_IXUSR
|
||||
# endif
|
||||
|
||||
char * arg0;
|
||||
struct stat sbuf;
|
||||
extern int errno;
|
||||
int first_file= 1;
|
||||
#ifndef S_IFLNK
|
||||
#define lstat stat
|
||||
#endif
|
||||
|
||||
struct field {
|
||||
char* f_name; /* field name in stat */
|
||||
u_char* f_addr; /* address of the field in sbuf */
|
||||
u_short f_size; /* size of the object, needed for pointer arith */
|
||||
u_short f_print; /* show this field? */
|
||||
} fields[] = {
|
||||
{ "dev", addr(st_dev), size(st_dev), 0 },
|
||||
{ "ino", addr(st_ino), size(st_ino), 0 },
|
||||
{ "mode", addr(st_mode), size(st_mode), 0 },
|
||||
{ "nlink", addr(st_nlink), size(st_nlink), 0 },
|
||||
{ "uid", addr(st_uid), size(st_uid), 0 },
|
||||
{ "gid", addr(st_gid), size(st_gid), 0 },
|
||||
{ "rdev", addr(st_rdev), size(st_rdev), 0 },
|
||||
{ "size", addr(st_size), size(st_size), 0 },
|
||||
{ "Atime", addr(st_atime), size(st_atime), 0 },
|
||||
{ "atime", addr(st_atime), size(st_atime), 0 },
|
||||
{ "Mtime", addr(st_mtime), size(st_mtime), 0 },
|
||||
{ "mtime", addr(st_mtime), size(st_mtime), 0 },
|
||||
{ "Ctime", addr(st_ctime), size(st_ctime), 0 },
|
||||
{ "ctime", addr(st_ctime), size(st_ctime), 0 },
|
||||
{ "blksize", addr(st_blksize), size(st_blksize), 0 },
|
||||
{ "blocks", addr(st_blocks), size(st_blocks), 0 },
|
||||
{ NULL, 0, 0, 0 },
|
||||
};
|
||||
|
||||
void printstat(struct stat *sbuf, int nprint);
|
||||
void printit(struct stat* sb, struct field* f, int n);
|
||||
void rwx(mode_t mode, char *bit);
|
||||
void usage(void);
|
||||
|
||||
int do_readlink=0;
|
||||
|
||||
int main(int ac, char** av)
|
||||
{
|
||||
int i, j, nprint = 0, files = 0;
|
||||
char buf[PATH_MAX], *check;
|
||||
int sym=0, ret=0, from_stdin = 0;
|
||||
int err;
|
||||
u_long fd;
|
||||
|
||||
if ((arg0 = strrchr(av[0], '/')) == NULL) arg0 = av[0]; else arg0++;
|
||||
#ifdef S_IFLNK
|
||||
if (equal(arg0, "lstat")) sym = 1;
|
||||
if (equal(arg0, "readlink")) do_readlink = 1;
|
||||
#endif
|
||||
|
||||
if (ac > 1 && equal(av[i = 1], "-"))
|
||||
i++, from_stdin++;
|
||||
|
||||
for (i= 1; i<ac; i++) {
|
||||
if (av[i][0] == '-') {
|
||||
if (equal(av[i], "-")) {
|
||||
from_stdin= 1;
|
||||
files++;
|
||||
continue;
|
||||
}
|
||||
if (equal("-all", av[i])) {
|
||||
for (j=0; fields[j].f_name; j++)
|
||||
nprint++, fields[j].f_print++;
|
||||
continue;
|
||||
}
|
||||
if (equal("-s", av[i])) {
|
||||
#ifdef S_IFLNK
|
||||
sym=1;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
fd = strtoul(av[i]+1, &check, 0);
|
||||
if (check != av[i]+1 && *check == '\0')
|
||||
{
|
||||
files++;
|
||||
continue;
|
||||
}
|
||||
for (j=0; fields[j].f_name; j++)
|
||||
if (equal(fields[j].f_name, &av[i][1])) {
|
||||
nprint++, fields[j].f_print++;
|
||||
break;
|
||||
}
|
||||
if (!fields[j].f_name) {
|
||||
if (!equal("-?", av[i])) {
|
||||
fprintf(stderr, "stat: %s: bad field\n", av[i]);
|
||||
}
|
||||
usage();
|
||||
}
|
||||
}
|
||||
else
|
||||
files++;
|
||||
}
|
||||
if (!nprint) {
|
||||
# ifndef ALLDEF
|
||||
usage();
|
||||
# else
|
||||
for (j=0; fields[j].f_name; j++)
|
||||
nprint++, fields[j].f_print++;
|
||||
# endif
|
||||
}
|
||||
|
||||
if (from_stdin)
|
||||
files++; /* We don't know how many files come from stdin. */
|
||||
|
||||
if (files == 0) { /* Stat all file descriptors. */
|
||||
if(do_readlink) return 0;
|
||||
for (i= 0; i<OPEN_MAX; i++) {
|
||||
err= fstat(i, &sbuf);
|
||||
if (err == -1 && errno == EBADF)
|
||||
continue;
|
||||
if (err == 0) {
|
||||
if (!first_file) fputc('\n', stdout);
|
||||
printf("fd %d:\n", i);
|
||||
printstat(&sbuf, nprint);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: fd %d: %s\n", arg0, i, strerror(errno));
|
||||
ret= 1;
|
||||
}
|
||||
}
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
for (i=1; i<ac; i++) {
|
||||
if (equal(av[i], "-")) {
|
||||
while (fgets(buf, sizeof(buf), stdin)) {
|
||||
char *p= strchr(buf, '\n');
|
||||
if (p) *p= 0;
|
||||
#ifdef S_IFLNK
|
||||
if(do_readlink) {
|
||||
char sbuf[300];
|
||||
int n;
|
||||
if((n=readlink(buf, sbuf, sizeof(sbuf)-1)) < 0) {
|
||||
perror(buf);
|
||||
continue;
|
||||
}
|
||||
sbuf[n] = '\0';
|
||||
printf("%s: %s\n", buf, sbuf);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (!sym) err= stat(av[i], &sbuf);
|
||||
if (sym || (err != 0 && errno == ENOENT)) {
|
||||
err= lstat(av[i], &sbuf);
|
||||
}
|
||||
if (err == -1) {
|
||||
fprintf(stderr, "%s: %s: %s\n",
|
||||
arg0, av[i], strerror(errno));
|
||||
ret= 1;
|
||||
}
|
||||
else {
|
||||
if (!first_file) fputc('\n', stdout);
|
||||
printf("%s:\n", buf);
|
||||
printstat(&sbuf, nprint);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (av[i][0] == '-') {
|
||||
fd= strtoul(av[i]+1, &check, 10);
|
||||
if (check == av[i]+1 || *check != '\0') continue;
|
||||
if (fd >= INT_MAX) {
|
||||
err= -1;
|
||||
errno= EBADF;
|
||||
}
|
||||
else {
|
||||
err= fstat((int) fd, &sbuf);
|
||||
}
|
||||
if (err != -1) {
|
||||
if (!first_file) fputc('\n', stdout);
|
||||
if (files != 1) printf("fd %lu:\n", fd);
|
||||
printstat(&sbuf, nprint);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "fd %lu: %s\n", fd, strerror(errno));
|
||||
ret= 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(do_readlink) {
|
||||
char sbuf[300];
|
||||
int n;
|
||||
if((n=err=readlink(av[i], sbuf, sizeof(sbuf)-1)) < 0) {
|
||||
perror(av[i]);
|
||||
continue;
|
||||
}
|
||||
sbuf[n] = '\0';
|
||||
printf("%s: %s\n", av[i], sbuf);
|
||||
continue;
|
||||
}
|
||||
if (!sym) err= stat(av[i], &sbuf);
|
||||
if (sym || (err != 0 && errno == ENOENT)) err= lstat(av[i], &sbuf);
|
||||
if (err != -1) {
|
||||
if (!first_file) fputc('\n', stdout);
|
||||
if (files != 1) printf("%s:\n", av[i]);
|
||||
printstat(&sbuf, nprint);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: %s: %s\n", arg0, av[i], strerror(errno));
|
||||
ret= 1;
|
||||
}
|
||||
}
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------30/Jan/87-*
|
||||
* printstat(file, nprint) - do the work
|
||||
*----------------------------------------------------------------larry mcvoy-*/
|
||||
void printstat(struct stat *sbuf, int nprint)
|
||||
{
|
||||
int j;
|
||||
int first_field= 1;
|
||||
|
||||
for (j=0; fields[j].f_name; j++) {
|
||||
if (fields[j].f_print) {
|
||||
if (!first_field) fputc('\n', stdout);
|
||||
printit(sbuf, &fields[j], nprint);
|
||||
first_field= 0;
|
||||
}
|
||||
}
|
||||
fputc('\n', stdout);
|
||||
first_file= 0;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------30/Jan/87-*
|
||||
* printit(sb, f, n) - print the field
|
||||
*
|
||||
* Inputs -> (struct stat*), (struct field*), (int)
|
||||
*
|
||||
* Results -> Displays the field, with special handling of weird fields like
|
||||
* mode and mtime. The mode field is dumped in octal, followed
|
||||
* by one or more of the S_IF<X> and/or S_I<X> values.
|
||||
*----------------------------------------------------------------larry mcvoy-*/
|
||||
void printit(struct stat* sb, struct field* f, int n)
|
||||
{
|
||||
if (n > 1)
|
||||
printf("%s: ", f->f_name);
|
||||
if (equal(f->f_name, "mode")) {
|
||||
/* This lot changed to my personal liking. (kjb) */
|
||||
char bit[11];
|
||||
|
||||
printf("%07lo, ", (u_long) sb->st_mode);
|
||||
|
||||
strcpy(bit, "----------");
|
||||
|
||||
switch (sb->st_mode&S_IFMT) {
|
||||
case S_IFDIR: bit[0]='d'; break;
|
||||
# ifdef S_IFFIFO
|
||||
case S_IFFIFO: bit[0]='p'; break;
|
||||
# endif
|
||||
case S_IFCHR: bit[0]='c'; break;
|
||||
case S_IFBLK: bit[0]='b'; break;
|
||||
# ifdef S_IFSOCK
|
||||
case S_IFSOCK: bit[0]='S'; break;
|
||||
# endif
|
||||
# ifdef S_IFMPC
|
||||
case S_IFMPC: bit[0]='C'; break;
|
||||
# endif
|
||||
# ifdef S_IFMPB
|
||||
case S_IFMPB: bit[0]='B'; break;
|
||||
# endif
|
||||
# ifdef S_IFLNK
|
||||
case S_IFLNK: bit[0]='l'; break;
|
||||
# endif
|
||||
}
|
||||
rwx(sb->st_mode, bit+1);
|
||||
rwx(sb->st_mode<<3, bit+4);
|
||||
rwx(sb->st_mode<<6, bit+7);
|
||||
if (sb->st_mode&S_ISUID) bit[3]='s';
|
||||
if (sb->st_mode&S_ISGID) bit[6]='s';
|
||||
if (sb->st_mode&S_ISVTX) bit[9]='t';
|
||||
printf("\"%s\"", bit);
|
||||
}
|
||||
/* times in human form, uppercase first letter */
|
||||
else if (equal("Ctime", f->f_name)) {
|
||||
printf("%.24s (%lu)", ctime(&sb->st_ctime), (u_long) sb->st_ctime);
|
||||
f[1].f_print= 0;
|
||||
}
|
||||
else if (equal("Mtime", f->f_name)) {
|
||||
printf("%.24s (%lu)", ctime(&sb->st_mtime), (u_long) sb->st_mtime);
|
||||
f[1].f_print= 0;
|
||||
}
|
||||
else if (equal("Atime", f->f_name)) {
|
||||
printf("%.24s (%lu)", ctime(&sb->st_atime), (u_long) sb->st_atime);
|
||||
f[1].f_print= 0;
|
||||
}
|
||||
else if (equal("ctime", f->f_name)) {
|
||||
printf("%lu", (u_long) sb->st_ctime);
|
||||
}
|
||||
else if (equal("mtime", f->f_name)) {
|
||||
printf("%lu", (u_long) sb->st_mtime);
|
||||
}
|
||||
else if (equal("atime", f->f_name)) {
|
||||
printf("%lu", (u_long) sb->st_atime);
|
||||
}
|
||||
else {
|
||||
switch (f->f_size) {
|
||||
case sizeof(char):
|
||||
printf("%d", * (u_char *) f->f_addr);
|
||||
break;
|
||||
case sizeof(short):
|
||||
printf("%u", (u_int) * (u_short *) f->f_addr);
|
||||
break;
|
||||
#if INT_MAX != SHRT_MAX
|
||||
case sizeof(int):
|
||||
printf("%u", * (u_int *) f->f_addr);
|
||||
break;
|
||||
#endif
|
||||
#if LONG_MAX != INT_MAX && LONG_MAX != SHRT_MAX
|
||||
case sizeof(long):
|
||||
printf("%lu", * (u_long *) f->f_addr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
fprintf(stderr, "\nProgram error: bad '%s' field size %d\n",
|
||||
f->f_name, f->f_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rwx(mode_t mode, char *bit)
|
||||
{
|
||||
if (mode&S_IREAD) bit[0]='r';
|
||||
if (mode&S_IWRITE) bit[1]='w';
|
||||
if (mode&S_IEXEC) bit[2]='x';
|
||||
}
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s [-] [-fd] [-all] [-s] [-field ...] [file1 ...]\n",
|
||||
arg0);
|
||||
exit(1);
|
||||
}
|
|
@ -18,7 +18,7 @@ MAN= acd.1 anm.1 ar.1 ash.1 asize.1 at.1 banner.1 basename.1 \
|
|||
profile.1 ps.1 pwd.1 rcp.1 readall.1 readfs.1 recwave.1 \
|
||||
ref.1 remsync.1 rget.1 rlogin.1 rmdir.1 rsh.1 rz.1 \
|
||||
shar.1 size.1 sleep.1 sort.1 soundoff.1 soundon.1 spell.1 \
|
||||
split.1 stat.1 strings.1 strip.1 stty.1 su.1 sum.1 svc.1 \
|
||||
split.1 strings.1 strip.1 stty.1 su.1 sum.1 svc.1 \
|
||||
synctree.1 sysenv.1 sz.1 tail.1 tee.1 telnet.1 template.1 \
|
||||
term.1 termcap.1 tget.1 time.1 top.1 tr.1 true.1 \
|
||||
truncate.1 tsort.1 tty.1 umount.1 uname.1 unexpand.1 uniq.1 \
|
||||
|
|
111
man/man1/stat.1
111
man/man1/stat.1
|
@ -1,111 +0,0 @@
|
|||
.TH STAT 1
|
||||
.SH NAME
|
||||
stat, lstat, readlink \- provide a shell interface to the stat(2) system call
|
||||
.SH SYNOPSIS
|
||||
.B stat
|
||||
.RB [ - ]
|
||||
.RB [ -\fIfd ]
|
||||
.RB [ -all ]
|
||||
.RB [ -s ]
|
||||
.RB [ -\fIfield " ...]"
|
||||
.RI [ file1 " ...]"
|
||||
.SH DESCRIPTION
|
||||
.B Stat
|
||||
does little more than provide access to the fields in the
|
||||
.B struct stat
|
||||
as defined in the
|
||||
.BR stat (2)
|
||||
manual page. Each field that is to be listed
|
||||
is specified as the field name without the leading
|
||||
.BR st_ .
|
||||
This and the other two options are described below. All options are then
|
||||
applied to the files listed. If
|
||||
.B stat
|
||||
is called as
|
||||
.B lstat
|
||||
then the
|
||||
.BR lstat (2)
|
||||
system call is used, if called as
|
||||
.B stat
|
||||
symbolic links are expanded with
|
||||
.BR stat (2).
|
||||
If called as
|
||||
.B readlink
|
||||
then the output is only the contents of the symbolic link.
|
||||
.PP
|
||||
If no fields are named then all fields are printed. If no files are listed
|
||||
then all open filedescriptors are printed.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-
|
||||
If the first argument is ``\-'', the list of files is assumed to come from stdin.
|
||||
This is useful for things like ``ls | stat \-uid \-mtime.''
|
||||
.B \-\fIfd
|
||||
If an argument is a ``\-'' followed by a number then that number is used as
|
||||
a file descriptor whose information is to be printed.
|
||||
.TP
|
||||
.B \-all
|
||||
List all fields for each file.
|
||||
.TP
|
||||
.B \-s
|
||||
Use
|
||||
.BR lstat (2).
|
||||
.TP
|
||||
.B \-mode
|
||||
List the
|
||||
.B mode
|
||||
field. Similarly for
|
||||
.BR ino ,
|
||||
.BR dev ,
|
||||
.BR rdev ,
|
||||
.BR nlink ,
|
||||
.BR uid ,
|
||||
.BR gid ,
|
||||
.BR size ,
|
||||
.BR atime ,
|
||||
.BR mtime ,
|
||||
and
|
||||
.BR ctime .
|
||||
Under BSD derived systems you also have
|
||||
.B blksize
|
||||
and
|
||||
.BR blocks .
|
||||
.PP
|
||||
.B \-Atime
|
||||
.br
|
||||
.B \-Mtime
|
||||
.br
|
||||
.B \-Ctime
|
||||
.RS
|
||||
The lower case versions of these three options display the time as an integer
|
||||
that is the ``seconds since 00:00 Jan 1. 1970.''
|
||||
Listing the fields with the first letter
|
||||
in caps causes the times to be printed in
|
||||
.BR ctime (3)
|
||||
format (i.e., human readable).
|
||||
.RE
|
||||
.SH EXAMPLES
|
||||
.LP
|
||||
# Find out the number of links to each file
|
||||
.br
|
||||
$ stat \-nlink *.c
|
||||
.LP
|
||||
# sort files by age (much like ls \-t)
|
||||
.br
|
||||
$ stat \-atime * | sort +1
|
||||
.LP
|
||||
# Find out which file is older in sh(1)
|
||||
.br
|
||||
if test `stat -mtime $1` -lt `stat -mtime $2`; then
|
||||
.br
|
||||
echo $1 is older than $2
|
||||
.br
|
||||
else
|
||||
.br
|
||||
echo $2 is older than $1
|
||||
.br
|
||||
fi
|
||||
.SH "SEE ALSO"
|
||||
.BR stat (2).
|
||||
.SH AUTHOR
|
||||
Larry McVoy (mcvoy@rsch.wisc.edu)
|
|
@ -5,3 +5,4 @@ lib/libcrypt src/lib/libcrypt
|
|||
nbsd_include src/include
|
||||
usr.bin/m4 src/usr.bin/m4
|
||||
usr.bin/indent src/usr.bin/indent
|
||||
usr.bin/stat src/usr.bin/stat
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
.include <bsd.own.mk>
|
||||
|
||||
# NetBSD imports
|
||||
SUBDIR= indent m4 mkimage
|
||||
SUBDIR= indent m4 mkimage stat
|
||||
|
||||
# Non-NetBSD imports
|
||||
SUBDIR+= ministat
|
||||
|
|
15
usr.bin/stat/Makefile
Normal file
15
usr.bin/stat/Makefile
Normal file
|
@ -0,0 +1,15 @@
|
|||
# $NetBSD: Makefile,v 1.7 2003/07/25 03:21:17 atatat Exp $
|
||||
|
||||
PROG= stat
|
||||
|
||||
.if !defined(HOSTPROG)
|
||||
LINKS= ${BINDIR}/stat ${BINDIR}/readlink
|
||||
.if defined(__MINIX)
|
||||
# To prevent breaking of existing utilities in commands/
|
||||
LINKS+= ${BINDIR}/stat ${BINDIR}/fstat
|
||||
LINKS+= ${BINDIR}/stat ${BINDIR}/lstat
|
||||
.endif
|
||||
MLINKS= stat.1 readlink.1
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
31
usr.bin/stat/minix-port.patch
Normal file
31
usr.bin/stat/minix-port.patch
Normal file
|
@ -0,0 +1,31 @@
|
|||
diff -ru nbsdsrc/src/usr.bin/stat/Makefile usr.bin/stat/Makefile
|
||||
--- nbsdsrc/src/usr.bin/stat/Makefile
|
||||
+++ usr.bin/stat/Makefile
|
||||
@@ -4,6 +4,11 @@
|
||||
|
||||
.if !defined(HOSTPROG)
|
||||
LINKS= ${BINDIR}/stat ${BINDIR}/readlink
|
||||
+.if defined(__MINIX)
|
||||
+# To prevent breaking of existing utilities in commands/
|
||||
+LINKS+= ${BINDIR}/stat ${BINDIR}/fstat
|
||||
+LINKS+= ${BINDIR}/stat ${BINDIR}/lstat
|
||||
+.endif
|
||||
MLINKS= stat.1 readlink.1
|
||||
.endif
|
||||
|
||||
diff -ru nbsdsrc/src/usr.bin/stat/stat.c usr.bin/stat/stat.c
|
||||
--- nbsdsrc/src/usr.bin/stat/stat.c
|
||||
+++ usr.bin/stat/stat.c
|
||||
@@ -44,7 +44,12 @@
|
||||
#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
|
||||
#define HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC 1
|
||||
#define HAVE_STRUCT_STAT_ST_MTIMENSEC 1
|
||||
+#ifdef __minix
|
||||
+/* Not supported in Minix. */
|
||||
+#define HAVE_DEVNAME 0
|
||||
+#else /* __minix */
|
||||
#define HAVE_DEVNAME 1
|
||||
+#endif /* __minx */
|
||||
#endif /* HAVE_NBTOOL_CONFIG_H */
|
||||
|
||||
#include <sys/types.h>
|
569
usr.bin/stat/stat.1
Normal file
569
usr.bin/stat/stat.1
Normal file
|
@ -0,0 +1,569 @@
|
|||
.\" $NetBSD: stat.1,v 1.28 2010/04/05 21:25:01 joerg Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2002-2005 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to The NetBSD Foundation
|
||||
.\" by Andrew Brown and Jan Schaumann.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 7, 2008
|
||||
.Dt STAT 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm stat ,
|
||||
.Nm readlink
|
||||
.Nd display file status
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl FLnq
|
||||
.Oo
|
||||
.Fl f Ar format |
|
||||
.Fl l |
|
||||
.Fl r |
|
||||
.Fl s |
|
||||
.Fl x
|
||||
.Oc
|
||||
.Op Fl t Ar timefmt
|
||||
.Op Ar
|
||||
.Nm readlink
|
||||
.Op Fl fn
|
||||
.Op Ar
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility displays information about the file pointed to by
|
||||
.Ar file .
|
||||
Read, write, or execute permissions of the named file are not required, but
|
||||
all directories listed in the pathname leading to the file must be
|
||||
searchable.
|
||||
If no argument is given,
|
||||
.Nm
|
||||
displays information about the file descriptor for standard input.
|
||||
.Pp
|
||||
When invoked as
|
||||
.Nm readlink ,
|
||||
only the target of the symbolic link is printed.
|
||||
If the given argument is not a symbolic link and the
|
||||
.Fl f
|
||||
option is not specified,
|
||||
.Nm readlink
|
||||
will print nothing and exit with an error.
|
||||
If the
|
||||
.Fl f
|
||||
option is specified, the output is canonicalized by following every symlink
|
||||
in every component of the given path recursively.
|
||||
.Nm readlink
|
||||
will resolve both absolute and relative paths, and return the absolute pathname
|
||||
corresponding to
|
||||
.Ar file .
|
||||
In this case, the argument does not need to be a symbolic link.
|
||||
.Pp
|
||||
The information displayed is obtained by calling
|
||||
.Xr lstat 2
|
||||
with the given argument and evaluating the returned structure.
|
||||
The default format displays the
|
||||
.Fa st_dev ,
|
||||
.Fa st_ino ,
|
||||
.Fa st_mode ,
|
||||
.Fa st_nlink ,
|
||||
.Fa st_uid ,
|
||||
.Fa st_gid ,
|
||||
.Fa st_rdev ,
|
||||
.Fa st_size ,
|
||||
.Fa st_atime ,
|
||||
.Fa st_mtime ,
|
||||
.Fa st_ctime ,
|
||||
.Fa st_birthtime ,
|
||||
.Fa st_blksize ,
|
||||
.Fa st_blocks ,
|
||||
and
|
||||
.Fa st_flags
|
||||
fields, in that order.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width XFXformatXXX
|
||||
.It Fl F
|
||||
As in
|
||||
.Xr ls 1 ,
|
||||
display a slash
|
||||
.Pq Sq /
|
||||
immediately after each pathname that is a directory, an
|
||||
asterisk
|
||||
.Pq Sq *
|
||||
after each that is executable, an at sign
|
||||
.Pq Sq @
|
||||
after each symbolic link, a percent sign
|
||||
.Pq Sq %
|
||||
after each whiteout, an equal sign
|
||||
.Pq Sq =
|
||||
after each socket, and a vertical bar
|
||||
.Pq Sq \&|
|
||||
after each that is a FIFO.
|
||||
The use of
|
||||
.Fl F
|
||||
implies
|
||||
.Fl l .
|
||||
.It Fl f Ar format
|
||||
Display information using the specified format.
|
||||
See the
|
||||
.Sx FORMATS
|
||||
section for a description of valid formats.
|
||||
.It Fl L
|
||||
Use
|
||||
.Xr stat 2
|
||||
instead of
|
||||
.Xr lstat 2 .
|
||||
The information reported by
|
||||
.Nm
|
||||
will refer to the target of
|
||||
.Ar file ,
|
||||
if file is a symbolic link, and not to
|
||||
.Ar file
|
||||
itself.
|
||||
.It Fl l
|
||||
Display output in
|
||||
.Ic ls Fl lT
|
||||
format.
|
||||
.It Fl n
|
||||
Do not force a newline to appear at the end of each piece of output.
|
||||
.It Fl q
|
||||
Suppress failure messages if calls to
|
||||
.Xr stat 2
|
||||
or
|
||||
.Xr lstat 2
|
||||
fail.
|
||||
When run as
|
||||
.Nm readlink ,
|
||||
error messages are automatically suppressed.
|
||||
.It Fl r
|
||||
Display raw information.
|
||||
That is, for all the fields in the stat-structure,
|
||||
display the raw, numerical value (for example, times in seconds since the
|
||||
epoch, etc.)
|
||||
.It Fl s
|
||||
Display information in
|
||||
.Dq shell output ,
|
||||
suitable for initializing variables.
|
||||
.It Fl t Ar timefmt
|
||||
Display timestamps using the specified format.
|
||||
This format is
|
||||
passed directly to
|
||||
.Xr strftime 3 .
|
||||
.It Fl x
|
||||
Display information in a more verbose way as known from some Linux
|
||||
distributions.
|
||||
.El
|
||||
.Ss FORMATS
|
||||
Format strings are similar to
|
||||
.Xr printf 3
|
||||
formats in that they start with
|
||||
.Cm % ,
|
||||
are then followed by a sequence of formatting characters, and end in
|
||||
a character that selects the field of the struct stat which is to be
|
||||
formatted.
|
||||
If the
|
||||
.Cm %
|
||||
is immediately followed by one of
|
||||
.Cm n ,
|
||||
.Cm t ,
|
||||
.Cm % ,
|
||||
or
|
||||
.Cm @ ,
|
||||
then a newline character, a tab character, a percent character,
|
||||
or the current file number is printed, otherwise the string is
|
||||
examined for the following:
|
||||
.Pp
|
||||
Any of the following optional flags:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm #
|
||||
Selects an alternate output form for octal and hexadecimal output.
|
||||
Non-zero octal output will have a leading zero, and non-zero
|
||||
hexadecimal output will have
|
||||
.Dq 0x
|
||||
prepended to it.
|
||||
.It Cm +
|
||||
Asserts that a sign indicating whether a number is positive or negative
|
||||
should always be printed.
|
||||
Non-negative numbers are not usually printed with a sign.
|
||||
.It Cm -
|
||||
Aligns string output to the left of the field, instead of to the right.
|
||||
.It Cm 0
|
||||
Sets the fill character for left padding to the 0 character, instead of
|
||||
a space.
|
||||
.It space
|
||||
Reserves a space at the front of non-negative signed output fields.
|
||||
A
|
||||
.Sq Cm +
|
||||
overrides a space if both are used.
|
||||
.El
|
||||
.Pp
|
||||
Then the following fields:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm size
|
||||
An optional decimal digit string specifying the minimum field width.
|
||||
.It Cm prec
|
||||
An optional precision composed of a decimal point
|
||||
.Sq Cm \&.
|
||||
and a decimal digit string that indicates the maximum string length,
|
||||
the number of digits to appear after the decimal point in floating point
|
||||
output, or the minimum number of digits to appear in numeric output.
|
||||
.It Cm fmt
|
||||
An optional output format specifier which is one of
|
||||
.Cm D ,
|
||||
.Cm O ,
|
||||
.Cm U ,
|
||||
.Cm X ,
|
||||
.Cm F ,
|
||||
or
|
||||
.Cm S .
|
||||
These represent signed decimal output, octal output, unsigned decimal
|
||||
output, hexadecimal output, floating point output, and string output,
|
||||
respectively.
|
||||
Some output formats do not apply to all fields.
|
||||
Floating point output only applies to timespec fields (the
|
||||
.Cm a ,
|
||||
.Cm m ,
|
||||
and
|
||||
.Cm c
|
||||
fields).
|
||||
.Pp
|
||||
The special output specifier
|
||||
.Cm S
|
||||
may be used to indicate that the output, if
|
||||
applicable, should be in string format.
|
||||
May be used in combination with
|
||||
.Bl -tag -width Ds
|
||||
.It Cm amc
|
||||
Display date in strftime(3) format.
|
||||
.It Cm dr
|
||||
Display actual device name.
|
||||
.It Cm gu
|
||||
Display group or user name.
|
||||
.It Cm p
|
||||
Display the mode of
|
||||
.Ar file
|
||||
as in
|
||||
.Ic ls -lTd .
|
||||
.It Cm N
|
||||
Displays the name of
|
||||
.Ar file .
|
||||
.It Cm T
|
||||
Displays the type of
|
||||
.Ar file .
|
||||
.It Cm Y
|
||||
Insert a `` -\*[Gt] '' into the output.
|
||||
Note that the default output format for
|
||||
.Cm Y
|
||||
is a string, but if specified explicitly, these four characters are
|
||||
prepended.
|
||||
.El
|
||||
.It Cm sub
|
||||
An optional sub field specifier (high, middle, or low).
|
||||
Only applies to the
|
||||
.Cm p ,
|
||||
.Cm d ,
|
||||
.Cm r ,
|
||||
.Cm T ,
|
||||
.Cm N ,
|
||||
and
|
||||
.Cm z
|
||||
output formats.
|
||||
It can be one of the following:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm H
|
||||
.Dq High
|
||||
-- depending on the
|
||||
.Cm datum :
|
||||
.Bl -tag -compact -width door
|
||||
.It Cm d , r
|
||||
Major number for devices
|
||||
.It Cm p
|
||||
.Dq User
|
||||
bits from the string form of permissions or the file
|
||||
.Dq type
|
||||
bits from the numeric forms
|
||||
.It Cm T
|
||||
The long output form of file type
|
||||
.It Cm N
|
||||
Directory path of the file, similar to what
|
||||
.Xr dirname 1
|
||||
would show
|
||||
.It Cm z
|
||||
File size, rounded to the nearest gigabyte
|
||||
.El
|
||||
.It Cm M
|
||||
.Dq Middle
|
||||
-- depending on the
|
||||
.Cm datum :
|
||||
.Bl -tag -compact -width door
|
||||
.It Cm p
|
||||
The
|
||||
.Dq group
|
||||
bits from the string form of permissions or the
|
||||
.Dq suid ,
|
||||
.Dq sgid ,
|
||||
and
|
||||
.Dq sticky
|
||||
bits from the numeric forms
|
||||
.It Cm z
|
||||
File size, rounded to the nearest megabyte
|
||||
.El
|
||||
.It Cm L
|
||||
.Dq Low
|
||||
-- depending on the
|
||||
.Cm datum :
|
||||
.Bl -tag -compact -width door
|
||||
.It Cm r , d
|
||||
Minor number for devices
|
||||
.It Cm p
|
||||
The
|
||||
.Dq other
|
||||
bits from the string form of permissions or the
|
||||
.Dq user ,
|
||||
.Dq group ,
|
||||
and
|
||||
.Dq other
|
||||
bits from the numeric forms
|
||||
.It Cm T
|
||||
The
|
||||
.Ic ls -F
|
||||
style output character for file type (the use of
|
||||
.Cm L
|
||||
here is optional)
|
||||
.It Cm N
|
||||
Base filename of the file, similar to what
|
||||
.Xr basename 1
|
||||
would show
|
||||
.It Cm z
|
||||
File size, rounded to the nearest kilobyte
|
||||
.El
|
||||
.El
|
||||
.It Cm datum
|
||||
A required field specifier, being one of the following:
|
||||
.Bl -tag -width 11n
|
||||
.It Cm d
|
||||
Device upon which
|
||||
.Ar file
|
||||
resides
|
||||
.Pq Fa st_dev .
|
||||
.It Cm i
|
||||
.Ar file Ap s
|
||||
inode number
|
||||
.Pq Fa st_ino .
|
||||
.It Cm p
|
||||
File type and permissions
|
||||
.Pq Fa st_mode .
|
||||
.It Cm l
|
||||
Number of hard links to
|
||||
.Ar file
|
||||
.Pq Fa st_nlink .
|
||||
.It Cm u , g
|
||||
User-id and group-id of
|
||||
.Ar file Ap s
|
||||
owner
|
||||
.Pq Fa st_uid , st_gid .
|
||||
.It Cm r
|
||||
Device number for character and block device special files
|
||||
.Pq Fa st_rdev .
|
||||
.It Cm a , m , c , B
|
||||
The time
|
||||
.Ar file
|
||||
was last accessed or modified, or when the inode was last changed, or
|
||||
the birth time of the inode
|
||||
.Pq Fa st_atime , st_mtime , st_ctime, st_birthtime .
|
||||
.It Cm z
|
||||
The size of
|
||||
.Ar file
|
||||
in bytes
|
||||
.Pq Fa st_size .
|
||||
.It Cm b
|
||||
Number of blocks allocated for
|
||||
.Ar file
|
||||
.Pq Fa st_blocks .
|
||||
.It Cm k
|
||||
Optimal file system I/O operation block size
|
||||
.Pq Fa st_blksize .
|
||||
.It Cm f
|
||||
User defined flags for
|
||||
.Ar file
|
||||
.Pq Fa st_flags .
|
||||
.It Cm v
|
||||
Inode generation number
|
||||
.Pq Fa st_gen .
|
||||
.El
|
||||
.Pp
|
||||
The following five field specifiers are not drawn directly from the
|
||||
data in struct stat, but are:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm N
|
||||
The name of the file.
|
||||
.It Cm R
|
||||
The absolute pathname corresponding to the file.
|
||||
.It Cm T
|
||||
The file type, either as in
|
||||
.Ic ls -F
|
||||
or in a more descriptive form if the sub field specifier
|
||||
.Cm H
|
||||
is given.
|
||||
.It Cm Y
|
||||
The target of a symbolic link.
|
||||
.It Cm Z
|
||||
Expands to
|
||||
.Dq major,minor
|
||||
from the rdev field for character or block
|
||||
special devices and gives size output for all others.
|
||||
.El
|
||||
.El
|
||||
.Pp
|
||||
Only the
|
||||
.Cm %
|
||||
and the field specifier are required.
|
||||
Most field specifiers default to
|
||||
.Cm U
|
||||
as an output form, with the
|
||||
exception of
|
||||
.Cm p
|
||||
which defaults to
|
||||
.Cm O ;
|
||||
.Cm a , m ,
|
||||
and
|
||||
.Cm c
|
||||
which default to
|
||||
.Cm D ;
|
||||
and
|
||||
.Cm Y , T ,
|
||||
and
|
||||
.Cm N ,
|
||||
which default to
|
||||
.Cm S .
|
||||
.Sh EXIT STATUS
|
||||
.Nm
|
||||
exits 0 on success, and \*[Gt]0 if an error occurred.
|
||||
.Sh EXAMPLES
|
||||
If no options are specified, the default format is
|
||||
"%d %i %Sp %l %Su %Sg %r %z \e"%Sa\e" \e"%Sm\e" \e"%Sc\e" \e"%SB\e" %k %b %#Xf %N".
|
||||
.Bd -literal -offset indent
|
||||
\*[Gt] stat /tmp/bar
|
||||
0 78852 -rw-r--r-- 1 root wheel 0 0 "Jul 8 10:26:03 2004" "Jul 8 10:26:03 2004" "Jul 8 10:28:13 2004" "Jan 1 09:00:00 1970" 16384 0 0 /tmp/bar
|
||||
.Ed
|
||||
.Pp
|
||||
Given a symbolic link
|
||||
.Dq foo
|
||||
that points from
|
||||
.Pa /tmp/foo
|
||||
to
|
||||
.Pa / ,
|
||||
you would use
|
||||
.Nm
|
||||
as follows:
|
||||
.Bd -literal -offset indent
|
||||
\*[Gt] stat -F /tmp/foo
|
||||
lrwxrwxrwx 1 jschauma cs 1 Apr 24 16:37:28 2002 /tmp/foo@ -\*[Gt] /
|
||||
|
||||
\*[Gt] stat -LF /tmp/foo
|
||||
drwxr-xr-x 16 root wheel 512 Apr 19 10:57:54 2002 /tmp/foo/
|
||||
.Ed
|
||||
.Pp
|
||||
To initialize some shell-variables, you could use the
|
||||
.Fl s
|
||||
flag as follows:
|
||||
.Bd -literal -offset indent
|
||||
\*[Gt] csh
|
||||
% eval set `stat -s .cshrc`
|
||||
% echo $st_size $st_mtime
|
||||
1148 1015432481
|
||||
|
||||
\*[Gt] sh
|
||||
$ eval $(stat -s .profile)
|
||||
$ echo $st_size $st_mtime
|
||||
1148 1015432481
|
||||
.Ed
|
||||
.Pp
|
||||
In order to get a list of the kind of files including files pointed to if the
|
||||
file is a symbolic link, you could use the following format:
|
||||
.Bd -literal -offset indent
|
||||
$ stat -f "%N: %HT%SY" /tmp/*
|
||||
/tmp/bar: Symbolic Link -\*[Gt] /tmp/foo
|
||||
/tmp/output25568: Regular File
|
||||
/tmp/blah: Directory
|
||||
/tmp/foo: Symbolic Link -\*[Gt] /
|
||||
.Ed
|
||||
.Pp
|
||||
In order to get a list of the devices, their types and the major and minor
|
||||
device numbers, formatted with tabs and linebreaks, you could use the
|
||||
following format:
|
||||
.Bd -literal -offset indent
|
||||
stat -f "Name: %N%n%tType: %HT%n%tMajor: %Hr%n%tMinor: %Lr%n%n" /dev/*
|
||||
[...]
|
||||
Name: /dev/wt8
|
||||
Type: Block Device
|
||||
Major: 3
|
||||
Minor: 8
|
||||
|
||||
Name: /dev/zero
|
||||
Type: Character Device
|
||||
Major: 2
|
||||
Minor: 12
|
||||
.Ed
|
||||
.Pp
|
||||
In order to determine the permissions set on a file separately, you could use
|
||||
the following format:
|
||||
.Bd -literal -offset indent
|
||||
\*[Gt] stat -f "%Sp -\*[Gt] owner=%SHp group=%SMp other=%SLp" .
|
||||
drwxr-xr-x -\*[Gt] owner=rwx group=r-x other=r-x
|
||||
.Ed
|
||||
.Pp
|
||||
In order to determine the three files that have been modified most recently,
|
||||
you could use the following format:
|
||||
.Bd -literal -offset indent
|
||||
\*[Gt] stat -f "%m%t%Sm %N" /tmp/* | sort -rn | head -3 | cut -f2-
|
||||
Apr 25 11:47:00 2002 /tmp/blah
|
||||
Apr 25 10:36:34 2002 /tmp/bar
|
||||
Apr 24 16:47:35 2002 /tmp/foo
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr basename 1 ,
|
||||
.Xr dirname 1 ,
|
||||
.Xr file 1 ,
|
||||
.Xr ls 1 ,
|
||||
.Xr lstat 2 ,
|
||||
.Xr readlink 2 ,
|
||||
.Xr stat 2 ,
|
||||
.Xr printf 3 ,
|
||||
.Xr strftime 3
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility appeared in
|
||||
.Nx 1.6 .
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Andrew Brown
|
||||
.Aq atatat@NetBSD.org .
|
||||
This man page was written by
|
||||
.An Jan Schaumann
|
||||
.Aq jschauma@NetBSD.org .
|
1111
usr.bin/stat/stat.c
Normal file
1111
usr.bin/stat/stat.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue