Deleted Added
full compact
print.c (88584) print.c (88586)
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 88584 2001-12-28 18:20:23Z joe $";
42 "$FreeBSD: head/bin/ls/print.c 88586 2001-12-28 18:43:32Z 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 {
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 ;
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 = "exfxcxdxbxegedabagacad";
98
99/* colors for file types */
100static struct {
96
97char *defcolors = "exfxcxdxbxegedabagacad";
98
99/* colors for file types */
100static struct {
101 int num[2];
102 int bold;
101 int num[2];
102 int bold;
103} colors[C_NUMCOLORS];
104
105#endif
106
107void
108printscol(dp)
103} colors[C_NUMCOLORS];
104
105#endif
106
107void
108printscol(dp)
109 DISPLAY *dp;
109 DISPLAY *dp;
110{
110{
111 FTSENT *p;
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;
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];
141 FTSENT *p;
142 NAMES *np;
143 char buf[20];
144#ifdef COLORLS
144#ifdef COLORLS
145 int color_printed = 0;
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)
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;
207 DISPLAY *dp;
208{
209 extern int termwidth;
210 static FTSENT **array;
211 static int lastentries = -1;
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;
212 FTSENT *p;
213 int base;
214 int chcnt;
215 int cnt;
216 int col;
217 int colwidth;
218 int endcol;
219 int num;
220 int numcols;
221 int numrows;
222 int row;
223 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)
224
225 if (f_notabs)
226 tabwidth = 1;
227 else
228 tabwidth = 8;
229
230 /*
231 * Have to do random access in the linked list -- build a table
232 * of pointers.
233 */
234 if (dp->entries > lastentries) {
235 lastentries = dp->entries;
236 if ((array =
237 realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
238 warn(NULL);
239 printscol(dp);
240 }
241 }
242 for (p = dp->list, num = 0; p; p = p->fts_link)
243 if (p->fts_number != NO_PRINT)
244 array[num++] = p;
245
246 colwidth = dp->maxlen;
247 if (f_inode)
248 colwidth += dp->s_inode + 1;
249 if (f_size)
250 colwidth += dp->s_block + 1;
251 if (f_type)
252 colwidth += 1;
253
254 colwidth = (colwidth + tabwidth) & ~(tabwidth - 1);
255 if (termwidth < 2 * colwidth) {
256 printscol(dp);
257 return;
258 }
259
260 numcols = termwidth / colwidth;
261 numrows = num / numcols;
262 if (num % numcols)
263 ++numrows;
264
265 if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
266 (void)printf("total %lu\n", howmany(dp->btotal, blocksize));
267 for (row = 0; row < numrows; ++row) {
268 endcol = colwidth;
269 for (base = row, chcnt = col = 0; col < numcols; ++col) {
270 chcnt += printaname(array[base], dp->s_inode,
271 dp->s_block);
272 if ((base += numrows) >= num)
273 break;
274 while ((cnt = ((chcnt + tabwidth) & ~(tabwidth - 1)))
275 <= endcol){
276 (void)putchar(f_notabs ? ' ' : '\t');
277 chcnt = cnt;
278 }
279 endcol += colwidth;
280 }
281 (void)putchar('\n');
282 }
283}
284
285/*
286 * print [inode] [size] name
287 * return # of characters printed, no trailing characters.
288 */
289static int
290printaname(p, inodefield, sizefield)
283 FTSENT *p;
284 u_long sizefield, inodefield;
291 FTSENT *p;
292 u_long inodefield;
293 u_long sizefield;
285{
286 struct stat *sp;
294{
295 struct stat *sp;
287 int chcnt;
296 int chcnt;
288#ifdef COLORLS
297#ifdef COLORLS
289 int color_printed = 0;
298 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)
299#endif
300
301 sp = p->fts_statp;
302 chcnt = 0;
303 if (f_inode)
304 chcnt += printf("%*lu ", (int)inodefield, (u_long)sp->st_ino);
305 if (f_size)
306 chcnt += printf("%*qd ",
307 (int)sizefield, howmany(sp->st_blocks, blocksize));
308#ifdef COLORLS
309 if (f_color)
310 color_printed = colortype(sp->st_mode);
311#endif
312 chcnt += printname(p->fts_name);
313#ifdef COLORLS
314 if (f_color && color_printed)
315 endcolor(0);
316#endif
317 if (f_type)
318 chcnt += printtype(sp->st_mode);
319 return (chcnt);
320}
321
322static void
323printtime(ftime)
315 time_t ftime;
324 time_t ftime;
316{
325{
317 char longstring[80];
318 static time_t now;
319 const char *format;
320 static int d_first = -1;
326 char longstring[80];
327 static time_t now;
328 const char *format;
329 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)
330
331 if (d_first < 0)
332 d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
333 if (now == 0)
334 now = time(NULL);
335
336#define SIXMONTHS ((365 / 2) * 86400)
337 if (f_sectime)
338 /* mmm dd hh:mm:ss yyyy || dd mmm hh:mm:ss yyyy */
339 format = d_first ? "%e %b %T %Y " : "%b %e %T %Y ";
340 else if (ftime + SIXMONTHS > now && ftime < now + SIXMONTHS)
341 /* mmm dd hh:mm || dd mmm hh:mm */
342 format = d_first ? "%e %b %R " : "%b %e %R ";
343 else
344 /* mmm dd yyyy || dd mmm yyyy */
345 format = d_first ? "%e %b %Y " : "%b %e %Y ";
346 strftime(longstring, sizeof(longstring), format, localtime(&ftime));
347 fputs(longstring, stdout);
348}
349
350static int
351printtype(mode)
343 u_int mode;
352 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)
353{
354 switch (mode & S_IFMT) {
355 case S_IFDIR:
356 (void)putchar('/');
357 return (1);
358 case S_IFIFO:
359 (void)putchar('|');
360 return (1);
361 case S_IFLNK:
362 (void)putchar('@');
363 return (1);
364 case S_IFSOCK:
365 (void)putchar('=');
366 return (1);
367 case S_IFWHT:
368 (void)putchar('%');
369 return (1);
370 }
371 if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
372 (void)putchar('*');
373 return (1);
374 }
375 return (0);
376}
377
378#ifdef COLORLS
379static int
380putch(c)
372 int c;
381 int c;
373{
374 (void) putchar(c);
375 return 0;
376}
377
378static int
379writech(c)
382{
383 (void) putchar(c);
384 return 0;
385}
386
387static int
388writech(c)
380 int c;
389 int c;
381{
390{
382 char tmp = c;
391 char tmp = c;
383
384 (void) write(STDOUT_FILENO, &tmp, 1);
385 return 0;
386}
387
388static void
389printcolor(c)
392
393 (void) write(STDOUT_FILENO, &tmp, 1);
394 return 0;
395}
396
397static void
398printcolor(c)
390 Colors c;
399 Colors c;
391{
400{
392 char *ansiseq;
401 char *ansiseq;
393
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]);
399 if (ansiseq)
400 tputs(ansiseq, 1, putch);
401 }
402
403 if (colors[c].num[1] != -1) {
404 ansiseq = tgoto(ansi_bgcol, 0, colors[c].num[1]);
405 if (ansiseq)
406 tputs(ansiseq, 1, putch);
407 }
408}
409
410static void
411endcolor(sig)
402
403 if (colors[c].bold)
404 tputs(enter_bold, 1, putch);
405
406 if (colors[c].num[0] != -1) {
407 ansiseq = tgoto(ansi_fgcol, 0, colors[c].num[0]);
408 if (ansiseq)
409 tputs(ansiseq, 1, putch);
410 }
411
412 if (colors[c].num[1] != -1) {
413 ansiseq = tgoto(ansi_bgcol, 0, colors[c].num[1]);
414 if (ansiseq)
415 tputs(ansiseq, 1, putch);
416 }
417}
418
419static void
420endcolor(sig)
412 int sig;
421 int sig;
413{
414 tputs(ansi_coloff, 1, sig ? writech : putch);
415 tputs(attrs_off, 1, sig ? writech : putch);
416}
417
418static int
419colortype(mode)
422{
423 tputs(ansi_coloff, 1, sig ? writech : putch);
424 tputs(attrs_off, 1, sig ? writech : putch);
425}
426
427static int
428colortype(mode)
420 mode_t mode;
429 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)
430{
431 switch(mode & S_IFMT) {
432 case S_IFDIR:
433 if (mode & S_IWOTH)
434 if (mode & S_ISTXT)
435 printcolor(C_WSDIR);
436 else
437 printcolor(C_WDIR);
438 else
439 printcolor(C_DIR);
440 return(1);
441 case S_IFLNK:
442 printcolor(C_LNK);
443 return(1);
444 case S_IFSOCK:
445 printcolor(C_SOCK);
446 return(1);
447 case S_IFIFO:
448 printcolor(C_FIFO);
449 return(1);
450 case S_IFBLK:
451 printcolor(C_BLK);
452 return(1);
453 case S_IFCHR:
454 printcolor(C_CHR);
455 return(1);
456 }
457 if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
458 if (mode & S_ISUID)
459 printcolor(C_SUID);
460 else if (mode & S_ISGID)
461 printcolor(C_SGID);
462 else
463 printcolor(C_EXEC);
464 return(1);
465 }
466 return(0);
467}
468
469void
470parsecolors(cs)
462char *cs;
471 char *cs;
463{
472{
464 int i, j, len;
465 char c[2];
466 short legacy_warn = 0;
473 int i;
474 int j;
475 int len;
476 char c[2];
477 short legacy_warn = 0;
467
478
468 if (cs == NULL) cs = ""; /* LSCOLORS not set */
479 if (cs == NULL)
480 cs = ""; /* LSCOLORS not set */
469 len = strlen(cs);
470 for (i = 0 ; i < C_NUMCOLORS ; i++) {
471 colors[i].bold = 0;
472
481 len = strlen(cs);
482 for (i = 0 ; i < C_NUMCOLORS ; i++) {
483 colors[i].bold = 0;
484
473 if (len <= 2*i) {
474 c[0] = defcolors[2*i];
475 c[1] = defcolors[2*i+1];
485 if (len <= 2 * i) {
486 c[0] = defcolors[2 * i];
487 c[1] = defcolors[2 * i + 1];
476 }
477 else {
488 }
489 else {
478 c[0] = cs[2*i];
479 c[1] = cs[2*i+1];
490 c[0] = cs[2 * i];
491 c[1] = cs[2 * i + 1];
480 }
481 for (j = 0 ; j < 2 ; j++) {
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 {
500 fprintf(stderr,
501 "error: invalid character '%c' in LSCOLORS"
502 " env var\n", c[j]);
503 colors[i].num[j] = -1;
504 }
505 }
506 }
507}
508
509void
510colorquit(sig)
492 }
493 for (j = 0 ; j < 2 ; j++) {
494 /* Legacy colours used 0-7 */
495 if (c[j] >= '0' && c[j] <= '7') {
496 colors[i].num[j] = c[j] - '0';
497 if (!legacy_warn) {
498 fprintf(stderr,
499 "warn: colors are now defined "
500 "using a-h instead of 0-9. "
501 "see manual page.\n");
502 }
503 legacy_warn = 1;
504 } else if (c[j] >= 'a' && c[j] <= 'h')
505 colors[i].num[j] = c[j] - 'a';
506 else if (c[j] >= 'A' && c[j] <= 'H') {
507 colors[i].num[j] = c[j] - 'A';
508 colors[i].bold = 1;
509 } else if (tolower((unsigned char)c[j] == 'x'))
510 colors[i].num[j] = -1;
511 else {
512 fprintf(stderr,
513 "error: invalid character '%c' in LSCOLORS"
514 " env var\n", c[j]);
515 colors[i].num[j] = -1;
516 }
517 }
518 }
519}
520
521void
522colorquit(sig)
511 int sig;
523 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)
524{
525 endcolor(sig);
526
527 (void) signal(sig, SIG_DFL);
528 (void) kill(getpid(), sig);
529}
530#endif /*COLORLS*/
531
532static void
533printlink(p)
522 FTSENT *p;
534 FTSENT *p;
523{
535{
524 int lnklen;
525 char name[MAXPATHLEN + 1], path[MAXPATHLEN + 1];
536 int lnklen;
537 char name[MAXPATHLEN + 1];
538 char 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}
539
540 if (p->fts_level == FTS_ROOTLEVEL)
541 (void)snprintf(name, sizeof(name), "%s", p->fts_name);
542 else
543 (void)snprintf(name, sizeof(name),
544 "%s/%s", p->fts_parent->fts_accpath, p->fts_name);
545 if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
546 (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
547 return;
548 }
549 path[lnklen] = '\0';
550 (void)printf(" -> ");
551 printname(path);
552}