*
* See http://opengroup.org/onlinepubs/9699919799/utilities/ls.html
-USE_LS(NEWTOY(ls, USE_LS_COLOR("(color):;")"goACFHLRSacdfiklmnpqrstux1[-1Cglmnox][-cu][-ftS][-HL]", TOYFLAG_BIN|TOYFLAG_LOCALE))
+USE_LS(NEWTOY(ls, USE_LS_COLOR("(color):;")"goACFHLRZSacdfiklmnpqrstux1[-1Cglmnox][-cu][-ftS][-HL]", TOYFLAG_BIN|TOYFLAG_LOCALE))
config LS
bool "ls"
default y
help
- usage: ls [-ACFHLRSacdfiklmnpqrstux1] [directory...]
+ usage: ls [-ACFHLRSZacdfiklmnpqrstux1] [directory...]
list files
what to show:
-u use access time for timestamps -A list all files but . and ..
-H follow command line symlinks -L follow symlinks
-R recursively list files in subdirs -F append /dir *exe @sym |FIFO
+ -Z security context
output formats:
-1 list one file per line -C columns (sorted vertically)
#ifdef USE_SMACK
#include <sys/smack.h>
+#include <linux/xattr.h>
#endif //USE_SMACK
// test sst output (suid/sticky in ls flaglist)
return gr ? gr->gr_name : TT.gid_buf;
}
+static unsigned getseccontextlen(struct dirtree *st)
+{
+ unsigned ret = 0;
+#ifdef USE_SMACK
+ {
+ char *p = dirtree_path(st, 0);
+ ret = getxattr(p, XATTR_NAME_SMACK, 0, 0);
+ free(p);
+ if (ret < 0)
+ ret = 1;
+ }
+#endif
+ return ret;
+}
+
+static unsigned getseccontext(struct dirtree *st, char *where)
+{
+ unsigned ret = 0;
+#ifdef USE_SMACK
+ {
+ char *p = dirtree_path(st, 0);
+ ret = getxattr(p, XATTR_NAME_SMACK, where, SMACK_LABEL_LEN);
+ free (p);
+ if (ret < 0) {
+ *where = '?';
+ ret = 1;
+ }
+ }
+#endif
+ where[ret] = '\0';
+ return ret;
+}
+
// Figure out size of printable entry fields for display indent/wrap
static void entrylen(struct dirtree *dt, unsigned *len, unsigned *totals)
else
*len += len[6];
}
+
+ if (flags & FLAG_Z) {
+ len[7] = getseccontextlen(dt) + 1;
+ if (totals)
+ *len += totals[7];
+ else
+ *len += len[7];
+ }
+
}
static int compare(void *a, void *b)
unsigned long dtlen = 0, ul = 0;
unsigned width, flags = toys.optflags, totals[LEN_MAX], len[LEN_MAX],
*colsizes = (unsigned *)(toybuf+260), columns = (sizeof(toybuf)-260)/4;
+#ifdef USE_SMACK
+ char ctx_buf[SMACK_LABEL_LEN +1];
+#else
+ char ctx_buf[2];
+#endif
memset(totals, 0, sizeof(totals));
printf("%s% *ld %s%s%s%s", perm, totals[2]+1, (long)st->st_nlink,
usr, upad, grp, grpad);
+ if (flags & FLAG_Z) {
+ getseccontext(sort[next], ctx_buf);
+ xprintf(" %s%s", ctx_buf, toybuf+256-(totals[7]-len[7]));
+ }
+
if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
printf("% *d,% 4d", totals[5]-4, major(st->st_rdev),minor(st->st_rdev));
else printf("% *"PRId64, totals[5]+1, (int64_t)st->st_size);
tm = localtime(&(st->st_mtime));
strftime(thyme, sizeof(thyme), "%F %H:%M", tm);
xprintf(" %s ", thyme);
+ } else if (flags & FLAG_Z) {
+ getseccontext(sort[next], ctx_buf);
+ xprintf("%s%s ", toybuf+256-(totals[7]-len[7]), ctx_buf);
}
if (flags & FLAG_color) {