Deleted Added
full compact
print.c (86922) print.c (88583)
1/*
2 * Copyright (c) 1989, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Michael Fischbein.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38#if 0
39static char sccsid[] = "@(#)print.c 8.4 (Berkeley) 4/17/94";
40#else
41static const char rcsid[] =
1/*
2 * Copyright (c) 1989, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Michael Fischbein.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38#if 0
39static char sccsid[] = "@(#)print.c 8.4 (Berkeley) 4/17/94";
40#else
41static const char rcsid[] =
42 "$FreeBSD: head/bin/ls/print.c 86922 2001-11-26 22:21:15Z green $";
42 "$FreeBSD: head/bin/ls/print.c 88583 2001-12-28 18:14:50Z joe $";
43#endif
44#endif /* not lint */
45
46#include <sys/param.h>
47#include <sys/stat.h>
48
49#include <err.h>
50#include <errno.h>
51#include <fts.h>
52#include <grp.h>
53#include <langinfo.h>
54#include <pwd.h>
55#include <stdio.h>
56#include <stdlib.h>
57#include <string.h>
58#include <time.h>
59#include <unistd.h>
60#ifdef COLORLS
61#include <ctype.h>
62#include <termcap.h>
63#include <signal.h>
64#endif
65
66#include "ls.h"
67#include "extern.h"
68
69static int printaname __P((FTSENT *, u_long, u_long));
70static void printlink __P((FTSENT *));
71static void printtime __P((time_t));
72static int printtype __P((u_int));
73#ifdef COLORLS
74static void endcolor __P((int));
75static int colortype __P((mode_t));
76#endif
77
78#define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT)
79
80#ifdef COLORLS
81/* Most of these are taken from <sys/stat.h> */
82typedef enum Colors {
83 C_DIR, /* directory */
84 C_LNK, /* symbolic link */
85 C_SOCK, /* socket */
86 C_FIFO, /* pipe */
87 C_EXEC, /* executable */
88 C_BLK, /* block special */
89 C_CHR, /* character special */
90 C_SUID, /* setuid executable */
91 C_SGID, /* setgid executable */
92 C_WSDIR, /* directory writeble to others, with sticky bit */
93 C_WDIR, /* directory writeble to others, without sticky bit */
94 C_NUMCOLORS /* just a place-holder */
95} Colors ;
96
43#endif
44#endif /* not lint */
45
46#include <sys/param.h>
47#include <sys/stat.h>
48
49#include <err.h>
50#include <errno.h>
51#include <fts.h>
52#include <grp.h>
53#include <langinfo.h>
54#include <pwd.h>
55#include <stdio.h>
56#include <stdlib.h>
57#include <string.h>
58#include <time.h>
59#include <unistd.h>
60#ifdef COLORLS
61#include <ctype.h>
62#include <termcap.h>
63#include <signal.h>
64#endif
65
66#include "ls.h"
67#include "extern.h"
68
69static int printaname __P((FTSENT *, u_long, u_long));
70static void printlink __P((FTSENT *));
71static void printtime __P((time_t));
72static int printtype __P((u_int));
73#ifdef COLORLS
74static void endcolor __P((int));
75static int colortype __P((mode_t));
76#endif
77
78#define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT)
79
80#ifdef COLORLS
81/* Most of these are taken from <sys/stat.h> */
82typedef enum Colors {
83 C_DIR, /* directory */
84 C_LNK, /* symbolic link */
85 C_SOCK, /* socket */
86 C_FIFO, /* pipe */
87 C_EXEC, /* executable */
88 C_BLK, /* block special */
89 C_CHR, /* character special */
90 C_SUID, /* setuid executable */
91 C_SGID, /* setgid executable */
92 C_WSDIR, /* directory writeble to others, with sticky bit */
93 C_WDIR, /* directory writeble to others, without sticky bit */
94 C_NUMCOLORS /* just a place-holder */
95} Colors ;
96
97char *defcolors = "4x5x2x3x1x464301060203";
97char *defcolors = "exfxcxdxbxegedabagacad";
98
98
99static int colors[C_NUMCOLORS][2];
99/* colors for file types */
100static struct {
101 int num[2];
102 int bold;
103} colors[C_NUMCOLORS];
104
100#endif
101
102void
103printscol(dp)
104 DISPLAY *dp;
105{
106 FTSENT *p;
107
108 for (p = dp->list; p; p = p->fts_link) {
109 if (IS_NOPRINT(p))
110 continue;
111 (void)printaname(p, dp->s_inode, dp->s_block);
112 (void)putchar('\n');
113 }
114}
115
116/*
117 * print name in current style
118 */
119static int
120printname(name)
121 const char *name;
122{
123 if (f_octal || f_octal_escape)
124 return prn_octal(name);
125 else if (f_nonprint)
126 return prn_printable(name);
127 else
128 return printf("%s", name);
129}
130
131void
132printlong(dp)
133 DISPLAY *dp;
134{
135 struct stat *sp;
136 FTSENT *p;
137 NAMES *np;
138 char buf[20];
139#ifdef COLORLS
140 int color_printed = 0;
141#endif
142
143 if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
144 (void)printf("total %lu\n", howmany(dp->btotal, blocksize));
145
146 for (p = dp->list; p; p = p->fts_link) {
147 if (IS_NOPRINT(p))
148 continue;
149 sp = p->fts_statp;
150 if (f_inode)
151 (void)printf("%*lu ", dp->s_inode, (u_long)sp->st_ino);
152 if (f_size)
153 (void)printf("%*qd ",
154 dp->s_block, howmany(sp->st_blocks, blocksize));
155 (void)strmode(sp->st_mode, buf);
156 np = p->fts_pointer;
157 (void)printf("%s %*u %-*s %-*s ", buf, dp->s_nlink,
158 sp->st_nlink, dp->s_user, np->user, dp->s_group,
159 np->group);
160 if (f_flags)
161 (void)printf("%-*s ", dp->s_flags, np->flags);
162 if (f_lomac)
163 (void)printf("%-*s ", dp->s_lattr, np->lattr);
164 if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
165 if (minor(sp->st_rdev) > 255 || minor(sp->st_rdev) < 0)
166 (void)printf("%3d, 0x%08x ",
167 major(sp->st_rdev),
168 (u_int)minor(sp->st_rdev));
169 else
170 (void)printf("%3d, %3d ",
171 major(sp->st_rdev), minor(sp->st_rdev));
172 else if (dp->bcfile)
173 (void)printf("%*s%*qd ",
174 8 - dp->s_size, "", dp->s_size, sp->st_size);
175 else
176 (void)printf("%*qd ", dp->s_size, sp->st_size);
177 if (f_accesstime)
178 printtime(sp->st_atime);
179 else if (f_statustime)
180 printtime(sp->st_ctime);
181 else
182 printtime(sp->st_mtime);
183#ifdef COLORLS
184 if (f_color)
185 color_printed = colortype(sp->st_mode);
186#endif
187 (void)printname(p->fts_name);
188#ifdef COLORLS
189 if (f_color && color_printed)
190 endcolor(0);
191#endif
192 if (f_type)
193 (void)printtype(sp->st_mode);
194 if (S_ISLNK(sp->st_mode))
195 printlink(p);
196 (void)putchar('\n');
197 }
198}
199
200void
201printcol(dp)
202 DISPLAY *dp;
203{
204 extern int termwidth;
205 static FTSENT **array;
206 static int lastentries = -1;
207 FTSENT *p;
208 int base, chcnt, cnt, col, colwidth, num;
209 int endcol, numcols, numrows, row;
210 int tabwidth;
211
212 if (f_notabs)
213 tabwidth = 1;
214 else
215 tabwidth = 8;
216
217 /*
218 * Have to do random access in the linked list -- build a table
219 * of pointers.
220 */
221 if (dp->entries > lastentries) {
222 lastentries = dp->entries;
223 if ((array =
224 realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
225 warn(NULL);
226 printscol(dp);
227 }
228 }
229 for (p = dp->list, num = 0; p; p = p->fts_link)
230 if (p->fts_number != NO_PRINT)
231 array[num++] = p;
232
233 colwidth = dp->maxlen;
234 if (f_inode)
235 colwidth += dp->s_inode + 1;
236 if (f_size)
237 colwidth += dp->s_block + 1;
238 if (f_type)
239 colwidth += 1;
240
241 colwidth = (colwidth + tabwidth) & ~(tabwidth - 1);
242 if (termwidth < 2 * colwidth) {
243 printscol(dp);
244 return;
245 }
246
247 numcols = termwidth / colwidth;
248 numrows = num / numcols;
249 if (num % numcols)
250 ++numrows;
251
252 if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
253 (void)printf("total %lu\n", howmany(dp->btotal, blocksize));
254 for (row = 0; row < numrows; ++row) {
255 endcol = colwidth;
256 for (base = row, chcnt = col = 0; col < numcols; ++col) {
257 chcnt += printaname(array[base], dp->s_inode,
258 dp->s_block);
259 if ((base += numrows) >= num)
260 break;
261 while ((cnt = ((chcnt + tabwidth) & ~(tabwidth - 1)))
262 <= endcol){
263 (void)putchar(f_notabs ? ' ' : '\t');
264 chcnt = cnt;
265 }
266 endcol += colwidth;
267 }
268 (void)putchar('\n');
269 }
270}
271
272/*
273 * print [inode] [size] name
274 * return # of characters printed, no trailing characters.
275 */
276static int
277printaname(p, inodefield, sizefield)
278 FTSENT *p;
279 u_long sizefield, inodefield;
280{
281 struct stat *sp;
282 int chcnt;
283#ifdef COLORLS
284 int color_printed = 0;
285#endif
286
287 sp = p->fts_statp;
288 chcnt = 0;
289 if (f_inode)
290 chcnt += printf("%*lu ", (int)inodefield, (u_long)sp->st_ino);
291 if (f_size)
292 chcnt += printf("%*qd ",
293 (int)sizefield, howmany(sp->st_blocks, blocksize));
294#ifdef COLORLS
295 if (f_color)
296 color_printed = colortype(sp->st_mode);
297#endif
298 chcnt += printname(p->fts_name);
299#ifdef COLORLS
300 if (f_color && color_printed)
301 endcolor(0);
302#endif
303 if (f_type)
304 chcnt += printtype(sp->st_mode);
305 return (chcnt);
306}
307
308static void
309printtime(ftime)
310 time_t ftime;
311{
312 char longstring[80];
313 static time_t now;
314 const char *format;
315 static int d_first = -1;
316
317 if (d_first < 0)
318 d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
319 if (now == 0)
320 now = time(NULL);
321
322#define SIXMONTHS ((365 / 2) * 86400)
323 if (f_sectime)
324 /* mmm dd hh:mm:ss yyyy || dd mmm hh:mm:ss yyyy */
325 format = d_first ? "%e %b %T %Y " : "%b %e %T %Y ";
326 else if (ftime + SIXMONTHS > now && ftime < now + SIXMONTHS)
327 /* mmm dd hh:mm || dd mmm hh:mm */
328 format = d_first ? "%e %b %R " : "%b %e %R ";
329 else
330 /* mmm dd yyyy || dd mmm yyyy */
331 format = d_first ? "%e %b %Y " : "%b %e %Y ";
332 strftime(longstring, sizeof(longstring), format, localtime(&ftime));
333 fputs(longstring, stdout);
334}
335
336static int
337printtype(mode)
338 u_int mode;
339{
340 switch (mode & S_IFMT) {
341 case S_IFDIR:
342 (void)putchar('/');
343 return (1);
344 case S_IFIFO:
345 (void)putchar('|');
346 return (1);
347 case S_IFLNK:
348 (void)putchar('@');
349 return (1);
350 case S_IFSOCK:
351 (void)putchar('=');
352 return (1);
353 case S_IFWHT:
354 (void)putchar('%');
355 return (1);
356 }
357 if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
358 (void)putchar('*');
359 return (1);
360 }
361 return (0);
362}
363
364#ifdef COLORLS
365static int
366putch(c)
367 int c;
368{
369 (void) putchar(c);
370 return 0;
371}
372
373static int
374writech(c)
375 int c;
376{
377 char tmp = c;
378
379 (void) write(STDOUT_FILENO, &tmp, 1);
380 return 0;
381}
382
383static void
384printcolor(c)
385 Colors c;
386{
387 char *ansiseq;
388
105#endif
106
107void
108printscol(dp)
109 DISPLAY *dp;
110{
111 FTSENT *p;
112
113 for (p = dp->list; p; p = p->fts_link) {
114 if (IS_NOPRINT(p))
115 continue;
116 (void)printaname(p, dp->s_inode, dp->s_block);
117 (void)putchar('\n');
118 }
119}
120
121/*
122 * print name in current style
123 */
124static int
125printname(name)
126 const char *name;
127{
128 if (f_octal || f_octal_escape)
129 return prn_octal(name);
130 else if (f_nonprint)
131 return prn_printable(name);
132 else
133 return printf("%s", name);
134}
135
136void
137printlong(dp)
138 DISPLAY *dp;
139{
140 struct stat *sp;
141 FTSENT *p;
142 NAMES *np;
143 char buf[20];
144#ifdef COLORLS
145 int color_printed = 0;
146#endif
147
148 if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
149 (void)printf("total %lu\n", howmany(dp->btotal, blocksize));
150
151 for (p = dp->list; p; p = p->fts_link) {
152 if (IS_NOPRINT(p))
153 continue;
154 sp = p->fts_statp;
155 if (f_inode)
156 (void)printf("%*lu ", dp->s_inode, (u_long)sp->st_ino);
157 if (f_size)
158 (void)printf("%*qd ",
159 dp->s_block, howmany(sp->st_blocks, blocksize));
160 (void)strmode(sp->st_mode, buf);
161 np = p->fts_pointer;
162 (void)printf("%s %*u %-*s %-*s ", buf, dp->s_nlink,
163 sp->st_nlink, dp->s_user, np->user, dp->s_group,
164 np->group);
165 if (f_flags)
166 (void)printf("%-*s ", dp->s_flags, np->flags);
167 if (f_lomac)
168 (void)printf("%-*s ", dp->s_lattr, np->lattr);
169 if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
170 if (minor(sp->st_rdev) > 255 || minor(sp->st_rdev) < 0)
171 (void)printf("%3d, 0x%08x ",
172 major(sp->st_rdev),
173 (u_int)minor(sp->st_rdev));
174 else
175 (void)printf("%3d, %3d ",
176 major(sp->st_rdev), minor(sp->st_rdev));
177 else if (dp->bcfile)
178 (void)printf("%*s%*qd ",
179 8 - dp->s_size, "", dp->s_size, sp->st_size);
180 else
181 (void)printf("%*qd ", dp->s_size, sp->st_size);
182 if (f_accesstime)
183 printtime(sp->st_atime);
184 else if (f_statustime)
185 printtime(sp->st_ctime);
186 else
187 printtime(sp->st_mtime);
188#ifdef COLORLS
189 if (f_color)
190 color_printed = colortype(sp->st_mode);
191#endif
192 (void)printname(p->fts_name);
193#ifdef COLORLS
194 if (f_color && color_printed)
195 endcolor(0);
196#endif
197 if (f_type)
198 (void)printtype(sp->st_mode);
199 if (S_ISLNK(sp->st_mode))
200 printlink(p);
201 (void)putchar('\n');
202 }
203}
204
205void
206printcol(dp)
207 DISPLAY *dp;
208{
209 extern int termwidth;
210 static FTSENT **array;
211 static int lastentries = -1;
212 FTSENT *p;
213 int base, chcnt, cnt, col, colwidth, num;
214 int endcol, numcols, numrows, row;
215 int tabwidth;
216
217 if (f_notabs)
218 tabwidth = 1;
219 else
220 tabwidth = 8;
221
222 /*
223 * Have to do random access in the linked list -- build a table
224 * of pointers.
225 */
226 if (dp->entries > lastentries) {
227 lastentries = dp->entries;
228 if ((array =
229 realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
230 warn(NULL);
231 printscol(dp);
232 }
233 }
234 for (p = dp->list, num = 0; p; p = p->fts_link)
235 if (p->fts_number != NO_PRINT)
236 array[num++] = p;
237
238 colwidth = dp->maxlen;
239 if (f_inode)
240 colwidth += dp->s_inode + 1;
241 if (f_size)
242 colwidth += dp->s_block + 1;
243 if (f_type)
244 colwidth += 1;
245
246 colwidth = (colwidth + tabwidth) & ~(tabwidth - 1);
247 if (termwidth < 2 * colwidth) {
248 printscol(dp);
249 return;
250 }
251
252 numcols = termwidth / colwidth;
253 numrows = num / numcols;
254 if (num % numcols)
255 ++numrows;
256
257 if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
258 (void)printf("total %lu\n", howmany(dp->btotal, blocksize));
259 for (row = 0; row < numrows; ++row) {
260 endcol = colwidth;
261 for (base = row, chcnt = col = 0; col < numcols; ++col) {
262 chcnt += printaname(array[base], dp->s_inode,
263 dp->s_block);
264 if ((base += numrows) >= num)
265 break;
266 while ((cnt = ((chcnt + tabwidth) & ~(tabwidth - 1)))
267 <= endcol){
268 (void)putchar(f_notabs ? ' ' : '\t');
269 chcnt = cnt;
270 }
271 endcol += colwidth;
272 }
273 (void)putchar('\n');
274 }
275}
276
277/*
278 * print [inode] [size] name
279 * return # of characters printed, no trailing characters.
280 */
281static int
282printaname(p, inodefield, sizefield)
283 FTSENT *p;
284 u_long sizefield, inodefield;
285{
286 struct stat *sp;
287 int chcnt;
288#ifdef COLORLS
289 int color_printed = 0;
290#endif
291
292 sp = p->fts_statp;
293 chcnt = 0;
294 if (f_inode)
295 chcnt += printf("%*lu ", (int)inodefield, (u_long)sp->st_ino);
296 if (f_size)
297 chcnt += printf("%*qd ",
298 (int)sizefield, howmany(sp->st_blocks, blocksize));
299#ifdef COLORLS
300 if (f_color)
301 color_printed = colortype(sp->st_mode);
302#endif
303 chcnt += printname(p->fts_name);
304#ifdef COLORLS
305 if (f_color && color_printed)
306 endcolor(0);
307#endif
308 if (f_type)
309 chcnt += printtype(sp->st_mode);
310 return (chcnt);
311}
312
313static void
314printtime(ftime)
315 time_t ftime;
316{
317 char longstring[80];
318 static time_t now;
319 const char *format;
320 static int d_first = -1;
321
322 if (d_first < 0)
323 d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
324 if (now == 0)
325 now = time(NULL);
326
327#define SIXMONTHS ((365 / 2) * 86400)
328 if (f_sectime)
329 /* mmm dd hh:mm:ss yyyy || dd mmm hh:mm:ss yyyy */
330 format = d_first ? "%e %b %T %Y " : "%b %e %T %Y ";
331 else if (ftime + SIXMONTHS > now && ftime < now + SIXMONTHS)
332 /* mmm dd hh:mm || dd mmm hh:mm */
333 format = d_first ? "%e %b %R " : "%b %e %R ";
334 else
335 /* mmm dd yyyy || dd mmm yyyy */
336 format = d_first ? "%e %b %Y " : "%b %e %Y ";
337 strftime(longstring, sizeof(longstring), format, localtime(&ftime));
338 fputs(longstring, stdout);
339}
340
341static int
342printtype(mode)
343 u_int mode;
344{
345 switch (mode & S_IFMT) {
346 case S_IFDIR:
347 (void)putchar('/');
348 return (1);
349 case S_IFIFO:
350 (void)putchar('|');
351 return (1);
352 case S_IFLNK:
353 (void)putchar('@');
354 return (1);
355 case S_IFSOCK:
356 (void)putchar('=');
357 return (1);
358 case S_IFWHT:
359 (void)putchar('%');
360 return (1);
361 }
362 if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
363 (void)putchar('*');
364 return (1);
365 }
366 return (0);
367}
368
369#ifdef COLORLS
370static int
371putch(c)
372 int c;
373{
374 (void) putchar(c);
375 return 0;
376}
377
378static int
379writech(c)
380 int c;
381{
382 char tmp = c;
383
384 (void) write(STDOUT_FILENO, &tmp, 1);
385 return 0;
386}
387
388static void
389printcolor(c)
390 Colors c;
391{
392 char *ansiseq;
393
389 if (colors[c][0] != -1) {
390 ansiseq = tgoto(ansi_fgcol, 0, colors[c][0]);
394 if (colors[c].bold)
395 tputs(enter_bold, 1, putch);
396
397 if (colors[c].num[0] != -1) {
398 ansiseq = tgoto(ansi_fgcol, 0, colors[c].num[0]);
391 if (ansiseq)
392 tputs(ansiseq, 1, putch);
393 }
394
399 if (ansiseq)
400 tputs(ansiseq, 1, putch);
401 }
402
395 if (colors[c][1] != -1) {
396 ansiseq = tgoto(ansi_bgcol, 0, colors[c][1]);
403 if (colors[c].num[1] != -1) {
404 ansiseq = tgoto(ansi_bgcol, 0, colors[c].num[1]);
397 if (ansiseq)
398 tputs(ansiseq, 1, putch);
399 }
400}
401
402static void
403endcolor(sig)
404 int sig;
405{
406 tputs(ansi_coloff, 1, sig ? writech : putch);
405 if (ansiseq)
406 tputs(ansiseq, 1, putch);
407 }
408}
409
410static void
411endcolor(sig)
412 int sig;
413{
414 tputs(ansi_coloff, 1, sig ? writech : putch);
415 tputs(attrs_off, 1, sig ? writech : putch);
407}
408
409static int
410colortype(mode)
411 mode_t mode;
412{
413 switch(mode & S_IFMT) {
414 case S_IFDIR:
415 if (mode & S_IWOTH)
416 if (mode & S_ISTXT)
417 printcolor(C_WSDIR);
418 else
419 printcolor(C_WDIR);
420 else
421 printcolor(C_DIR);
422 return(1);
423 case S_IFLNK:
424 printcolor(C_LNK);
425 return(1);
426 case S_IFSOCK:
427 printcolor(C_SOCK);
428 return(1);
429 case S_IFIFO:
430 printcolor(C_FIFO);
431 return(1);
432 case S_IFBLK:
433 printcolor(C_BLK);
434 return(1);
435 case S_IFCHR:
436 printcolor(C_CHR);
437 return(1);
438 }
439 if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
440 if (mode & S_ISUID)
441 printcolor(C_SUID);
442 else if (mode & S_ISGID)
443 printcolor(C_SGID);
444 else
445 printcolor(C_EXEC);
446 return(1);
447 }
448 return(0);
449}
450
451void
452parsecolors(cs)
453char *cs;
454{
455 int i, j, len;
456 char c[2];
416}
417
418static int
419colortype(mode)
420 mode_t mode;
421{
422 switch(mode & S_IFMT) {
423 case S_IFDIR:
424 if (mode & S_IWOTH)
425 if (mode & S_ISTXT)
426 printcolor(C_WSDIR);
427 else
428 printcolor(C_WDIR);
429 else
430 printcolor(C_DIR);
431 return(1);
432 case S_IFLNK:
433 printcolor(C_LNK);
434 return(1);
435 case S_IFSOCK:
436 printcolor(C_SOCK);
437 return(1);
438 case S_IFIFO:
439 printcolor(C_FIFO);
440 return(1);
441 case S_IFBLK:
442 printcolor(C_BLK);
443 return(1);
444 case S_IFCHR:
445 printcolor(C_CHR);
446 return(1);
447 }
448 if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
449 if (mode & S_ISUID)
450 printcolor(C_SUID);
451 else if (mode & S_ISGID)
452 printcolor(C_SGID);
453 else
454 printcolor(C_EXEC);
455 return(1);
456 }
457 return(0);
458}
459
460void
461parsecolors(cs)
462char *cs;
463{
464 int i, j, len;
465 char c[2];
466 short legacy_warn = 0;
457
458 if (cs == NULL) cs = ""; /* LSCOLORS not set */
459 len = strlen(cs);
460 for (i = 0 ; i < C_NUMCOLORS ; i++) {
467
468 if (cs == NULL) cs = ""; /* LSCOLORS not set */
469 len = strlen(cs);
470 for (i = 0 ; i < C_NUMCOLORS ; i++) {
471 colors[i].bold = 0;
472
461 if (len <= 2*i) {
462 c[0] = defcolors[2*i];
463 c[1] = defcolors[2*i+1];
464 }
465 else {
466 c[0] = cs[2*i];
467 c[1] = cs[2*i+1];
468 }
469 for (j = 0 ; j < 2 ; j++) {
473 if (len <= 2*i) {
474 c[0] = defcolors[2*i];
475 c[1] = defcolors[2*i+1];
476 }
477 else {
478 c[0] = cs[2*i];
479 c[1] = cs[2*i+1];
480 }
481 for (j = 0 ; j < 2 ; j++) {
470 if ((c[j] < '0' || c[j] > '7') &&
471 tolower((unsigned char)c[j]) != 'x') {
482 /* Legacy colours used 0-7 */
483 if (c[j] >= '0' && c[j] <= '7') {
484 colors[i].num[j] = c[j] - '0';
485 if (!legacy_warn) {
486 fprintf(stderr,
487 "warn: colors are now defined "
488 "using a-h instead of 0-9. "
489 "see manual page.\n");
490 }
491 legacy_warn = 1;
492 } else if (c[j] >= 'a' && c[j] <= 'h')
493 colors[i].num[j] = c[j] - 'a';
494 else if (c[j] >= 'A' && c[j] <= 'H') {
495 colors[i].num[j] = c[j] - 'A';
496 colors[i].bold = 1;
497 } else if (tolower((unsigned char)c[j] == 'x'))
498 colors[i].num[j] = -1;
499 else {
472 fprintf(stderr,
500 fprintf(stderr,
473 "error: invalid character '%c' in LSCOLORS env var\n",
474 c[j]);
475 c[j] = defcolors[2*i+j];
501 "error: invalid character '%c' in LSCOLORS"
502 " env var\n", c[j]);
503 colors[i].num[j] = defcolors[2*i+j]-'0';
476 }
504 }
477 if (tolower((unsigned char)c[j]) == 'x')
478 colors[i][j] = -1;
479 else
480 colors[i][j] = c[j]-'0';
481 }
482 }
483}
484
485void
486colorquit(sig)
487 int sig;
488{
489 endcolor(sig);
490
491 (void) signal(sig, SIG_DFL);
492 (void) kill(getpid(), sig);
493}
494#endif /*COLORLS*/
495
496static void
497printlink(p)
498 FTSENT *p;
499{
500 int lnklen;
501 char name[MAXPATHLEN + 1], path[MAXPATHLEN + 1];
502
503 if (p->fts_level == FTS_ROOTLEVEL)
504 (void)snprintf(name, sizeof(name), "%s", p->fts_name);
505 else
506 (void)snprintf(name, sizeof(name),
507 "%s/%s", p->fts_parent->fts_accpath, p->fts_name);
508 if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
509 (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
510 return;
511 }
512 path[lnklen] = '\0';
513 (void)printf(" -> ");
514 printname(path);
515}
505 }
506 }
507}
508
509void
510colorquit(sig)
511 int sig;
512{
513 endcolor(sig);
514
515 (void) signal(sig, SIG_DFL);
516 (void) kill(getpid(), sig);
517}
518#endif /*COLORLS*/
519
520static void
521printlink(p)
522 FTSENT *p;
523{
524 int lnklen;
525 char name[MAXPATHLEN + 1], path[MAXPATHLEN + 1];
526
527 if (p->fts_level == FTS_ROOTLEVEL)
528 (void)snprintf(name, sizeof(name), "%s", p->fts_name);
529 else
530 (void)snprintf(name, sizeof(name),
531 "%s/%s", p->fts_parent->fts_accpath, p->fts_name);
532 if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
533 (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
534 return;
535 }
536 path[lnklen] = '\0';
537 (void)printf(" -> ");
538 printname(path);
539}