Convert ls(1) to not use libxo(3)
libxo imposes a large burden on system utilities. In the case of ls, that burden is difficult to justify -- any language that can interact with json output can use readdir(3) and stat(2). Logically, this reverts r291607, r285857, r285803, r285734, r285425, r284494, r284489, r284252, and r284198. Kyua tests continue to pass (libxo integration was entirely untested). Reported by: many Reviewed by: imp Discussed with: manu, bdrewery Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D13959
This commit is contained in:
parent
b1288166e0
commit
0fdf7fa846
@ -6,7 +6,7 @@
|
|||||||
PACKAGE=runtime
|
PACKAGE=runtime
|
||||||
PROG= ls
|
PROG= ls
|
||||||
SRCS= cmp.c ls.c print.c util.c
|
SRCS= cmp.c ls.c print.c util.c
|
||||||
LIBADD= xo util
|
LIBADD= util
|
||||||
|
|
||||||
.if !defined(RELEASE_CRUNCH) && \
|
.if !defined(RELEASE_CRUNCH) && \
|
||||||
${MK_LS_COLORS} != no
|
${MK_LS_COLORS} != no
|
||||||
|
@ -9,7 +9,6 @@ DIRDEPS = \
|
|||||||
lib/libc \
|
lib/libc \
|
||||||
lib/libcompiler_rt \
|
lib/libcompiler_rt \
|
||||||
lib/libutil \
|
lib/libutil \
|
||||||
lib/libxo \
|
|
||||||
lib/ncurses/ncursesw \
|
lib/ncurses/ncursesw \
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,17 +47,14 @@ int revsizecmp(const FTSENT *, const FTSENT *);
|
|||||||
|
|
||||||
void printcol(const DISPLAY *);
|
void printcol(const DISPLAY *);
|
||||||
void printlong(const DISPLAY *);
|
void printlong(const DISPLAY *);
|
||||||
int printname(const char *, const char *);
|
int printname(const char *);
|
||||||
void printscol(const DISPLAY *);
|
void printscol(const DISPLAY *);
|
||||||
void printstream(const DISPLAY *);
|
void printstream(const DISPLAY *);
|
||||||
void usage(void);
|
void usage(void);
|
||||||
int prn_normal(const char *, const char *);
|
int prn_normal(const char *);
|
||||||
char * getname(const char *);
|
|
||||||
size_t len_octal(const char *, int);
|
size_t len_octal(const char *, int);
|
||||||
int prn_octal(const char *, const char *);
|
int prn_octal(const char *);
|
||||||
char * get_octal(const char *);
|
int prn_printable(const char *);
|
||||||
int prn_printable(const char *, const char *);
|
|
||||||
char * get_printable(const char *);
|
|
||||||
#ifdef COLORLS
|
#ifdef COLORLS
|
||||||
void parsecolors(const char *cs);
|
void parsecolors(const char *cs);
|
||||||
void colorquit(int);
|
void colorquit(int);
|
||||||
|
12
bin/ls/ls.1
12
bin/ls/ls.1
@ -32,7 +32,7 @@
|
|||||||
.\" @(#)ls.1 8.7 (Berkeley) 7/29/94
|
.\" @(#)ls.1 8.7 (Berkeley) 7/29/94
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd December 1, 2015
|
.Dd January 17, 2018
|
||||||
.Dt LS 1
|
.Dt LS 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -40,7 +40,6 @@
|
|||||||
.Nd list directory contents
|
.Nd list directory contents
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl -libxo
|
|
||||||
.Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,
|
.Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,
|
||||||
.Op Fl D Ar format
|
.Op Fl D Ar format
|
||||||
.Op Ar
|
.Op Ar
|
||||||
@ -69,13 +68,6 @@ lexicographical order.
|
|||||||
.Pp
|
.Pp
|
||||||
The following options are available:
|
The following options are available:
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Fl -libxo
|
|
||||||
Generate output via
|
|
||||||
.Xr libxo 3
|
|
||||||
in a selection of different human and machine readable formats.
|
|
||||||
See
|
|
||||||
.Xr xo_parse_args 3
|
|
||||||
for details on command line arguments.
|
|
||||||
.It Fl A
|
.It Fl A
|
||||||
Include directory entries whose names begin with a
|
Include directory entries whose names begin with a
|
||||||
dot
|
dot
|
||||||
@ -805,11 +797,9 @@ specification.
|
|||||||
.Xr getfacl 1 ,
|
.Xr getfacl 1 ,
|
||||||
.Xr sort 1 ,
|
.Xr sort 1 ,
|
||||||
.Xr xterm 1 ,
|
.Xr xterm 1 ,
|
||||||
.Xr libxo 3 ,
|
|
||||||
.Xr localeconv 3 ,
|
.Xr localeconv 3 ,
|
||||||
.Xr strftime 3 ,
|
.Xr strftime 3 ,
|
||||||
.Xr strmode 3 ,
|
.Xr strmode 3 ,
|
||||||
.Xr xo_parse_args 3 ,
|
|
||||||
.Xr termcap 5 ,
|
.Xr termcap 5 ,
|
||||||
.Xr maclabel 7 ,
|
.Xr maclabel 7 ,
|
||||||
.Xr sticky 7 ,
|
.Xr sticky 7 ,
|
||||||
|
57
bin/ls/ls.c
57
bin/ls/ls.c
@ -68,7 +68,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <termcap.h>
|
#include <termcap.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#endif
|
#endif
|
||||||
#include <libxo/xo.h>
|
|
||||||
|
|
||||||
#include "ls.h"
|
#include "ls.h"
|
||||||
#include "extern.h"
|
#include "extern.h"
|
||||||
@ -121,7 +120,7 @@ static int f_nofollow; /* don't follow symbolic link arguments */
|
|||||||
int f_nonprint; /* show unprintables as ? */
|
int f_nonprint; /* show unprintables as ? */
|
||||||
static int f_nosort; /* don't sort output */
|
static int f_nosort; /* don't sort output */
|
||||||
int f_notabs; /* don't use tab-separated multi-col output */
|
int f_notabs; /* don't use tab-separated multi-col output */
|
||||||
int f_numericonly; /* don't convert uid/gid to name */
|
static int f_numericonly; /* don't convert uid/gid to name */
|
||||||
int f_octal; /* show unprintables as \xxx */
|
int f_octal; /* show unprintables as \xxx */
|
||||||
int f_octal_escape; /* like f_octal but use C escapes if possible */
|
int f_octal_escape; /* like f_octal but use C escapes if possible */
|
||||||
static int f_recursive; /* ls subdirectories also */
|
static int f_recursive; /* ls subdirectories also */
|
||||||
@ -192,13 +191,6 @@ main(int argc, char *argv[])
|
|||||||
fts_options = FTS_PHYSICAL;
|
fts_options = FTS_PHYSICAL;
|
||||||
if (getenv("LS_SAMESORT"))
|
if (getenv("LS_SAMESORT"))
|
||||||
f_samesort = 1;
|
f_samesort = 1;
|
||||||
|
|
||||||
argc = xo_parse_args(argc, argv);
|
|
||||||
if (argc < 0)
|
|
||||||
return (1);
|
|
||||||
xo_set_flags(NULL, XOF_COLUMNS);
|
|
||||||
xo_set_version(LS_XO_VERSION);
|
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv,
|
while ((ch = getopt(argc, argv,
|
||||||
"1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) {
|
"1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
@ -395,7 +387,7 @@ main(int argc, char *argv[])
|
|||||||
f_color = 1;
|
f_color = 1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
xo_warnx("color support not compiled in");
|
warnx("color support not compiled in");
|
||||||
#endif /*COLORLS*/
|
#endif /*COLORLS*/
|
||||||
|
|
||||||
#ifdef COLORLS
|
#ifdef COLORLS
|
||||||
@ -493,13 +485,10 @@ main(int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
printfcn = printcol;
|
printfcn = printcol;
|
||||||
|
|
||||||
xo_open_container("file-information");
|
|
||||||
if (argc)
|
if (argc)
|
||||||
traverse(argc, argv, fts_options);
|
traverse(argc, argv, fts_options);
|
||||||
else
|
else
|
||||||
traverse(1, dotav, fts_options);
|
traverse(1, dotav, fts_options);
|
||||||
xo_close_container("file-information");
|
|
||||||
xo_finish();
|
|
||||||
exit(rval);
|
exit(rval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,11 +506,10 @@ traverse(int argc, char *argv[], int options)
|
|||||||
FTS *ftsp;
|
FTS *ftsp;
|
||||||
FTSENT *p, *chp;
|
FTSENT *p, *chp;
|
||||||
int ch_options;
|
int ch_options;
|
||||||
int first = 1;
|
|
||||||
|
|
||||||
if ((ftsp =
|
if ((ftsp =
|
||||||
fts_open(argv, options, f_nosort ? NULL : mastercmp)) == NULL)
|
fts_open(argv, options, f_nosort ? NULL : mastercmp)) == NULL)
|
||||||
xo_err(1, "fts_open");
|
err(1, "fts_open");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We ignore errors from fts_children here since they will be
|
* We ignore errors from fts_children here since they will be
|
||||||
@ -543,11 +531,11 @@ traverse(int argc, char *argv[], int options)
|
|||||||
while ((p = fts_read(ftsp)) != NULL)
|
while ((p = fts_read(ftsp)) != NULL)
|
||||||
switch (p->fts_info) {
|
switch (p->fts_info) {
|
||||||
case FTS_DC:
|
case FTS_DC:
|
||||||
xo_warnx("%s: directory causes a cycle", p->fts_name);
|
warnx("%s: directory causes a cycle", p->fts_name);
|
||||||
break;
|
break;
|
||||||
case FTS_DNR:
|
case FTS_DNR:
|
||||||
case FTS_ERR:
|
case FTS_ERR:
|
||||||
xo_warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
|
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
|
||||||
rval = 1;
|
rval = 1;
|
||||||
break;
|
break;
|
||||||
case FTS_D:
|
case FTS_D:
|
||||||
@ -555,40 +543,31 @@ traverse(int argc, char *argv[], int options)
|
|||||||
p->fts_name[0] == '.' && !f_listdot)
|
p->fts_name[0] == '.' && !f_listdot)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (first) {
|
|
||||||
first = 0;
|
|
||||||
xo_open_list("directory");
|
|
||||||
}
|
|
||||||
xo_open_instance("directory");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If already output something, put out a newline as
|
* If already output something, put out a newline as
|
||||||
* a separator. If multiple arguments, precede each
|
* a separator. If multiple arguments, precede each
|
||||||
* directory with its name.
|
* directory with its name.
|
||||||
*/
|
*/
|
||||||
if (output) {
|
if (output) {
|
||||||
xo_emit("\n");
|
putchar('\n');
|
||||||
(void)printname("path", p->fts_path);
|
(void)printname(p->fts_path);
|
||||||
xo_emit(":\n");
|
puts(":");
|
||||||
} else if (argc > 1) {
|
} else if (argc > 1) {
|
||||||
(void)printname("path", p->fts_path);
|
(void)printname(p->fts_path);
|
||||||
xo_emit(":\n");
|
puts(":");
|
||||||
output = 1;
|
output = 1;
|
||||||
}
|
}
|
||||||
chp = fts_children(ftsp, ch_options);
|
chp = fts_children(ftsp, ch_options);
|
||||||
display(p, chp, options);
|
display(p, chp, options);
|
||||||
|
|
||||||
xo_close_instance("directory");
|
|
||||||
if (!f_recursive && chp != NULL)
|
if (!f_recursive && chp != NULL)
|
||||||
(void)fts_set(ftsp, p, FTS_SKIP);
|
(void)fts_set(ftsp, p, FTS_SKIP);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!first)
|
|
||||||
xo_close_list("directory");
|
|
||||||
if (errno)
|
if (errno)
|
||||||
xo_err(1, "fts_read");
|
err(1, "fts_read");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -635,7 +614,7 @@ display(const FTSENT *p, FTSENT *list, int options)
|
|||||||
/* Fill-in "::" as "0:0:0" for the sake of scanf. */
|
/* Fill-in "::" as "0:0:0" for the sake of scanf. */
|
||||||
jinitmax = malloc(strlen(initmax) * 2 + 2);
|
jinitmax = malloc(strlen(initmax) * 2 + 2);
|
||||||
if (jinitmax == NULL)
|
if (jinitmax == NULL)
|
||||||
xo_err(1, "malloc");
|
err(1, "malloc");
|
||||||
initmax2 = jinitmax;
|
initmax2 = jinitmax;
|
||||||
if (*initmax == ':')
|
if (*initmax == ':')
|
||||||
strcpy(initmax2, "0:"), initmax2 += 2;
|
strcpy(initmax2, "0:"), initmax2 += 2;
|
||||||
@ -706,7 +685,7 @@ display(const FTSENT *p, FTSENT *list, int options)
|
|||||||
flags = NULL;
|
flags = NULL;
|
||||||
for (cur = list, entries = 0; cur; cur = cur->fts_link) {
|
for (cur = list, entries = 0; cur; cur = cur->fts_link) {
|
||||||
if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
|
if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
|
||||||
xo_warnx("%s: %s",
|
warnx("%s: %s",
|
||||||
cur->fts_name, strerror(cur->fts_errno));
|
cur->fts_name, strerror(cur->fts_errno));
|
||||||
cur->fts_number = NO_PRINT;
|
cur->fts_number = NO_PRINT;
|
||||||
rval = 1;
|
rval = 1;
|
||||||
@ -772,7 +751,7 @@ display(const FTSENT *p, FTSENT *list, int options)
|
|||||||
flags = strdup("-");
|
flags = strdup("-");
|
||||||
}
|
}
|
||||||
if (flags == NULL)
|
if (flags == NULL)
|
||||||
xo_err(1, "fflagstostr");
|
err(1, "fflagstostr");
|
||||||
flen = strlen(flags);
|
flen = strlen(flags);
|
||||||
if (flen > (size_t)maxflags)
|
if (flen > (size_t)maxflags)
|
||||||
maxflags = flen;
|
maxflags = flen;
|
||||||
@ -786,7 +765,7 @@ display(const FTSENT *p, FTSENT *list, int options)
|
|||||||
|
|
||||||
error = mac_prepare_file_label(&label);
|
error = mac_prepare_file_label(&label);
|
||||||
if (error == -1) {
|
if (error == -1) {
|
||||||
xo_warn("MAC label for %s/%s",
|
warn("MAC label for %s/%s",
|
||||||
cur->fts_parent->fts_path,
|
cur->fts_parent->fts_path,
|
||||||
cur->fts_name);
|
cur->fts_name);
|
||||||
goto label_out;
|
goto label_out;
|
||||||
@ -807,7 +786,7 @@ display(const FTSENT *p, FTSENT *list, int options)
|
|||||||
error = mac_get_link(name,
|
error = mac_get_link(name,
|
||||||
label);
|
label);
|
||||||
if (error == -1) {
|
if (error == -1) {
|
||||||
xo_warn("MAC label for %s/%s",
|
warn("MAC label for %s/%s",
|
||||||
cur->fts_parent->fts_path,
|
cur->fts_parent->fts_path,
|
||||||
cur->fts_name);
|
cur->fts_name);
|
||||||
mac_free(label);
|
mac_free(label);
|
||||||
@ -817,7 +796,7 @@ display(const FTSENT *p, FTSENT *list, int options)
|
|||||||
error = mac_to_text(label,
|
error = mac_to_text(label,
|
||||||
&labelstr);
|
&labelstr);
|
||||||
if (error == -1) {
|
if (error == -1) {
|
||||||
xo_warn("MAC label for %s/%s",
|
warn("MAC label for %s/%s",
|
||||||
cur->fts_parent->fts_path,
|
cur->fts_parent->fts_path,
|
||||||
cur->fts_name);
|
cur->fts_name);
|
||||||
mac_free(label);
|
mac_free(label);
|
||||||
@ -835,7 +814,7 @@ label_out:
|
|||||||
|
|
||||||
if ((np = malloc(sizeof(NAMES) + labelstrlen +
|
if ((np = malloc(sizeof(NAMES) + labelstrlen +
|
||||||
ulen + glen + flen + 4)) == NULL)
|
ulen + glen + flen + 4)) == NULL)
|
||||||
xo_err(1, "malloc");
|
err(1, "malloc");
|
||||||
|
|
||||||
np->user = &np->data[0];
|
np->user = &np->data[0];
|
||||||
(void)strcpy(np->user, user);
|
(void)strcpy(np->user, user);
|
||||||
|
@ -39,8 +39,6 @@
|
|||||||
|
|
||||||
#define HUMANVALSTR_LEN 5
|
#define HUMANVALSTR_LEN 5
|
||||||
|
|
||||||
#define LS_XO_VERSION "1"
|
|
||||||
|
|
||||||
extern long blocksize; /* block size units */
|
extern long blocksize; /* block size units */
|
||||||
|
|
||||||
extern int f_accesstime; /* use time of last access */
|
extern int f_accesstime; /* use time of last access */
|
||||||
@ -62,7 +60,6 @@ extern int f_statustime; /* use time of last mode change */
|
|||||||
extern int f_thousands; /* show file sizes with thousands separators */
|
extern int f_thousands; /* show file sizes with thousands separators */
|
||||||
extern char *f_timeformat; /* user-specified time format */
|
extern char *f_timeformat; /* user-specified time format */
|
||||||
extern int f_notabs; /* don't use tab-separated multi-col output */
|
extern int f_notabs; /* don't use tab-separated multi-col output */
|
||||||
extern int f_numericonly; /* don't convert uid/gid to name */
|
|
||||||
extern int f_type; /* add type character for non-regular files */
|
extern int f_type; /* add type character for non-regular files */
|
||||||
#ifdef COLORLS
|
#ifdef COLORLS
|
||||||
extern int f_color; /* add type in color for non-regular files */
|
extern int f_color; /* add type in color for non-regular files */
|
||||||
|
205
bin/ls/print.c
205
bin/ls/print.c
@ -62,7 +62,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <termcap.h>
|
#include <termcap.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#endif
|
#endif
|
||||||
#include <libxo/xo.h>
|
|
||||||
|
|
||||||
#include "ls.h"
|
#include "ls.h"
|
||||||
#include "extern.h"
|
#include "extern.h"
|
||||||
@ -70,9 +69,9 @@ __FBSDID("$FreeBSD$");
|
|||||||
static int printaname(const FTSENT *, u_long, u_long);
|
static int printaname(const FTSENT *, u_long, u_long);
|
||||||
static void printdev(size_t, dev_t);
|
static void printdev(size_t, dev_t);
|
||||||
static void printlink(const FTSENT *);
|
static void printlink(const FTSENT *);
|
||||||
static void printtime(const char *, time_t);
|
static void printtime(time_t);
|
||||||
static int printtype(u_int);
|
static int printtype(u_int);
|
||||||
static void printsize(const char *, size_t, off_t);
|
static void printsize(size_t, off_t);
|
||||||
#ifdef COLORLS
|
#ifdef COLORLS
|
||||||
static void endcolor(int);
|
static void endcolor(int);
|
||||||
static int colortype(mode_t);
|
static int colortype(mode_t);
|
||||||
@ -117,32 +116,26 @@ printscol(const DISPLAY *dp)
|
|||||||
{
|
{
|
||||||
FTSENT *p;
|
FTSENT *p;
|
||||||
|
|
||||||
xo_open_list("entry");
|
|
||||||
for (p = dp->list; p; p = p->fts_link) {
|
for (p = dp->list; p; p = p->fts_link) {
|
||||||
if (IS_NOPRINT(p))
|
if (IS_NOPRINT(p))
|
||||||
continue;
|
continue;
|
||||||
xo_open_instance("entry");
|
|
||||||
(void)printaname(p, dp->s_inode, dp->s_block);
|
(void)printaname(p, dp->s_inode, dp->s_block);
|
||||||
xo_close_instance("entry");
|
(void)putchar('\n');
|
||||||
xo_emit("\n");
|
|
||||||
}
|
}
|
||||||
xo_close_list("entry");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* print name in current style
|
* print name in current style
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
printname(const char *field, const char *name)
|
printname(const char *name)
|
||||||
{
|
{
|
||||||
char fmt[BUFSIZ];
|
if (f_octal || f_octal_escape)
|
||||||
char *s = getname(name);
|
return prn_octal(name);
|
||||||
int rc;
|
else if (f_nonprint)
|
||||||
|
return prn_printable(name);
|
||||||
snprintf(fmt, sizeof(fmt), "{:%s/%%hs}", field);
|
else
|
||||||
rc = xo_emit(fmt, s);
|
return prn_normal(name);
|
||||||
free(s);
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
@ -209,20 +202,6 @@ compute_abbreviated_month_size(void)
|
|||||||
padding_for_month[i] = month_max_size - months_width[i];
|
padding_for_month[i] = month_max_size - months_width[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* print name in current style
|
|
||||||
*/
|
|
||||||
char *
|
|
||||||
getname(const char *name)
|
|
||||||
{
|
|
||||||
if (f_octal || f_octal_escape)
|
|
||||||
return get_octal(name);
|
|
||||||
else if (f_nonprint)
|
|
||||||
return get_printable(name);
|
|
||||||
else
|
|
||||||
return strdup(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
printlong(const DISPLAY *dp)
|
printlong(const DISPLAY *dp)
|
||||||
{
|
{
|
||||||
@ -236,83 +215,46 @@ printlong(const DISPLAY *dp)
|
|||||||
|
|
||||||
if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
|
if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
|
||||||
(f_longform || f_size)) {
|
(f_longform || f_size)) {
|
||||||
xo_emit("{L:total} {:total-blocks/%lu}\n",
|
(void)printf("total %lu\n", howmany(dp->btotal, blocksize));
|
||||||
howmany(dp->btotal, blocksize));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xo_open_list("entry");
|
|
||||||
for (p = dp->list; p; p = p->fts_link) {
|
for (p = dp->list; p; p = p->fts_link) {
|
||||||
char *name, *type;
|
|
||||||
if (IS_NOPRINT(p))
|
if (IS_NOPRINT(p))
|
||||||
continue;
|
continue;
|
||||||
xo_open_instance("entry");
|
|
||||||
sp = p->fts_statp;
|
sp = p->fts_statp;
|
||||||
name = getname(p->fts_name);
|
|
||||||
if (name)
|
|
||||||
xo_emit("{ke:name/%hs}", name);
|
|
||||||
if (f_inode)
|
if (f_inode)
|
||||||
xo_emit("{t:inode/%*ju} ",
|
(void)printf("%*ju ",
|
||||||
dp->s_inode, (uintmax_t)sp->st_ino);
|
dp->s_inode, (uintmax_t)sp->st_ino);
|
||||||
if (f_size)
|
if (f_size)
|
||||||
xo_emit("{t:blocks/%*jd} ",
|
(void)printf("%*jd ",
|
||||||
dp->s_block, howmany(sp->st_blocks, blocksize));
|
dp->s_block, howmany(sp->st_blocks, blocksize));
|
||||||
strmode(sp->st_mode, buf);
|
strmode(sp->st_mode, buf);
|
||||||
aclmode(buf, p);
|
aclmode(buf, p);
|
||||||
np = p->fts_pointer;
|
np = p->fts_pointer;
|
||||||
xo_attr("value", "%03o", (int) sp->st_mode & ALLPERMS);
|
(void)printf("%s %*ju %-*s %-*s ", buf, dp->s_nlink,
|
||||||
if (f_numericonly) {
|
(uintmax_t)sp->st_nlink, dp->s_user, np->user, dp->s_group,
|
||||||
xo_emit("{t:mode/%s}{e:mode_octal/%03o} {t:links/%*ju} {td:user/%-*s}{e:user/%ju} {td:group/%-*s}{e:group/%ju} ",
|
np->group);
|
||||||
buf, (int) sp->st_mode & ALLPERMS, dp->s_nlink, (uintmax_t)sp->st_nlink,
|
|
||||||
dp->s_user, np->user, (uintmax_t)sp->st_uid, dp->s_group, np->group, (uintmax_t)sp->st_gid);
|
|
||||||
} else {
|
|
||||||
xo_emit("{t:mode/%s}{e:mode_octal/%03o} {t:links/%*ju} {t:user/%-*s} {t:group/%-*s} ",
|
|
||||||
buf, (int) sp->st_mode & ALLPERMS, dp->s_nlink, (uintmax_t)sp->st_nlink,
|
|
||||||
dp->s_user, np->user, dp->s_group, np->group);
|
|
||||||
}
|
|
||||||
if (S_ISBLK(sp->st_mode))
|
|
||||||
asprintf(&type, "block");
|
|
||||||
if (S_ISCHR(sp->st_mode))
|
|
||||||
asprintf(&type, "character");
|
|
||||||
if (S_ISDIR(sp->st_mode))
|
|
||||||
asprintf(&type, "directory");
|
|
||||||
if (S_ISFIFO(sp->st_mode))
|
|
||||||
asprintf(&type, "fifo");
|
|
||||||
if (S_ISLNK(sp->st_mode))
|
|
||||||
asprintf(&type, "symlink");
|
|
||||||
if (S_ISREG(sp->st_mode))
|
|
||||||
asprintf(&type, "regular");
|
|
||||||
if (S_ISSOCK(sp->st_mode))
|
|
||||||
asprintf(&type, "socket");
|
|
||||||
if (S_ISWHT(sp->st_mode))
|
|
||||||
asprintf(&type, "whiteout");
|
|
||||||
xo_emit("{e:type/%s}", type);
|
|
||||||
free(type);
|
|
||||||
if (f_flags)
|
if (f_flags)
|
||||||
xo_emit("{:flags/%-*s} ", dp->s_flags, np->flags);
|
(void)printf("%-*s ", dp->s_flags, np->flags);
|
||||||
if (f_label)
|
if (f_label)
|
||||||
xo_emit("{t:label/%-*s} ", dp->s_label, np->label);
|
(void)printf("%-*s ", dp->s_label, np->label);
|
||||||
if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
|
if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
|
||||||
printdev(dp->s_size, sp->st_rdev);
|
printdev(dp->s_size, sp->st_rdev);
|
||||||
else
|
else
|
||||||
printsize("size", dp->s_size, sp->st_size);
|
printsize(dp->s_size, sp->st_size);
|
||||||
if (f_accesstime)
|
if (f_accesstime)
|
||||||
printtime("access-time", sp->st_atime);
|
printtime(sp->st_atime);
|
||||||
else if (f_birthtime)
|
else if (f_birthtime)
|
||||||
printtime("birth-time", sp->st_birthtime);
|
printtime(sp->st_birthtime);
|
||||||
else if (f_statustime)
|
else if (f_statustime)
|
||||||
printtime("change-time", sp->st_ctime);
|
printtime(sp->st_ctime);
|
||||||
else
|
else
|
||||||
printtime("modify-time", sp->st_mtime);
|
printtime(sp->st_mtime);
|
||||||
#ifdef COLORLS
|
#ifdef COLORLS
|
||||||
if (f_color)
|
if (f_color)
|
||||||
color_printed = colortype(sp->st_mode);
|
color_printed = colortype(sp->st_mode);
|
||||||
#endif
|
#endif
|
||||||
|
(void)printname(p->fts_name);
|
||||||
if (name) {
|
|
||||||
xo_emit("{dk:name/%hs}", name);
|
|
||||||
free(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef COLORLS
|
#ifdef COLORLS
|
||||||
if (f_color && color_printed)
|
if (f_color && color_printed)
|
||||||
endcolor(0);
|
endcolor(0);
|
||||||
@ -321,10 +263,8 @@ printlong(const DISPLAY *dp)
|
|||||||
(void)printtype(sp->st_mode);
|
(void)printtype(sp->st_mode);
|
||||||
if (S_ISLNK(sp->st_mode))
|
if (S_ISLNK(sp->st_mode))
|
||||||
printlink(p);
|
printlink(p);
|
||||||
xo_close_instance("entry");
|
(void)putchar('\n');
|
||||||
xo_emit("\n");
|
|
||||||
}
|
}
|
||||||
xo_close_list("entry");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -333,27 +273,23 @@ printstream(const DISPLAY *dp)
|
|||||||
FTSENT *p;
|
FTSENT *p;
|
||||||
int chcnt;
|
int chcnt;
|
||||||
|
|
||||||
xo_open_list("entry");
|
|
||||||
for (p = dp->list, chcnt = 0; p; p = p->fts_link) {
|
for (p = dp->list, chcnt = 0; p; p = p->fts_link) {
|
||||||
if (p->fts_number == NO_PRINT)
|
if (p->fts_number == NO_PRINT)
|
||||||
continue;
|
continue;
|
||||||
/* XXX strlen does not take octal escapes into account. */
|
/* XXX strlen does not take octal escapes into account. */
|
||||||
if (strlen(p->fts_name) + chcnt +
|
if (strlen(p->fts_name) + chcnt +
|
||||||
(p->fts_link ? 2 : 0) >= (unsigned)termwidth) {
|
(p->fts_link ? 2 : 0) >= (unsigned)termwidth) {
|
||||||
xo_emit("\n");
|
putchar('\n');
|
||||||
chcnt = 0;
|
chcnt = 0;
|
||||||
}
|
}
|
||||||
xo_open_instance("file");
|
|
||||||
chcnt += printaname(p, dp->s_inode, dp->s_block);
|
chcnt += printaname(p, dp->s_inode, dp->s_block);
|
||||||
xo_close_instance("file");
|
|
||||||
if (p->fts_link) {
|
if (p->fts_link) {
|
||||||
xo_emit(", ");
|
printf(", ");
|
||||||
chcnt += 2;
|
chcnt += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xo_close_list("entry");
|
|
||||||
if (chcnt)
|
if (chcnt)
|
||||||
xo_emit("\n");
|
putchar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -387,6 +323,7 @@ printcol(const DISPLAY *dp)
|
|||||||
if (dp->entries > lastentries) {
|
if (dp->entries > lastentries) {
|
||||||
if ((narray =
|
if ((narray =
|
||||||
realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
|
realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
|
||||||
|
warn(NULL);
|
||||||
printscol(dp);
|
printscol(dp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -417,21 +354,17 @@ printcol(const DISPLAY *dp)
|
|||||||
|
|
||||||
if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
|
if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
|
||||||
(f_longform || f_size)) {
|
(f_longform || f_size)) {
|
||||||
xo_emit("{L:total} {:total-blocks/%lu}\n",
|
(void)printf("total %lu\n", howmany(dp->btotal, blocksize));
|
||||||
howmany(dp->btotal, blocksize));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xo_open_list("entry");
|
|
||||||
base = 0;
|
base = 0;
|
||||||
for (row = 0; row < numrows; ++row) {
|
for (row = 0; row < numrows; ++row) {
|
||||||
endcol = colwidth;
|
endcol = colwidth;
|
||||||
if (!f_sortacross)
|
if (!f_sortacross)
|
||||||
base = row;
|
base = row;
|
||||||
for (col = 0, chcnt = 0; col < numcols; ++col) {
|
for (col = 0, chcnt = 0; col < numcols; ++col) {
|
||||||
xo_open_instance("entry");
|
|
||||||
chcnt += printaname(array[base], dp->s_inode,
|
chcnt += printaname(array[base], dp->s_inode,
|
||||||
dp->s_block);
|
dp->s_block);
|
||||||
xo_close_instance("entry");
|
|
||||||
if (f_sortacross)
|
if (f_sortacross)
|
||||||
base++;
|
base++;
|
||||||
else
|
else
|
||||||
@ -442,14 +375,13 @@ printcol(const DISPLAY *dp)
|
|||||||
<= endcol) {
|
<= endcol) {
|
||||||
if (f_sortacross && col + 1 >= numcols)
|
if (f_sortacross && col + 1 >= numcols)
|
||||||
break;
|
break;
|
||||||
xo_emit(f_notabs ? " " : "\t");
|
(void)putchar(f_notabs ? ' ' : '\t');
|
||||||
chcnt = cnt;
|
chcnt = cnt;
|
||||||
}
|
}
|
||||||
endcol += colwidth;
|
endcol += colwidth;
|
||||||
}
|
}
|
||||||
xo_emit("\n");
|
(void)putchar('\n');
|
||||||
}
|
}
|
||||||
xo_close_list("entry");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -468,16 +400,16 @@ printaname(const FTSENT *p, u_long inodefield, u_long sizefield)
|
|||||||
sp = p->fts_statp;
|
sp = p->fts_statp;
|
||||||
chcnt = 0;
|
chcnt = 0;
|
||||||
if (f_inode)
|
if (f_inode)
|
||||||
chcnt += xo_emit("{t:inode/%*ju} ",
|
chcnt += printf("%*ju ",
|
||||||
(int)inodefield, (uintmax_t)sp->st_ino);
|
(int)inodefield, (uintmax_t)sp->st_ino);
|
||||||
if (f_size)
|
if (f_size)
|
||||||
chcnt += xo_emit("{t:size/%*jd} ",
|
chcnt += printf("%*jd ",
|
||||||
(int)sizefield, howmany(sp->st_blocks, blocksize));
|
(int)sizefield, howmany(sp->st_blocks, blocksize));
|
||||||
#ifdef COLORLS
|
#ifdef COLORLS
|
||||||
if (f_color)
|
if (f_color)
|
||||||
color_printed = colortype(sp->st_mode);
|
color_printed = colortype(sp->st_mode);
|
||||||
#endif
|
#endif
|
||||||
chcnt += printname("name", p->fts_name);
|
chcnt += printname(p->fts_name);
|
||||||
#ifdef COLORLS
|
#ifdef COLORLS
|
||||||
if (f_color && color_printed)
|
if (f_color && color_printed)
|
||||||
endcolor(0);
|
endcolor(0);
|
||||||
@ -493,7 +425,8 @@ printaname(const FTSENT *p, u_long inodefield, u_long sizefield)
|
|||||||
static void
|
static void
|
||||||
printdev(size_t width, dev_t dev)
|
printdev(size_t width, dev_t dev)
|
||||||
{
|
{
|
||||||
xo_emit("{:device/%#*jx} ", (u_int)width, (uintmax_t)dev);
|
|
||||||
|
(void)printf("%#*jx ", (u_int)width, (uintmax_t)dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
@ -522,10 +455,9 @@ ls_strftime(char *str, size_t len, const char *fmt, const struct tm *tm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
printtime(const char *field, time_t ftime)
|
printtime(time_t ftime)
|
||||||
{
|
{
|
||||||
char longstring[80];
|
char longstring[80];
|
||||||
char fmt[BUFSIZ];
|
|
||||||
static time_t now = 0;
|
static time_t now = 0;
|
||||||
const char *format;
|
const char *format;
|
||||||
static int d_first = -1;
|
static int d_first = -1;
|
||||||
@ -548,12 +480,8 @@ printtime(const char *field, time_t ftime)
|
|||||||
/* mmm dd yyyy || dd mmm yyyy */
|
/* mmm dd yyyy || dd mmm yyyy */
|
||||||
format = d_first ? "%e %b %Y" : "%b %e %Y";
|
format = d_first ? "%e %b %Y" : "%b %e %Y";
|
||||||
ls_strftime(longstring, sizeof(longstring), format, localtime(&ftime));
|
ls_strftime(longstring, sizeof(longstring), format, localtime(&ftime));
|
||||||
|
fputs(longstring, stdout);
|
||||||
snprintf(fmt, sizeof(fmt), "{d:%s/%%hs} ", field);
|
fputc(' ', stdout);
|
||||||
xo_attr("value", "%ld", (long) ftime);
|
|
||||||
xo_emit(fmt, longstring);
|
|
||||||
snprintf(fmt, sizeof(fmt), "{en:%s/%%ld}", field);
|
|
||||||
xo_emit(fmt, (long) ftime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -562,7 +490,7 @@ printtype(u_int mode)
|
|||||||
|
|
||||||
if (f_slash) {
|
if (f_slash) {
|
||||||
if ((mode & S_IFMT) == S_IFDIR) {
|
if ((mode & S_IFMT) == S_IFDIR) {
|
||||||
xo_emit("{D:\\/}{e:type/directory}");
|
(void)putchar('/');
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
@ -570,25 +498,25 @@ printtype(u_int mode)
|
|||||||
|
|
||||||
switch (mode & S_IFMT) {
|
switch (mode & S_IFMT) {
|
||||||
case S_IFDIR:
|
case S_IFDIR:
|
||||||
xo_emit("{D:/\\/}{e:type/directory}");
|
(void)putchar('/');
|
||||||
return (1);
|
return (1);
|
||||||
case S_IFIFO:
|
case S_IFIFO:
|
||||||
xo_emit("{D:|}{e:type/fifo}");
|
(void)putchar('|');
|
||||||
return (1);
|
return (1);
|
||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
xo_emit("{D:@}{e:type/link}");
|
(void)putchar('@');
|
||||||
return (1);
|
return (1);
|
||||||
case S_IFSOCK:
|
case S_IFSOCK:
|
||||||
xo_emit("{D:=}{e:type/socket}");
|
(void)putchar('=');
|
||||||
return (1);
|
return (1);
|
||||||
case S_IFWHT:
|
case S_IFWHT:
|
||||||
xo_emit("{D:%%}{e:type/whiteout}");
|
(void)putchar('%');
|
||||||
return (1);
|
return (1);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
|
if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
|
||||||
xo_emit("{D:*}{e:executable/}");
|
(void)putchar('*');
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
@ -598,7 +526,7 @@ printtype(u_int mode)
|
|||||||
static int
|
static int
|
||||||
putch(int c)
|
putch(int c)
|
||||||
{
|
{
|
||||||
xo_emit("{D:/%c}", c);
|
(void)putchar(c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,7 +635,7 @@ parsecolors(const char *cs)
|
|||||||
if (c[j] >= '0' && c[j] <= '7') {
|
if (c[j] >= '0' && c[j] <= '7') {
|
||||||
colors[i].num[j] = c[j] - '0';
|
colors[i].num[j] = c[j] - '0';
|
||||||
if (!legacy_warn) {
|
if (!legacy_warn) {
|
||||||
xo_warnx("LSCOLORS should use "
|
warnx("LSCOLORS should use "
|
||||||
"characters a-h instead of 0-9 ("
|
"characters a-h instead of 0-9 ("
|
||||||
"see the manual page)");
|
"see the manual page)");
|
||||||
}
|
}
|
||||||
@ -720,7 +648,7 @@ parsecolors(const char *cs)
|
|||||||
} else if (tolower((unsigned char)c[j]) == 'x')
|
} else if (tolower((unsigned char)c[j]) == 'x')
|
||||||
colors[i].num[j] = -1;
|
colors[i].num[j] = -1;
|
||||||
else {
|
else {
|
||||||
xo_warnx("invalid character '%c' in LSCOLORS"
|
warnx("invalid character '%c' in LSCOLORS"
|
||||||
" env var", c[j]);
|
" env var", c[j]);
|
||||||
colors[i].num[j] = -1;
|
colors[i].num[j] = -1;
|
||||||
}
|
}
|
||||||
@ -752,19 +680,18 @@ printlink(const FTSENT *p)
|
|||||||
(void)snprintf(name, sizeof(name),
|
(void)snprintf(name, sizeof(name),
|
||||||
"%s/%s", p->fts_parent->fts_accpath, p->fts_name);
|
"%s/%s", p->fts_parent->fts_accpath, p->fts_name);
|
||||||
if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
|
if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
|
||||||
xo_error("\nls: %s: %s\n", name, strerror(errno));
|
(void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
path[lnklen] = '\0';
|
path[lnklen] = '\0';
|
||||||
xo_emit(" -> ");
|
(void)printf(" -> ");
|
||||||
(void)printname("target", path);
|
(void)printname(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
printsize(const char *field, size_t width, off_t bytes)
|
printsize(size_t width, off_t bytes)
|
||||||
{
|
{
|
||||||
char fmt[BUFSIZ];
|
|
||||||
|
|
||||||
if (f_humanval) {
|
if (f_humanval) {
|
||||||
/*
|
/*
|
||||||
* Reserve one space before the size and allocate room for
|
* Reserve one space before the size and allocate room for
|
||||||
@ -774,15 +701,13 @@ printsize(const char *field, size_t width, off_t bytes)
|
|||||||
|
|
||||||
humanize_number(buf, sizeof(buf), (int64_t)bytes, "",
|
humanize_number(buf, sizeof(buf), (int64_t)bytes, "",
|
||||||
HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
|
HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
|
||||||
snprintf(fmt, sizeof(fmt), "{:%s/%%%ds} ", field, (int) width);
|
(void)printf("%*s ", (u_int)width, buf);
|
||||||
xo_attr("value", "%jd", (intmax_t) bytes);
|
} else if (f_thousands) { /* with commas */
|
||||||
xo_emit(fmt, buf);
|
|
||||||
} else { /* with commas */
|
|
||||||
/* This format assignment needed to work round gcc bug. */
|
/* This format assignment needed to work round gcc bug. */
|
||||||
snprintf(fmt, sizeof(fmt), "{:%s/%%%dj%sd} ",
|
const char *format = "%*j'd ";
|
||||||
field, (int) width, f_thousands ? "'" : "");
|
(void)printf(format, (u_int)width, bytes);
|
||||||
xo_emit(fmt, (intmax_t) bytes);
|
} else
|
||||||
}
|
(void)printf("%*jd ", (u_int)width, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -825,7 +750,7 @@ aclmode(char *buf, const FTSENT *p)
|
|||||||
type = ACL_TYPE_NFS4;
|
type = ACL_TYPE_NFS4;
|
||||||
supports_acls = 1;
|
supports_acls = 1;
|
||||||
} else if (ret < 0 && errno != EINVAL) {
|
} else if (ret < 0 && errno != EINVAL) {
|
||||||
xo_warn("%s", name);
|
warn("%s", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (supports_acls == 0) {
|
if (supports_acls == 0) {
|
||||||
@ -834,7 +759,7 @@ aclmode(char *buf, const FTSENT *p)
|
|||||||
type = ACL_TYPE_ACCESS;
|
type = ACL_TYPE_ACCESS;
|
||||||
supports_acls = 1;
|
supports_acls = 1;
|
||||||
} else if (ret < 0 && errno != EINVAL) {
|
} else if (ret < 0 && errno != EINVAL) {
|
||||||
xo_warn("%s", name);
|
warn("%s", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -843,12 +768,12 @@ aclmode(char *buf, const FTSENT *p)
|
|||||||
return;
|
return;
|
||||||
facl = acl_get_link_np(name, type);
|
facl = acl_get_link_np(name, type);
|
||||||
if (facl == NULL) {
|
if (facl == NULL) {
|
||||||
xo_warn("%s", name);
|
warn("%s", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (acl_is_trivial_np(facl, &trivial)) {
|
if (acl_is_trivial_np(facl, &trivial)) {
|
||||||
acl_free(facl);
|
acl_free(facl);
|
||||||
xo_warn("%s", name);
|
warn("%s", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!trivial)
|
if (!trivial)
|
||||||
|
@ -52,19 +52,13 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
#include <libxo/xo.h>
|
|
||||||
|
|
||||||
#include "ls.h"
|
#include "ls.h"
|
||||||
#include "extern.h"
|
#include "extern.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
prn_normal(const char *field, const char *s)
|
prn_normal(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;
|
mbstate_t mbs;
|
||||||
wchar_t wc;
|
wchar_t wc;
|
||||||
int i, n;
|
int i, n;
|
||||||
@ -91,47 +85,43 @@ prn_normal(const char *field, const char *s)
|
|||||||
n += wcwidth(wc);
|
n += wcwidth(wc);
|
||||||
}
|
}
|
||||||
return (n);
|
return (n);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
int
|
||||||
get_printable(const char *s)
|
prn_printable(const char *s)
|
||||||
{
|
{
|
||||||
mbstate_t mbs;
|
mbstate_t mbs;
|
||||||
wchar_t wc;
|
wchar_t wc;
|
||||||
int i, n;
|
int i, n;
|
||||||
size_t clen;
|
size_t clen;
|
||||||
int slen = strlen(s);
|
|
||||||
char *buf = alloca(slen + 1), *bp = buf;
|
|
||||||
|
|
||||||
memset(&mbs, 0, sizeof(mbs));
|
memset(&mbs, 0, sizeof(mbs));
|
||||||
n = 0;
|
n = 0;
|
||||||
while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
|
while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
|
||||||
if (clen == (size_t)-1) {
|
if (clen == (size_t)-1) {
|
||||||
*bp++ = '?';
|
putchar('?');
|
||||||
s++;
|
s++;
|
||||||
n++;
|
n++;
|
||||||
memset(&mbs, 0, sizeof(mbs));
|
memset(&mbs, 0, sizeof(mbs));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (clen == (size_t)-2) {
|
if (clen == (size_t)-2) {
|
||||||
*bp++ = '?';
|
putchar('?');
|
||||||
n++;
|
n++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!iswprint(wc)) {
|
if (!iswprint(wc)) {
|
||||||
*bp++ = '?';
|
putchar('?');
|
||||||
s += clen;
|
s += clen;
|
||||||
n++;
|
n++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (i = 0; i < (int)clen; i++)
|
for (i = 0; i < (int)clen; i++)
|
||||||
*bp++ = (unsigned char)s[i];
|
putchar((unsigned char)s[i]);
|
||||||
s += clen;
|
s += clen;
|
||||||
n += wcwidth(wc);
|
n += wcwidth(wc);
|
||||||
}
|
}
|
||||||
*bp = '\0';
|
return (n);
|
||||||
return strdup(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -177,8 +167,8 @@ len_octal(const char *s, int len)
|
|||||||
return (r);
|
return (r);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
int
|
||||||
get_octal(const char *s)
|
prn_octal(const char *s)
|
||||||
{
|
{
|
||||||
static const char esc[] = "\\\\\"\"\aa\bb\ff\nn\rr\tt\vv";
|
static const char esc[] = "\\\\\"\"\aa\bb\ff\nn\rr\tt\vv";
|
||||||
const char *p;
|
const char *p;
|
||||||
@ -187,8 +177,6 @@ get_octal(const char *s)
|
|||||||
size_t clen;
|
size_t clen;
|
||||||
unsigned char ch;
|
unsigned char ch;
|
||||||
int goodchar, i, len, prtlen;
|
int goodchar, i, len, prtlen;
|
||||||
int slen = strlen(s);
|
|
||||||
char *buf = alloca(slen * 4 + 1), *bp = buf;
|
|
||||||
|
|
||||||
memset(&mbs, 0, sizeof(mbs));
|
memset(&mbs, 0, sizeof(mbs));
|
||||||
len = 0;
|
len = 0;
|
||||||
@ -196,7 +184,7 @@ get_octal(const char *s)
|
|||||||
goodchar = clen != (size_t)-1 && clen != (size_t)-2;
|
goodchar = clen != (size_t)-1 && clen != (size_t)-2;
|
||||||
if (goodchar && iswprint(wc) && wc != L'\"' && wc != L'\\') {
|
if (goodchar && iswprint(wc) && wc != L'\"' && wc != L'\\') {
|
||||||
for (i = 0; i < (int)clen; i++)
|
for (i = 0; i < (int)clen; i++)
|
||||||
*bp++ = (unsigned char)s[i];
|
putchar((unsigned char)s[i]);
|
||||||
len += wcwidth(wc);
|
len += wcwidth(wc);
|
||||||
} else if (goodchar && f_octal_escape &&
|
} else if (goodchar && f_octal_escape &&
|
||||||
#if WCHAR_MIN < 0
|
#if WCHAR_MIN < 0
|
||||||
@ -204,8 +192,8 @@ get_octal(const char *s)
|
|||||||
#endif
|
#endif
|
||||||
wc <= (wchar_t)UCHAR_MAX &&
|
wc <= (wchar_t)UCHAR_MAX &&
|
||||||
(p = strchr(esc, (char)wc)) != NULL) {
|
(p = strchr(esc, (char)wc)) != NULL) {
|
||||||
*bp ++ = '\\';
|
putchar('\\');
|
||||||
*bp++ = p[1];
|
putchar(p[1]);
|
||||||
len += 2;
|
len += 2;
|
||||||
} else {
|
} else {
|
||||||
if (goodchar)
|
if (goodchar)
|
||||||
@ -216,10 +204,10 @@ get_octal(const char *s)
|
|||||||
prtlen = strlen(s);
|
prtlen = strlen(s);
|
||||||
for (i = 0; i < prtlen; i++) {
|
for (i = 0; i < prtlen; i++) {
|
||||||
ch = (unsigned char)s[i];
|
ch = (unsigned char)s[i];
|
||||||
*bp++ = '\\';
|
putchar('\\');
|
||||||
*bp++ = '0' + (ch >> 6);
|
putchar('0' + (ch >> 6));
|
||||||
*bp++ = '0' + ((ch >> 3) & 7);
|
putchar('0' + ((ch >> 3) & 7));
|
||||||
*bp++ = '0' + (ch & 7);
|
putchar('0' + (ch & 7));
|
||||||
len += 4;
|
len += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,15 +219,13 @@ get_octal(const char *s)
|
|||||||
} else
|
} else
|
||||||
s += clen;
|
s += clen;
|
||||||
}
|
}
|
||||||
|
return (len);
|
||||||
*bp = '\0';
|
|
||||||
return strdup(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
xo_error(
|
(void)fprintf(stderr,
|
||||||
#ifdef COLORLS
|
#ifdef COLORLS
|
||||||
"usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
|
"usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
|
||||||
#else
|
#else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user