Convert ls(1) to use libxo(3).
Obtained from: Phil Shafer <phil@juniper.net> Sponsored by: Juniper Networks, Inc.
This commit is contained in:
parent
458f2175ca
commit
52e4a08c45
@ -10,7 +10,7 @@ LIBADD= util
|
||||
.if !defined(RELEASE_CRUNCH) && \
|
||||
${MK_LS_COLORS} != no
|
||||
CFLAGS+= -DCOLORLS
|
||||
LIBADD+= termcapw
|
||||
LIBADD+= termcapw xo
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -45,14 +45,17 @@ int revsizecmp(const FTSENT *, const FTSENT *);
|
||||
|
||||
void printcol(const DISPLAY *);
|
||||
void printlong(const DISPLAY *);
|
||||
int printname(const char *);
|
||||
int printname(const char *, const char *);
|
||||
void printscol(const DISPLAY *);
|
||||
void printstream(const DISPLAY *);
|
||||
void usage(void);
|
||||
int prn_normal(const char *);
|
||||
int prn_normal(const char *, const char *);
|
||||
char * getname(const char *);
|
||||
size_t len_octal(const char *, int);
|
||||
int prn_octal(const char *);
|
||||
int prn_printable(const char *);
|
||||
int prn_octal(const char *, const char *);
|
||||
char * get_octal(const char *);
|
||||
int prn_printable(const char *, const char *);
|
||||
char * get_printable(const char *);
|
||||
#ifdef COLORLS
|
||||
void parsecolors(const char *cs);
|
||||
void colorquit(int);
|
||||
|
@ -32,7 +32,7 @@
|
||||
.\" @(#)ls.1 8.7 (Berkeley) 7/29/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 4, 2014
|
||||
.Dd June 8, 2015
|
||||
.Dt LS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -40,6 +40,7 @@
|
||||
.Nd list directory contents
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl -libxo
|
||||
.Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,
|
||||
.Op Fl D Ar format
|
||||
.Op Ar
|
||||
@ -797,9 +798,11 @@ specification.
|
||||
.Xr getfacl 1 ,
|
||||
.Xr sort 1 ,
|
||||
.Xr xterm 1 ,
|
||||
.Xr libxo 3 ,
|
||||
.Xr localeconv 3 ,
|
||||
.Xr strftime 3 ,
|
||||
.Xr strmode 3 ,
|
||||
.Xr xo_parse_args 3 ,
|
||||
.Xr termcap 5 ,
|
||||
.Xr maclabel 7 ,
|
||||
.Xr sticky 7 ,
|
||||
|
54
bin/ls/ls.c
54
bin/ls/ls.c
@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <termcap.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#include <libxo/xo.h>
|
||||
|
||||
#include "ls.h"
|
||||
#include "extern.h"
|
||||
@ -185,6 +186,12 @@ main(int argc, char *argv[])
|
||||
fts_options = FTS_PHYSICAL;
|
||||
if (getenv("LS_SAMESORT"))
|
||||
f_samesort = 1;
|
||||
|
||||
argc = xo_parse_args(argc, argv);
|
||||
if (argc < 0)
|
||||
return (1);
|
||||
xo_set_flags(NULL, XOF_COLUMNS);
|
||||
|
||||
while ((ch = getopt(argc, argv,
|
||||
"1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) {
|
||||
switch (ch) {
|
||||
@ -381,7 +388,7 @@ main(int argc, char *argv[])
|
||||
f_color = 1;
|
||||
}
|
||||
#else
|
||||
warnx("color support not compiled in");
|
||||
xo_warnx("color support not compiled in");
|
||||
#endif /*COLORLS*/
|
||||
|
||||
#ifdef COLORLS
|
||||
@ -479,10 +486,13 @@ main(int argc, char *argv[])
|
||||
else
|
||||
printfcn = printcol;
|
||||
|
||||
xo_open_container("file-information");
|
||||
if (argc)
|
||||
traverse(argc, argv, fts_options);
|
||||
else
|
||||
traverse(1, dotav, fts_options);
|
||||
xo_close_container("file-information");
|
||||
xo_finish();
|
||||
exit(rval);
|
||||
}
|
||||
|
||||
@ -500,10 +510,11 @@ traverse(int argc, char *argv[], int options)
|
||||
FTS *ftsp;
|
||||
FTSENT *p, *chp;
|
||||
int ch_options;
|
||||
int first = 1;
|
||||
|
||||
if ((ftsp =
|
||||
fts_open(argv, options, f_nosort ? NULL : mastercmp)) == NULL)
|
||||
err(1, "fts_open");
|
||||
xo_err(1, "fts_open");
|
||||
|
||||
/*
|
||||
* We ignore errors from fts_children here since they will be
|
||||
@ -525,11 +536,11 @@ traverse(int argc, char *argv[], int options)
|
||||
while ((p = fts_read(ftsp)) != NULL)
|
||||
switch (p->fts_info) {
|
||||
case FTS_DC:
|
||||
warnx("%s: directory causes a cycle", p->fts_name);
|
||||
xo_warnx("%s: directory causes a cycle", p->fts_name);
|
||||
break;
|
||||
case FTS_DNR:
|
||||
case FTS_ERR:
|
||||
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
|
||||
xo_warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
|
||||
rval = 1;
|
||||
break;
|
||||
case FTS_D:
|
||||
@ -537,31 +548,40 @@ traverse(int argc, char *argv[], int options)
|
||||
p->fts_name[0] == '.' && !f_listdot)
|
||||
break;
|
||||
|
||||
if (first) {
|
||||
first = 0;
|
||||
xo_open_list("directory");
|
||||
}
|
||||
xo_open_instance("directory");
|
||||
|
||||
/*
|
||||
* If already output something, put out a newline as
|
||||
* a separator. If multiple arguments, precede each
|
||||
* directory with its name.
|
||||
*/
|
||||
if (output) {
|
||||
putchar('\n');
|
||||
(void)printname(p->fts_path);
|
||||
puts(":");
|
||||
xo_emit("\n");
|
||||
(void)printname("path", p->fts_path);
|
||||
xo_emit(":\n");
|
||||
} else if (argc > 1) {
|
||||
(void)printname(p->fts_path);
|
||||
puts(":");
|
||||
(void)printname("path", p->fts_path);
|
||||
xo_emit(":\n");
|
||||
output = 1;
|
||||
}
|
||||
chp = fts_children(ftsp, ch_options);
|
||||
display(p, chp, options);
|
||||
|
||||
xo_close_instance("directory");
|
||||
if (!f_recursive && chp != NULL)
|
||||
(void)fts_set(ftsp, p, FTS_SKIP);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!first)
|
||||
xo_close_list("directory");
|
||||
if (errno)
|
||||
err(1, "fts_read");
|
||||
xo_err(1, "fts_read");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -608,7 +628,7 @@ display(const FTSENT *p, FTSENT *list, int options)
|
||||
/* Fill-in "::" as "0:0:0" for the sake of scanf. */
|
||||
jinitmax = malloc(strlen(initmax) * 2 + 2);
|
||||
if (jinitmax == NULL)
|
||||
err(1, "malloc");
|
||||
xo_err(1, "malloc");
|
||||
initmax2 = jinitmax;
|
||||
if (*initmax == ':')
|
||||
strcpy(initmax2, "0:"), initmax2 += 2;
|
||||
@ -679,7 +699,7 @@ display(const FTSENT *p, FTSENT *list, int options)
|
||||
flags = NULL;
|
||||
for (cur = list, entries = 0; cur; cur = cur->fts_link) {
|
||||
if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
|
||||
warnx("%s: %s",
|
||||
xo_warnx("%s: %s",
|
||||
cur->fts_name, strerror(cur->fts_errno));
|
||||
cur->fts_number = NO_PRINT;
|
||||
rval = 1;
|
||||
@ -745,7 +765,7 @@ display(const FTSENT *p, FTSENT *list, int options)
|
||||
flags = strdup("-");
|
||||
}
|
||||
if (flags == NULL)
|
||||
err(1, "fflagstostr");
|
||||
xo_err(1, "fflagstostr");
|
||||
flen = strlen(flags);
|
||||
if (flen > (size_t)maxflags)
|
||||
maxflags = flen;
|
||||
@ -759,7 +779,7 @@ display(const FTSENT *p, FTSENT *list, int options)
|
||||
|
||||
error = mac_prepare_file_label(&label);
|
||||
if (error == -1) {
|
||||
warn("MAC label for %s/%s",
|
||||
xo_warn("MAC label for %s/%s",
|
||||
cur->fts_parent->fts_path,
|
||||
cur->fts_name);
|
||||
goto label_out;
|
||||
@ -780,7 +800,7 @@ display(const FTSENT *p, FTSENT *list, int options)
|
||||
error = mac_get_link(name,
|
||||
label);
|
||||
if (error == -1) {
|
||||
warn("MAC label for %s/%s",
|
||||
xo_warn("MAC label for %s/%s",
|
||||
cur->fts_parent->fts_path,
|
||||
cur->fts_name);
|
||||
mac_free(label);
|
||||
@ -790,7 +810,7 @@ display(const FTSENT *p, FTSENT *list, int options)
|
||||
error = mac_to_text(label,
|
||||
&labelstr);
|
||||
if (error == -1) {
|
||||
warn("MAC label for %s/%s",
|
||||
xo_warn("MAC label for %s/%s",
|
||||
cur->fts_parent->fts_path,
|
||||
cur->fts_name);
|
||||
mac_free(label);
|
||||
@ -808,7 +828,7 @@ label_out:
|
||||
|
||||
if ((np = malloc(sizeof(NAMES) + labelstrlen +
|
||||
ulen + glen + flen + 4)) == NULL)
|
||||
err(1, "malloc");
|
||||
xo_err(1, "malloc");
|
||||
|
||||
np->user = &np->data[0];
|
||||
(void)strcpy(np->user, user);
|
||||
|
170
bin/ls/print.c
170
bin/ls/print.c
@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <termcap.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#include <libxo/xo.h>
|
||||
|
||||
#include "ls.h"
|
||||
#include "extern.h"
|
||||
@ -65,9 +66,9 @@ __FBSDID("$FreeBSD$");
|
||||
static int printaname(const FTSENT *, u_long, u_long);
|
||||
static void printdev(size_t, dev_t);
|
||||
static void printlink(const FTSENT *);
|
||||
static void printtime(time_t);
|
||||
static void printtime(const char *, time_t);
|
||||
static int printtype(u_int);
|
||||
static void printsize(size_t, off_t);
|
||||
static void printsize(const char *, size_t, off_t);
|
||||
#ifdef COLORLS
|
||||
static void endcolor(int);
|
||||
static int colortype(mode_t);
|
||||
@ -109,26 +110,46 @@ printscol(const DISPLAY *dp)
|
||||
{
|
||||
FTSENT *p;
|
||||
|
||||
xo_open_list("entry");
|
||||
for (p = dp->list; p; p = p->fts_link) {
|
||||
if (IS_NOPRINT(p))
|
||||
continue;
|
||||
xo_open_instance("entry");
|
||||
(void)printaname(p, dp->s_inode, dp->s_block);
|
||||
(void)putchar('\n');
|
||||
xo_close_instance("entry");
|
||||
xo_emit("\n");
|
||||
}
|
||||
xo_close_list("entry");
|
||||
}
|
||||
|
||||
/*
|
||||
* print name in current style
|
||||
*/
|
||||
int
|
||||
printname(const char *name)
|
||||
printname(const char *field, const char *name)
|
||||
{
|
||||
char fmt[BUFSIZ];
|
||||
char *s = getname(name);
|
||||
int rc;
|
||||
|
||||
snprintf(fmt, sizeof(fmt), "{:%s/%%hs}", field);
|
||||
rc = xo_emit(fmt, s);
|
||||
free(s);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* print name in current style
|
||||
*/
|
||||
char *
|
||||
getname(const char *name)
|
||||
{
|
||||
if (f_octal || f_octal_escape)
|
||||
return prn_octal(name);
|
||||
return get_octal(name);
|
||||
else if (f_nonprint)
|
||||
return prn_printable(name);
|
||||
return get_printable(name);
|
||||
else
|
||||
return prn_normal(name);
|
||||
return strdup(name);
|
||||
}
|
||||
|
||||
void
|
||||
@ -144,46 +165,59 @@ printlong(const DISPLAY *dp)
|
||||
|
||||
if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
|
||||
(f_longform || f_size)) {
|
||||
(void)printf("total %lu\n", howmany(dp->btotal, blocksize));
|
||||
xo_emit("{L:total} {:total-blocks/%lu}\n",
|
||||
howmany(dp->btotal, blocksize));
|
||||
}
|
||||
|
||||
xo_open_list("entry");
|
||||
for (p = dp->list; p; p = p->fts_link) {
|
||||
char *name;
|
||||
if (IS_NOPRINT(p))
|
||||
continue;
|
||||
xo_open_instance("entry");
|
||||
sp = p->fts_statp;
|
||||
name = getname(p->fts_name);
|
||||
if (name)
|
||||
xo_emit("{ke:name}", name);
|
||||
if (f_inode)
|
||||
(void)printf("%*ju ",
|
||||
xo_emit("{:inode/%*ju} ",
|
||||
dp->s_inode, (uintmax_t)sp->st_ino);
|
||||
if (f_size)
|
||||
(void)printf("%*jd ",
|
||||
xo_emit("{:blocks/%*jd} ",
|
||||
dp->s_block, howmany(sp->st_blocks, blocksize));
|
||||
strmode(sp->st_mode, buf);
|
||||
aclmode(buf, p);
|
||||
np = p->fts_pointer;
|
||||
(void)printf("%s %*u %-*s %-*s ", buf, dp->s_nlink,
|
||||
sp->st_nlink, dp->s_user, np->user, dp->s_group,
|
||||
np->group);
|
||||
xo_attr("value", "%03o", (int) sp->st_mode & ALLPERMS);
|
||||
xo_emit("{t:mode/%s} {:links/%*u} {:user/%-*s} {:group/%-*s} ",
|
||||
buf, dp->s_nlink, sp->st_nlink,
|
||||
dp->s_user, np->user, dp->s_group, np->group);
|
||||
if (f_flags)
|
||||
(void)printf("%-*s ", dp->s_flags, np->flags);
|
||||
xo_emit("{:flags/%-*s} ", dp->s_flags, np->flags);
|
||||
if (f_label)
|
||||
(void)printf("%-*s ", dp->s_label, np->label);
|
||||
xo_emit("{:label/%-*s} ", dp->s_label, np->label);
|
||||
if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
|
||||
printdev(dp->s_size, sp->st_rdev);
|
||||
else
|
||||
printsize(dp->s_size, sp->st_size);
|
||||
printsize("size", dp->s_size, sp->st_size);
|
||||
if (f_accesstime)
|
||||
printtime(sp->st_atime);
|
||||
printtime("access-time", sp->st_atime);
|
||||
else if (f_birthtime)
|
||||
printtime(sp->st_birthtime);
|
||||
printtime("birth-time", sp->st_birthtime);
|
||||
else if (f_statustime)
|
||||
printtime(sp->st_ctime);
|
||||
printtime("change-time", sp->st_ctime);
|
||||
else
|
||||
printtime(sp->st_mtime);
|
||||
printtime("modify-time", sp->st_mtime);
|
||||
#ifdef COLORLS
|
||||
if (f_color)
|
||||
color_printed = colortype(sp->st_mode);
|
||||
#endif
|
||||
(void)printname(p->fts_name);
|
||||
|
||||
if (name) {
|
||||
xo_emit("{dk:name}", name);
|
||||
free(name);
|
||||
}
|
||||
|
||||
#ifdef COLORLS
|
||||
if (f_color && color_printed)
|
||||
endcolor(0);
|
||||
@ -192,8 +226,10 @@ printlong(const DISPLAY *dp)
|
||||
(void)printtype(sp->st_mode);
|
||||
if (S_ISLNK(sp->st_mode))
|
||||
printlink(p);
|
||||
(void)putchar('\n');
|
||||
xo_close_instance("entry");
|
||||
xo_emit("\n");
|
||||
}
|
||||
xo_close_list("entry");
|
||||
}
|
||||
|
||||
void
|
||||
@ -208,17 +244,17 @@ printstream(const DISPLAY *dp)
|
||||
/* XXX strlen does not take octal escapes into account. */
|
||||
if (strlen(p->fts_name) + chcnt +
|
||||
(p->fts_link ? 2 : 0) >= (unsigned)termwidth) {
|
||||
putchar('\n');
|
||||
xo_emit("\n");
|
||||
chcnt = 0;
|
||||
}
|
||||
chcnt += printaname(p, dp->s_inode, dp->s_block);
|
||||
if (p->fts_link) {
|
||||
printf(", ");
|
||||
xo_emit(", ");
|
||||
chcnt += 2;
|
||||
}
|
||||
}
|
||||
if (chcnt)
|
||||
putchar('\n');
|
||||
xo_emit("\n");
|
||||
}
|
||||
|
||||
void
|
||||
@ -252,7 +288,7 @@ printcol(const DISPLAY *dp)
|
||||
if (dp->entries > lastentries) {
|
||||
if ((narray =
|
||||
realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
|
||||
warn(NULL);
|
||||
xo_warn(NULL);
|
||||
printscol(dp);
|
||||
return;
|
||||
}
|
||||
@ -283,17 +319,21 @@ printcol(const DISPLAY *dp)
|
||||
|
||||
if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
|
||||
(f_longform || f_size)) {
|
||||
(void)printf("total %lu\n", howmany(dp->btotal, blocksize));
|
||||
xo_emit("{L:total} {:total-blocks/%lu}\n",
|
||||
howmany(dp->btotal, blocksize));
|
||||
}
|
||||
|
||||
xo_open_list("entry");
|
||||
base = 0;
|
||||
for (row = 0; row < numrows; ++row) {
|
||||
endcol = colwidth;
|
||||
if (!f_sortacross)
|
||||
base = row;
|
||||
for (col = 0, chcnt = 0; col < numcols; ++col) {
|
||||
xo_open_instance("entry");
|
||||
chcnt += printaname(array[base], dp->s_inode,
|
||||
dp->s_block);
|
||||
xo_close_instance("entry");
|
||||
if (f_sortacross)
|
||||
base++;
|
||||
else
|
||||
@ -304,13 +344,14 @@ printcol(const DISPLAY *dp)
|
||||
<= endcol) {
|
||||
if (f_sortacross && col + 1 >= numcols)
|
||||
break;
|
||||
(void)putchar(f_notabs ? ' ' : '\t');
|
||||
xo_emit(f_notabs ? " " : "\t");
|
||||
chcnt = cnt;
|
||||
}
|
||||
endcol += colwidth;
|
||||
}
|
||||
(void)putchar('\n');
|
||||
xo_emit("\n");
|
||||
}
|
||||
xo_close_list("entry");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -329,16 +370,16 @@ printaname(const FTSENT *p, u_long inodefield, u_long sizefield)
|
||||
sp = p->fts_statp;
|
||||
chcnt = 0;
|
||||
if (f_inode)
|
||||
chcnt += printf("%*ju ",
|
||||
chcnt += xo_emit("{:inode/%*ju} ",
|
||||
(int)inodefield, (uintmax_t)sp->st_ino);
|
||||
if (f_size)
|
||||
chcnt += printf("%*jd ",
|
||||
chcnt += xo_emit("{:size/%*jd} ",
|
||||
(int)sizefield, howmany(sp->st_blocks, blocksize));
|
||||
#ifdef COLORLS
|
||||
if (f_color)
|
||||
color_printed = colortype(sp->st_mode);
|
||||
#endif
|
||||
chcnt += printname(p->fts_name);
|
||||
chcnt += printname("name", p->fts_name);
|
||||
#ifdef COLORLS
|
||||
if (f_color && color_printed)
|
||||
endcolor(0);
|
||||
@ -354,14 +395,14 @@ printaname(const FTSENT *p, u_long inodefield, u_long sizefield)
|
||||
static void
|
||||
printdev(size_t width, dev_t dev)
|
||||
{
|
||||
|
||||
(void)printf("%#*jx ", (u_int)width, (uintmax_t)dev);
|
||||
xo_emit("{:device/%#*jx} ", (u_int)width, (uintmax_t)dev);
|
||||
}
|
||||
|
||||
static void
|
||||
printtime(time_t ftime)
|
||||
printtime(const char *field, time_t ftime)
|
||||
{
|
||||
char longstring[80];
|
||||
char fmt[BUFSIZ];
|
||||
static time_t now = 0;
|
||||
const char *format;
|
||||
static int d_first = -1;
|
||||
@ -384,8 +425,10 @@ printtime(time_t ftime)
|
||||
/* mmm dd yyyy || dd mmm yyyy */
|
||||
format = d_first ? "%e %b %Y" : "%b %e %Y";
|
||||
strftime(longstring, sizeof(longstring), format, localtime(&ftime));
|
||||
fputs(longstring, stdout);
|
||||
fputc(' ', stdout);
|
||||
|
||||
snprintf(fmt, sizeof(fmt), "{:%s/%%s} ", field);
|
||||
xo_attr("value", "%ld", (long) ftime);
|
||||
xo_emit(fmt, longstring);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -394,7 +437,7 @@ printtype(u_int mode)
|
||||
|
||||
if (f_slash) {
|
||||
if ((mode & S_IFMT) == S_IFDIR) {
|
||||
(void)putchar('/');
|
||||
xo_emit("{D:\\/}{e:type/directory}");
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
@ -402,25 +445,25 @@ printtype(u_int mode)
|
||||
|
||||
switch (mode & S_IFMT) {
|
||||
case S_IFDIR:
|
||||
(void)putchar('/');
|
||||
xo_emit("{D:/\\/}{e:type/directory}");
|
||||
return (1);
|
||||
case S_IFIFO:
|
||||
(void)putchar('|');
|
||||
xo_emit("{D:|}{e:type/fifo}");
|
||||
return (1);
|
||||
case S_IFLNK:
|
||||
(void)putchar('@');
|
||||
xo_emit("{D:@}{e:type/link}");
|
||||
return (1);
|
||||
case S_IFSOCK:
|
||||
(void)putchar('=');
|
||||
xo_emit("{D:=}{e:type/socket}");
|
||||
return (1);
|
||||
case S_IFWHT:
|
||||
(void)putchar('%');
|
||||
xo_emit("{D:%}{e:type/whiteout}");
|
||||
return (1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
|
||||
(void)putchar('*');
|
||||
xo_emit("{D:*}{e:executable/}");
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
@ -430,7 +473,7 @@ printtype(u_int mode)
|
||||
static int
|
||||
putch(int c)
|
||||
{
|
||||
(void)putchar(c);
|
||||
xo_emit("{D:/%c}", c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -539,7 +582,7 @@ parsecolors(const char *cs)
|
||||
if (c[j] >= '0' && c[j] <= '7') {
|
||||
colors[i].num[j] = c[j] - '0';
|
||||
if (!legacy_warn) {
|
||||
warnx("LSCOLORS should use "
|
||||
xo_warnx("LSCOLORS should use "
|
||||
"characters a-h instead of 0-9 ("
|
||||
"see the manual page)");
|
||||
}
|
||||
@ -552,7 +595,7 @@ parsecolors(const char *cs)
|
||||
} else if (tolower((unsigned char)c[j]) == 'x')
|
||||
colors[i].num[j] = -1;
|
||||
else {
|
||||
warnx("invalid character '%c' in LSCOLORS"
|
||||
xo_warnx("invalid character '%c' in LSCOLORS"
|
||||
" env var", c[j]);
|
||||
colors[i].num[j] = -1;
|
||||
}
|
||||
@ -584,18 +627,19 @@ printlink(const FTSENT *p)
|
||||
(void)snprintf(name, sizeof(name),
|
||||
"%s/%s", p->fts_parent->fts_accpath, p->fts_name);
|
||||
if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
|
||||
(void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
|
||||
xo_error("\nls: %s: %s\n", name, strerror(errno));
|
||||
return;
|
||||
}
|
||||
path[lnklen] = '\0';
|
||||
(void)printf(" -> ");
|
||||
(void)printname(path);
|
||||
xo_emit(" -> ");
|
||||
(void)printname("target", path);
|
||||
}
|
||||
|
||||
static void
|
||||
printsize(size_t width, off_t bytes)
|
||||
printsize(const char *field, size_t width, off_t bytes)
|
||||
{
|
||||
|
||||
char fmt[BUFSIZ];
|
||||
|
||||
if (f_humanval) {
|
||||
/*
|
||||
* Reserve one space before the size and allocate room for
|
||||
@ -605,13 +649,15 @@ printsize(size_t width, off_t bytes)
|
||||
|
||||
humanize_number(buf, sizeof(buf), (int64_t)bytes, "",
|
||||
HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
|
||||
(void)printf("%*s ", (u_int)width, buf);
|
||||
} else if (f_thousands) { /* with commas */
|
||||
snprintf(fmt, sizeof(fmt), "{:%s/%%%ds} ", field, (int) width);
|
||||
xo_attr("value", "%jd", (intmax_t) bytes);
|
||||
xo_emit(fmt, buf);
|
||||
} else { /* with commas */
|
||||
/* This format assignment needed to work round gcc bug. */
|
||||
const char *format = "%*j'd ";
|
||||
(void)printf(format, (u_int)width, bytes);
|
||||
} else
|
||||
(void)printf("%*jd ", (u_int)width, bytes);
|
||||
snprintf(fmt, sizeof(fmt), "{:%s/%%%dj%sd} ",
|
||||
field, (int) width, f_thousands ? "'" : "");
|
||||
xo_emit(fmt, (intmax_t) bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -654,7 +700,7 @@ aclmode(char *buf, const FTSENT *p)
|
||||
type = ACL_TYPE_NFS4;
|
||||
supports_acls = 1;
|
||||
} else if (ret < 0 && errno != EINVAL) {
|
||||
warn("%s", name);
|
||||
xo_warn("%s", name);
|
||||
return;
|
||||
}
|
||||
if (supports_acls == 0) {
|
||||
@ -663,7 +709,7 @@ aclmode(char *buf, const FTSENT *p)
|
||||
type = ACL_TYPE_ACCESS;
|
||||
supports_acls = 1;
|
||||
} else if (ret < 0 && errno != EINVAL) {
|
||||
warn("%s", name);
|
||||
xo_warn("%s", name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -672,12 +718,12 @@ aclmode(char *buf, const FTSENT *p)
|
||||
return;
|
||||
facl = acl_get_link_np(name, type);
|
||||
if (facl == NULL) {
|
||||
warn("%s", name);
|
||||
xo_warn("%s", name);
|
||||
return;
|
||||
}
|
||||
if (acl_is_trivial_np(facl, &trivial)) {
|
||||
acl_free(facl);
|
||||
warn("%s", name);
|
||||
xo_warn("%s", name);
|
||||
return;
|
||||
}
|
||||
if (!trivial)
|
||||
|
@ -50,13 +50,19 @@ __FBSDID("$FreeBSD$");
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
#include <libxo/xo.h>
|
||||
|
||||
#include "ls.h"
|
||||
#include "extern.h"
|
||||
|
||||
int
|
||||
prn_normal(const char *s)
|
||||
prn_normal(const char *field, const char *s)
|
||||
{
|
||||
char fmt[_POSIX2_LINE_MAX];
|
||||
|
||||
snprintf(fmt, sizeof(fmt), "{:%s/%%hs}", field);
|
||||
return xo_emit(fmt, s);
|
||||
#if 0
|
||||
mbstate_t mbs;
|
||||
wchar_t wc;
|
||||
int i, n;
|
||||
@ -83,43 +89,47 @@ prn_normal(const char *s)
|
||||
n += wcwidth(wc);
|
||||
}
|
||||
return (n);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
prn_printable(const char *s)
|
||||
char *
|
||||
get_printable(const char *s)
|
||||
{
|
||||
mbstate_t mbs;
|
||||
wchar_t wc;
|
||||
int i, n;
|
||||
size_t clen;
|
||||
int slen = strlen(s);
|
||||
char *buf = alloca(slen + 1), *bp = buf;
|
||||
|
||||
memset(&mbs, 0, sizeof(mbs));
|
||||
n = 0;
|
||||
while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
|
||||
if (clen == (size_t)-1) {
|
||||
putchar('?');
|
||||
*bp++ = '?';
|
||||
s++;
|
||||
n++;
|
||||
memset(&mbs, 0, sizeof(mbs));
|
||||
continue;
|
||||
}
|
||||
if (clen == (size_t)-2) {
|
||||
putchar('?');
|
||||
*bp++ = '?';
|
||||
n++;
|
||||
break;
|
||||
}
|
||||
if (!iswprint(wc)) {
|
||||
putchar('?');
|
||||
*bp++ = '?';
|
||||
s += clen;
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < (int)clen; i++)
|
||||
putchar((unsigned char)s[i]);
|
||||
*bp++ = (unsigned char)s[i];
|
||||
s += clen;
|
||||
n += wcwidth(wc);
|
||||
}
|
||||
return (n);
|
||||
*bp = '\0';
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -165,8 +175,8 @@ len_octal(const char *s, int len)
|
||||
return (r);
|
||||
}
|
||||
|
||||
int
|
||||
prn_octal(const char *s)
|
||||
char *
|
||||
get_octal(const char *s)
|
||||
{
|
||||
static const char esc[] = "\\\\\"\"\aa\bb\ff\nn\rr\tt\vv";
|
||||
const char *p;
|
||||
@ -175,6 +185,8 @@ prn_octal(const char *s)
|
||||
size_t clen;
|
||||
unsigned char ch;
|
||||
int goodchar, i, len, prtlen;
|
||||
int slen = strlen(s);
|
||||
char *buf = alloca(slen * 4 + 1), *bp = buf;
|
||||
|
||||
memset(&mbs, 0, sizeof(mbs));
|
||||
len = 0;
|
||||
@ -182,7 +194,7 @@ prn_octal(const char *s)
|
||||
goodchar = clen != (size_t)-1 && clen != (size_t)-2;
|
||||
if (goodchar && iswprint(wc) && wc != L'\"' && wc != L'\\') {
|
||||
for (i = 0; i < (int)clen; i++)
|
||||
putchar((unsigned char)s[i]);
|
||||
*bp++ = (unsigned char)s[i];
|
||||
len += wcwidth(wc);
|
||||
} else if (goodchar && f_octal_escape &&
|
||||
#if WCHAR_MIN < 0
|
||||
@ -190,8 +202,8 @@ prn_octal(const char *s)
|
||||
#endif
|
||||
wc <= (wchar_t)UCHAR_MAX &&
|
||||
(p = strchr(esc, (char)wc)) != NULL) {
|
||||
putchar('\\');
|
||||
putchar(p[1]);
|
||||
*bp ++ = '\\';
|
||||
*bp++ = p[1];
|
||||
len += 2;
|
||||
} else {
|
||||
if (goodchar)
|
||||
@ -202,10 +214,10 @@ prn_octal(const char *s)
|
||||
prtlen = strlen(s);
|
||||
for (i = 0; i < prtlen; i++) {
|
||||
ch = (unsigned char)s[i];
|
||||
putchar('\\');
|
||||
putchar('0' + (ch >> 6));
|
||||
putchar('0' + ((ch >> 3) & 7));
|
||||
putchar('0' + (ch & 7));
|
||||
*bp++ = '\\';
|
||||
*bp++ = '0' + (ch >> 6);
|
||||
*bp++ = '0' + ((ch >> 3) & 7);
|
||||
*bp++ = '0' + (ch & 7);
|
||||
len += 4;
|
||||
}
|
||||
}
|
||||
@ -217,13 +229,15 @@ prn_octal(const char *s)
|
||||
} else
|
||||
s += clen;
|
||||
}
|
||||
return (len);
|
||||
|
||||
*bp = '\0';
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
xo_error(
|
||||
#ifdef COLORLS
|
||||
"usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
|
||||
#else
|
||||
|
Loading…
x
Reference in New Issue
Block a user