14b88c807SRodney W. Grimes /* 24b88c807SRodney W. Grimes * Copyright (c) 1989, 1993, 1994 34b88c807SRodney W. Grimes * The Regents of the University of California. All rights reserved. 44b88c807SRodney W. Grimes * 54b88c807SRodney W. Grimes * This code is derived from software contributed to Berkeley by 64b88c807SRodney W. Grimes * Michael Fischbein. 74b88c807SRodney W. Grimes * 84b88c807SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 94b88c807SRodney W. Grimes * modification, are permitted provided that the following conditions 104b88c807SRodney W. Grimes * are met: 114b88c807SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 124b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 134b88c807SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 144b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 154b88c807SRodney W. Grimes * documentation and/or other materials provided with the distribution. 164b88c807SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 174b88c807SRodney W. Grimes * must display the following acknowledgement: 184b88c807SRodney W. Grimes * This product includes software developed by the University of 194b88c807SRodney W. Grimes * California, Berkeley and its contributors. 204b88c807SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 214b88c807SRodney W. Grimes * may be used to endorse or promote products derived from this software 224b88c807SRodney W. Grimes * without specific prior written permission. 234b88c807SRodney W. Grimes * 244b88c807SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 254b88c807SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 264b88c807SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 274b88c807SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 284b88c807SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 294b88c807SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 304b88c807SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 314b88c807SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 324b88c807SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 334b88c807SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 344b88c807SRodney W. Grimes * SUCH DAMAGE. 354b88c807SRodney W. Grimes */ 364b88c807SRodney W. Grimes 374b88c807SRodney W. Grimes #ifndef lint 38febad2fcSSteve Price #if 0 39febad2fcSSteve Price static char sccsid[] = "@(#)print.c 8.4 (Berkeley) 4/17/94"; 40febad2fcSSteve Price #else 41d46c1a60SSteve Price static const char rcsid[] = 422a456239SPeter Wemm "$FreeBSD$"; 43febad2fcSSteve Price #endif 444b88c807SRodney W. Grimes #endif /* not lint */ 454b88c807SRodney W. Grimes 464b88c807SRodney W. Grimes #include <sys/param.h> 474b88c807SRodney W. Grimes #include <sys/stat.h> 484b88c807SRodney W. Grimes 494b88c807SRodney W. Grimes #include <err.h> 504b88c807SRodney W. Grimes #include <errno.h> 514b88c807SRodney W. Grimes #include <fts.h> 524b88c807SRodney W. Grimes #include <grp.h> 5328fd017aSAndrey A. Chernov #include <langinfo.h> 544b88c807SRodney W. Grimes #include <pwd.h> 554b88c807SRodney W. Grimes #include <stdio.h> 564b88c807SRodney W. Grimes #include <stdlib.h> 574b88c807SRodney W. Grimes #include <string.h> 584b88c807SRodney W. Grimes #include <time.h> 594b88c807SRodney W. Grimes #include <unistd.h> 60faebfe2eSAndrey A. Chernov #ifdef COLORLS 61faebfe2eSAndrey A. Chernov #include <ctype.h> 62faebfe2eSAndrey A. Chernov #include <termcap.h> 63faebfe2eSAndrey A. Chernov #include <signal.h> 64faebfe2eSAndrey A. Chernov #endif 654b88c807SRodney W. Grimes 664b88c807SRodney W. Grimes #include "ls.h" 674b88c807SRodney W. Grimes #include "extern.h" 684b88c807SRodney W. Grimes 694b88c807SRodney W. Grimes static int printaname __P((FTSENT *, u_long, u_long)); 704b88c807SRodney W. Grimes static void printlink __P((FTSENT *)); 714b88c807SRodney W. Grimes static void printtime __P((time_t)); 724b88c807SRodney W. Grimes static int printtype __P((u_int)); 7338782c25SAndrey A. Chernov #ifdef COLORLS 7438782c25SAndrey A. Chernov static void endcolor __P((int)); 7538782c25SAndrey A. Chernov static int colortype __P((mode_t)); 7638782c25SAndrey A. Chernov #endif 774b88c807SRodney W. Grimes 784b88c807SRodney W. Grimes #define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT) 794b88c807SRodney W. Grimes 8074985094SJosef Karthauser #ifdef COLORLS 813885812cSJosef Karthauser /* Most of these are taken from <sys/stat.h> */ 823885812cSJosef Karthauser typedef enum Colors { 833885812cSJosef Karthauser C_DIR, /* directory */ 843885812cSJosef Karthauser C_LNK, /* symbolic link */ 853885812cSJosef Karthauser C_SOCK, /* socket */ 863885812cSJosef Karthauser C_FIFO, /* pipe */ 873885812cSJosef Karthauser C_EXEC, /* executable */ 883885812cSJosef Karthauser C_BLK, /* block special */ 893885812cSJosef Karthauser C_CHR, /* character special */ 903885812cSJosef Karthauser C_SUID, /* setuid executable */ 913885812cSJosef Karthauser C_SGID, /* setgid executable */ 923885812cSJosef Karthauser C_WSDIR, /* directory writeble to others, with sticky bit */ 933885812cSJosef Karthauser C_WDIR, /* directory writeble to others, without sticky bit */ 943885812cSJosef Karthauser C_NUMCOLORS /* just a place-holder */ 953885812cSJosef Karthauser } Colors ; 963885812cSJosef Karthauser 97c1499cf6SJosef Karthauser char *defcolors = "exfxcxdxbxegedabagacad"; 983885812cSJosef Karthauser 99c1499cf6SJosef Karthauser /* colors for file types */ 100c1499cf6SJosef Karthauser static struct { 101c1499cf6SJosef Karthauser int num[2]; 102c1499cf6SJosef Karthauser int bold; 103c1499cf6SJosef Karthauser } colors[C_NUMCOLORS]; 104c1499cf6SJosef Karthauser 10574985094SJosef Karthauser #endif 1063885812cSJosef Karthauser 1074b88c807SRodney W. Grimes void 1084b88c807SRodney W. Grimes printscol(dp) 1094b88c807SRodney W. Grimes DISPLAY *dp; 1104b88c807SRodney W. Grimes { 1114b88c807SRodney W. Grimes FTSENT *p; 1124b88c807SRodney W. Grimes 1134b88c807SRodney W. Grimes for (p = dp->list; p; p = p->fts_link) { 1144b88c807SRodney W. Grimes if (IS_NOPRINT(p)) 1154b88c807SRodney W. Grimes continue; 1164b88c807SRodney W. Grimes (void)printaname(p, dp->s_inode, dp->s_block); 1174b88c807SRodney W. Grimes (void)putchar('\n'); 1184b88c807SRodney W. Grimes } 1194b88c807SRodney W. Grimes } 1204b88c807SRodney W. Grimes 121ee579ffbSAssar Westerlund /* 122ee579ffbSAssar Westerlund * print name in current style 123ee579ffbSAssar Westerlund */ 124ee579ffbSAssar Westerlund static int 125ee579ffbSAssar Westerlund printname(name) 126ee579ffbSAssar Westerlund const char *name; 127ee579ffbSAssar Westerlund { 128ee579ffbSAssar Westerlund if (f_octal || f_octal_escape) 129ee579ffbSAssar Westerlund return prn_octal(name); 130ee579ffbSAssar Westerlund else if (f_nonprint) 131ee579ffbSAssar Westerlund return prn_printable(name); 132ee579ffbSAssar Westerlund else 133ee579ffbSAssar Westerlund return printf("%s", name); 134ee579ffbSAssar Westerlund } 135ee579ffbSAssar Westerlund 1364b88c807SRodney W. Grimes void 1374b88c807SRodney W. Grimes printlong(dp) 1384b88c807SRodney W. Grimes DISPLAY *dp; 1394b88c807SRodney W. Grimes { 1404b88c807SRodney W. Grimes struct stat *sp; 1414b88c807SRodney W. Grimes FTSENT *p; 1424b88c807SRodney W. Grimes NAMES *np; 1434b88c807SRodney W. Grimes char buf[20]; 14447bb6b11SAndrey A. Chernov #ifdef COLORLS 14547bb6b11SAndrey A. Chernov int color_printed = 0; 14647bb6b11SAndrey A. Chernov #endif 1474b88c807SRodney W. Grimes 1484b88c807SRodney W. Grimes if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) 1494b88c807SRodney W. Grimes (void)printf("total %lu\n", howmany(dp->btotal, blocksize)); 1504b88c807SRodney W. Grimes 1514b88c807SRodney W. Grimes for (p = dp->list; p; p = p->fts_link) { 1524b88c807SRodney W. Grimes if (IS_NOPRINT(p)) 1534b88c807SRodney W. Grimes continue; 1544b88c807SRodney W. Grimes sp = p->fts_statp; 1554b88c807SRodney W. Grimes if (f_inode) 156fb5cb208SSteve Price (void)printf("%*lu ", dp->s_inode, (u_long)sp->st_ino); 1574b88c807SRodney W. Grimes if (f_size) 1584b88c807SRodney W. Grimes (void)printf("%*qd ", 1594b88c807SRodney W. Grimes dp->s_block, howmany(sp->st_blocks, blocksize)); 1604b88c807SRodney W. Grimes (void)strmode(sp->st_mode, buf); 1614b88c807SRodney W. Grimes np = p->fts_pointer; 1624b88c807SRodney W. Grimes (void)printf("%s %*u %-*s %-*s ", buf, dp->s_nlink, 1634b88c807SRodney W. Grimes sp->st_nlink, dp->s_user, np->user, dp->s_group, 1644b88c807SRodney W. Grimes np->group); 1654b88c807SRodney W. Grimes if (f_flags) 1664b88c807SRodney W. Grimes (void)printf("%-*s ", dp->s_flags, np->flags); 1677304f61fSBrian Feldman if (f_lomac) 1687304f61fSBrian Feldman (void)printf("%-*s ", dp->s_lattr, np->lattr); 1694b88c807SRodney W. Grimes if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode)) 170029b2bd0SBruce Evans if (minor(sp->st_rdev) > 255 || minor(sp->st_rdev) < 0) 171df2fbf15SJoerg Wunsch (void)printf("%3d, 0x%08x ", 172029b2bd0SBruce Evans major(sp->st_rdev), 173029b2bd0SBruce Evans (u_int)minor(sp->st_rdev)); 174df2fbf15SJoerg Wunsch else 1754b88c807SRodney W. Grimes (void)printf("%3d, %3d ", 1764b88c807SRodney W. Grimes major(sp->st_rdev), minor(sp->st_rdev)); 1774b88c807SRodney W. Grimes else if (dp->bcfile) 1784b88c807SRodney W. Grimes (void)printf("%*s%*qd ", 1794b88c807SRodney W. Grimes 8 - dp->s_size, "", dp->s_size, sp->st_size); 1804b88c807SRodney W. Grimes else 1814b88c807SRodney W. Grimes (void)printf("%*qd ", dp->s_size, sp->st_size); 1824b88c807SRodney W. Grimes if (f_accesstime) 1834b88c807SRodney W. Grimes printtime(sp->st_atime); 1844b88c807SRodney W. Grimes else if (f_statustime) 1854b88c807SRodney W. Grimes printtime(sp->st_ctime); 1864b88c807SRodney W. Grimes else 1874b88c807SRodney W. Grimes printtime(sp->st_mtime); 18874985094SJosef Karthauser #ifdef COLORLS 1893885812cSJosef Karthauser if (f_color) 190cf0feaeeSAndrey A. Chernov color_printed = colortype(sp->st_mode); 19174985094SJosef Karthauser #endif 192ee579ffbSAssar Westerlund (void)printname(p->fts_name); 19374985094SJosef Karthauser #ifdef COLORLS 194cf0feaeeSAndrey A. Chernov if (f_color && color_printed) 19538782c25SAndrey A. Chernov endcolor(0); 19674985094SJosef Karthauser #endif 1974b88c807SRodney W. Grimes if (f_type) 1984b88c807SRodney W. Grimes (void)printtype(sp->st_mode); 1994b88c807SRodney W. Grimes if (S_ISLNK(sp->st_mode)) 2004b88c807SRodney W. Grimes printlink(p); 2014b88c807SRodney W. Grimes (void)putchar('\n'); 2024b88c807SRodney W. Grimes } 2034b88c807SRodney W. Grimes } 2044b88c807SRodney W. Grimes 2054b88c807SRodney W. Grimes void 2064b88c807SRodney W. Grimes printcol(dp) 2074b88c807SRodney W. Grimes DISPLAY *dp; 2084b88c807SRodney W. Grimes { 2094b88c807SRodney W. Grimes extern int termwidth; 2104b88c807SRodney W. Grimes static FTSENT **array; 2114b88c807SRodney W. Grimes static int lastentries = -1; 2124b88c807SRodney W. Grimes FTSENT *p; 2134b88c807SRodney W. Grimes int base, chcnt, cnt, col, colwidth, num; 2144b88c807SRodney W. Grimes int endcol, numcols, numrows, row; 215545f583cSTim Vanderhoek int tabwidth; 216545f583cSTim Vanderhoek 217545f583cSTim Vanderhoek if (f_notabs) 218545f583cSTim Vanderhoek tabwidth = 1; 219545f583cSTim Vanderhoek else 220545f583cSTim Vanderhoek tabwidth = 8; 2214b88c807SRodney W. Grimes 2224b88c807SRodney W. Grimes /* 2234b88c807SRodney W. Grimes * Have to do random access in the linked list -- build a table 2244b88c807SRodney W. Grimes * of pointers. 2254b88c807SRodney W. Grimes */ 2264b88c807SRodney W. Grimes if (dp->entries > lastentries) { 2274b88c807SRodney W. Grimes lastentries = dp->entries; 2284b88c807SRodney W. Grimes if ((array = 2294b88c807SRodney W. Grimes realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) { 2304b88c807SRodney W. Grimes warn(NULL); 2314b88c807SRodney W. Grimes printscol(dp); 2324b88c807SRodney W. Grimes } 2334b88c807SRodney W. Grimes } 2344b88c807SRodney W. Grimes for (p = dp->list, num = 0; p; p = p->fts_link) 2354b88c807SRodney W. Grimes if (p->fts_number != NO_PRINT) 2364b88c807SRodney W. Grimes array[num++] = p; 2374b88c807SRodney W. Grimes 2384b88c807SRodney W. Grimes colwidth = dp->maxlen; 2394b88c807SRodney W. Grimes if (f_inode) 2404b88c807SRodney W. Grimes colwidth += dp->s_inode + 1; 2414b88c807SRodney W. Grimes if (f_size) 2424b88c807SRodney W. Grimes colwidth += dp->s_block + 1; 2434b88c807SRodney W. Grimes if (f_type) 2444b88c807SRodney W. Grimes colwidth += 1; 2454b88c807SRodney W. Grimes 246545f583cSTim Vanderhoek colwidth = (colwidth + tabwidth) & ~(tabwidth - 1); 2474b88c807SRodney W. Grimes if (termwidth < 2 * colwidth) { 2484b88c807SRodney W. Grimes printscol(dp); 2494b88c807SRodney W. Grimes return; 2504b88c807SRodney W. Grimes } 2514b88c807SRodney W. Grimes 2524b88c807SRodney W. Grimes numcols = termwidth / colwidth; 2534b88c807SRodney W. Grimes numrows = num / numcols; 2544b88c807SRodney W. Grimes if (num % numcols) 2554b88c807SRodney W. Grimes ++numrows; 2564b88c807SRodney W. Grimes 2574b88c807SRodney W. Grimes if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) 2584b88c807SRodney W. Grimes (void)printf("total %lu\n", howmany(dp->btotal, blocksize)); 2594b88c807SRodney W. Grimes for (row = 0; row < numrows; ++row) { 2604b88c807SRodney W. Grimes endcol = colwidth; 2614b88c807SRodney W. Grimes for (base = row, chcnt = col = 0; col < numcols; ++col) { 2624b88c807SRodney W. Grimes chcnt += printaname(array[base], dp->s_inode, 2634b88c807SRodney W. Grimes dp->s_block); 2644b88c807SRodney W. Grimes if ((base += numrows) >= num) 2654b88c807SRodney W. Grimes break; 266545f583cSTim Vanderhoek while ((cnt = ((chcnt + tabwidth) & ~(tabwidth - 1))) 267545f583cSTim Vanderhoek <= endcol){ 268545f583cSTim Vanderhoek (void)putchar(f_notabs ? ' ' : '\t'); 2694b88c807SRodney W. Grimes chcnt = cnt; 2704b88c807SRodney W. Grimes } 2714b88c807SRodney W. Grimes endcol += colwidth; 2724b88c807SRodney W. Grimes } 2734b88c807SRodney W. Grimes (void)putchar('\n'); 2744b88c807SRodney W. Grimes } 2754b88c807SRodney W. Grimes } 2764b88c807SRodney W. Grimes 2774b88c807SRodney W. Grimes /* 2784b88c807SRodney W. Grimes * print [inode] [size] name 2794b88c807SRodney W. Grimes * return # of characters printed, no trailing characters. 2804b88c807SRodney W. Grimes */ 2814b88c807SRodney W. Grimes static int 2824b88c807SRodney W. Grimes printaname(p, inodefield, sizefield) 2834b88c807SRodney W. Grimes FTSENT *p; 2844b88c807SRodney W. Grimes u_long sizefield, inodefield; 2854b88c807SRodney W. Grimes { 2864b88c807SRodney W. Grimes struct stat *sp; 2874b88c807SRodney W. Grimes int chcnt; 28847bb6b11SAndrey A. Chernov #ifdef COLORLS 28947bb6b11SAndrey A. Chernov int color_printed = 0; 29047bb6b11SAndrey A. Chernov #endif 2914b88c807SRodney W. Grimes 2924b88c807SRodney W. Grimes sp = p->fts_statp; 2934b88c807SRodney W. Grimes chcnt = 0; 2944b88c807SRodney W. Grimes if (f_inode) 295fb5cb208SSteve Price chcnt += printf("%*lu ", (int)inodefield, (u_long)sp->st_ino); 2964b88c807SRodney W. Grimes if (f_size) 2974b88c807SRodney W. Grimes chcnt += printf("%*qd ", 2984b88c807SRodney W. Grimes (int)sizefield, howmany(sp->st_blocks, blocksize)); 29974985094SJosef Karthauser #ifdef COLORLS 3003885812cSJosef Karthauser if (f_color) 301cf0feaeeSAndrey A. Chernov color_printed = colortype(sp->st_mode); 30274985094SJosef Karthauser #endif 303ee579ffbSAssar Westerlund chcnt += printname(p->fts_name); 30474985094SJosef Karthauser #ifdef COLORLS 305cf0feaeeSAndrey A. Chernov if (f_color && color_printed) 30638782c25SAndrey A. Chernov endcolor(0); 30774985094SJosef Karthauser #endif 3084b88c807SRodney W. Grimes if (f_type) 3094b88c807SRodney W. Grimes chcnt += printtype(sp->st_mode); 3104b88c807SRodney W. Grimes return (chcnt); 3114b88c807SRodney W. Grimes } 3124b88c807SRodney W. Grimes 3134b88c807SRodney W. Grimes static void 3144b88c807SRodney W. Grimes printtime(ftime) 3154b88c807SRodney W. Grimes time_t ftime; 3164b88c807SRodney W. Grimes { 317fc4a9bafSAndrey A. Chernov char longstring[80]; 318f173abd0SMike Pritchard static time_t now; 31997e4e97bSJosef Karthauser const char *format; 3208234eb25SAndrey A. Chernov static int d_first = -1; 321f173abd0SMike Pritchard 32228fd017aSAndrey A. Chernov if (d_first < 0) 32328fd017aSAndrey A. Chernov d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); 324f173abd0SMike Pritchard if (now == 0) 325f173abd0SMike Pritchard now = time(NULL); 3264b88c807SRodney W. Grimes 327656dcd43SGarrett Wollman #define SIXMONTHS ((365 / 2) * 86400) 3284b88c807SRodney W. Grimes if (f_sectime) 3291e715e34SJosef Karthauser /* mmm dd hh:mm:ss yyyy || dd mmm hh:mm:ss yyyy */ 33028fd017aSAndrey A. Chernov format = d_first ? "%e %b %T %Y " : "%b %e %T %Y "; 331f173abd0SMike Pritchard else if (ftime + SIXMONTHS > now && ftime < now + SIXMONTHS) 3321e715e34SJosef Karthauser /* mmm dd hh:mm || dd mmm hh:mm */ 33328fd017aSAndrey A. Chernov format = d_first ? "%e %b %R " : "%b %e %R "; 33497e4e97bSJosef Karthauser else 3351e715e34SJosef Karthauser /* mmm dd yyyy || dd mmm yyyy */ 33628fd017aSAndrey A. Chernov format = d_first ? "%e %b %Y " : "%b %e %Y "; 33797e4e97bSJosef Karthauser strftime(longstring, sizeof(longstring), format, localtime(&ftime)); 33897e4e97bSJosef Karthauser fputs(longstring, stdout); 3394b88c807SRodney W. Grimes } 3404b88c807SRodney W. Grimes 3414b88c807SRodney W. Grimes static int 3424b88c807SRodney W. Grimes printtype(mode) 3434b88c807SRodney W. Grimes u_int mode; 3444b88c807SRodney W. Grimes { 3454b88c807SRodney W. Grimes switch (mode & S_IFMT) { 3464b88c807SRodney W. Grimes case S_IFDIR: 3474b88c807SRodney W. Grimes (void)putchar('/'); 3484b88c807SRodney W. Grimes return (1); 3494b88c807SRodney W. Grimes case S_IFIFO: 3504b88c807SRodney W. Grimes (void)putchar('|'); 3514b88c807SRodney W. Grimes return (1); 3524b88c807SRodney W. Grimes case S_IFLNK: 3534b88c807SRodney W. Grimes (void)putchar('@'); 3544b88c807SRodney W. Grimes return (1); 3554b88c807SRodney W. Grimes case S_IFSOCK: 3564b88c807SRodney W. Grimes (void)putchar('='); 3574b88c807SRodney W. Grimes return (1); 358fb5cb208SSteve Price case S_IFWHT: 359fb5cb208SSteve Price (void)putchar('%'); 360fb5cb208SSteve Price return (1); 3614b88c807SRodney W. Grimes } 3624b88c807SRodney W. Grimes if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { 3634b88c807SRodney W. Grimes (void)putchar('*'); 3644b88c807SRodney W. Grimes return (1); 3654b88c807SRodney W. Grimes } 3664b88c807SRodney W. Grimes return (0); 3674b88c807SRodney W. Grimes } 3684b88c807SRodney W. Grimes 36974985094SJosef Karthauser #ifdef COLORLS 3701bf1478aSAndrey A. Chernov static int 3711bf1478aSAndrey A. Chernov putch(c) 372cf0feaeeSAndrey A. Chernov int c; 373cf0feaeeSAndrey A. Chernov { 37438782c25SAndrey A. Chernov (void) putchar(c); 37538782c25SAndrey A. Chernov return 0; 376cf0feaeeSAndrey A. Chernov } 377cf0feaeeSAndrey A. Chernov 3781bf1478aSAndrey A. Chernov static int 3791bf1478aSAndrey A. Chernov writech(c) 38038782c25SAndrey A. Chernov int c; 38138782c25SAndrey A. Chernov { 38238782c25SAndrey A. Chernov char tmp = c; 38338782c25SAndrey A. Chernov 38438782c25SAndrey A. Chernov (void) write(STDOUT_FILENO, &tmp, 1); 38538782c25SAndrey A. Chernov return 0; 38638782c25SAndrey A. Chernov } 387cf0feaeeSAndrey A. Chernov 3881bf1478aSAndrey A. Chernov static void 3893885812cSJosef Karthauser printcolor(c) 3903885812cSJosef Karthauser Colors c; 3913885812cSJosef Karthauser { 39274985094SJosef Karthauser char *ansiseq; 39374985094SJosef Karthauser 394c1499cf6SJosef Karthauser if (colors[c].bold) 395c1499cf6SJosef Karthauser tputs(enter_bold, 1, putch); 396c1499cf6SJosef Karthauser 397c1499cf6SJosef Karthauser if (colors[c].num[0] != -1) { 398c1499cf6SJosef Karthauser ansiseq = tgoto(ansi_fgcol, 0, colors[c].num[0]); 39938782c25SAndrey A. Chernov if (ansiseq) 400cf0feaeeSAndrey A. Chernov tputs(ansiseq, 1, putch); 4013885812cSJosef Karthauser } 40274985094SJosef Karthauser 403c1499cf6SJosef Karthauser if (colors[c].num[1] != -1) { 404c1499cf6SJosef Karthauser ansiseq = tgoto(ansi_bgcol, 0, colors[c].num[1]); 40538782c25SAndrey A. Chernov if (ansiseq) 406cf0feaeeSAndrey A. Chernov tputs(ansiseq, 1, putch); 40774985094SJosef Karthauser } 40874985094SJosef Karthauser } 40974985094SJosef Karthauser 41038782c25SAndrey A. Chernov static void 41138782c25SAndrey A. Chernov endcolor(sig) 41238782c25SAndrey A. Chernov int sig; 41374985094SJosef Karthauser { 41438782c25SAndrey A. Chernov tputs(ansi_coloff, 1, sig ? writech : putch); 415c1499cf6SJosef Karthauser tputs(attrs_off, 1, sig ? writech : putch); 4163885812cSJosef Karthauser } 4173885812cSJosef Karthauser 41838782c25SAndrey A. Chernov static int 4193885812cSJosef Karthauser colortype(mode) 4203885812cSJosef Karthauser mode_t mode; 4213885812cSJosef Karthauser { 4223885812cSJosef Karthauser switch(mode & S_IFMT) { 4233885812cSJosef Karthauser case S_IFDIR: 4243885812cSJosef Karthauser if (mode & S_IWOTH) 4253885812cSJosef Karthauser if (mode & S_ISTXT) 4263885812cSJosef Karthauser printcolor(C_WSDIR); 4273885812cSJosef Karthauser else 4283885812cSJosef Karthauser printcolor(C_WDIR); 4293885812cSJosef Karthauser else 4303885812cSJosef Karthauser printcolor(C_DIR); 4313885812cSJosef Karthauser return(1); 4323885812cSJosef Karthauser case S_IFLNK: 4333885812cSJosef Karthauser printcolor(C_LNK); 4343885812cSJosef Karthauser return(1); 4353885812cSJosef Karthauser case S_IFSOCK: 4363885812cSJosef Karthauser printcolor(C_SOCK); 4373885812cSJosef Karthauser return(1); 4383885812cSJosef Karthauser case S_IFIFO: 4393885812cSJosef Karthauser printcolor(C_FIFO); 4403885812cSJosef Karthauser return(1); 4413885812cSJosef Karthauser case S_IFBLK: 4423885812cSJosef Karthauser printcolor(C_BLK); 4433885812cSJosef Karthauser return(1); 4443885812cSJosef Karthauser case S_IFCHR: 4453885812cSJosef Karthauser printcolor(C_CHR); 4463885812cSJosef Karthauser return(1); 4473885812cSJosef Karthauser } 4483885812cSJosef Karthauser if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { 4493885812cSJosef Karthauser if (mode & S_ISUID) 4503885812cSJosef Karthauser printcolor(C_SUID); 4513885812cSJosef Karthauser else if (mode & S_ISGID) 4523885812cSJosef Karthauser printcolor(C_SGID); 4533885812cSJosef Karthauser else 4543885812cSJosef Karthauser printcolor(C_EXEC); 4553885812cSJosef Karthauser return(1); 4563885812cSJosef Karthauser } 4573885812cSJosef Karthauser return(0); 4583885812cSJosef Karthauser } 4593885812cSJosef Karthauser 4603885812cSJosef Karthauser void 4613885812cSJosef Karthauser parsecolors(cs) 4623885812cSJosef Karthauser char *cs; 4633885812cSJosef Karthauser { 4643885812cSJosef Karthauser int i, j, len; 4653885812cSJosef Karthauser char c[2]; 466c1499cf6SJosef Karthauser short legacy_warn = 0; 46738782c25SAndrey A. Chernov 4683885812cSJosef Karthauser if (cs == NULL) cs = ""; /* LSCOLORS not set */ 4693885812cSJosef Karthauser len = strlen(cs); 4703885812cSJosef Karthauser for (i = 0 ; i < C_NUMCOLORS ; i++) { 471c1499cf6SJosef Karthauser colors[i].bold = 0; 472c1499cf6SJosef Karthauser 4733885812cSJosef Karthauser if (len <= 2*i) { 4743885812cSJosef Karthauser c[0] = defcolors[2*i]; 4753885812cSJosef Karthauser c[1] = defcolors[2*i+1]; 4763885812cSJosef Karthauser } 4773885812cSJosef Karthauser else { 4783885812cSJosef Karthauser c[0] = cs[2*i]; 4793885812cSJosef Karthauser c[1] = cs[2*i+1]; 4803885812cSJosef Karthauser } 4813885812cSJosef Karthauser for (j = 0 ; j < 2 ; j++) { 482c1499cf6SJosef Karthauser /* Legacy colours used 0-7 */ 483c1499cf6SJosef Karthauser if (c[j] >= '0' && c[j] <= '7') { 484c1499cf6SJosef Karthauser colors[i].num[j] = c[j] - '0'; 485c1499cf6SJosef Karthauser if (!legacy_warn) { 4863885812cSJosef Karthauser fprintf(stderr, 487c1499cf6SJosef Karthauser "warn: colors are now defined " 488c1499cf6SJosef Karthauser "using a-h instead of 0-9. " 489c1499cf6SJosef Karthauser "see manual page.\n"); 4903885812cSJosef Karthauser } 491c1499cf6SJosef Karthauser legacy_warn = 1; 492c1499cf6SJosef Karthauser } else if (c[j] >= 'a' && c[j] <= 'h') 493c1499cf6SJosef Karthauser colors[i].num[j] = c[j] - 'a'; 494c1499cf6SJosef Karthauser else if (c[j] >= 'A' && c[j] <= 'H') { 495c1499cf6SJosef Karthauser colors[i].num[j] = c[j] - 'A'; 496c1499cf6SJosef Karthauser colors[i].bold = 1; 497c1499cf6SJosef Karthauser } else if (tolower((unsigned char)c[j] == 'x')) 498c1499cf6SJosef Karthauser colors[i].num[j] = -1; 499c1499cf6SJosef Karthauser else { 500c1499cf6SJosef Karthauser fprintf(stderr, 501c1499cf6SJosef Karthauser "error: invalid character '%c' in LSCOLORS" 502c1499cf6SJosef Karthauser " env var\n", c[j]); 5030d72516eSJosef Karthauser colors[i].num[j] = -1; 504c1499cf6SJosef Karthauser } 5053885812cSJosef Karthauser } 5063885812cSJosef Karthauser } 5073885812cSJosef Karthauser } 508cf0feaeeSAndrey A. Chernov 5091bf1478aSAndrey A. Chernov void 5101bf1478aSAndrey A. Chernov colorquit(sig) 511cf0feaeeSAndrey A. Chernov int sig; 512cf0feaeeSAndrey A. Chernov { 51338782c25SAndrey A. Chernov endcolor(sig); 514faebfe2eSAndrey A. Chernov 515faebfe2eSAndrey A. Chernov (void) signal(sig, SIG_DFL); 516faebfe2eSAndrey A. Chernov (void) kill(getpid(), sig); 517cf0feaeeSAndrey A. Chernov } 51874985094SJosef Karthauser #endif /*COLORLS*/ 5193885812cSJosef Karthauser 5204b88c807SRodney W. Grimes static void 5214b88c807SRodney W. Grimes printlink(p) 5224b88c807SRodney W. Grimes FTSENT *p; 5234b88c807SRodney W. Grimes { 5244b88c807SRodney W. Grimes int lnklen; 5254b88c807SRodney W. Grimes char name[MAXPATHLEN + 1], path[MAXPATHLEN + 1]; 5264b88c807SRodney W. Grimes 5274b88c807SRodney W. Grimes if (p->fts_level == FTS_ROOTLEVEL) 5284b88c807SRodney W. Grimes (void)snprintf(name, sizeof(name), "%s", p->fts_name); 5294b88c807SRodney W. Grimes else 5304b88c807SRodney W. Grimes (void)snprintf(name, sizeof(name), 5314b88c807SRodney W. Grimes "%s/%s", p->fts_parent->fts_accpath, p->fts_name); 5324b88c807SRodney W. Grimes if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) { 5334b88c807SRodney W. Grimes (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno)); 5344b88c807SRodney W. Grimes return; 5354b88c807SRodney W. Grimes } 5364b88c807SRodney W. Grimes path[lnklen] = '\0'; 5377ea30648SDag-Erling Smørgrav (void)printf(" -> "); 538ee579ffbSAssar Westerlund printname(path); 5394b88c807SRodney W. Grimes } 540