diff --git a/releasetools/nbsd_ports b/releasetools/nbsd_ports index ae64d6ce9..62104e61d 100644 --- a/releasetools/nbsd_ports +++ b/releasetools/nbsd_ports @@ -228,7 +228,7 @@ 2012/10/17 12:00:00,usr.bin/soelim 2012/10/17 12:00:00,usr.bin/sort 2012/10/17 12:00:00,usr.bin/split -2011/01/15 22:54:10,usr.bin/stat +2012/10/17 12:00:00,usr.bin/stat 2012/02/10 16:16:12,usr.bin/su 2013/10/06 12:00:00,usr.bin/tee 2012/06/01 12:08:40,usr.bin/tic diff --git a/usr.bin/stat/stat.1 b/usr.bin/stat/stat.1 index 98c279576..6bbfc4eac 100644 --- a/usr.bin/stat/stat.1 +++ b/usr.bin/stat/stat.1 @@ -1,6 +1,6 @@ -.\" $NetBSD: stat.1,v 1.28 2010/04/05 21:25:01 joerg Exp $ +.\" $NetBSD: stat.1,v 1.34 2011/09/22 20:23:55 apb Exp $ .\" -.\" Copyright (c) 2002-2005 The NetBSD Foundation, Inc. +.\" Copyright (c) 2002-2011 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This code is derived from software contributed to The NetBSD Foundation @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd November 7, 2008 +.Dd September 22, 2011 .Dt STAT 1 .Os .Sh NAME @@ -47,7 +47,7 @@ .Op Fl t Ar timefmt .Op Ar .Nm readlink -.Op Fl fn +.Op Fl fnqsv .Op Ar .Sh DESCRIPTION The @@ -165,11 +165,16 @@ epoch, etc.) Display information in .Dq shell output , suitable for initializing variables. +When run as +.Nm readlink , +suppress error messages. .It Fl t Ar timefmt Display timestamps using the specified format. This format is passed directly to .Xr strftime 3 . +.It Fl v +Turn off quiet mode. .It Fl x Display information in a more verbose way as known from some Linux distributions. @@ -197,9 +202,12 @@ examined for the following: 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 +Selects an alternate output form for string, octal and hexadecimal output. +String output will be encoded in +.Xr vis 3 +style. +Non-zero octal output will have a leading zero. +Non-zero hexadecimal output will have .Dq 0x prepended to it. .It Cm + @@ -430,7 +438,7 @@ is given. The target of a symbolic link. .It Cm Z Expands to -.Dq major,minor +.Dq Ar major , Ns Ar minor from the rdev field for character or block special devices and gives size output for all others. .El @@ -468,6 +476,41 @@ If no options are specified, the default format is 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 +This example produces output very similar to that from +.Ic find ... -ls +(except that +.Xr find 1 +displays the time in a different format, and +.Xr find 1 +sometimes adds one or more spaces after the comma in +.Dq Ar major , Ns Ar minor +for device nodes): +.Bd -literal -offset indent +\*[Gt] stat -f "%7i %6b %-11Sp %3l %-17Su %-17Sg %9Z %Sm %N%SY" /tmp/bar + 78852 0 -rw-r--r-- 1 root wheel 0 Jul 8 10:26:03 2004 /tmp/bar + +\*[Gt] find /tmp/bar -ls -exit + 78852 0 -rw-r--r-- 1 root wheel 0 Jul 8 2004 /tmp/bar +.Ed +.Pp +This example produces output very similar to that from +.Ic ls -lTd +(except that +.Xr ls 1 +adjusts the column spacing differently when listing multiple files, +and +.Xr ls 1 +adds at least one space after the comma in +.Dq Ar major , Ns Ar minor +for device nodes): +.Bd -literal -offset indent +\*[Gt] stat -f "%-11Sp %l %Su %Sg %Z %Sm %N%SY" /tmp/bar +-rw-r--r-- 1 root wheel 0 Jul 8 10:26:03 2004 /tmp/bar + +\*[Gt] ls -lTd /tmp/bar +-rw-r--r-- 1 root wheel 0 Jul 8 10:26:03 2004 /tmp/bar +.Ed +.Pp Given a symbolic link .Dq foo that points from @@ -542,6 +585,18 @@ 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 +.Pp +User names, group names, and file names that contain spaces +or other special characters may be encoded in +.Xr vis 3 +style, using the +.Cm \&# +modifier: +.Bd -literal -offset indent +\*[Gt] ln -s 'target with spaces' 'link with spaces' +\*[Gt] stat -f "%#N%#SY" 'link with spaces' +link\eswith\esspaces -\*[Gt] target\eswith\esspaces +.Ed .Sh SEE ALSO .Xr basename 1 , .Xr dirname 1 , diff --git a/usr.bin/stat/stat.c b/usr.bin/stat/stat.c index 8beadb3bf..ec66fc0aa 100644 --- a/usr.bin/stat/stat.c +++ b/usr.bin/stat/stat.c @@ -1,7 +1,7 @@ -/* $NetBSD: stat.c,v 1.33 2011/01/15 22:54:10 njoly Exp $ */ +/* $NetBSD: stat.c,v 1.36 2011/09/22 20:23:56 apb Exp $ */ /* - * Copyright (c) 2002 The NetBSD Foundation, Inc. + * Copyright (c) 2002-2011 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -35,7 +35,7 @@ #include #if !defined(lint) -__RCSID("$NetBSD: stat.c,v 1.33 2011/01/15 22:54:10 njoly Exp $"); +__RCSID("$NetBSD: stat.c,v 1.36 2011/09/22 20:23:56 apb Exp $"); #endif #if ! HAVE_NBTOOL_CONFIG_H @@ -46,7 +46,7 @@ __RCSID("$NetBSD: stat.c,v 1.33 2011/01/15 22:54:10 njoly Exp $"); #define HAVE_STRUCT_STAT_ST_MTIMENSEC 1 #ifdef __minix /* Not supported in Minix. */ -#define HAVE_DEVNAME 0 +#define HAVE_DEVNAME 0 #else /* __minix */ #define HAVE_DEVNAME 1 #endif /* __minx */ @@ -66,6 +66,7 @@ __RCSID("$NetBSD: stat.c,v 1.33 2011/01/15 22:54:10 njoly Exp $"); #include #include #include +#include #if HAVE_STRUCT_STAT_ST_FLAGS #define DEF_F "%#Xf " @@ -179,18 +180,18 @@ __RCSID("$NetBSD: stat.c,v 1.33 2011/01/15 22:54:10 njoly Exp $"); #define SHOW_filename 'N' #define SHOW_sizerdev 'Z' -void usage(const char *); -void output(const struct stat *, const char *, - const char *, int, int); -int format1(const struct stat *, /* stat info */ +static void usage(const char *) __dead; +static void output(const struct stat *, const char *, + const char *, int, int, int); +static int format1(const struct stat *, /* stat info */ const char *, /* the file name */ const char *, int, /* the format string itself */ char *, size_t, /* a place to put the output */ int, int, int, int, /* the parsed format */ - int, int); + int, int, int); -const char *timefmt; -int linkfail; +static const char *timefmt; +static int linkfail; #define addchar(s, c, nl) \ do { \ @@ -216,10 +217,12 @@ main(int argc, char *argv[]) statfmt = NULL; timefmt = NULL; + setprogname(argv[0]); + if (strcmp(getprogname(), "readlink") == 0) { am_readlink = 1; - options = "fn"; - synopsis = "[-fn] [file ...]"; + options = "fnqsv"; + synopsis = "[-fnqsv] [file ...]"; statfmt = "%Y"; fmtchar = 'f'; quiet = 1; @@ -252,6 +255,11 @@ main(int argc, char *argv[]) case 'l': case 'r': case 's': + if (am_readlink) { + quiet = 1; + break; + } + /*FALLTHROUGH*/ case 'x': if (fmtchar != 0) errx(1, "can't use format '%c' with '%c'", @@ -261,6 +269,9 @@ main(int argc, char *argv[]) case 't': timefmt = optarg; break; + case 'v': + quiet = 0; + break; default: usage(synopsis); } @@ -334,7 +345,7 @@ main(int argc, char *argv[]) usestat ? "stat" : "lstat"); } else - output(&st, argv[0], statfmt, fn, nonl); + output(&st, argv[0], statfmt, fn, nonl, quiet); argv++; argc--; @@ -344,7 +355,7 @@ main(int argc, char *argv[]) return (am_readlink ? linkfail : errs); } -void +static void usage(const char *synopsis) { @@ -355,12 +366,17 @@ usage(const char *synopsis) /* * Parses a format string. */ -void +static void output(const struct stat *st, const char *file, - const char *statfmt, int fn, int nonl) + const char *statfmt, int fn, int nonl, int quiet) { int flags, size, prec, ofmt, hilo, what; - char buf[PATH_MAX + 4 + 1]; + /* + * buf size is enough for an item of length PATH_MAX, + * multiplied by 4 for vis encoding, plus 4 for symlink + * " -> " prefix, plus 1 for \0 terminator. + */ + char buf[PATH_MAX * 4 + 4 + 1]; const char *subfmt; int nl, t, i; @@ -431,6 +447,7 @@ output(const struct stat *st, const char *file, * the leading " -> " if STRING is explicitly specified. The * sizerdev datum will generate rdev output for character or * block devices, and size output for all others. + * For STRING output, the # format requests vis encoding. */ flags = 0; do { @@ -528,7 +545,7 @@ output(const struct stat *st, const char *file, file, subfmt, statfmt - subfmt, buf, sizeof(buf), - flags, size, prec, ofmt, hilo, what); + flags, size, prec, ofmt, hilo, what, quiet); for (i = 0; i < t && i < (int)(sizeof(buf) - 1); i++) addchar(stdout, buf[i], &nl); @@ -548,24 +565,29 @@ output(const struct stat *st, const char *file, /* * Arranges output according to a single parsed format substring. */ -int +static int format1(const struct stat *st, const char *file, const char *fmt, int flen, char *buf, size_t blen, int flags, int size, int prec, int ofmt, - int hilo, int what) + int hilo, int what, int quiet) { u_int64_t data; char *stmp, lfmt[24], tmp[20]; const char *sdata; - char smode[12], sid[12], path[PATH_MAX + 4]; + char smode[12], sid[12], path[PATH_MAX + 4], visbuf[PATH_MAX * 4 + 4]; struct passwd *pw; struct group *gr; struct tm *tm; time_t secs; long nsecs; - int l, small, formats, gottime, shift; + int l; + int formats; /* bitmap of allowed formats for this datum */ + int small; /* true if datum is a small integer */ + int gottime; /* true if secs and nsecs are valid */ + int shift; /* powers of 2 to scale numbers before printing */ + size_t prefixlen; /* length of constant prefix for string data */ formats = 0; small = 0; @@ -573,6 +595,7 @@ format1(const struct stat *st, secs = 0; nsecs = 0; shift = 0; + prefixlen = 0; /* * First, pick out the data and tweak it based on hilo or @@ -802,11 +825,14 @@ format1(const struct stat *st, } else { snprintf(path, sizeof(path), " -> "); if (realpath(file, path + 4) == NULL) { + if (!quiet) + warn("realpath `%s'", file); linkfail = 1; l = 0; path[0] = '\0'; } sdata = path + (ofmt == FMTF_STRING ? 0 : 4); + prefixlen = (ofmt == FMTF_STRING ? 4 : 0); } formats = FMTF_STRING; @@ -820,12 +846,15 @@ format1(const struct stat *st, snprintf(path, sizeof(path), " -> "); l = readlink(file, path + 4, sizeof(path) - 4 - 1); if (l == -1) { + if (!quiet) + warn("readlink `%s'", file); linkfail = 1; l = 0; path[0] = '\0'; } path[l + 4] = '\0'; sdata = path + (ofmt == FMTF_STRING ? 0 : 4); + prefixlen = (ofmt == FMTF_STRING ? 4 : 0); } else { linkfail = 1; @@ -938,13 +967,13 @@ format1(const struct stat *st, fmt, flen, majdev, sizeof(majdev), flags, size, prec, - ofmt, HIGH_PIECE, SHOW_st_rdev); + ofmt, HIGH_PIECE, SHOW_st_rdev, quiet); l2 = format1(st, file, fmt, flen, mindev, sizeof(mindev), flags, size, prec, - ofmt, LOW_PIECE, SHOW_st_rdev); + ofmt, LOW_PIECE, SHOW_st_rdev, quiet); return (snprintf(buf, blen, "%.*s,%.*s", l1, majdev, l2, mindev)); } @@ -954,7 +983,7 @@ format1(const struct stat *st, fmt, flen, buf, blen, flags, size, prec, - ofmt, 0, SHOW_st_size)); + ofmt, 0, SHOW_st_size, quiet)); } /*NOTREACHED*/ default: @@ -968,6 +997,18 @@ format1(const struct stat *st, if (hilo != 0 || (ofmt & formats) == 0) errx(1, "%.*s: bad format", (int)flen, fmt); + /* + * FLAG_POUND with FMTF_STRING means use vis(3) encoding. + * First prefixlen chars are not encoded. + */ + if ((flags & FLAG_POUND) != 0 && ofmt == FMTF_STRING) { + flags &= !FLAG_POUND; + strncpy(visbuf, sdata, prefixlen); + strnvis(visbuf + prefixlen, sizeof(visbuf) - prefixlen, + sdata + prefixlen, VIS_WHITE | VIS_OCTAL | VIS_CSTYLE); + sdata = visbuf; + } + /* * Assemble the format string for passing to printf(3). */