From 76218e5eb0c081ac8718fd1a1cfc28da16595a71 Mon Sep 17 00:00:00 2001 From: Tai Chi Minh Ralph Eastwood Date: Sun, 15 Feb 2015 10:23:21 +0000 Subject: [PATCH 3/4] ls: add implementation of -q and -u flags --- ls.1 | 5 +++++ ls.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/ls.1 b/ls.1 index ad90b37..2aa37b2 100644 --- a/ls.1 +++ b/ls.1 @@ -38,6 +38,8 @@ themselves. .It Fl l List detailed information about each file, including their type, permissions, links, owner, group, size, and last file status/modification time. +.It Fl q +When printing file names, replace all non-printable characters with 'q'. .It Fl R Traverse directories recursively. .It Fl r @@ -46,6 +48,9 @@ Reverse the sort order. Sort files by last file status/modification time instead of by name. .It Fl U Keep the list unsorted. +.It Fl u +Use time file was last access instead of last modification time for sorting +or printing. .El .Sh SEE ALSO .Xr stat 2 diff --git a/ls.c b/ls.c index eec5145..75cb418 100644 --- a/ls.c +++ b/ls.c @@ -12,6 +12,7 @@ #include #include "util.h" +#include "utf.h" typedef struct { char *name; @@ -46,6 +47,8 @@ static int tflag = 0; static int Uflag = 0; static int Cflag = 0; static int Rflag = 0; +static int qflag = 0; +static int uflag = 0; static int many; static int first = 1; static struct winsize ws; @@ -53,7 +56,7 @@ static struct winsize ws; static void usage(void) { - eprintf("usage: %s [-1aCcdFHhiLlRrtU] [file ...]\n", argv0); + eprintf("usage: %s [-1aCcdFHhiLlqRrtUu] [file ...]\n", argv0); } int @@ -74,6 +77,7 @@ main(int argc, char *argv[]) break; case 'c': cflag = 1; + uflag = 0; break; case 'd': dflag = 1; @@ -112,6 +116,13 @@ main(int argc, char *argv[]) case 'R': Rflag = 1; break; + case 'q': + qflag = 1; + break; + case 'u': + uflag = 1; + cflag = 0; + break; default: usage(); } ARGEND; @@ -276,7 +287,12 @@ mkent(Entry *ent, char *path, int dostat, int follow) ent->uid = st.st_uid; ent->gid = st.st_gid; ent->size = st.st_size; - ent->t = cflag ? st.st_ctime : st.st_mtime; + if (cflag) + ent->t = st.st_ctime; + else if (uflag) + ent->t = st.st_atime; + else + ent->t = st.st_mtime; ent->ino = st.st_ino; if (S_ISLNK(ent->mode)) ent->tmode = stat(path, &st) == 0 ? st.st_mode : 0; @@ -314,12 +330,32 @@ output(Entry *ent, FILE *f) struct passwd *pw; char pwname[_SC_LOGIN_NAME_MAX]; char grname[_SC_LOGIN_NAME_MAX]; + char *name = ent->name, *p, *n; + Rune r; first = 0; + + if (qflag) { + n = name = emalloc(utflen(ent->name) + 1); + strcpy(name, (p = ent->name)); + while (*p) { + len = chartorune(&r, p); + if (isprintrune(r)) { + while (len) { + *n++ = *p++; + --len; + } + } else { + *n++ = '?'; + p += len; + } + } + *n++ = '\0'; + } if (iflag) fprintf(f, "%lu ", (unsigned long)ent->ino); if (!lflag) { - fprintf(f, "%s%s\n", ent->name, indicator(ent->mode)); + fprintf(f, "%s%s\n", name, indicator(ent->mode)); return; } if (S_ISREG(ent->mode)) @@ -376,14 +412,17 @@ output(Entry *ent, FILE *f) fprintf(f, "%10s ", humansize((unsigned long)ent->size)); else fprintf(f, "%10lu ", (unsigned long)ent->size); - fprintf(f, "%s %s%s", buf, ent->name, indicator(ent->mode)); + fprintf(f, "%s %s%s", buf, name, indicator(ent->mode)); if (S_ISLNK(ent->mode)) { - if ((len = readlink(ent->name, buf, sizeof buf - 1)) < 0) - eprintf("readlink %s:", ent->name); + if ((len = readlink(name, buf, sizeof buf - 1)) < 0) + eprintf("readlink %s:", name); buf[len] = '\0'; fprintf(f, " -> %s%s", buf, indicator(ent->tmode)); } fputc('\n', f); + + if (name != ent->name) + free(name); } static void columns(char *buf, size_t sz, int cnt) -- 2.3.0