Module Name: src Committed By: apb Date: Thu Sep 22 20:23:56 UTC 2011
Modified Files: src/usr.bin/stat: stat.1 stat.c Log Message: Use vis(3) encoding when a string format is modified by the '#' flag. Also bump copyright years. To generate a diff of this commit: cvs rdiff -u -r1.33 -r1.34 src/usr.bin/stat/stat.1 cvs rdiff -u -r1.35 -r1.36 src/usr.bin/stat/stat.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/stat/stat.1 diff -u src/usr.bin/stat/stat.1:1.33 src/usr.bin/stat/stat.1:1.34 --- src/usr.bin/stat/stat.1:1.33 Fri Sep 16 14:32:53 2011 +++ src/usr.bin/stat/stat.1 Thu Sep 22 20:23:55 2011 @@ -1,6 +1,6 @@ -.\" $NetBSD: stat.1,v 1.33 2011/09/16 14:32:53 apb 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 September 16, 2011 +.Dd September 22, 2011 .Dt STAT 1 .Os .Sh NAME @@ -202,9 +202,12 @@ 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 + @@ -582,6 +585,18 @@ 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 , Index: src/usr.bin/stat/stat.c diff -u src/usr.bin/stat/stat.c:1.35 src/usr.bin/stat/stat.c:1.36 --- src/usr.bin/stat/stat.c:1.35 Tue Sep 6 18:31:22 2011 +++ src/usr.bin/stat/stat.c Thu Sep 22 20:23:56 2011 @@ -1,7 +1,7 @@ -/* $NetBSD: stat.c,v 1.35 2011/09/06 18:31:22 joerg 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 <sys/cdefs.h> #if !defined(lint) -__RCSID("$NetBSD: stat.c,v 1.35 2011/09/06 18:31:22 joerg Exp $"); +__RCSID("$NetBSD: stat.c,v 1.36 2011/09/22 20:23:56 apb Exp $"); #endif #if ! HAVE_NBTOOL_CONFIG_H @@ -61,6 +61,7 @@ #include <string.h> #include <time.h> #include <unistd.h> +#include <vis.h> #if HAVE_STRUCT_STAT_ST_FLAGS #define DEF_F "%#Xf " @@ -365,7 +366,12 @@ 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; @@ -436,6 +442,7 @@ * 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 { @@ -564,13 +571,18 @@ 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; @@ -578,6 +590,7 @@ secs = 0; nsecs = 0; shift = 0; + prefixlen = 0; /* * First, pick out the data and tweak it based on hilo or @@ -814,6 +827,7 @@ path[0] = '\0'; } sdata = path + (ofmt == FMTF_STRING ? 0 : 4); + prefixlen = (ofmt == FMTF_STRING ? 4 : 0); } formats = FMTF_STRING; @@ -835,6 +849,7 @@ } path[l + 4] = '\0'; sdata = path + (ofmt == FMTF_STRING ? 0 : 4); + prefixlen = (ofmt == FMTF_STRING ? 4 : 0); } else { linkfail = 1; @@ -978,6 +993,18 @@ 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). */ lfmt[0] = '\0';