print.c revision 88587
11556Srgrimes/* 21556Srgrimes * Copyright (c) 1989, 1993, 1994 31556Srgrimes * The Regents of the University of California. All rights reserved. 41556Srgrimes * 51556Srgrimes * This code is derived from software contributed to Berkeley by 61556Srgrimes * Michael Fischbein. 71556Srgrimes * 81556Srgrimes * Redistribution and use in source and binary forms, with or without 91556Srgrimes * modification, are permitted provided that the following conditions 101556Srgrimes * are met: 111556Srgrimes * 1. Redistributions of source code must retain the above copyright 121556Srgrimes * notice, this list of conditions and the following disclaimer. 131556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141556Srgrimes * notice, this list of conditions and the following disclaimer in the 151556Srgrimes * documentation and/or other materials provided with the distribution. 161556Srgrimes * 3. All advertising materials mentioning features or use of this software 171556Srgrimes * must display the following acknowledgement: 181556Srgrimes * This product includes software developed by the University of 191556Srgrimes * California, Berkeley and its contributors. 201556Srgrimes * 4. Neither the name of the University nor the names of its contributors 211556Srgrimes * may be used to endorse or promote products derived from this software 221556Srgrimes * without specific prior written permission. 231556Srgrimes * 241556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271556Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341556Srgrimes * SUCH DAMAGE. 351556Srgrimes */ 361556Srgrimes 371556Srgrimes#ifndef lint 3827967Ssteve#if 0 3927967Sstevestatic char sccsid[] = "@(#)print.c 8.4 (Berkeley) 4/17/94"; 4027967Ssteve#else 4127958Sstevestatic const char rcsid[] = 4250471Speter "$FreeBSD: head/bin/ls/print.c 88587 2001-12-28 19:26:06Z joe $"; 4327967Ssteve#endif 441556Srgrimes#endif /* not lint */ 451556Srgrimes 461556Srgrimes#include <sys/param.h> 471556Srgrimes#include <sys/stat.h> 481556Srgrimes 491556Srgrimes#include <err.h> 501556Srgrimes#include <errno.h> 511556Srgrimes#include <fts.h> 521556Srgrimes#include <grp.h> 5374566Sache#include <langinfo.h> 541556Srgrimes#include <pwd.h> 551556Srgrimes#include <stdio.h> 561556Srgrimes#include <stdlib.h> 571556Srgrimes#include <string.h> 581556Srgrimes#include <time.h> 591556Srgrimes#include <unistd.h> 6061294Sache#ifdef COLORLS 6161294Sache#include <ctype.h> 6261294Sache#include <termcap.h> 6361294Sache#include <signal.h> 6461294Sache#endif 651556Srgrimes 661556Srgrimes#include "ls.h" 671556Srgrimes#include "extern.h" 681556Srgrimes 691556Srgrimesstatic int printaname __P((FTSENT *, u_long, u_long)); 701556Srgrimesstatic void printlink __P((FTSENT *)); 711556Srgrimesstatic void printtime __P((time_t)); 721556Srgrimesstatic int printtype __P((u_int)); 7361321Sache#ifdef COLORLS 7461321Sachestatic void endcolor __P((int)); 7561321Sachestatic int colortype __P((mode_t)); 7661321Sache#endif 771556Srgrimes 781556Srgrimes#define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT) 791556Srgrimes 8061268Sjoe#ifdef COLORLS 8161178Sjoe/* Most of these are taken from <sys/stat.h> */ 8261178Sjoetypedef enum Colors { 8388586Sjoe C_DIR, /* directory */ 8488586Sjoe C_LNK, /* symbolic link */ 8588586Sjoe C_SOCK, /* socket */ 8688586Sjoe C_FIFO, /* pipe */ 8788586Sjoe C_EXEC, /* executable */ 8888586Sjoe C_BLK, /* block special */ 8988586Sjoe C_CHR, /* character special */ 9088586Sjoe C_SUID, /* setuid executable */ 9188586Sjoe C_SGID, /* setgid executable */ 9288586Sjoe C_WSDIR, /* directory writeble to others, with sticky bit */ 9388586Sjoe C_WDIR, /* directory writeble to others, without sticky bit */ 9488586Sjoe C_NUMCOLORS /* just a place-holder */ 9588586Sjoe} Colors; 9661178Sjoe 9788587Sjoeconst char *defcolors = "exfxcxdxbxegedabagacad"; 9861178Sjoe 9988583Sjoe/* colors for file types */ 10088583Sjoestatic struct { 10188586Sjoe int num[2]; 10288586Sjoe int bold; 10388583Sjoe} colors[C_NUMCOLORS]; 10488583Sjoe 10561268Sjoe#endif 10661178Sjoe 1071556Srgrimesvoid 1081556Srgrimesprintscol(dp) 10988586Sjoe DISPLAY *dp; 1101556Srgrimes{ 11188586Sjoe FTSENT *p; 1121556Srgrimes 1131556Srgrimes for (p = dp->list; p; p = p->fts_link) { 1141556Srgrimes if (IS_NOPRINT(p)) 1151556Srgrimes continue; 1161556Srgrimes (void)printaname(p, dp->s_inode, dp->s_block); 1171556Srgrimes (void)putchar('\n'); 1181556Srgrimes } 1191556Srgrimes} 1201556Srgrimes 12162597Sassar/* 12262597Sassar * print name in current style 12362597Sassar */ 12462597Sassarstatic int 12562597Sassarprintname(name) 12662597Sassar const char *name; 12762597Sassar{ 12862597Sassar if (f_octal || f_octal_escape) 12962597Sassar return prn_octal(name); 13062597Sassar else if (f_nonprint) 13162597Sassar return prn_printable(name); 13262597Sassar else 13362597Sassar return printf("%s", name); 13462597Sassar} 13562597Sassar 1361556Srgrimesvoid 1371556Srgrimesprintlong(dp) 1381556Srgrimes DISPLAY *dp; 1391556Srgrimes{ 1401556Srgrimes struct stat *sp; 14188586Sjoe FTSENT *p; 14288586Sjoe NAMES *np; 14388586Sjoe char buf[20]; 14461292Sache#ifdef COLORLS 14588586Sjoe int color_printed = 0; 14661292Sache#endif 1471556Srgrimes 1481556Srgrimes if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) 1491556Srgrimes (void)printf("total %lu\n", howmany(dp->btotal, blocksize)); 1501556Srgrimes 1511556Srgrimes for (p = dp->list; p; p = p->fts_link) { 1521556Srgrimes if (IS_NOPRINT(p)) 1531556Srgrimes continue; 1541556Srgrimes sp = p->fts_statp; 1551556Srgrimes if (f_inode) 15620417Ssteve (void)printf("%*lu ", dp->s_inode, (u_long)sp->st_ino); 1571556Srgrimes if (f_size) 1581556Srgrimes (void)printf("%*qd ", 1591556Srgrimes dp->s_block, howmany(sp->st_blocks, blocksize)); 1601556Srgrimes (void)strmode(sp->st_mode, buf); 1611556Srgrimes np = p->fts_pointer; 1621556Srgrimes (void)printf("%s %*u %-*s %-*s ", buf, dp->s_nlink, 1631556Srgrimes sp->st_nlink, dp->s_user, np->user, dp->s_group, 1641556Srgrimes np->group); 1651556Srgrimes if (f_flags) 1661556Srgrimes (void)printf("%-*s ", dp->s_flags, np->flags); 16786922Sgreen if (f_lomac) 16886922Sgreen (void)printf("%-*s ", dp->s_lattr, np->lattr); 1691556Srgrimes if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode)) 17055514Sbde if (minor(sp->st_rdev) > 255 || minor(sp->st_rdev) < 0) 17113120Sjoerg (void)printf("%3d, 0x%08x ", 17255514Sbde major(sp->st_rdev), 17355514Sbde (u_int)minor(sp->st_rdev)); 17413120Sjoerg else 17513120Sjoerg (void)printf("%3d, %3d ", 17613120Sjoerg major(sp->st_rdev), minor(sp->st_rdev)); 1771556Srgrimes else if (dp->bcfile) 1781556Srgrimes (void)printf("%*s%*qd ", 1791556Srgrimes 8 - dp->s_size, "", dp->s_size, sp->st_size); 1801556Srgrimes else 1811556Srgrimes (void)printf("%*qd ", dp->s_size, sp->st_size); 1821556Srgrimes if (f_accesstime) 1831556Srgrimes printtime(sp->st_atime); 1841556Srgrimes else if (f_statustime) 1851556Srgrimes printtime(sp->st_ctime); 1861556Srgrimes else 1871556Srgrimes printtime(sp->st_mtime); 18861268Sjoe#ifdef COLORLS 18961178Sjoe if (f_color) 19061291Sache color_printed = colortype(sp->st_mode); 19161268Sjoe#endif 19262597Sassar (void)printname(p->fts_name); 19361268Sjoe#ifdef COLORLS 19461291Sache if (f_color && color_printed) 19561321Sache endcolor(0); 19661268Sjoe#endif 1971556Srgrimes if (f_type) 1981556Srgrimes (void)printtype(sp->st_mode); 1991556Srgrimes if (S_ISLNK(sp->st_mode)) 2001556Srgrimes printlink(p); 2011556Srgrimes (void)putchar('\n'); 2021556Srgrimes } 2031556Srgrimes} 2041556Srgrimes 2051556Srgrimesvoid 2061556Srgrimesprintcol(dp) 20788586Sjoe DISPLAY *dp; 2081556Srgrimes{ 2091556Srgrimes extern int termwidth; 2101556Srgrimes static FTSENT **array; 2111556Srgrimes static int lastentries = -1; 21288586Sjoe FTSENT *p; 21388586Sjoe int base; 21488586Sjoe int chcnt; 21588586Sjoe int cnt; 21688586Sjoe int col; 21788586Sjoe int colwidth; 21888586Sjoe int endcol; 21988586Sjoe int num; 22088586Sjoe int numcols; 22188586Sjoe int numrows; 22288586Sjoe int row; 22388586Sjoe int tabwidth; 2241556Srgrimes 22537932Shoek if (f_notabs) 22637932Shoek tabwidth = 1; 22737932Shoek else 22837932Shoek tabwidth = 8; 22937932Shoek 2301556Srgrimes /* 2311556Srgrimes * Have to do random access in the linked list -- build a table 2321556Srgrimes * of pointers. 2331556Srgrimes */ 2341556Srgrimes if (dp->entries > lastentries) { 2351556Srgrimes lastentries = dp->entries; 2361556Srgrimes if ((array = 2371556Srgrimes realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) { 2381556Srgrimes warn(NULL); 2391556Srgrimes printscol(dp); 2401556Srgrimes } 2411556Srgrimes } 2421556Srgrimes for (p = dp->list, num = 0; p; p = p->fts_link) 2431556Srgrimes if (p->fts_number != NO_PRINT) 2441556Srgrimes array[num++] = p; 2451556Srgrimes 2461556Srgrimes colwidth = dp->maxlen; 2471556Srgrimes if (f_inode) 2481556Srgrimes colwidth += dp->s_inode + 1; 2491556Srgrimes if (f_size) 2501556Srgrimes colwidth += dp->s_block + 1; 2511556Srgrimes if (f_type) 2521556Srgrimes colwidth += 1; 2531556Srgrimes 25437932Shoek colwidth = (colwidth + tabwidth) & ~(tabwidth - 1); 2551556Srgrimes if (termwidth < 2 * colwidth) { 2561556Srgrimes printscol(dp); 2571556Srgrimes return; 2581556Srgrimes } 2591556Srgrimes 2601556Srgrimes numcols = termwidth / colwidth; 2611556Srgrimes numrows = num / numcols; 2621556Srgrimes if (num % numcols) 2631556Srgrimes ++numrows; 2641556Srgrimes 2651556Srgrimes if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) 2661556Srgrimes (void)printf("total %lu\n", howmany(dp->btotal, blocksize)); 2671556Srgrimes for (row = 0; row < numrows; ++row) { 2681556Srgrimes endcol = colwidth; 2691556Srgrimes for (base = row, chcnt = col = 0; col < numcols; ++col) { 2701556Srgrimes chcnt += printaname(array[base], dp->s_inode, 2711556Srgrimes dp->s_block); 2721556Srgrimes if ((base += numrows) >= num) 2731556Srgrimes break; 27437932Shoek while ((cnt = ((chcnt + tabwidth) & ~(tabwidth - 1))) 27537932Shoek <= endcol){ 27637932Shoek (void)putchar(f_notabs ? ' ' : '\t'); 2771556Srgrimes chcnt = cnt; 2781556Srgrimes } 2791556Srgrimes endcol += colwidth; 2801556Srgrimes } 2811556Srgrimes (void)putchar('\n'); 2821556Srgrimes } 2831556Srgrimes} 2841556Srgrimes 2851556Srgrimes/* 2861556Srgrimes * print [inode] [size] name 2871556Srgrimes * return # of characters printed, no trailing characters. 2881556Srgrimes */ 2891556Srgrimesstatic int 2901556Srgrimesprintaname(p, inodefield, sizefield) 29188586Sjoe FTSENT *p; 29288586Sjoe u_long inodefield; 29388586Sjoe u_long sizefield; 2941556Srgrimes{ 2951556Srgrimes struct stat *sp; 29688586Sjoe int chcnt; 29761292Sache#ifdef COLORLS 29888586Sjoe int color_printed = 0; 29961292Sache#endif 3001556Srgrimes 3011556Srgrimes sp = p->fts_statp; 3021556Srgrimes chcnt = 0; 3031556Srgrimes if (f_inode) 30420417Ssteve chcnt += printf("%*lu ", (int)inodefield, (u_long)sp->st_ino); 3051556Srgrimes if (f_size) 3061556Srgrimes chcnt += printf("%*qd ", 3071556Srgrimes (int)sizefield, howmany(sp->st_blocks, blocksize)); 30861268Sjoe#ifdef COLORLS 30961178Sjoe if (f_color) 31061291Sache color_printed = colortype(sp->st_mode); 31161268Sjoe#endif 31262597Sassar chcnt += printname(p->fts_name); 31361268Sjoe#ifdef COLORLS 31461291Sache if (f_color && color_printed) 31561321Sache endcolor(0); 31661268Sjoe#endif 3171556Srgrimes if (f_type) 3181556Srgrimes chcnt += printtype(sp->st_mode); 3191556Srgrimes return (chcnt); 3201556Srgrimes} 3211556Srgrimes 3221556Srgrimesstatic void 3231556Srgrimesprinttime(ftime) 32488586Sjoe time_t ftime; 3251556Srgrimes{ 32688586Sjoe char longstring[80]; 32788586Sjoe static time_t now; 32888586Sjoe const char *format; 32988586Sjoe static int d_first = -1; 3301556Srgrimes 33174566Sache if (d_first < 0) 33274566Sache d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); 33321545Smpp if (now == 0) 33421545Smpp now = time(NULL); 33521545Smpp 3369987Swollman#define SIXMONTHS ((365 / 2) * 86400) 3371556Srgrimes if (f_sectime) 33861920Sjoe /* mmm dd hh:mm:ss yyyy || dd mmm hh:mm:ss yyyy */ 33974566Sache format = d_first ? "%e %b %T %Y " : "%b %e %T %Y "; 34021545Smpp else if (ftime + SIXMONTHS > now && ftime < now + SIXMONTHS) 34161920Sjoe /* mmm dd hh:mm || dd mmm hh:mm */ 34274566Sache format = d_first ? "%e %b %R " : "%b %e %R "; 34361814Sjoe else 34461920Sjoe /* mmm dd yyyy || dd mmm yyyy */ 34574566Sache format = d_first ? "%e %b %Y " : "%b %e %Y "; 34661814Sjoe strftime(longstring, sizeof(longstring), format, localtime(&ftime)); 34761814Sjoe fputs(longstring, stdout); 3481556Srgrimes} 3491556Srgrimes 3501556Srgrimesstatic int 3511556Srgrimesprinttype(mode) 35288586Sjoe u_int mode; 3531556Srgrimes{ 3541556Srgrimes switch (mode & S_IFMT) { 3551556Srgrimes case S_IFDIR: 3561556Srgrimes (void)putchar('/'); 3571556Srgrimes return (1); 3581556Srgrimes case S_IFIFO: 3591556Srgrimes (void)putchar('|'); 3601556Srgrimes return (1); 3611556Srgrimes case S_IFLNK: 3621556Srgrimes (void)putchar('@'); 3631556Srgrimes return (1); 3641556Srgrimes case S_IFSOCK: 3651556Srgrimes (void)putchar('='); 3661556Srgrimes return (1); 36720417Ssteve case S_IFWHT: 36820417Ssteve (void)putchar('%'); 36920417Ssteve return (1); 3701556Srgrimes } 3711556Srgrimes if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { 3721556Srgrimes (void)putchar('*'); 3731556Srgrimes return (1); 3741556Srgrimes } 3751556Srgrimes return (0); 3761556Srgrimes} 3771556Srgrimes 37861268Sjoe#ifdef COLORLS 37961323Sachestatic int 38061323Sacheputch(c) 38188586Sjoe int c; 38261291Sache{ 38361321Sache (void) putchar(c); 38461321Sache return 0; 38561291Sache} 38661291Sache 38761323Sachestatic int 38861323Sachewritech(c) 38988586Sjoe int c; 39061321Sache{ 39188586Sjoe char tmp = c; 39261291Sache 39361321Sache (void) write(STDOUT_FILENO, &tmp, 1); 39461321Sache return 0; 39561321Sache} 39661321Sache 39761323Sachestatic void 39861178Sjoeprintcolor(c) 39988586Sjoe Colors c; 40061178Sjoe{ 40188586Sjoe char *ansiseq; 40261268Sjoe 40388583Sjoe if (colors[c].bold) 40488583Sjoe tputs(enter_bold, 1, putch); 40588583Sjoe 40688583Sjoe if (colors[c].num[0] != -1) { 40788583Sjoe ansiseq = tgoto(ansi_fgcol, 0, colors[c].num[0]); 40861321Sache if (ansiseq) 40961291Sache tputs(ansiseq, 1, putch); 41061178Sjoe } 41161268Sjoe 41288583Sjoe if (colors[c].num[1] != -1) { 41388583Sjoe ansiseq = tgoto(ansi_bgcol, 0, colors[c].num[1]); 41461321Sache if (ansiseq) 41561291Sache tputs(ansiseq, 1, putch); 41661268Sjoe } 41761178Sjoe} 41861178Sjoe 41961321Sachestatic void 42061321Sacheendcolor(sig) 42188586Sjoe int sig; 42261268Sjoe{ 42361321Sache tputs(ansi_coloff, 1, sig ? writech : putch); 42488583Sjoe tputs(attrs_off, 1, sig ? writech : putch); 42561268Sjoe} 42661268Sjoe 42761321Sachestatic int 42861178Sjoecolortype(mode) 42988586Sjoe mode_t mode; 43061178Sjoe{ 43161178Sjoe switch(mode & S_IFMT) { 43261178Sjoe case S_IFDIR: 43361178Sjoe if (mode & S_IWOTH) 43461178Sjoe if (mode & S_ISTXT) 43561178Sjoe printcolor(C_WSDIR); 43661178Sjoe else 43761178Sjoe printcolor(C_WDIR); 43861178Sjoe else 43961178Sjoe printcolor(C_DIR); 44061178Sjoe return(1); 44161178Sjoe case S_IFLNK: 44261178Sjoe printcolor(C_LNK); 44361178Sjoe return(1); 44461178Sjoe case S_IFSOCK: 44561178Sjoe printcolor(C_SOCK); 44661178Sjoe return(1); 44761178Sjoe case S_IFIFO: 44861178Sjoe printcolor(C_FIFO); 44961178Sjoe return(1); 45061178Sjoe case S_IFBLK: 45161178Sjoe printcolor(C_BLK); 45261178Sjoe return(1); 45361178Sjoe case S_IFCHR: 45461178Sjoe printcolor(C_CHR); 45561178Sjoe return(1); 45661178Sjoe } 45761178Sjoe if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { 45861178Sjoe if (mode & S_ISUID) 45961178Sjoe printcolor(C_SUID); 46061178Sjoe else if (mode & S_ISGID) 46161178Sjoe printcolor(C_SGID); 46261178Sjoe else 46361178Sjoe printcolor(C_EXEC); 46461178Sjoe return(1); 46561178Sjoe } 46661178Sjoe return(0); 46761178Sjoe} 46861178Sjoe 46961178Sjoevoid 47061178Sjoeparsecolors(cs) 47188587Sjoe const char *cs; 47261178Sjoe{ 47388586Sjoe int i; 47488586Sjoe int j; 47588586Sjoe int len; 47688586Sjoe char c[2]; 47788586Sjoe short legacy_warn = 0; 47861321Sache 47988586Sjoe if (cs == NULL) 48088586Sjoe cs = ""; /* LSCOLORS not set */ 48161178Sjoe len = strlen(cs); 48261178Sjoe for (i = 0 ; i < C_NUMCOLORS ; i++) { 48388583Sjoe colors[i].bold = 0; 48488583Sjoe 48588586Sjoe if (len <= 2 * i) { 48688586Sjoe c[0] = defcolors[2 * i]; 48788586Sjoe c[1] = defcolors[2 * i + 1]; 48861178Sjoe } 48961178Sjoe else { 49088586Sjoe c[0] = cs[2 * i]; 49188586Sjoe c[1] = cs[2 * i + 1]; 49261178Sjoe } 49361178Sjoe for (j = 0 ; j < 2 ; j++) { 49488583Sjoe /* Legacy colours used 0-7 */ 49588583Sjoe if (c[j] >= '0' && c[j] <= '7') { 49688583Sjoe colors[i].num[j] = c[j] - '0'; 49788583Sjoe if (!legacy_warn) { 49888583Sjoe fprintf(stderr, 49988583Sjoe "warn: colors are now defined " 50088583Sjoe "using a-h instead of 0-9. " 50188583Sjoe "see manual page.\n"); 50288583Sjoe } 50388583Sjoe legacy_warn = 1; 50488583Sjoe } else if (c[j] >= 'a' && c[j] <= 'h') 50588583Sjoe colors[i].num[j] = c[j] - 'a'; 50688583Sjoe else if (c[j] >= 'A' && c[j] <= 'H') { 50788583Sjoe colors[i].num[j] = c[j] - 'A'; 50888583Sjoe colors[i].bold = 1; 50988583Sjoe } else if (tolower((unsigned char)c[j] == 'x')) 51088583Sjoe colors[i].num[j] = -1; 51188583Sjoe else { 51261178Sjoe fprintf(stderr, 51388583Sjoe "error: invalid character '%c' in LSCOLORS" 51488583Sjoe " env var\n", c[j]); 51588584Sjoe colors[i].num[j] = -1; 51661178Sjoe } 51761178Sjoe } 51861178Sjoe } 51961178Sjoe} 52061291Sache 52161323Sachevoid 52261323Sachecolorquit(sig) 52388586Sjoe int sig; 52461291Sache{ 52561321Sache endcolor(sig); 52661294Sache 52761294Sache (void) signal(sig, SIG_DFL); 52861294Sache (void) kill(getpid(), sig); 52961291Sache} 53061268Sjoe#endif /*COLORLS*/ 53161178Sjoe 5321556Srgrimesstatic void 5331556Srgrimesprintlink(p) 53488586Sjoe FTSENT *p; 5351556Srgrimes{ 53688586Sjoe int lnklen; 53788586Sjoe char name[MAXPATHLEN + 1]; 53888586Sjoe char path[MAXPATHLEN + 1]; 5391556Srgrimes 5401556Srgrimes if (p->fts_level == FTS_ROOTLEVEL) 5411556Srgrimes (void)snprintf(name, sizeof(name), "%s", p->fts_name); 5428855Srgrimes else 5431556Srgrimes (void)snprintf(name, sizeof(name), 5441556Srgrimes "%s/%s", p->fts_parent->fts_accpath, p->fts_name); 5451556Srgrimes if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) { 5461556Srgrimes (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno)); 5471556Srgrimes return; 5481556Srgrimes } 5491556Srgrimes path[lnklen] = '\0'; 55062597Sassar (void)printf(" -> "); 55162597Sassar printname(path); 5521556Srgrimes} 553