1
/* `dir', `vdir' and `ls' directory listing programs for GNU.
3
Modified by Chet Ramey for Readline.
5
Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012 Free Software Foundation,
8
This program is free software: you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation, either version 3 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
/* Written by Richard Stallman and David MacKenzie. */
23
/* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
24
Flaherty <dennisf@denix.elk.miles.com> based on original patches by
25
Greg Lee <lee@uhunix.uhcc.hawaii.edu>. */
27
#define READLINE_LIBRARY
29
#if defined (HAVE_CONFIG_H)
37
#include "posixstat.h" // stat related macros (S_ISREG, ...)
38
#include <fcntl.h> // S_ISUID
41
#if defined (HAVE_STRING_H)
43
#else /* !HAVE_STRING_H */
45
#endif /* !HAVE_STRING_H */
48
#if defined (HAVE_STDLIB_H)
51
# include "ansi_stdlib.h"
52
#endif /* HAVE_STDLIB_H */
62
static bool is_colored (enum indicator_no type);
63
static void restore_default_color (void);
65
COLOR_EXT_TYPE *_rl_color_ext_list = 0;
67
/* Output a color indicator (which may contain nulls). */
69
_rl_put_indicator (const struct bin_str *ind) {
70
fwrite (ind->string, ind->len, 1, rl_outstream);
74
is_colored (enum indicator_no colored_filetype)
76
size_t len = _rl_color_indicator[colored_filetype].len;
77
char const *s = _rl_color_indicator[colored_filetype].string;
79
|| (len == 1 && strncmp (s, "0", 1) == 0)
80
|| (len == 2 && strncmp (s, "00", 2) == 0));
84
restore_default_color (void)
86
_rl_put_indicator (&_rl_color_indicator[C_LEFT]);
87
_rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
91
_rl_set_normal_color (void)
93
if (is_colored (C_NORM))
95
_rl_put_indicator (&_rl_color_indicator[C_LEFT]);
96
_rl_put_indicator (&_rl_color_indicator[C_NORM]);
97
_rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
101
/* Returns whether any color sequence was printed. */
103
_rl_print_color_indicator (char *f)
105
enum indicator_no colored_filetype;
106
COLOR_EXT_TYPE *ext; /* Color extension */
107
size_t len; /* Length of name */
119
/* This should already have undergone tilde expansion */
121
if (rl_filename_stat_hook)
123
filename = savestring (f);
124
(*rl_filename_stat_hook) (&filename);
128
#if defined (HAVE_LSTAT)
129
stat_ok = lstat(name, &astat);
131
stat_ok = stat(name, &astat);
134
mode = astat.st_mode;
135
linkok = 1; //f->linkok;
140
/* Is this a nonexistent file? If so, linkok == -1. */
142
if (linkok == -1 && _rl_color_indicator[C_MISSING].string != NULL)
143
colored_filetype = C_MISSING;
144
else if(stat_ok != 0)
146
static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS;
147
colored_filetype = filetype_indicator[normal]; //f->filetype];
153
colored_filetype = C_FILE;
155
if ((mode & S_ISUID) != 0 && is_colored (C_SETUID))
156
colored_filetype = C_SETUID;
157
else if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
158
colored_filetype = C_SETGID;
159
else if (is_colored (C_CAP) && 0) //f->has_capability)
160
colored_filetype = C_CAP;
161
else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC))
162
colored_filetype = C_EXEC;
163
else if ((1 < astat.st_nlink) && is_colored (C_MULTIHARDLINK))
164
colored_filetype = C_MULTIHARDLINK;
166
else if (S_ISDIR (mode))
168
colored_filetype = C_DIR;
170
#if defined (S_ISVTX)
171
if ((mode & S_ISVTX) && (mode & S_IWOTH)
172
&& is_colored (C_STICKY_OTHER_WRITABLE))
173
colored_filetype = C_STICKY_OTHER_WRITABLE;
176
if ((mode & S_IWOTH) != 0 && is_colored (C_OTHER_WRITABLE))
177
colored_filetype = C_OTHER_WRITABLE;
178
#if defined (S_ISVTX)
179
else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY))
180
colored_filetype = C_STICKY;
183
else if (S_ISLNK (mode))
184
colored_filetype = ((linkok == 0
185
&& (!strncmp (_rl_color_indicator[C_LINK].string, "target", 6)
186
|| _rl_color_indicator[C_ORPHAN].string))
187
? C_ORPHAN : C_LINK);
188
else if (S_ISFIFO (mode))
189
colored_filetype = C_FIFO;
190
else if (S_ISSOCK (mode))
191
colored_filetype = C_SOCK;
192
else if (S_ISBLK (mode))
193
colored_filetype = C_BLK;
194
else if (S_ISCHR (mode))
195
colored_filetype = C_CHR;
198
/* Classify a file of some other type as C_ORPHAN. */
199
colored_filetype = C_ORPHAN;
203
/* Check the file's suffix only if still classified as C_FILE. */
205
if (colored_filetype == C_FILE)
207
/* Test if NAME has a recognized suffix. */
209
name += len; /* Pointer to final \0. */
210
for (ext = _rl_color_ext_list; ext != NULL; ext = ext->next)
212
if (ext->ext.len <= len
213
&& strncmp (name - ext->ext.len, ext->ext.string,
219
free (filename); /* NULL or savestring return value */
222
const struct bin_str *const s
223
= ext ? &(ext->seq) : &_rl_color_indicator[colored_filetype];
224
if (s->string != NULL)
226
/* Need to reset so not dealing with attribute combinations */
227
if (is_colored (C_NORM))
228
restore_default_color ();
229
_rl_put_indicator (&_rl_color_indicator[C_LEFT]);
230
_rl_put_indicator (s);
231
_rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
240
_rl_prep_non_filename_text (void)
242
if (_rl_color_indicator[C_END].string != NULL)
243
_rl_put_indicator (&_rl_color_indicator[C_END]);
246
_rl_put_indicator (&_rl_color_indicator[C_LEFT]);
247
_rl_put_indicator (&_rl_color_indicator[C_RESET]);
248
_rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
251
#endif /* COLOR_SUPPORT */