Changeset View
Changeset View
Standalone View
Standalone View
head/bin/ls/print.c
Show First 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | |||||
#include <time.h> | #include <time.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <wchar.h> | #include <wchar.h> | ||||
#ifdef COLORLS | #ifdef COLORLS | ||||
#include <ctype.h> | #include <ctype.h> | ||||
#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" | ||||
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); | ||||
#endif | #endif | ||||
static void aclmode(char *, const FTSENT *); | static void aclmode(char *, const FTSENT *); | ||||
#define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT) | #define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT) | ||||
Show All 28 Lines | |||||
static size_t padding_for_month[12]; | static size_t padding_for_month[12]; | ||||
static size_t month_max_size = 0; | static size_t month_max_size = 0; | ||||
void | void | ||||
printscol(const DISPLAY *dp) | 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 * | ||||
get_abmon(int mon) | get_abmon(int mon) | ||||
{ | { | ||||
switch (mon) { | switch (mon) { | ||||
case 0: return (nl_langinfo(ABMON_1)); | case 0: return (nl_langinfo(ABMON_1)); | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | for (i = 0; i < 12; i++) { | ||||
if (width > month_max_size) | if (width > month_max_size) | ||||
month_max_size = width; | month_max_size = width; | ||||
} | } | ||||
for (i = 0; i < 12; i++) | for (i = 0; i < 12; i++) | ||||
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) | ||||
{ | { | ||||
struct stat *sp; | struct stat *sp; | ||||
FTSENT *p; | FTSENT *p; | ||||
NAMES *np; | NAMES *np; | ||||
char buf[20]; | char buf[20]; | ||||
#ifdef COLORLS | #ifdef COLORLS | ||||
int color_printed = 0; | int color_printed = 0; | ||||
#endif | #endif | ||||
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); | ||||
#endif | #endif | ||||
if (f_type) | if (f_type) | ||||
(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 | ||||
printstream(const DISPLAY *dp) | 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 | ||||
printcol(const DISPLAY *dp) | printcol(const DISPLAY *dp) | ||||
{ | { | ||||
static FTSENT **array; | static FTSENT **array; | ||||
static int lastentries = -1; | static int lastentries = -1; | ||||
FTSENT *p; | FTSENT *p; | ||||
Show All 17 Lines | printcol(const DISPLAY *dp) | ||||
/* | /* | ||||
* Have to do random access in the linked list -- build a table | * Have to do random access in the linked list -- build a table | ||||
* of pointers. | * of pointers. | ||||
*/ | */ | ||||
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; | ||||
} | } | ||||
lastentries = dp->entries; | lastentries = dp->entries; | ||||
array = narray; | array = narray; | ||||
} | } | ||||
for (p = dp->list, num = 0; p; p = p->fts_link) | for (p = dp->list, num = 0; p; p = p->fts_link) | ||||
if (p->fts_number != NO_PRINT) | if (p->fts_number != NO_PRINT) | ||||
Show All 14 Lines | printcol(const DISPLAY *dp) | ||||
} | } | ||||
numcols = termwidth / colwidth; | numcols = termwidth / colwidth; | ||||
numrows = num / numcols; | numrows = num / numcols; | ||||
if (num % numcols) | if (num % numcols) | ||||
++numrows; | ++numrows; | ||||
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 | ||||
base += numrows; | base += numrows; | ||||
if (base >= num) | if (base >= num) | ||||
break; | break; | ||||
while ((cnt = ((chcnt + tabwidth) & ~(tabwidth - 1))) | while ((cnt = ((chcnt + tabwidth) & ~(tabwidth - 1))) | ||||
<= 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"); | |||||
} | } | ||||
/* | /* | ||||
* print [inode] [size] name | * print [inode] [size] name | ||||
* return # of characters printed, no trailing characters. | * return # of characters printed, no trailing characters. | ||||
*/ | */ | ||||
static int | static int | ||||
printaname(const FTSENT *p, u_long inodefield, u_long sizefield) | printaname(const FTSENT *p, u_long inodefield, u_long sizefield) | ||||
{ | { | ||||
struct stat *sp; | struct stat *sp; | ||||
int chcnt; | int chcnt; | ||||
#ifdef COLORLS | #ifdef COLORLS | ||||
int color_printed = 0; | int color_printed = 0; | ||||
#endif | #endif | ||||
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); | ||||
#endif | #endif | ||||
if (f_type) | if (f_type) | ||||
chcnt += printtype(sp->st_mode); | chcnt += printtype(sp->st_mode); | ||||
return (chcnt); | return (chcnt); | ||||
} | } | ||||
/* | /* | ||||
* Print device special file major and minor numbers. | * Print device special file major and minor numbers. | ||||
*/ | */ | ||||
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 | ||||
ls_strftime(char *str, size_t len, const char *fmt, const struct tm *tm) | ls_strftime(char *str, size_t len, const char *fmt, const struct tm *tm) | ||||
{ | { | ||||
char *posb, nfmt[BUFSIZ]; | char *posb, nfmt[BUFSIZ]; | ||||
const char *format = fmt; | const char *format = fmt; | ||||
size_t ret; | size_t ret; | ||||
Show All 12 Lines | if (month_max_size > 0) { | ||||
format = nfmt; | format = nfmt; | ||||
} | } | ||||
} | } | ||||
ret = strftime(str, len, format, tm); | ret = strftime(str, len, format, tm); | ||||
return (ret); | return (ret); | ||||
} | } | ||||
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; | ||||
if (d_first < 0) | if (d_first < 0) | ||||
d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); | d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); | ||||
if (now == 0) | if (now == 0) | ||||
now = time(NULL); | now = time(NULL); | ||||
#define SIXMONTHS ((365 / 2) * 86400) | #define SIXMONTHS ((365 / 2) * 86400) | ||||
if (f_timeformat) /* user specified format */ | if (f_timeformat) /* user specified format */ | ||||
format = f_timeformat; | format = f_timeformat; | ||||
else if (f_sectime) | else if (f_sectime) | ||||
/* mmm dd hh:mm:ss yyyy || dd mmm hh:mm:ss yyyy */ | /* mmm dd hh:mm:ss yyyy || dd mmm hh:mm:ss yyyy */ | ||||
format = d_first ? "%e %b %T %Y" : "%b %e %T %Y"; | format = d_first ? "%e %b %T %Y" : "%b %e %T %Y"; | ||||
else if (ftime + SIXMONTHS > now && ftime < now + SIXMONTHS) | else if (ftime + SIXMONTHS > now && ftime < now + SIXMONTHS) | ||||
/* mmm dd hh:mm || dd mmm hh:mm */ | /* mmm dd hh:mm || dd mmm hh:mm */ | ||||
format = d_first ? "%e %b %R" : "%b %e %R"; | format = d_first ? "%e %b %R" : "%b %e %R"; | ||||
else | else | ||||
/* 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 | ||||
printtype(u_int mode) | 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); | ||||
} | } | ||||
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); | ||||
} | } | ||||
#ifdef COLORLS | #ifdef COLORLS | ||||
static int | static int | ||||
putch(int c) | putch(int c) | ||||
{ | { | ||||
xo_emit("{D:/%c}", c); | (void)putchar(c); | ||||
return 0; | return 0; | ||||
} | } | ||||
static int | static int | ||||
writech(int c) | writech(int c) | ||||
{ | { | ||||
char tmp = (char)c; | char tmp = (char)c; | ||||
▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | if (len <= 2 * (size_t)i) { | ||||
c[0] = cs[2 * i]; | c[0] = cs[2 * i]; | ||||
c[1] = cs[2 * i + 1]; | c[1] = cs[2 * i + 1]; | ||||
} | } | ||||
for (j = 0; j < 2; j++) { | for (j = 0; j < 2; j++) { | ||||
/* Legacy colours used 0-7 */ | /* Legacy colours used 0-7 */ | ||||
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)"); | ||||
} | } | ||||
legacy_warn = 1; | legacy_warn = 1; | ||||
} else if (c[j] >= 'a' && c[j] <= 'h') | } else if (c[j] >= 'a' && c[j] <= 'h') | ||||
colors[i].num[j] = c[j] - 'a'; | colors[i].num[j] = c[j] - 'a'; | ||||
else if (c[j] >= 'A' && c[j] <= 'H') { | else if (c[j] >= 'A' && c[j] <= 'H') { | ||||
colors[i].num[j] = c[j] - 'A'; | colors[i].num[j] = c[j] - 'A'; | ||||
colors[i].bold = 1; | colors[i].bold = 1; | ||||
} 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; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
void | void | ||||
Show All 15 Lines | printlink(const FTSENT *p) | ||||
char path[MAXPATHLEN + 1]; | char path[MAXPATHLEN + 1]; | ||||
if (p->fts_level == FTS_ROOTLEVEL) | if (p->fts_level == FTS_ROOTLEVEL) | ||||
(void)snprintf(name, sizeof(name), "%s", p->fts_name); | (void)snprintf(name, sizeof(name), "%s", p->fts_name); | ||||
else | else | ||||
(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 | ||||
* the trailing '\0'. | * the trailing '\0'. | ||||
*/ | */ | ||||
char buf[HUMANVALSTR_LEN - 1 + 1]; | char buf[HUMANVALSTR_LEN - 1 + 1]; | ||||
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); | |||||
} | } | ||||
} | |||||
/* | /* | ||||
* Add a + after the standard rwxrwxrwx mode if the file has an | * Add a + after the standard rwxrwxrwx mode if the file has an | ||||
* ACL. strmode() reserves space at the end of the string. | * ACL. strmode() reserves space at the end of the string. | ||||
*/ | */ | ||||
static void | static void | ||||
aclmode(char *buf, const FTSENT *p) | aclmode(char *buf, const FTSENT *p) | ||||
{ | { | ||||
Show All 25 Lines | if (previous_dev != p->fts_statp->st_dev) { | ||||
previous_dev = p->fts_statp->st_dev; | previous_dev = p->fts_statp->st_dev; | ||||
supports_acls = 0; | supports_acls = 0; | ||||
ret = lpathconf(name, _PC_ACL_NFS4); | ret = lpathconf(name, _PC_ACL_NFS4); | ||||
if (ret > 0) { | if (ret > 0) { | ||||
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) { | ||||
ret = lpathconf(name, _PC_ACL_EXTENDED); | ret = lpathconf(name, _PC_ACL_EXTENDED); | ||||
if (ret > 0) { | if (ret > 0) { | ||||
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; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (supports_acls == 0) | if (supports_acls == 0) | ||||
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) | ||||
buf[10] = '+'; | buf[10] = '+'; | ||||
acl_free(facl); | acl_free(facl); | ||||
} | } |