diff options
| author | Andrey A. Chernov <ache@FreeBSD.org> | 2000-07-04 18:45:27 +0000 |
|---|---|---|
| committer | Andrey A. Chernov <ache@FreeBSD.org> | 2000-07-04 18:45:27 +0000 |
| commit | 8d11ea018dedd9ed02b8326db65bcc1d95aa2ef3 (patch) | |
| tree | feca5f9b882fb5457c7d03d5d7e92beb067d423a /bin | |
| parent | c226261be470f9f7ab1736659474ff9f116b8174 (diff) | |
Notes
Diffstat (limited to 'bin')
| -rw-r--r-- | bin/ls/Makefile | 6 | ||||
| -rw-r--r-- | bin/ls/extern.h | 8 | ||||
| -rw-r--r-- | bin/ls/ls.1 | 84 | ||||
| -rw-r--r-- | bin/ls/ls.c | 68 | ||||
| -rw-r--r-- | bin/ls/ls.h | 3 | ||||
| -rw-r--r-- | bin/ls/print.c | 185 | ||||
| -rw-r--r-- | bin/ls/util.c | 7 |
7 files changed, 355 insertions, 6 deletions
diff --git a/bin/ls/Makefile b/bin/ls/Makefile index 1ab70dc78a17..96dffe1015de 100644 --- a/bin/ls/Makefile +++ b/bin/ls/Makefile @@ -5,4 +5,10 @@ PROG= ls SRCS= cmp.c ls.c print.c util.c +.if !defined(RELEASE_BUILD_FIXIT) +CFLAGS+= -DCOLORLS +LDADD+= -ltermcap +DPADD+= ${LIBTERMCAP} +.endif + .include <bsd.prog.mk> diff --git a/bin/ls/extern.h b/bin/ls/extern.h index f17607394d3e..4b27be666580 100644 --- a/bin/ls/extern.h +++ b/bin/ls/extern.h @@ -50,3 +50,11 @@ void printscol __P((DISPLAY *)); void usage __P((void)); int len_octal __P((char *, int)); int prn_octal __P((char *)); +#ifdef COLORLS +void parsecolors __P((char *cs)); +void colorquit __P((int)); + +extern char *ansi_fgcol; +extern char *ansi_bgcol; +extern char *ansi_coloff; +#endif diff --git a/bin/ls/ls.1 b/bin/ls/ls.1 index 146066075565..4bbf62074f7a 100644 --- a/bin/ls/ls.1 +++ b/bin/ls/ls.1 @@ -43,7 +43,7 @@ .Nd list directory contents .Sh SYNOPSIS .Nm ls -.Op Fl ABCFHLPRTWabcdfgiklnoqrstu1 +.Op Fl ABCFGHLPRTWabcdfgiklnoqrstu1 .Op Ar file ... .Sh DESCRIPTION For each operand that names a @@ -90,6 +90,16 @@ an equals sign (=) after each socket, a percent sign (%) after each whiteout, and a vertical bar (|) after each that is a .Tn FIFO . +.It Fl G +Use +.Tn ANSI +color sequences to distinguish file types. +See +.Ev LSCOLORS +below. +In addition to those mentioned above in +.Fl F , +some extra attributes (setuid bit set, etc.) are also displayed. .It Fl H Symbolic links on the command line are followed. This option is assumed if none of the @@ -388,6 +398,78 @@ format output. See .Xr environ 7 for more information. +.It LSCOLORS +The value of this variable describes what color to use for which +attribute when the color output +.Pq Fl G +is specified. +This string is a concatenation of pairs of the format +.Sy fb , +where +.Sy f +is the foreground color and +.Sy b +is the background color. +.Pp +The color designators are as follows: +.Pp +.Bl -tag -width 4n -offset indent -compact +.It Sy 0 +black +.It Sy 1 +red +.It Sy 2 +green +.It Sy 3 +brown +.It Sy 4 +blue +.It Sy 5 +magenta +.It Sy 6 +cyan +.It Sy 7 +light grey +.It Sy x +default foreground or background +.El +.Pp +Note that the above are standard +.Tn ANSI +colors. +The actual display may differ +depending on the color capabilities of your terminal. +.Pp +The order of the attributes are as follows: +.Pp +.Bl -enum -offset indent -compact +.It +directory +.It +symbolic link +.It +socket +.It +pipe +.It +executable +.It +block special +.It +character special +.It +executable with setuid bit set +.It +executable with setgid bit set +.It +directory writable to others, with sticky bit +.It +directory writable to others, without sticky bit +.El +.Pp +The default is "4x5x2x3x1x464301060203", i.e. blue foreground and +default background for regular directories, black foreground and red +background for setuid executables, etc. .It Ev LS_COLWIDTHS If this variable is set, it is considered to be a colon-delimited list of minimum column widths. Unreasonable diff --git a/bin/ls/ls.c b/bin/ls/ls.c index 5a637f5f848f..69b8d774b042 100644 --- a/bin/ls/ls.c +++ b/bin/ls/ls.c @@ -63,6 +63,10 @@ static const char rcsid[] = #include <stdlib.h> #include <string.h> #include <unistd.h> +#ifdef COLORLS +#include <termcap.h> +#include <signal.h> +#endif #include "ls.h" #include "extern.h" @@ -109,6 +113,13 @@ int f_statustime; /* use time of last mode change */ int f_timesort; /* sort by time vice name */ int f_type; /* add type character for non-regular files */ int f_whiteout; /* show whiteout entries */ +#ifdef COLORLS +int f_color; /* add type in color for non-regular files */ + +char *ansi_bgcol; /* ANSI sequence to set background colour */ +char *ansi_fgcol; /* ANSI sequence to set foreground colour */ +char *ansi_coloff; /* ANSI sequence to reset colours */ +#endif int rval; @@ -122,6 +133,12 @@ main(argc, argv) int ch, fts_options, notused; char *p; +#ifdef COLORLS + char termcapbuf[1024]; /* termcap definition buffer */ + char tcapbuf[512]; /* capability buffer */ + char *bp = tcapbuf; +#endif + (void) setlocale(LC_ALL, ""); /* Terminal defaults to -Cq, non-terminal defaults to -1. */ @@ -146,7 +163,7 @@ main(argc, argv) f_listdot = 1; fts_options = FTS_PHYSICAL; - while ((ch = getopt(argc, argv, "1ABCFHLPRTWabcdfgiklnoqrstu")) != -1) { + while ((ch = getopt(argc, argv, "1ABCFGHLPRTWabcdfgiklnoqrstu")) != -1) { switch (ch) { /* * The -1, -C and -l options all override each other so shell @@ -184,6 +201,26 @@ main(argc, argv) case 'H': fts_options |= FTS_COMFOLLOW; break; + case 'G': + if (isatty(STDOUT_FILENO)) +#ifdef COLORLS + if (tgetent(termcapbuf, getenv("TERM")) == 1) { + ansi_fgcol = tgetstr("AF", &bp); + ansi_bgcol = tgetstr("AB", &bp); + + /* To switch colours off use 'op' if + * available, otherwise use 'oc', or + * don't do colours at all. */ + ansi_coloff = tgetstr("op", &bp); + if (!ansi_coloff) + ansi_coloff = tgetstr("oc", &bp); + if (ansi_fgcol && ansi_bgcol && ansi_coloff) + f_color = 1; + } +#else + (void)fprintf(stderr, "Color support not compiled in.\n"); +#endif + break; case 'L': fts_options &= ~FTS_PHYSICAL; fts_options |= FTS_LOGICAL; @@ -257,11 +294,30 @@ main(argc, argv) argc -= optind; argv += optind; +#ifdef COLORLS + if (f_color) { + /* + * We can't put tabs and color sequences together: + * column number will be incremented incorrectly + * for "stty oxtabs" mode. + */ + f_notabs = 1; + (void) signal(SIGINT, colorquit); + (void) signal(SIGQUIT, colorquit); + parsecolors(getenv("LSCOLORS")); + } +#endif + /* * If not -F, -i, -l, -s or -t options, don't require stat - * information. + * information, unless in color mode in which case we do + * need this to determine which colors to display. */ - if (!f_inode && !f_longform && !f_size && !f_timesort && !f_type) + if (!f_inode && !f_longform && !f_size && !f_timesort && !f_type +#ifdef COLORLS + && !f_color +#endif + ) fts_options |= FTS_NOSTAT; /* @@ -469,7 +525,11 @@ display(p, list) case 4: maxgroup = 0; case 5: maxflags = 0; case 6: maxsize = 0; - case 7: maxlen = 0, f_notabs = 0; + case 7: maxlen = 0; +#ifdef COLORLS + if (!f_color) +#endif + f_notabs = 0; } maxinode = makenines(maxinode); maxblock = makenines(maxblock); diff --git a/bin/ls/ls.h b/bin/ls/ls.h index 33c98c45aab8..3da163d95319 100644 --- a/bin/ls/ls.h +++ b/bin/ls/ls.h @@ -53,6 +53,9 @@ extern int f_size; /* list size in short listing */ extern int f_statustime; /* use time of last mode change */ 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 +extern int f_color; /* add type in color for non-regular files */ +#endif typedef struct { FTSENT *list; diff --git a/bin/ls/print.c b/bin/ls/print.c index d6792ee3699e..736754abe292 100644 --- a/bin/ls/print.c +++ b/bin/ls/print.c @@ -56,6 +56,11 @@ static const char rcsid[] = #include <string.h> #include <time.h> #include <unistd.h> +#ifdef COLORLS +#include <ctype.h> +#include <termcap.h> +#include <signal.h> +#endif #include "ls.h" #include "extern.h" @@ -64,9 +69,35 @@ static int printaname __P((FTSENT *, u_long, u_long)); static void printlink __P((FTSENT *)); static void printtime __P((time_t)); static int printtype __P((u_int)); +#ifdef COLORLS +static void endcolor __P((int)); +static int colortype __P((mode_t)); +#endif #define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT) +#ifdef COLORLS +/* Most of these are taken from <sys/stat.h> */ +typedef enum Colors { + C_DIR, /* directory */ + C_LNK, /* symbolic link */ + C_SOCK, /* socket */ + C_FIFO, /* pipe */ + C_EXEC, /* executable */ + C_BLK, /* block special */ + C_CHR, /* character special */ + C_SUID, /* setuid executable */ + C_SGID, /* setgid executable */ + C_WSDIR, /* directory writeble to others, with sticky bit */ + C_WDIR, /* directory writeble to others, without sticky bit */ + C_NUMCOLORS /* just a place-holder */ +} Colors ; + +char *defcolors = "4x5x2x3x1x464301060203"; + +static int colors[C_NUMCOLORS][2]; +#endif + void printscol(dp) DISPLAY *dp; @@ -89,6 +120,9 @@ printlong(dp) FTSENT *p; NAMES *np; char buf[20]; +#ifdef COLORLS + int color_printed = 0; +#endif if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) (void)printf("total %lu\n", howmany(dp->btotal, blocksize)); @@ -128,8 +162,16 @@ printlong(dp) printtime(sp->st_ctime); else printtime(sp->st_mtime); +#ifdef COLORLS + if (f_color) + color_printed = colortype(sp->st_mode); +#endif if (f_octal || f_octal_escape) (void)prn_octal(p->fts_name); else (void)printf("%s", p->fts_name); +#ifdef COLORLS + if (f_color && color_printed) + endcolor(0); +#endif if (f_type) (void)printtype(sp->st_mode); if (S_ISLNK(sp->st_mode)) @@ -221,6 +263,9 @@ printaname(p, inodefield, sizefield) { struct stat *sp; int chcnt; +#ifdef COLORLS + int color_printed = 0; +#endif sp = p->fts_statp; chcnt = 0; @@ -229,8 +274,16 @@ printaname(p, inodefield, sizefield) if (f_size) chcnt += printf("%*qd ", (int)sizefield, howmany(sp->st_blocks, blocksize)); +#ifdef COLORLS + if (f_color) + color_printed = colortype(sp->st_mode); +#endif chcnt += (f_octal || f_octal_escape) ? prn_octal(p->fts_name) : printf("%s", p->fts_name); +#ifdef COLORLS + if (f_color && color_printed) + endcolor(0); +#endif if (f_type) chcnt += printtype(sp->st_mode); return (chcnt); @@ -292,6 +345,138 @@ printtype(mode) return (0); } +#ifdef COLORLS +static int +putch(c) + int c; +{ + (void) putchar(c); + return 0; +} + +static int +writech(c) + int c; +{ + char tmp = c; + + (void) write(STDOUT_FILENO, &tmp, 1); + return 0; +} + +static void +printcolor(c) + Colors c; +{ + char *ansiseq; + + if (colors[c][0] != -1) { + ansiseq = tgoto(ansi_fgcol, 0, colors[c][0]); + if (ansiseq) + tputs(ansiseq, 1, putch); + } + + if (colors[c][1] != -1) { + ansiseq = tgoto(ansi_bgcol, 0, colors[c][1]); + if (ansiseq) + tputs(ansiseq, 1, putch); + } +} + +static void +endcolor(sig) + int sig; +{ + tputs(ansi_coloff, 1, sig ? writech : putch); +} + +static int +colortype(mode) + mode_t mode; +{ + switch(mode & S_IFMT) { + case S_IFDIR: + if (mode & S_IWOTH) + if (mode & S_ISTXT) + printcolor(C_WSDIR); + else + printcolor(C_WDIR); + else + printcolor(C_DIR); + return(1); + case S_IFLNK: + printcolor(C_LNK); + return(1); + case S_IFSOCK: + printcolor(C_SOCK); + return(1); + case S_IFIFO: + printcolor(C_FIFO); + return(1); + case S_IFBLK: + printcolor(C_BLK); + return(1); + case S_IFCHR: + printcolor(C_CHR); + return(1); + } + if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { + if (mode & S_ISUID) + printcolor(C_SUID); + else if (mode & S_ISGID) + printcolor(C_SGID); + else + printcolor(C_EXEC); + return(1); + } + return(0); +} + +void +parsecolors(cs) +char *cs; +{ + int i, j, len; + char c[2]; + + if (cs == NULL) cs = ""; /* LSCOLORS not set */ + len = strlen(cs); + for (i = 0 ; i < C_NUMCOLORS ; i++) { + if (len <= 2*i) { + c[0] = defcolors[2*i]; + c[1] = defcolors[2*i+1]; + } + else { + c[0] = cs[2*i]; + c[1] = cs[2*i+1]; + } + for (j = 0 ; j < 2 ; j++) { + if ((c[j] < '0' || c[j] > '7') && + tolower((unsigned char)c[j]) != 'x') { + fprintf(stderr, + "error: invalid character '%c' in LSCOLORS env var\n", + c[j]); + c[j] = defcolors[2*i+j]; + } + if (tolower((unsigned char)c[j]) == 'x') + colors[i][j] = -1; + else + colors[i][j] = c[j]-'0'; + } + } +} + +void +colorquit(sig) + int sig; +{ + endcolor(sig); + + (void) signal(sig, SIG_DFL); + (void) kill(getpid(), sig); +} +#endif /*COLORLS*/ + static void printlink(p) FTSENT *p; diff --git a/bin/ls/util.c b/bin/ls/util.c index eea247587a9c..7239d9776abf 100644 --- a/bin/ls/util.c +++ b/bin/ls/util.c @@ -158,7 +158,12 @@ prn_octal(s) void usage() { - (void)fprintf(stderr, "usage: ls [-ACFHLPRTWacdfgiklnoqrstu1]" + (void)fprintf(stderr, +#ifdef COLORLS + "usage: ls [-ACFGHLPRTWacdfgiklnoqrstu1]" +#else + "usage: ls [-ACFHLPRTWacdfgiklnoqrstu1]" +#endif " [file ...]\n"); exit(1); } |
