$OpenBSD: patch-ls_c,v 1.19 2021/05/09 13:38:57 naddy Exp $
--- ls.c.orig	Fri Aug  5 21:32:46 2016
+++ ls.c	Fri Aug  5 21:41:30 2016
@@ -50,6 +50,10 @@
 #include <limits.h>
 #include <locale.h>
 #include <util.h>
+#ifdef COLORLS
+#include <termcap.h>
+#include <signal.h>
+#endif
 
 #include "ls.h"
 #include "extern.h"
@@ -92,6 +96,15 @@ int f_statustime;		/* use time of last mode change */
 int f_stream;			/* stream format */
 int f_type;			/* add type character for non-regular files */
 int f_typedir;			/* add type character for directories */
+#ifdef COLORLS
+int f_color;			/* add type in color for non-regular files */
+ 
+char *ansi_bgcol;		/* ANSI sequence to set background color */
+char *ansi_fgcol;		/* ANSI sequence to set foreground color */
+char *ansi_coloff;		/* ANSI sequence to reset colors */
+char *attrs_off;		/* ANSI sequence to turn off attributes */
+char *enter_bold;		/* ANSI sequence to set color to bold mode */
+#endif
 
 int rval;
 
@@ -103,6 +116,11 @@ ls_main(int argc, char *argv[])
 	int ch, fts_options, notused;
 	int kflag = 0;
 	char *p;
+#ifdef COLORLS
+	char termcapbuf[1024];	/* termcap definition buffer */
+	char tcapbuf[512];	/* capability buffer */
+	char *bp = tcapbuf;
+#endif
 
 #ifndef SMALL
 	setlocale(LC_CTYPE, "");
@@ -124,7 +142,11 @@ ls_main(int argc, char *argv[])
 	if (termwidth == 0)
 		termwidth = 80;
 
+#ifdef COLORLS
+	if (pledge("stdio rpath getpw tty", NULL) == -1)
+#else
 	if (pledge("stdio rpath getpw", NULL) == -1)
+#endif
 		err(1, "pledge");
 
 	/* Root is -A automatically. */
@@ -132,7 +154,7 @@ ls_main(int argc, char *argv[])
 		f_listdot = 1;
 
 	fts_options = FTS_PHYSICAL;
-	while ((ch = getopt(argc, argv, "1ACFHLRSTacdfghiklmnopqrstux")) != -1) {
+	while ((ch = getopt(argc, argv, "1ACFGHLRSTacdfghiklmnopqrstux")) != -1) {
 		switch (ch) {
 		/*
 		 * The -1, -C and -l, -m, -n and -x options all override each
@@ -186,6 +208,9 @@ ls_main(int argc, char *argv[])
 		case 'F':
 			f_type = 1;
 			break;
+		case 'G':
+			setenv("CLICOLOR", "", 1);
+			break;
 		case 'H':
 			fts_options |= FTS_COMFOLLOW;
 			break;
@@ -258,19 +283,59 @@ ls_main(int argc, char *argv[])
 	if (f_grouponly == -1)
 		f_grouponly = 0;
 
+	/* Enabling of colours is conditional on the environment. */
+	if (getenv("CLICOLOR") &&
+	    (isatty(STDOUT_FILENO) || getenv("CLICOLOR_FORCE")))
+#ifdef COLORLS
+		if (tgetent(termcapbuf, getenv("TERM")) == 1) {
+			ansi_fgcol = tgetstr("AF", &bp);
+			ansi_bgcol = tgetstr("AB", &bp);
+			attrs_off = tgetstr("me", &bp);
+			enter_bold = tgetstr("md", &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
+		warnx("color support not compiled in");
+#endif /*COLORLS*/
+ 
+#ifdef COLORLS
+	if (f_color) {
+		(void)signal(SIGINT, colorquit);
+		(void)signal(SIGQUIT, colorquit);
+		parsecolors(getenv("LSCOLORS"));
+	}
+#endif
+
 	/*
 	 * If not -F, -i, -l, -p, -S, -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_longform && !f_inode && !f_size && !f_type && !f_typedir &&
+#ifdef COLORLS
+	    !f_color &&
+#endif
 	    sortkey == BY_NAME)
 		fts_options |= FTS_NOSTAT;
 
 	/*
 	 * If not -F, -d or -l options, follow any symbolic links listed on
-	 * the command line.
+	 * the command line, unless in color mode in which case we need to
+	 * distinguish file type for a symbolic link itself and its target.
 	 */
-	if (!f_longform && !f_listdir && !f_type)
+	if (!f_longform && !f_listdir && !f_type
+#ifdef COLORLS
+	    && !f_color
+#endif
+	    )
 		fts_options |= FTS_COMFOLLOW;
 
 	/* If -l or -s, figure out block size. */
