home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / colorls2.zip / color-ls.dif next >
Text File  |  1996-03-04  |  46KB  |  1,634 lines

  1. *** /tmp/fu/man/ls.1    Tue Apr 26 22:08:54 1994
  2. --- man/ls.1    Thu Feb 29 03:36:20 1996
  3. ***************
  4. *** 1,9 ****
  5. ! .TH LS 1L "GNU File Utilities" "FSF" \" -*- nroff -*-
  6.   .SH NAME
  7.   ls, dir, vdir \- list contents of directories
  8.   .SH SYNOPSIS
  9.   .B ls
  10. ! [\-abcdfgiklmnpqrstuxABCFGLNQRSUX1] [\-w cols] [\-T cols] [\-I pattern]
  11.   [\-\-all] [\-\-escape] [\-\-directory] [\-\-inode] [\-\-kilobytes]
  12.   [\-\-numeric-uid-gid] [--no-group] [\-\-hide-control-chars] [\-\-reverse]
  13.   [\-\-size] [\-\-width=cols] [\-\-tabsize=cols] [\-\-almost-all]
  14. --- 1,9 ----
  15. ! .TH LS 1L "GNU File Utilities" "FSF" \" -*- nroff -*- "
  16.   .SH NAME
  17.   ls, dir, vdir \- list contents of directories
  18.   .SH SYNOPSIS
  19.   .B ls
  20. ! [\-abcdefgiklmnopqrstuxABCFGLNQRSUX178] [\-w cols] [\-T cols] [\-I pattern]
  21.   [\-\-all] [\-\-escape] [\-\-directory] [\-\-inode] [\-\-kilobytes]
  22.   [\-\-numeric-uid-gid] [--no-group] [\-\-hide-control-chars] [\-\-reverse]
  23.   [\-\-size] [\-\-width=cols] [\-\-tabsize=cols] [\-\-almost-all]
  24. ***************
  25. *** 11,21 ****
  26.   [\-\-ignore=pattern] [\-\-dereference] [\-\-literal] [\-\-quote-name]
  27.   [\-\-recursive] [\-\-sort={none,time,size,extension}]
  28.   [\-\-format={long,verbose,commas,across,vertical,single-column}]
  29. ! [\-\-time={atime,access,use,ctime,status}] [\-\-help] [\-\-version] [name...]
  30.   .SH DESCRIPTION
  31.   This manual page
  32.   documents the GNU version of
  33. ! .BR ls .
  34.   .B dir
  35.   and
  36.   .B vdir
  37. --- 11,24 ----
  38.   [\-\-ignore=pattern] [\-\-dereference] [\-\-literal] [\-\-quote-name]
  39.   [\-\-recursive] [\-\-sort={none,time,size,extension}]
  40.   [\-\-format={long,verbose,commas,across,vertical,single-column}]
  41. ! [\-\-time={atime,access,use,ctime,status}]
  42. ! [\-\-color[={yes,no,tty}]] [\-\-colour[={yes,no,tty}]]
  43. ! [\-\-unix] [\-\-help] [\-\-version] [name...]
  44.   .SH DESCRIPTION
  45.   This manual page
  46.   documents the GNU version of
  47. ! .BR ls ,
  48. ! with color extensions.
  49.   .B dir
  50.   and
  51.   .B vdir
  52. ***************
  53. *** 49,54 ****
  54. --- 52,61 ----
  55.   .I "\-d, \-\-directory"
  56.   List directories like other files, rather than listing their contents.
  57.   .TP
  58. + .I "\-e, \-\-full-time"
  59. + List times in full, rather than using the standard abbreviation
  60. + heuristics.
  61. + .TP
  62.   .I "\-f"
  63.   Do not sort directory contents; list them in whatever order they are
  64.   stored on the disk.
  65. ***************
  66. *** 58,71 ****
  67.   .I \-U
  68.   and disabling
  69.   .I \-l,
  70.   .I \-s,
  71.   and
  72.   .I \-t.
  73.   .TP
  74. - .I "\-\-full-time"
  75. - List times in full, rather than using the standard abbreviation
  76. - heuristics.
  77. - .TP
  78.   .I \-g
  79.   Ignored; for Unix compatibility.
  80.   .TP
  81. --- 65,75 ----
  82.   .I \-U
  83.   and disabling
  84.   .I \-l,
  85. + .I \-o,
  86.   .I \-s,
  87.   and
  88.   .I \-t.
  89.   .TP
  90.   .I \-g
  91.   Ignored; for Unix compatibility.
  92.   .TP
  93. ***************
  94. *** 74,80 ****
  95.   .TP
  96.   .I "\-k, \-\-kilobytes"
  97.   If file sizes are being listed, print them in kilobytes.  This
  98. ! overrides the environment variable POSIXLY_CORRECT.
  99.   .TP
  100.   .I "\-l, \-\-format=long, \-\-format=verbose"
  101.   In addition to the name of each file, print the file type,
  102. --- 78,85 ----
  103.   .TP
  104.   .I "\-k, \-\-kilobytes"
  105.   If file sizes are being listed, print them in kilobytes.  This
  106. ! overrides the environment variable 
  107. ! .BR POSIXLY_CORRECT .
  108.   .TP
  109.   .I "\-l, \-\-format=long, \-\-format=verbose"
  110.   In addition to the name of each file, print the file type,
  111. ***************
  112. *** 91,96 ****
  113. --- 96,109 ----
  114.   .I "\-n, \-\-numeric-uid-gid"
  115.   List the numeric UID and GID instead of the names.
  116.   .TP
  117. + .I "\-o, \-\-color, \-\-colour, \-\-color=yes, \-\-colour=yes"
  118. + Colorize the names of files depending on the type of file.
  119. + See `DISPLAY COLORIZATION' below.  Note that
  120. + .I \-o
  121. + unlike
  122. + .I \-\-color
  123. + is a toggle.
  124. + .TP
  125.   .I \-p
  126.   Append a character to each file name indicating the file type.
  127.   .TP
  128. ***************
  129. *** 102,108 ****
  130.   .TP
  131.   .I "\-s, \-\-size"
  132.   Print the size of each file in 1K blocks to the left of the file name.
  133. ! If the environment variable POSIXLY_CORRECT is set, 512-byte blocks
  134.   are used instead.
  135.   .TP
  136.   .I "\-t, \-\-sort=time"
  137. --- 115,123 ----
  138.   .TP
  139.   .I "\-s, \-\-size"
  140.   Print the size of each file in 1K blocks to the left of the file name.
  141. ! If the environment variable 
  142. ! .B POSIXLY_CORRECT
  143. ! is set, 512-byte blocks
  144.   are used instead.
  145.   .TP
  146.   .I "\-t, \-\-sort=time"
  147. ***************
  148. *** 190,196 ****
  149.   .I "\-T, \-\-tabsize cols"
  150.   Assume that each tabstop is
  151.   .I cols
  152. ! columns wide.  The default is 8.
  153.   .TP
  154.   .I "\-I, \-\-ignore pattern"
  155.   Do not list files whose names match the shell pattern
  156. --- 205,214 ----
  157.   .I "\-T, \-\-tabsize cols"
  158.   Assume that each tabstop is
  159.   .I cols
  160. ! columns wide.  The default is 8, or whatever the
  161. ! .B TABSIZE
  162. ! environment variable says.  Setting the tabsize to 0 disables
  163. ! the use of tab characters completely.
  164.   .TP
  165.   .I "\-I, \-\-ignore pattern"
  166.   Do not list files whose names match the shell pattern
  167. ***************
  168. *** 199,209 ****
  169. --- 217,356 ----
  170.   initial `.' in a filename does not match a wildcard at the start of
  171.   .I pattern.
  172.   .TP
  173. + .I "\-\-color=tty, \-\-colour=tty"
  174. + Same as
  175. + .I \-o
  176. + but only if standard output is a terminal.  This is very useful for
  177. + shell scripts and command aliases, especially if your favorite pager
  178. + does not support color control codes.
  179. + .TP
  180. + .I "\-\-color=no, \-\-colour=no"
  181. + Disables colorization.  This is the default.  Provided to override a
  182. + previous color option.
  183. + .TP
  184.   .I "\-\-help"
  185.   Print a usage message on standard output and exit successfully.
  186.   .TP
  187.   .I "\-\-version"
  188.   Print version information on standard output then exit successfully.
  189. + .TP
  190. + .I "\-\-unix"
  191. + Print plain UNIX long format instead of OS/2 format. 
  192. + .SS DISPLAY COLORIZATION
  193. + When using the
  194. + .I "\-o"
  195. + or
  196. + .I "\-\-color"
  197. + options, this version of
  198. + .B ls
  199. + will colorize the file names printed according to the name and type of
  200. + file.  By default, this colorization is by type only, and the codes
  201. + used are ISO 6429 (ANSI) compliant.
  202. + .PP
  203. + You can override the default colors by defining the environment
  204. + variable 
  205. + .B LS_COLORS
  206. + (or 
  207. + .BR LS_COLOURS ).
  208. + The format of this variable is reminicent of the termcap(5) file
  209. + format; a colon-separated list of expressions of the form "xx=string",
  210. + where "xx" is a two-character variable name.  The variables with their
  211. + associated defaults are:
  212. + .sp
  213. + .RS +.2i
  214. + .ta 1.0i 2.5i
  215. + .nf
  216. + \fBno\fR    0    Normal (non-filename) text
  217. + \fBfi\fR    1    Regular file
  218. + \fBdi\fR    32;1    Directory
  219. + .\"" \fBln\fR    36    Symbolic link
  220. + .\"" \fBpi\fR    31    Named pipe (FIFO)
  221. + .\"" \fBso\fR    33    Socket
  222. + .\"" \fBbd\fR    44;37    Block device
  223. + .\"" \fBcd\fR    44;37    Character device
  224. + \fBex\fR    35;1    Executable file
  225. + \fBsy\fR    31;1    System file
  226. + \fBro\fR    33;1    Read-only file
  227. + \fBhi\fR    44;37;1    Hidden file
  228. + .\"" \fBmi\fR    (none)    Missing file (defaults to fi)
  229. + .\"" \fBor\fR    (none)    Orphanned symbolic link (defaults to ln)
  230. + \fBlc\fR    \ee[    Left code
  231. + \fBrc\fR    m    Right code
  232. + \fBec\fR    (none)    End code (replaces lc+no+rc)
  233. + .fi
  234. + .RE
  235. + .sp
  236. + You only need to include the variables you want to change from the
  237. + default.
  238. + .PP
  239. + File names can also be colorized based on filename extension.  This is
  240. + specified in the LS_COLORS variable using the syntax "*ext=string".
  241. + For example, using ISO 6429 codes, to color all C-language source
  242. + files blue you would specify "*.c=34".  This would color all files
  243. + ending in .c in blue (34) color.
  244. + .PP
  245. + Control characters can be written either in C-style \e-escaped
  246. + notation, or in
  247. + .BR stty -like
  248. + ^-notation.  The C-style notation adds \ee for Escape, \e_ for a
  249. + normal space characer, and \e? for Delete.  In addition, the \e escape
  250. + character can be used to override the default interpretation of \e, ^,
  251. + : and =.
  252. + .PP
  253. + Each file will be written as <lc> <color\ code> <rc> <filename> <ec>.
  254. + If the <ec> code is undefined, the sequence <lc> <no> <rc> will be
  255. + used instead.  This is generally more convenient to use, but less
  256. + general.  The left, right and end codes are provided so you don't have
  257. + to type common parts over and over again and to support weird
  258. + terminals; you will generally not need to change them at all unless
  259. + your terminal does not use ISO 6429 color sequences but a different
  260. + system.
  261. + .PP
  262. + If your terminal does use ISO 6429 color codes, you can compose the type
  263. + codes (i.e. all except the 
  264. + .BR lc ,
  265. + .BR rc ,
  266. + and
  267. + .B ec
  268. + codes) from numerical commands separated by semicolons.  The most
  269. + common commands are:
  270. + .sp
  271. + .RS +.2i
  272. + .ta 1.0i
  273. + .nf
  274. +  0    to restore default color
  275. +  1    for brighter colors 
  276. +  4    for underlined text
  277. +  5    for flashing text
  278. + 30    for black foreground
  279. + 31    for red foreground
  280. + 32    for green foreground
  281. + 33    for yellow (or brown) foreground
  282. + 34    for blue foreground
  283. + 35    for purple foreground
  284. + 36    for cyan foreground
  285. + 37    for white (or gray) foreground
  286. + 40    for black background
  287. + 41    for red background
  288. + 42    for green background
  289. + 43    for yellow (or brown) background
  290. + 44    for blue background
  291. + 45    for purple background
  292. + 46    for cyan background
  293. + 47    for white (or gray) background
  294. + .fi
  295. + .RE
  296. + .sp
  297. + Not all commands will work on all systems or display devices.
  298. + .PP
  299. + A few terminal programs do not recognize the default end code
  300. + properly.  If all text gets colorized after you do a directory
  301. + listing, try changing the
  302. + .B no
  303. + and
  304. + .B fi
  305. + codes from 0 to the numerical codes for your standard fore- and
  306. + background colors.
  307.   .SH BUGS
  308.   On BSD systems, the
  309.   .I \-s
  310. ***************
  311. *** 214,216 ****
  312. --- 361,374 ----
  313.   HP-UX
  314.   .B ls
  315.   program.
  316. + .PP
  317. + Character set selection should be more system independent.
  318. + .PP
  319. + Using the colorization options disables the use of the tab character for
  320. + column spacing unless the
  321. + .I \-T
  322. + option is used; apparently some systems do not like tabs and color
  323. + codes in conjunction.
  324. + .PP
  325. + If there was a single standard for the English language it would not
  326. + be necessary to support redundant spellings.
  327. *** /tmp/fu/src/ls.c    Fri Dec 16 22:13:16 1994
  328. --- src/ls.c    Mon Mar 04 00:00:48 1996
  329. ***************
  330. *** 15,37 ****
  331.      along with this program; if not, write to the Free Software
  332.      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  333.   
  334. ! /* If the macro MULTI_COL is defined,
  335.      the multi-column format is the default regardless
  336.      of the type of output device.
  337.      This is for the `dir' program.
  338.   
  339. !    If the macro LONG_FORMAT is defined,
  340.      the long format is the default regardless of the
  341.      type of output device.
  342.      This is for the `vdir' program.
  343.   
  344. !    If neither is defined,
  345.      the output format depends on whether the output
  346.      device is a terminal.
  347. !    This is for the `ls' program. */
  348.   
  349.   /* Written by Richard Stallman and David MacKenzie. */
  350.   
  351.   #ifdef _AIX
  352.    #pragma alloca
  353.   #endif
  354. --- 15,48 ----
  355.      along with this program; if not, write to the Free Software
  356.      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  357.   
  358. ! /* If the first character after the last slash in argv[0] is 'd',
  359.      the multi-column format is the default regardless
  360.      of the type of output device.
  361.      This is for the `dir' program.
  362.   
  363. !    If the first character after the last slash in argv[0] is 'v',
  364.      the long format is the default regardless of the
  365.      type of output device.
  366.      This is for the `vdir' program.
  367.   
  368. !    If the first character after the last slash in argv[0] is 'l',
  369.      the output format depends on whether the output
  370.      device is a terminal.
  371. !    This is for the `ls' program.
  372. !    If it is anything else, the default will depend on if this program
  373. !    is linked with ls-ls.c, ls-dir.c or ls-vdir.c.
  374. !    This behaviour can be overridden by defining NO_NAME_DEPENDENCE
  375. !    at compile time.  */
  376.   
  377.   /* Written by Richard Stallman and David MacKenzie. */
  378.   
  379. + /* Colour and 8-bit support by Peter Anvin <hpa@nwu.edu> and
  380. +    Dennis Flaherty <dennisf@denix.elk.miles.com> based on original
  381. +    patches by Greg Lee <lee@uhunix.uhcc.hawaii.edu>.  See file
  382. +    color-ls.log for revision history. */
  383.   #ifdef _AIX
  384.    #pragma alloca
  385.   #endif
  386. ***************
  387. *** 114,119 ****
  388. --- 125,131 ----
  389.   static int compare_extension ();
  390.   static int rev_cmp_extension ();
  391.   static int decode_switches ();
  392. + static void parse_ls_color ();
  393.   static int file_interesting ();
  394.   static int gobble_file ();
  395.   static int is_not_dot_or_dotdot ();
  396. ***************
  397. *** 130,137 ****
  398. --- 142,152 ----
  399.   static void print_horizontal ();
  400.   static void print_long_format ();
  401.   static void print_many_per_line ();
  402. + static void print_fancy_name ();
  403.   static void print_name_with_quoting ();
  404.   static void print_type_indicator ();
  405. + static void print_color_indicator ();
  406. + static void put_indicator ();
  407.   static void print_with_commas ();
  408.   static void queue_directory ();
  409.   static void sort_files ();
  410. ***************
  411. *** 162,167 ****
  412. --- 177,186 ----
  413.     /* For symbolic link and long listing, st_mode of file linked to, otherwise
  414.        zero. */
  415.     unsigned int linkmode;
  416. +   
  417. +   /* For symbolic link and color printing, 1 if linked-to file exits,
  418. +      otherwise 0 */
  419. +   int linkok;
  420.   
  421.     enum filetype filetype;
  422.   };
  423. ***************
  424. *** 214,220 ****
  425.      one_per_line for just names, one per line.
  426.      many_per_line for just names, many per line, sorted vertically.
  427.      horizontal for just names, many per line, sorted horizontally.
  428. !    with_commas for just names, many per line, separated by commas.
  429.   
  430.      -l, -1, -C, -x and -m control this parameter.  */
  431.   
  432. --- 233,239 ----
  433.      one_per_line for just names, one per line.
  434.      many_per_line for just names, many per line, sorted vertically.
  435.      horizontal for just names, many per line, sorted horizontally.
  436. !    with_commas for just names, many per line, separated by commas
  437.   
  438.      -l, -1, -C, -x and -m control this parameter.  */
  439.   
  440. ***************
  441. *** 240,246 ****
  442.   
  443.   static enum time_type time_type;
  444.   
  445. ! /* print the full time, otherwise the standard unix heuristics. */
  446.   
  447.   int full_time;
  448.   
  449. --- 259,265 ----
  450.   
  451.   static enum time_type time_type;
  452.   
  453. ! /* print the full time, otherwise the standard unix heuristics. -e */
  454.   
  455.   int full_time;
  456.   
  457. ***************
  458. *** 305,310 ****
  459. --- 324,439 ----
  460.   
  461.   static enum indicator_style indicator_style;
  462.   
  463. + /* Nonzero means use colors to mark types.  Also define the different
  464. +    colors as well as the stuff for the LS_COLORS environment variable.
  465. +    The LS_COLORS variable is now in a termcap-like format.  -o */
  466. + int print_with_color;
  467. + enum color_type
  468. + {
  469. +   color_no,            /* 0: default or --color=no */
  470. +   color_yes,            /* 1: -o or --color=yes */
  471. +   color_if_tty            /* 2: --color=tty */
  472. + };
  473. + /* Note that color_no and color_yes equals boolean values; they will
  474. +    be assigned to print_with_color which is a boolean variable */
  475. + #ifndef OS2
  476. + enum indicator_no
  477. + { C_LEFT, C_RIGHT, C_END, C_NORM, C_FILE, C_DIR, C_LINK, C_FIFO, C_SOCK, 
  478. +   C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC };
  479. + char *indicator_name[]=
  480. + {
  481. +   "lc","rc","ec","no","fi","di","ln","pi","so","bd","cd","mi","or",
  482. +   "ex",NULL
  483. + };
  484. + #else
  485. + enum indicator_no
  486. + { C_LEFT, C_RIGHT, C_END, C_NORM, C_FILE, C_DIR, C_LINK, C_FIFO, C_SOCK, 
  487. +   C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_SYSTEM, C_RDONLY, C_HIDDEN, };
  488. + char *indicator_name[]=
  489. + {
  490. +   "lc","rc","ec","no","fi","di","ln","pi","so","bd","cd","mi","or",
  491. +   "ex","sy","ro","hi",NULL
  492. + };
  493. + #define S_IFRDONLY    01000000
  494. + #define S_IFHIDDEN    02000000
  495. + #define S_IFSYSTEM    04000000
  496. + #define S_ISRDONLY(mode)    (((mode) & S_IFRDONLY) == S_IFRDONLY)
  497. + #define S_ISHIDDEN(mode)    (((mode) & S_IFHIDDEN) == S_IFHIDDEN)
  498. + #define S_ISSYSTEM(mode)    (((mode) & S_IFSYSTEM) == S_IFSYSTEM)
  499. + static __inline void os2_modify_stat( struct stat* buf ) {
  500. +     buf->st_mode |= (buf->st_attr&7)<<18;
  501. +     return;
  502. + }
  503. + #endif
  504. + /* Null is a valid character in a color indicator (think about Epson
  505. +    printers, for example) so we have to use a length/buffer string
  506. +    type. */
  507. + struct bin_str
  508. + {
  509. +   unsigned int len;        /* Number of bytes */
  510. +   char *string;            /* Pointer to the same */
  511. + };
  512. + struct bin_str color_indicator[] =
  513. + {
  514. +   { 2, "\033[" },        /* lc: Left of color sequence */
  515. +   { 1, "m" },            /* rc: Right of color sequence */
  516. +   { 0, NULL },            /* ec: End color (replaces lc+no+rc) */
  517. +   { 1, "0" },            /* no: Normal */
  518. + #ifndef OS2
  519. +   { 1, "0" },            /* fi: File: default */
  520. +   { 2, "32" },            /* di: Directory: green */
  521. +   { 2, "36" },            /* ln: Symlink: cyan */
  522. +   { 2, "31" },            /* pi: Pipe: red */
  523. +   { 2, "33" },            /* so: Socket: yellow/brown */
  524. +   { 5, "44;37" },        /* bd: Block device: white on blue */
  525. +   { 5, "44;37" },        /* cd: Char device: white on blue */
  526. +   { 0, NULL },            /* mi: Missing file: undefined */
  527. +   { 0, NULL },            /* or: Orphanned symlink: undefined */
  528. +   { 2, "35" }            /* ex: Executable: purple */
  529. + #else
  530. +   { 1, "1" },            /* fi: File: default+ */
  531. +   { 4, "32;1" },        /* di: Directory: green+ */
  532. +   { 2, "36" },            /* ln: Symlink: cyan */
  533. +   { 2, "31" },            /* pi: Pipe: red */
  534. +   { 2, "33" },            /* so: Socket: yellow/brown */
  535. +   { 5, "44;37" },        /* bd: Block device: white on blue */
  536. +   { 5, "44;37" },        /* cd: Char device: white on blue */
  537. +   { 0, NULL },            /* mi: Missing file: undefined */
  538. +   { 0, NULL },            /* or: Orphanned symlink: undefined */
  539. +   { 4, "35;1" },        /* ex: Executable: purple+ */
  540. +   { 4, "31;1" },        /* sy: System: red+ */
  541. +   { 4, "33;1" },        /* ro: Read-only: yellow+ */
  542. +   { 7, "44;37;1" },        /* hi: Hidden: white on blue + */
  543. + #endif
  544. + };
  545. + struct col_ext_type
  546. + {
  547. +   struct bin_str ext;        /* The extension we're looking for */
  548. +   struct bin_str seq;        /* The sequence to output when we do */
  549. +   struct col_ext_type *next;    /* Next in list */
  550. + };
  551. + struct col_ext_type *col_ext_list = NULL;
  552. + char *color_buf;        /* Buffer for color sequences */
  553. + /* Nonzero means print using ISO 8859 characters.  The default is specified
  554. +    here as well.  -8 enables, -7 disables.  */
  555. + int print_iso8859;
  556. + #ifndef DEFAULT_ISO8859
  557. + #define DEFAULT_ISO8859  1
  558. + #endif
  559.   /* Nonzero means mention the inode number of each file.  -i  */
  560.   
  561.   static int print_inode;
  562. ***************
  563. *** 407,413 ****
  564.     {"escape", no_argument, 0, 'b'},
  565.     {"directory", no_argument, 0, 'd'},
  566.     {"dired", no_argument, 0, 'D'},
  567. !   {"full-time", no_argument, &full_time, 1},
  568.     {"inode", no_argument, 0, 'i'},
  569.     {"kilobytes", no_argument, 0, 'k'},
  570.     {"numeric-uid-gid", no_argument, 0, 'n'},
  571. --- 536,542 ----
  572.     {"escape", no_argument, 0, 'b'},
  573.     {"directory", no_argument, 0, 'd'},
  574.     {"dired", no_argument, 0, 'D'},
  575. !   {"full-time", no_argument, 0, 'e'},
  576.     {"inode", no_argument, 0, 'i'},
  577.     {"kilobytes", no_argument, 0, 'k'},
  578.     {"numeric-uid-gid", no_argument, 0, 'n'},
  579. ***************
  580. *** 434,439 ****
  581. --- 563,572 ----
  582.   #endif
  583.     {"help", no_argument, &show_help, 1},
  584.     {"version", no_argument, &show_version, 1},
  585. +   {"color", optional_argument, 0, 13},
  586. +   {"colour", optional_argument, 0, 13},
  587. +   {"7bit", no_argument, 0, '7'},
  588. +   {"8bit", no_argument, 0, '8'},
  589.     {0, 0, 0, 0}
  590.   };
  591.   
  592. ***************
  593. *** 512,517 ****
  594. --- 645,662 ----
  595.     time_atime, time_atime, time_atime, time_ctime, time_ctime
  596.   };
  597.   
  598. + static char const* color_args[] = 
  599. + {
  600. +   /* Note: "no" is a prefix of "none" so we don't include it */
  601. +   /* force and none are for compatibility with another color-ls version */ 
  602. +   "yes", "force", "none", "tty", "if-tty"
  603. + };
  604. + static enum color_type const color_types[] =
  605. + {
  606. +   color_yes, color_yes, color_no, color_if_tty, color_if_tty
  607. + };
  608.   
  609.   /* Write to standard output the string PREFIX followed by a space-separated
  610.      list of the integers stored in OS all on one line.  */
  611. ***************
  612. *** 551,567 ****
  613.   
  614.     if (show_version)
  615.       {
  616. !       printf ("%s\n", version_string);
  617.         exit (0);
  618.       }
  619.   
  620.     if (show_help)
  621.       usage (0);
  622.   
  623.     format_needs_stat = sort_type == sort_time || sort_type == sort_size
  624.       || format == long_format
  625.       || trace_links || trace_dirs || indicator_style != none
  626. !     || print_block_size || print_inode;
  627.   
  628.     if (dired && format == long_format)
  629.       {
  630. --- 696,715 ----
  631.   
  632.     if (show_version)
  633.       {
  634. !       printf ("%s with color-ls patch %s\n", version_string, color_ls_version);
  635.         exit (0);
  636.       }
  637.   
  638.     if (show_help)
  639.       usage (0);
  640.   
  641. +   if ( print_with_color )
  642. +     parse_ls_color();
  643. +  
  644.     format_needs_stat = sort_type == sort_time || sort_type == sort_size
  645.       || format == long_format
  646.       || trace_links || trace_dirs || indicator_style != none
  647. !     || print_block_size || print_inode || print_with_color;
  648.   
  649.     if (dired && format == long_format)
  650.       {
  651. ***************
  652. *** 653,658 ****
  653. --- 801,819 ----
  654.       dired_dump_obstack ("//SUBDIRED//", &subdired_obstack);
  655.       }
  656.   
  657. +   if (print_with_color)
  658. +     {
  659. +       struct col_ext_type *ext;
  660. +       free(color_buf);
  661. +       while ( col_ext_list )
  662. +     {
  663. +       ext = col_ext_list;
  664. +       col_ext_list = col_ext_list->next;
  665. +       free(ext);
  666. +     }
  667. +     }
  668.     exit (exit_status);
  669.   }
  670.   
  671. ***************
  672. *** 673,678 ****
  673. --- 834,893 ----
  674.   
  675.     /* initialize all switches to default settings */
  676.   
  677. +   /* program_name is advertised as being the program name without
  678. +      any leading path, but that doesn't seem to be the case.  Get the
  679. +      first character of the actual program name. */
  680. + #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
  681. +   p = strrchr(program_name,'/');
  682. + #else
  683. +   {
  684. +     /* Lame version of strrchr() for lame systems */
  685. +     
  686. +     register char *q;
  687. +     p = NULL;
  688. +     for ( q = program_name ; *q ; q++ )
  689. +       {
  690. +     if ( *q == '/' )
  691. +       p = q;
  692. +       }
  693. +   }
  694. + #endif
  695. + #ifndef NO_NAME_DEPENDENCE
  696. +   if ( p )
  697. +     p++;            /* Get character after last / */
  698. +   else
  699. +     p = program_name;        /* Get first character */
  700. +   switch(*p)
  701. +     {
  702. +     case 'D':
  703. +     case 'd':
  704. +       /* This is for the 'dir' program. */
  705. +       ls_mode = LS_MULTI_COL;
  706. +       break;
  707. +     case 'V':
  708. +     case 'v':
  709. +       /* This is for the 'vdir' program. */
  710. +       ls_mode = LS_LONG_FORMAT;
  711. +       break;
  712. +     case 'L':
  713. +     case 'l':
  714. +       /* This is for the `ls' program. */
  715. +       ls_mode = LS_LS;
  716. +       break;
  717. +       
  718. +     default:
  719. +       /* Use default, depending on whenether linked with ls-ls.o,
  720. +      ls-dir.o or ls-vdir.o */
  721. +       break;
  722. +     }
  723. + #endif
  724.     switch (ls_mode)
  725.       {
  726.       case LS_MULTI_COL:
  727. ***************
  728. *** 721,726 ****
  729. --- 936,943 ----
  730.     really_all_files = 0;
  731.     ignore_patterns = 0;
  732.     quote_as_string = 0;
  733. +   print_with_color = 0;
  734. +   print_iso8859 = DEFAULT_ISO8859;  
  735.   
  736.     p = getenv ("COLUMNS");
  737.     line_length = p ? atoi (p) : 80;
  738. ***************
  739. *** 737,743 ****
  740.     p = getenv ("TABSIZE");
  741.     tabsize = p ? atoi (p) : 8;
  742.   
  743. !   while ((c = getopt_long (argc, argv, "abcdfgiklmnpqrstuw:xABCDFGI:LNQRST:UX1?h",
  744.                  long_options, (int *) 0)) != EOF)
  745.       {
  746.         switch (c)
  747. --- 954,961 ----
  748.     p = getenv ("TABSIZE");
  749.     tabsize = p ? atoi (p) : 8;
  750.   
  751. !   if ( tabsize == 0 )  tabsize = line_length;
  752. !   while ((c = getopt_long (argc, argv, "abcdefgiklmnopqrstuw:xABCDFGI:LNQRST:UX178?h",
  753.                  long_options, (int *) 0)) != EOF)
  754.       {
  755.         switch (c)
  756. ***************
  757. *** 763,770 ****
  758.         immediate_dirs = 1;
  759.         break;
  760.   
  761.       case 'f':
  762. !       /* Same as enabling -a -U and disabling -l -s.  */
  763.         all_files = 1;
  764.         really_all_files = 1;
  765.         sort_type = sort_none;
  766. --- 981,992 ----
  767.         immediate_dirs = 1;
  768.         break;
  769.   
  770. +     case 'e':
  771. +       full_time = 1;
  772. +       break;
  773.       case 'f':
  774. !       /* Same as enabling -a -U and disabling -l -s -o.  */
  775.         all_files = 1;
  776.         really_all_files = 1;
  777.         sort_type = sort_none;
  778. ***************
  779. *** 772,777 ****
  780. --- 994,1000 ----
  781.         if (format == long_format)
  782.           format = (isatty (1) ? many_per_line : one_per_line);
  783.         print_block_size = 0;  /* disable -s */
  784. +       print_with_color = 0;  /* disable -o */
  785.         break;
  786.   
  787.       case 'g':
  788. ***************
  789. *** 798,803 ****
  790. --- 1021,1034 ----
  791.         numeric_users = 1;
  792.         break;
  793.   
  794. +     case 'o':
  795. +       print_with_color = !print_with_color;
  796. +       
  797. +       if ( print_with_color )
  798. +         tabsize = line_length; /* Some systems don't like tabs and
  799. +                       color codes in combination */
  800. +       break;
  801.       case 'p':
  802.         indicator_style = not_programs;
  803.         break;
  804. ***************
  805. *** 887,894 ****
  806.   
  807.       case 'T':
  808.         tabsize = atoi (optarg);
  809. !       if (tabsize < 1)
  810.           error (1, 0, "invalid tab size: %s", optarg);
  811.         break;
  812.   
  813.       case 'U':
  814. --- 1118,1127 ----
  815.   
  816.       case 'T':
  817.         tabsize = atoi (optarg);
  818. !       if (tabsize < 0)
  819.           error (1, 0, "invalid tab size: %s", optarg);
  820. +       else if (tabsize == 0)
  821. +         tabsize = line_length;
  822.         break;
  823.   
  824.       case 'U':
  825. ***************
  826. *** 903,909 ****
  827.         format = one_per_line;
  828.         break;
  829.   
  830. !     case 10:        /* +sort */
  831.         i = argmatch (optarg, sort_args);
  832.         if (i < 0)
  833.           {
  834. --- 1136,1150 ----
  835.         format = one_per_line;
  836.         break;
  837.   
  838. !     case '7':
  839. !       print_iso8859 = 0;
  840. !       break;
  841. !     case '8':
  842. !       print_iso8859 = 1;
  843. !       break;
  844. !     case 10:        /* --sort */
  845.         i = argmatch (optarg, sort_args);
  846.         if (i < 0)
  847.           {
  848. ***************
  849. *** 913,919 ****
  850.         sort_type = sort_types[i];
  851.         break;
  852.   
  853. !     case 11:        /* +time */
  854.         i = argmatch (optarg, time_args);
  855.         if (i < 0)
  856.           {
  857. --- 1154,1160 ----
  858.         sort_type = sort_types[i];
  859.         break;
  860.   
  861. !     case 11:        /* --time */
  862.         i = argmatch (optarg, time_args);
  863.         if (i < 0)
  864.           {
  865. ***************
  866. *** 923,929 ****
  867.         time_type = time_types[i];
  868.         break;
  869.   
  870. !     case 12:        /* +format */
  871.         i = argmatch (optarg, format_args);
  872.         if (i < 0)
  873.           {
  874. --- 1164,1170 ----
  875.         time_type = time_types[i];
  876.         break;
  877.   
  878. !     case 12:        /* --format */
  879.         i = argmatch (optarg, format_args);
  880.         if (i < 0)
  881.           {
  882. ***************
  883. *** 933,938 ****
  884. --- 1174,1203 ----
  885.         format = formats[i];
  886.         break;
  887.   
  888. +     case 13:                /* --color */ 
  889. +       if (optarg)
  890. +         {
  891. +           i = argmatch(optarg, color_args);
  892. +           if (i < 0)
  893. +         {
  894. +           invalid_arg("colorization criterion", optarg, i);
  895. +           usage(1);
  896. +         }
  897. +           i = color_types[i];
  898. +         }
  899. +       else
  900. +         i = color_yes;    /* Only --color -> --color=yes */
  901. +       if ( i == color_if_tty )
  902. +         print_with_color = isatty(1) ? 1 : 0;
  903. +       else
  904. +         print_with_color = i;
  905. +       if ( print_with_color )
  906. +         tabsize = line_length; /* Some systems don't like tabs and
  907. +                       color codes in combination */
  908. +       break;
  909. +         
  910.       default:
  911.         usage (0);
  912.       }
  913. ***************
  914. *** 941,946 ****
  915. --- 1206,1537 ----
  916.     return optind;
  917.   }
  918.   
  919. + /* Parse the LS_COLORS/LS_COLOURS variable */
  920. + static void
  921. + parse_ls_color ()
  922. + {
  923. +   char *p;            /* Pointer to character being parsed */
  924. +   char *whichvar;        /* LS_COLORS or LS_COLOURS? */
  925. +   char *buf;            /* color_buf buffer pointer */
  926. +   int state;            /* State of parser */
  927. +   int ind_no;            /* Indicator number */
  928. +   char label[3] = "??";        /* Indicator label */
  929. +   struct col_ext_type *ext;    /* Extension we are working on */
  930. +   struct col_ext_type *ext2;    /* Extra pointer */
  931. +   if ( (p = getenv(whichvar = "LS_COLORS")) ||
  932. +        (p = getenv(whichvar = "LS_COLOURS")) )
  933. +     {
  934. +       buf = color_buf = xmalloc(strlen(p));
  935. +       /* This is an overly conservative estimate, but any possible
  936. +          LS_COLORS string will *not* generate a color_buf longer than
  937. +      itself, so it is a safe way of allocating a buffer in
  938. +      advance. */
  939. +       
  940. +       state = 1;
  941. +       while ( state > 0 )
  942. +     {
  943. +       switch(state)
  944. +         {
  945. +         case 1:        /* First label character */
  946. +           switch ( *p )
  947. +         {
  948. +         case ':':
  949. +           p++;
  950. +           break;
  951. +           
  952. +         case '*':
  953. +           /* Allocate new extension block and add to head
  954. +              of linked list (this way a later definition will
  955. +              override an earlier one, which can be useful for
  956. +              having terminal-specific defs override global) */
  957. +           
  958. +           ext = (struct col_ext_type *)
  959. +             xmalloc(sizeof(struct col_ext_type));
  960. +           ext->next = col_ext_list;
  961. +           col_ext_list = ext;
  962. +           p++;
  963. +           ext->ext.string = buf;
  964. +           
  965. +           state = (ext->ext.len =
  966. +                get_funky_string(&buf,&p,1)) < 0 ? -1 : 4;
  967. +           break;
  968. +           
  969. +         case '\0':
  970. +           state = 0;    /* Done! */
  971. +           break;
  972. +           
  973. +         default:    /* Assume it is file type label */
  974. +           label[0] = *(p++);
  975. +           state = 2;
  976. +           break;
  977. +         }
  978. +           break;
  979. +           
  980. +         case 2:        /* Second label character */
  981. +           if ( *p )
  982. +         {
  983. +           label[1] = *(p++);
  984. +           state = 3;
  985. +         }
  986. +           else
  987. +         state = -1;    /* Error */
  988. +           break;
  989. +         case 3:        /* Equal sign after indicator label */
  990. +           state = -1;    /* Assume failure... */
  991. +           if ( *(p++) == '=' )    /* It *should* be... */
  992. +         {
  993. +           for ( ind_no = 0 ; indicator_name[ind_no] != NULL ;
  994. +                ind_no++ )
  995. +             {
  996. +               if ( strcmp(label,indicator_name[ind_no]) == 0 )
  997. +             {
  998. +               color_indicator[ind_no].string = buf;
  999. +               state = (color_indicator[ind_no].len =
  1000. +                    get_funky_string(&buf,&p,0)) < 0 ?
  1001. +                      -1 : 1;
  1002. +               break;
  1003. +             }
  1004. +             }
  1005. +           if ( state == -1 )
  1006. +             fprintf(stderr, "Unknown prefix: %s\n", label);
  1007. +         }
  1008. +           break;
  1009. +         case 4:        /* Equal sign after *.ext */
  1010. +           if ( *(p++) == '=' )
  1011. +         {
  1012. +           ext->seq.string = buf;
  1013. +           state = (ext->seq.len =
  1014. +                get_funky_string(&buf,&p,0)) < 0 ?
  1015. +                  -1 : 1;
  1016. +         }
  1017. +           else
  1018. +         state = -1;
  1019. +           break;
  1020. +         }
  1021. +     }
  1022. +       if ( state < 0 )
  1023. +     {
  1024. +       fprintf(stderr, "Bad %s variable\n", whichvar);
  1025. +       free(color_buf);
  1026. +       for ( ext = col_ext_list ; ext != NULL ; )
  1027. +         {
  1028. +           ext2 = ext;
  1029. +           ext = ext->next;
  1030. +           free (ext2);
  1031. +         }
  1032. +       print_with_color = 0;
  1033. +     }
  1034. +     }
  1035. + }
  1036. + /* Parse a string as part of the LS_COLO(U)RS variable; this may involve
  1037. +    decoding all kinds of escape characters.  If equals_end is set an
  1038. +    unescaped equal sign ends the string, otherwise only a : or \0
  1039. +    does.  Returns the number of characters output, or -1 on failure.
  1040. +    The resulting string is *not* null-terminated, but may contain
  1041. +    embedded nulls.
  1042. +    Note that both dest and src are char **; on return they point to
  1043. +    the first free byte after the array and the character that ended
  1044. +    the input string, respectively. */
  1045. + int
  1046. + get_funky_string (dest, src, equals_end)
  1047. +      char **dest;
  1048. +      char **src;
  1049. +      int equals_end;
  1050. + {
  1051. +   int num;            /* For numerical codes */
  1052. +   int count;            /* Something to count with */
  1053. +   enum { st_gnd, st_backslash, st_octal, st_hex, st_caret,
  1054. +      st_end, st_error } state;
  1055. +   char *p, *q;
  1056. +   p = *src;  q = *dest;        /* We don't want to double-indirect
  1057. +                    the whole darn time */
  1058. +   
  1059. +   count = 0;            /* No characters counted in yet */
  1060. +   state = st_gnd;        /* Start in ground state */
  1061. +   while ( state < st_end )
  1062. +     {
  1063. +       switch ( state )
  1064. +     {
  1065. +     case st_gnd:        /* Ground state (no escapes) */
  1066. +       switch ( *p )
  1067. +         {
  1068. +         case ':':
  1069. +         case '\0':
  1070. +           state = st_end;    /* End of string */
  1071. +           break;
  1072. +         case '\\':
  1073. +           state = st_backslash; /* Backslash scape sequence */
  1074. +           p++;
  1075. +           break;
  1076. +         case '^':
  1077. +           state = st_caret;    /* Caret escape */
  1078. +           p++;
  1079. +           break;
  1080. +         case '=':
  1081. +           if ( equals_end )
  1082. +         {
  1083. +           state = st_end; /* End */
  1084. +           break;
  1085. +         }
  1086. +           /* else fall through */
  1087. +         default:
  1088. +           *(q++) = *(p++);
  1089. +           count++;
  1090. +           break;
  1091. +         }
  1092. +       break;
  1093. +     case st_backslash:    /* Backslash escaped character */
  1094. +       switch ( *p )
  1095. +         {
  1096. +         case '0':
  1097. +         case '1':
  1098. +         case '2':
  1099. +         case '3':
  1100. +         case '4':
  1101. +         case '5':
  1102. +         case '6':
  1103. +         case '7':
  1104. +           state = st_octal;    /* Octal sequence */
  1105. +           num = *p - '0';
  1106. +           break;
  1107. +         case 'x':
  1108. +         case 'X':
  1109. +           state = st_hex;    /* Hex sequence */
  1110. +           num = 0;
  1111. +           break;
  1112. +         case 'a':        /* Bell */
  1113. +           num = 7;        /* Not all C compilers know what \a means */
  1114. +           break;
  1115. +         case 'b':        /* Backspace */
  1116. +           num = '\b';
  1117. +           break;
  1118. +         case 'e':        /* Escape */
  1119. +           num = 27;
  1120. +           break;
  1121. +         case 'f':        /* Form feed */
  1122. +           num = '\f';
  1123. +           break;
  1124. +         case 'n':        /* Newline */
  1125. +           num = '\n';
  1126. +           break;
  1127. +         case 'r':        /* Carriage return */
  1128. +           num = '\r';
  1129. +           break;
  1130. +         case 't':        /* Tab */
  1131. +           num = '\t';
  1132. +           break;
  1133. +         case 'v':        /* Vtab */
  1134. +           num = '\v';
  1135. +           break;
  1136. +         case '?':        /* Delete */
  1137. +           num = 127;
  1138. +           break;
  1139. +         case '_':        /* Space */
  1140. +           num = ' ';
  1141. +           break;
  1142. +         case '\0':        /* End of string */
  1143. +           state = st_error;    /* Error! */
  1144. +           break;
  1145. +         default:        /* Escaped character like \ ^ : = */
  1146. +           num = *p;
  1147. +           break;
  1148. +         }
  1149. +       if ( state == st_backslash )
  1150. +         {
  1151. +           *(q++) = num;
  1152. +           count++;
  1153. +           state = st_gnd;
  1154. +         }
  1155. +       p++;
  1156. +       break;
  1157. +     case st_octal:        /* Octal sequence */
  1158. +       if ( *p < '0' || *p > '7' )
  1159. +         {
  1160. +           *(q++) = num;
  1161. +           count++;
  1162. +           state = st_gnd;
  1163. +         }
  1164. +       else
  1165. +           num = ( num << 3 ) + ( *(p++) - '0' );
  1166. +       break;
  1167. +     case st_hex:        /* Hex sequence */
  1168. +       switch ( *p )
  1169. +         {
  1170. +         case '0':
  1171. +         case '1':
  1172. +         case '2':
  1173. +         case '3':
  1174. +         case '4':
  1175. +         case '5':
  1176. +         case '6':
  1177. +         case '7':
  1178. +         case '8':
  1179. +         case '9':
  1180. +           num = ( num << 4 ) + ( *(p++) - '0' );
  1181. +           break;
  1182. +         case 'a':
  1183. +         case 'b':
  1184. +         case 'c':
  1185. +         case 'd':
  1186. +         case 'e':
  1187. +         case 'f':
  1188. +           num = ( num << 4 ) + ( *(p++) - 'a' ) + 10;
  1189. +           break;
  1190. +         case 'A':
  1191. +         case 'B':
  1192. +         case 'C':
  1193. +         case 'D':
  1194. +         case 'E':
  1195. +         case 'F':
  1196. +           num = ( num << 4 ) + ( *(p++) - 'A' ) + 10;
  1197. +           break;
  1198. +         default:
  1199. +           *(q++) = num;
  1200. +           count++;
  1201. +           state = st_gnd;
  1202. +           break;
  1203. +         }
  1204. +       break;
  1205. +     case st_caret:        /* Caret escape */
  1206. +       state = st_gnd;    /* Should be the next state... */
  1207. +       if ( *p >= '@' && *p <= '~' )
  1208. +         {
  1209. +           *(q++) = *(p++) & 037;
  1210. +           count++;
  1211. +         }
  1212. +       else if ( *p == '?' )
  1213. +         {
  1214. +           *(q++) = 127;
  1215. +           count++;
  1216. +         }
  1217. +       else
  1218. +         state = st_error;
  1219. +       break;
  1220. +     }
  1221. +     }
  1222. +   *dest = q;  *src = p;
  1223. +   return ( state == st_error ) ? -1 : count;
  1224. + }
  1225.   /* Request that the directory named `name' have its contents listed later.
  1226.      If `realname' is nonzero, it will be used instead of `name' when the
  1227.      directory name is printed.  This allows symbolic links to directories
  1228. ***************
  1229. *** 1166,1172 ****
  1230.   
  1231.   #ifdef S_ISLNK
  1232.         if (S_ISLNK (files[files_index].stat.st_mode)
  1233. !       && (explicit_arg || format == long_format))
  1234.       {
  1235.         char *linkpath;
  1236.         struct stat linkstats;
  1237. --- 1757,1763 ----
  1238.   
  1239.   #ifdef S_ISLNK
  1240.         if (S_ISLNK (files[files_index].stat.st_mode)
  1241. !       && (explicit_arg || format == long_format || print_with_color))
  1242.       {
  1243.         char *linkpath;
  1244.         struct stat linkstats;
  1245. ***************
  1246. *** 1178,1185 ****
  1247.            they won't be traced and when no indicator is needed. */
  1248.         if (linkpath
  1249.             && ((explicit_arg && format != long_format)
  1250. !            || indicator_style != none)
  1251. !           && SAFE_STAT (linkpath, &linkstats) == 0)
  1252.           {
  1253.             /* Symbolic links to directories that are mentioned on the
  1254.            command line are automatically traced if not being
  1255. --- 1769,1777 ----
  1256.            they won't be traced and when no indicator is needed. */
  1257.         if (linkpath
  1258.             && ((explicit_arg && format != long_format)
  1259. !            || indicator_style != none || print_with_color)
  1260. !           && ( files[files_index].linkok =
  1261. !           (SAFE_STAT (linkpath, &linkstats) == 0) ) )
  1262.           {
  1263.             /* Symbolic links to directories that are mentioned on the
  1264.            command line are automatically traced if not being
  1265. ***************
  1266. *** 1207,1213 ****
  1267.           free (linkpath);
  1268.       }
  1269.   #endif
  1270.   #ifdef S_ISLNK
  1271.         if (S_ISLNK (files[files_index].stat.st_mode))
  1272.       files[files_index].filetype = symbolic_link;
  1273. --- 1799,1805 ----
  1274.           free (linkpath);
  1275.       }
  1276.   #endif
  1277. !       
  1278.   #ifdef S_ISLNK
  1279.         if (S_ISLNK (files[files_index].stat.st_mode))
  1280.       files[files_index].filetype = symbolic_link;
  1281. ***************
  1282. *** 1690,1696 ****
  1283.     DIRED_INDENT ();
  1284.     FPUTS (bigbuf, stdout, p - bigbuf);
  1285.     PUSH_CURRENT_DIRED_POS (&dired_obstack);
  1286. !   print_name_with_quoting (f->name);
  1287.     PUSH_CURRENT_DIRED_POS (&dired_obstack);
  1288.   
  1289.     if (f->filetype == symbolic_link)
  1290. --- 2282,2291 ----
  1291.     DIRED_INDENT ();
  1292.     FPUTS (bigbuf, stdout, p - bigbuf);
  1293.     PUSH_CURRENT_DIRED_POS (&dired_obstack);
  1294. ! #ifdef OS2
  1295. !   os2_modify_stat( &f->stat );
  1296. ! #endif
  1297. !   print_fancy_name (f->name, f->stat.st_mode, f->linkok);
  1298.     PUSH_CURRENT_DIRED_POS (&dired_obstack);
  1299.   
  1300.     if (f->filetype == symbolic_link)
  1301. ***************
  1302. *** 1698,1704 ****
  1303.         if (f->linkname)
  1304.       {
  1305.         FPUTS_LITERAL (" -> ", stdout);
  1306. !       print_name_with_quoting (f->linkname);
  1307.         if (indicator_style != none)
  1308.           print_type_indicator (f->linkmode);
  1309.       }
  1310. --- 2293,2299 ----
  1311.         if (f->linkname)
  1312.       {
  1313.         FPUTS_LITERAL (" -> ", stdout);
  1314. !       print_fancy_name (f->linkname, f->linkmode, f->linkok-1);
  1315.         if (indicator_style != none)
  1316.           print_type_indicator (f->linkmode);
  1317.       }
  1318. ***************
  1319. *** 1717,1723 ****
  1320.        register const char *p;
  1321.        size_t *quoted_length;
  1322.   {
  1323. !   register unsigned char c;
  1324.     const char *p0 = p;
  1325.     char *quoted, *q;
  1326.     int found_quotable;
  1327. --- 2312,2318 ----
  1328.        register const char *p;
  1329.        size_t *quoted_length;
  1330.   {
  1331. !   register unsigned char c;    /* Unsigned for ISO 8859 test */
  1332.     const char *p0 = p;
  1333.     char *quoted, *q;
  1334.     int found_quotable;
  1335. ***************
  1336. *** 1887,1899 ****
  1337.           (unsigned) convert_blocks (ST_NBLOCKS (f->stat),
  1338.                          kilobyte_blocks));
  1339.   
  1340. !   print_name_with_quoting (f->name);
  1341.   
  1342.     if (indicator_style != none)
  1343.       print_type_indicator (f->stat.st_mode);
  1344.   }
  1345.   
  1346.   static void
  1347.   print_type_indicator (mode)
  1348.        unsigned int mode;
  1349.   {
  1350. --- 2482,2522 ----
  1351.           (unsigned) convert_blocks (ST_NBLOCKS (f->stat),
  1352.                          kilobyte_blocks));
  1353.   
  1354. ! #ifdef OS2
  1355. !   os2_modify_stat( &f->stat );
  1356. ! #endif
  1357. !   print_fancy_name (f->name, f->stat.st_mode, f->linkok);
  1358.   
  1359.     if (indicator_style != none)
  1360.       print_type_indicator (f->stat.st_mode);
  1361.   }
  1362.   
  1363.   static void
  1364. + print_fancy_name (name, mode, linkok)
  1365. +      char *name;
  1366. +      unsigned int mode;
  1367. +      int linkok;
  1368. + {
  1369. +   if (print_with_color)
  1370. +     {
  1371. +       print_color_indicator(name, mode, linkok);
  1372. +       print_name_with_quoting(name);
  1373. +       if ( color_indicator[C_END].string )
  1374. +     {
  1375. +       put_indicator(&color_indicator[C_END]);
  1376. +     }
  1377. +       else
  1378. +     {
  1379. +       put_indicator(&color_indicator[C_LEFT]);
  1380. +       put_indicator(&color_indicator[C_NORM]);
  1381. +       put_indicator(&color_indicator[C_RIGHT]);
  1382. +     }
  1383. +     }
  1384. +   else
  1385. +     print_name_with_quoting(name);
  1386. + }
  1387. + static void
  1388.   print_type_indicator (mode)
  1389.        unsigned int mode;
  1390.   {
  1391. ***************
  1392. *** 1920,1931 ****
  1393.       PUTCHAR ('*');
  1394.   }
  1395.   
  1396.   static int
  1397.   length_of_file_name_and_frills (f)
  1398.        struct fileinfo *f;
  1399.   {
  1400.     register char *p = f->name;
  1401. !   register char c;
  1402.     register int len = 0;
  1403.   
  1404.     if (print_inode)
  1405. --- 2543,2660 ----
  1406.       PUTCHAR ('*');
  1407.   }
  1408.   
  1409. + static void
  1410. + print_color_indicator (name, mode, linkok)
  1411. +      char *name;
  1412. +      unsigned int mode;
  1413. +      int linkok;
  1414. + {
  1415. +   int i;
  1416. +   int shi;            /* Bits to shift mode */
  1417. +   int type = C_FILE;
  1418. +   struct col_ext_type *ext;    /* Color extension */
  1419. +   int len;            /* Length of name */
  1420. +   /* Is this a nonexistent file?  If so, linkok == -1 */
  1421. +   if ( linkok == -1 && color_indicator[C_MISSING].string )
  1422. +     {
  1423. +       ext = NULL;
  1424. +       type = C_MISSING;
  1425. +     }
  1426. +   else
  1427. +     {
  1428. +       /* Test if is is a recognized extension */
  1429. +       len = strlen(name);
  1430. +       name += len;            /* Pointer to final \0 */
  1431. +       for ( ext = col_ext_list ; ext != NULL ; ext = ext->next )
  1432. +     {
  1433. +       if ( ext->ext.len <= len &&
  1434. + #ifdef OS2
  1435. +           strnicmp(name-ext->ext.len,ext->ext.string,ext->ext.len)  == 0 )
  1436. + #else
  1437. +           strncmp(name-ext->ext.len,ext->ext.string,ext->ext.len)  == 0 )
  1438. + #endif
  1439. +         break;
  1440. +     }
  1441. +       
  1442. +       if ( !ext )
  1443. +     {
  1444. +       if (S_ISDIR (mode))
  1445. +         type = C_DIR;
  1446. +       
  1447. + #ifdef S_ISSYSTEM
  1448. +       else if (S_ISSYSTEM (mode))
  1449. +         type = C_SYSTEM;
  1450. + #endif
  1451. + #ifdef S_ISHIDDEN
  1452. +       else if (S_ISHIDDEN (mode))
  1453. +         type = C_HIDDEN;
  1454. + #endif
  1455. + #ifdef S_ISRDONLY
  1456. +       else if (S_ISRDONLY (mode))
  1457. +         type = C_RDONLY;
  1458. + #endif
  1459. + #ifdef S_ISLNK
  1460. +       else if (S_ISLNK (mode))
  1461. +         type = (!linkok && color_indicator[C_ORPHAN].string) ?
  1462. +           C_ORPHAN : C_LINK;
  1463. + #endif
  1464. +       
  1465. + #ifdef S_ISFIFO
  1466. +       else if (S_ISFIFO (mode))
  1467. +         type = C_FIFO;
  1468. + #endif
  1469. +       
  1470. + #ifdef S_ISSOCK
  1471. +       else if (S_ISSOCK (mode))
  1472. +         type = C_SOCK;
  1473. + #endif
  1474. +       
  1475. + #ifdef S_ISBLK
  1476. +       else if (S_ISBLK (mode))
  1477. +         type = C_BLK;
  1478. + #endif
  1479. +       
  1480. + #ifdef S_ISCHR
  1481. +       else if (S_ISCHR (mode))
  1482. +         type = C_CHR;
  1483. + #endif
  1484. +     if ( type == C_FILE && (mode & (S_IEXEC|S_IEXEC>>3|S_IEXEC>>6)) )
  1485. +     type = C_EXEC;
  1486. +     }
  1487. +     }
  1488. +   put_indicator(&color_indicator[C_LEFT]);
  1489. +   put_indicator(ext ? &(ext->seq) : &color_indicator[type]);
  1490. +   put_indicator(&color_indicator[C_RIGHT]);
  1491. + }
  1492. + /* Output a color indicator (which may contain nulls) */
  1493. + static void
  1494. + put_indicator(ind)
  1495. +      struct bin_str *ind;
  1496. + {
  1497. +   register int i;
  1498. +   register char *p;
  1499. +   p = ind->string;
  1500. +   for ( i = ind->len ; i ; i-- )
  1501. +     putchar(*(p++));
  1502. + }
  1503.   static int
  1504.   length_of_file_name_and_frills (f)
  1505.        struct fileinfo *f;
  1506.   {
  1507.     register char *p = f->name;
  1508. !   register unsigned char c;    /* Unsigned for ISO 8859 test */
  1509.     register int len = 0;
  1510.   
  1511.     if (print_inode)
  1512. ***************
  1513. *** 1961,1967 ****
  1514.             break;
  1515.   
  1516.           default:
  1517. !           if (c >= 040 && c < 0177)
  1518.           len += 1;
  1519.             else
  1520.           len += 4;
  1521. --- 2690,2697 ----
  1522.             break;
  1523.   
  1524.           default:
  1525. !           if ( (c >= 0x20 && c <= 0x7E) ||
  1526. !            (print_iso8859 && c >= 0xA1 && c <= 0xFF) )
  1527.           len += 1;
  1528.             else
  1529.           len += 4;
  1530. ***************
  1531. *** 2209,2219 ****
  1532.     -c                         sort by change time; with -l: show ctime\n\
  1533.     -D, --dired                generate output well suited to Emacs' dired mode\n\
  1534.     -d, --directory            list directory entries instead of contents\n\
  1535.     -F, --classify             append a character for typing each entry\n\
  1536. !   -f                         do not sort, enable -aU, disable -lst\n\
  1537.         --format=WORD          across -x, commas -m, horizontal -x, long -l,\n\
  1538. !                                single-column -1, verbose -l, vertical -C\n\
  1539. !       --full-time            list both full date and full time\n");
  1540.   
  1541.         printf ("\
  1542.     -G, --no-group             inhibit display of group information\n\
  1543. --- 2939,2949 ----
  1544.     -c                         sort by change time; with -l: show ctime\n\
  1545.     -D, --dired                generate output well suited to Emacs' dired mode\n\
  1546.     -d, --directory            list directory entries instead of contents\n\
  1547. +   -e, --full-time            list both date and full time\n\
  1548.     -F, --classify             append a character for typing each entry\n\
  1549. !   -f                         do not sort, enable -aU, disable -lsto\n\
  1550.         --format=WORD          across -x, commas -m, horizontal -x, long -l,\n\
  1551. !                                single-column -1, verbose -l, vertical -C\n");
  1552.   
  1553.         printf ("\
  1554.     -G, --no-group             inhibit display of group information\n\
  1555. ***************
  1556. *** 2226,2231 ****
  1557. --- 2956,2963 ----
  1558.     -m                         fill width with a comma separated list of entries\n\
  1559.     -N, --literal              do not quote entry names\n\
  1560.     -n, --numeric-uid-gid      list numeric UIDs and GIDs instead of names\n\
  1561. +   -o, --color, --colour      colorize entries according to type\n\
  1562. +       --colo(u)r=WORD        yes -o, no, tty (if output is a terminal)\n\
  1563.     -p                         append a character for typing each entry\n\
  1564.     -Q, --quote-name           enclose entry names in double quotes\n\
  1565.     -q, --hide-control-chars   print ? instead of non graphic characters\n\
  1566.