Return to BSD News archive
Path: sserve!newshost.anu.edu.au!harbinger.cc.monash.edu.au!bunyip.cc.uq.oz.au!munnari.oz.au!ihnp4.ucsd.edu!agate!asami From: asami@cs.berkeley.edu (Satoshi ASAMI) Newsgroups: comp.os.386bsd.apps Subject: colorls for FreeBSD 2.0R Date: 03 Jan 1995 06:21:05 GMT Organization: CS Div. - EECS, The University of California, Berkeley, CA 94720 Lines: 374 Message-ID: <ASAMI.95Jan2222105@forgery.cs.berkeley.edu> NNTP-Posting-Host: forgery.cs.berkeley.edu I put a color version of ls in ftp://ftp.freebsd.org/pub/FreeBSD/incoming/colorls.tar.gz (source) ftp://ftp.freebsd.org/pub/FreeBSD/incoming/colorls.tgz (package) Note that the regular xterm doesn't understand ANSI color sequences. I use color_xterm and kterm (both available from ports). Diffs from the stock version are included below for your amusement. Satoshi ======= diff -ru /usr/src/bin/ls/Makefile colorls/Makefile --- /usr/src/bin/ls/Makefile Fri Sep 23 19:55:51 1994 +++ colorls/Makefile Mon Jan 2 21:50:53 1995 @@ -1,7 +1,15 @@ # @(#)Makefile 8.1 (Berkeley) 6/2/93 # Makefile,v 1.2 1994/09/24 02:55:51 davidg Exp -PROG= ls +PROG= colorls SRCS= cmp.c stat_flags.c ls.c print.c util.c +BINDIR= /usr/local/bin +MANDIR= /usr/local/man/man + +beforeinstall: + cp ls.1 colorls.1 + +package: all install + pkg_create -v -c pkg/COMMENT -d pkg/DESCR -f pkg/PLIST ${PROG}.tgz .include <bsd.prog.mk> diff -ru /usr/src/bin/ls/ls.1 colorls/ls.1 --- /usr/src/bin/ls/ls.1 Fri Sep 23 19:55:53 1994 +++ colorls/ls.1 Mon Jan 2 21:45:52 1995 @@ -36,16 +36,24 @@ .\" ls.1,v 1.3 1994/09/24 02:55:53 davidg Exp .\" .Dd April 18, 1994 -.Dt LS 1 +.Dt COLORLS 1 .Os .Sh NAME -.Nm ls -.Nd list directory contents +.Nm colorls +.Nd list directory contents in color .Sh SYNOPSIS -.Nm ls -.Op Fl ACFLRTacdfiloqrstu1 +.Nm colorls +.Op Fl ACFGLRTacdfiloqrstu1 .Op Ar file ... .Sh DESCRIPTION +(Note: This man page describes the color version of the program. To +minimize the differences from the original, the program is referred to +as +.Nm ls +in this manual. The new option +.Fl G +is for color display.) +.Pp For each operand that names a .Ar file of a type other than @@ -85,6 +93,12 @@ and an at sign (@) after each symbolic link. .\" and a vertical bar (|) after each that is a .\" .Tn FIFO . +.It Fl G +Use 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 L If argument is a symbolic link, list the file or directory the link references rather than the link itself. @@ -314,6 +328,74 @@ 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 +yellow +.It Sy 4 +blue +.It Sy 5 +magenta +.It Sy 6 +cyan +.It Sy 7 +white +.It Sy x +default foreground or background +.El +.Pp +(Note: the above are standard 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. .El .Sh COMPATIBILITY The group field is now automatically included in the long listing for diff -ru /usr/src/bin/ls/ls.c colorls/ls.c --- /usr/src/bin/ls/ls.c Fri Sep 23 19:55:54 1994 +++ colorls/ls.c Wed Nov 23 18:41:28 1994 @@ -93,6 +93,7 @@ int f_dirname; /* if precede with directory name */ int f_timesort; /* sort by time vice name */ int f_type; /* add type character for non-regular files */ +int f_color; /* add type in color for non-regular files */ int main(argc, argv) @@ -122,7 +123,7 @@ f_listdot = 1; fts_options = FTS_PHYSICAL; - while ((ch = getopt(argc, argv, "1ACFLRTacdfgikloqrstu")) != EOF) { + while ((ch = getopt(argc, argv, "1ACFGLRTacdfgikloqrstu")) != EOF) { switch (ch) { /* * The -1, -C and -l options all override each other so shell @@ -152,6 +153,9 @@ case 'F': f_type = 1; break; + case 'G': + f_color = 1; + break; case 'L': fts_options &= ~FTS_PHYSICAL; fts_options |= FTS_LOGICAL; @@ -207,18 +211,21 @@ argc -= optind; argv += optind; + parsecolors(getenv("LSCOLORS")); + /* * If not -F, -i, -l, -s or -t options, don't require stat * information. */ - if (!f_inode && !f_longform && !f_size && !f_timesort && !f_type) + if (!f_inode && !f_longform && !f_size && !f_timesort && !f_type + && !f_color) fts_options |= FTS_NOSTAT; /* * If not -F, -d or -l options, follow any symbolic links listed on * the command line. */ - if (!f_longform && !f_listdir && !f_type) + if (!f_longform && !f_listdir && !f_type && !f_color) fts_options |= FTS_COMFOLLOW; /* If -l or -s, figure out block size. */ diff -ru /usr/src/bin/ls/ls.h colorls/ls.h --- /usr/src/bin/ls/ls.h Fri Sep 23 19:55:55 1994 +++ colorls/ls.h Wed Nov 23 18:43:22 1994 @@ -49,6 +49,7 @@ extern int f_size; /* list size in short listing */ extern int f_statustime; /* use time of last mode change */ extern int f_type; /* add type character for non-regular files */ +extern int f_color; /* add type in color for non-regular files */ typedef struct { FTSENT *list; diff -ru /usr/src/bin/ls/print.c colorls/print.c --- /usr/src/bin/ls/print.c Fri Sep 23 19:55:56 1994 +++ colorls/print.c Wed Nov 23 19:04:26 1994 @@ -66,6 +66,26 @@ #define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT) +/* 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]; + void printscol(dp) DISPLAY *dp; @@ -122,10 +142,14 @@ printtime(sp->st_ctime); else printtime(sp->st_mtime); + if (f_color) + (void)colortype(sp->st_mode); (void)printf("%s", p->fts_name); if (f_type) (void)printtype(sp->st_mode); - if (S_ISLNK(sp->st_mode)) + if (f_color) + (void)printf("\033[m"); + if (S_ISLNK(sp->st_mode)) printlink(p); (void)putchar('\n'); } @@ -217,9 +241,13 @@ if (f_size) chcnt += printf("%*qd ", (int)sizefield, howmany(sp->st_blocks, blocksize)); + if (f_color) + (void)colortype(sp->st_mode); chcnt += printf("%s", p->fts_name); if (f_type) chcnt += printtype(sp->st_mode); + if (f_color) + printf("\033[m"); return (chcnt); } @@ -274,6 +302,95 @@ return (0); } +void +printcolor(c) + Colors c; +{ + printf("\033["); + if (colors[c][0] != -1) { + printf("3%d", colors[c][0]); + if (colors[c][1] != -1) + printf(";"); + } + if (colors[c][1] != -1) + printf("4%d", colors[c][1]); + printf("m"); +} + +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(c[j]) != 'x') { + fprintf(stderr, + "error: invalid character '%c' in LSCOLORS env var\n", + c[j]); + c[j] = defcolors[2*i+j]; + } + if (c[j] == 'x') + colors[i][j] = -1; + else + colors[i][j] = c[j]-'0'; + } + } +} + static void printlink(p) FTSENT *p;