From 2269fa5765176ddf8a4b3720f5116416e268ad3b Mon Sep 17 00:00:00 2001 From: Greg Lehey Date: Fri, 4 Apr 2008 03:57:46 +0000 Subject: [PATCH] Add -D option to specify exact format of date and time output with ls -l. --- bin/ls/ls.1 | 34 ++++++++++++++++++++++++++++------ bin/ls/ls.c | 8 ++++++-- bin/ls/ls.h | 3 ++- bin/ls/print.c | 17 ++++++++++------- 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/bin/ls/ls.1 b/bin/ls/ls.1 index 66d868759af6..ee1320409c62 100644 --- a/bin/ls/ls.1 +++ b/bin/ls/ls.1 @@ -41,6 +41,7 @@ .Sh SYNOPSIS .Nm .Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuwx1 +.Op Fl D Ar format .Op Ar .Sh DESCRIPTION For each operand that names a @@ -88,6 +89,20 @@ where is the numeric value of the character in octal. .It Fl C Force multi-column output; this is the default when output is to a terminal. +.It Fl D Ar format +When printing in the long +.Pq Fl l +format, use +.Ar format +to format the date and time output. +.Ar format +is a format string used by +.Xr strftime 3 . +Depending on the choice of format string, this may result in a +different number of columns in the output. +This option overrides the +.Fl T +option. .It Fl F Display a slash .Pq Ql / @@ -146,12 +161,13 @@ Recursively list subdirectories encountered. Sort by size (largest file first) before sorting the operands in lexicographical order. .It Fl T -When used with the -.Fl l -(lowercase letter -.Dq ell ) -option, display complete time information for the file, including +When printing in the long +.Pq Fl l +format, display complete time information for the file, including month, day, hour, minute, second, and year. +The +.Fl D +option gives even more control over the output format. .It Fl U Use time when file was created for sorting or printing. .It Fl W @@ -325,7 +341,12 @@ hour file last modified, minute file last modified, and the pathname. .Pp If the modification time of the file is more than 6 months -in the past or future, then the year of the last modification +in the past or future, and the +.Fl D +or +.Fl T +are not specified, +then the year of the last modification is displayed in place of the hour and minute fields. .Pp If the owner or group names are not a known user or group name, @@ -657,6 +678,7 @@ specification. .Xr getfacl 1 , .Xr sort 1 , .Xr xterm 1 , +.Xr strftime 3 , .Xr termcap 5 , .Xr maclabel 7 , .Xr symlink 7 , diff --git a/bin/ls/ls.c b/bin/ls/ls.c index e9a6e652dd77..644bc96eb5fe 100644 --- a/bin/ls/ls.c +++ b/bin/ls/ls.c @@ -125,10 +125,11 @@ static int f_reversesort; /* reverse whatever sort is used */ static int f_singlecol; /* use single column output */ int f_size; /* list size in short listing */ int f_slash; /* similar to f_type, but only for dirs */ - int f_sortacross; /* sort across rows, not down columns */ + int f_sortacross; /* sort across rows, not down columns */ int f_statustime; /* use time of last mode change */ static int f_stream; /* stream the output, separate with commas */ static int f_timesort; /* sort by time vice name */ + char *f_timeformat; /* user-specified time format */ static int f_sizesort; int f_type; /* add type character for non-regular files */ static int f_whiteout; /* show whiteout entries */ @@ -179,7 +180,7 @@ main(int argc, char *argv[]) fts_options = FTS_PHYSICAL; while ((ch = getopt(argc, argv, - "1ABCFGHILPRSTUWZabcdfghiklmnopqrstuwx")) != -1) { + "1ABCD:FGHILPRSTUWZabcdfghiklmnopqrstuwx")) != -1) { switch (ch) { /* * The -1, -C, -x and -l options all override each other so @@ -198,6 +199,9 @@ main(int argc, char *argv[]) case 'C': f_sortacross = f_longform = f_singlecol = 0; break; + case 'D': + f_timeformat = optarg; + break; case 'l': f_longform = 1; f_singlecol = 0; diff --git a/bin/ls/ls.h b/bin/ls/ls.h index 4d12b22b2360..f01e3519be12 100644 --- a/bin/ls/ls.h +++ b/bin/ls/ls.h @@ -50,8 +50,9 @@ extern int f_nonprint; /* show unprintables as ? */ extern int f_sectime; /* print the real time for all files */ extern int f_size; /* list size in short listing */ extern int f_slash; /* append a '/' if the file is a directory */ -extern int f_sortacross; /* sort across rows, not down columns */ +extern int f_sortacross; /* sort across rows, not down columns */ extern int f_statustime; /* use time of last mode change */ +extern char *f_timeformat; /* user-specified time format */ extern int f_notabs; /* don't use tab-separated multi-col output */ extern int f_type; /* add type character for non-regular files */ #ifdef COLORLS diff --git a/bin/ls/print.c b/bin/ls/print.c index 6578b93aff7a..479b772b39d3 100644 --- a/bin/ls/print.c +++ b/bin/ls/print.c @@ -168,7 +168,7 @@ printlong(const DISPLAY *dp) prevdev = sp->st_dev; } np = p->fts_pointer; - (void)printf("%s %*u %-*s %-*s ", buf, dp->s_nlink, + (void)printf("%s %*u %-*s %-*s ", buf, dp->s_nlink, sp->st_nlink, dp->s_user, np->user, dp->s_group, np->group); if (f_flags) @@ -237,7 +237,7 @@ printstream(const DISPLAY *dp) if (chcnt) putchar('\n'); } - + void printcol(const DISPLAY *dp) { @@ -378,17 +378,20 @@ printtime(time_t ftime) now = time(NULL); #define SIXMONTHS ((365 / 2) * 86400) - if (f_sectime) + if (f_timeformat) /* user specified format */ + format = f_timeformat; + else if (f_sectime) /* 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) /* 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 /* mmm dd yyyy || dd mmm yyyy */ - format = d_first ? "%e %b %Y " : "%b %e %Y "; + format = d_first ? "%e %b %Y" : "%b %e %Y"; strftime(longstring, sizeof(longstring), format, localtime(&ftime)); fputs(longstring, stdout); + fputc(' ', stdout); } static int @@ -625,7 +628,7 @@ aclmode(char *buf, const FTSENT *p, int *haveacls) snprintf(name, sizeof(name), "%s", p->fts_name); else snprintf(name, sizeof(name), "%s/%s", - p->fts_parent->fts_accpath, p->fts_name); + p->fts_parent->fts_accpath, p->fts_name); /* * We have no way to tell whether a symbolic link has an ACL since * pathconf() and acl_get_file() both follow them. They also don't