$NetBSD: patch-ae,v 1.6 2023/09/14 00:48:31 charlotte Exp $ Use nbcompat, and fix mangled datetime formatting. --- print.c.orig 1996-12-21 15:40:58.000000000 -0800 +++ print.c 2023-09-13 17:30:15.209912546 -0700 @@ -43,9 +43,15 @@ static char const sccsid[] = "@(#)print. #include #include +#include #include #include +#if defined(HAVE_NBCOMPAT_H) +#include +#include +#else #include +#endif #include #include #include @@ -64,6 +70,26 @@ static int printtype __P((u_int)); #define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT) +/* Most of these are taken from */ +typedef enum Colors { + C_DIR, /* directory */ + C_LNK, /* symbolic link */ + C_SOCK, /* socket */ + C_FIFO, /* pipe */ + C_EXEC, /* executable */ + C_BLK, /* block special */ + C_CHR, /* character special */ + C_SUID, /* setuid executable */ + C_SGID, /* setgid executable */ + C_WSDIR, /* directory writeble to others, with sticky bit */ + C_WDIR, /* directory writeble to others, without sticky bit */ + C_NUMCOLORS /* just a place-holder */ +} Colors ; + +char *defcolors = "4x5x2x3x1x464301060203"; + +static int colors[C_NUMCOLORS][2]; + void printscol(dp) DISPLAY *dp; @@ -97,15 +123,17 @@ printlong(dp) if (f_inode) (void)printf("%*lu ", dp->s_inode, (u_long)sp->st_ino); if (f_size) - (void)printf("%*qd ", - dp->s_block, howmany(sp->st_blocks, blocksize)); + (void)printf("%*lld ", + dp->s_block, (long long)howmany(sp->st_blocks, blocksize)); (void)strmode(sp->st_mode, buf); np = p->fts_pointer; (void)printf("%s %*u %-*s %-*s ", buf, dp->s_nlink, sp->st_nlink, dp->s_user, np->user, dp->s_group, np->group); +#ifndef __sun if (f_flags) (void)printf("%-*s ", dp->s_flags, np->flags); +#endif if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode)) if (minor(sp->st_rdev) > 255) (void)printf("%3d, 0x%08x ", @@ -114,19 +142,23 @@ printlong(dp) (void)printf("%3d, %3d ", major(sp->st_rdev), minor(sp->st_rdev)); else if (dp->bcfile) - (void)printf("%*s%*qd ", - 8 - dp->s_size, "", dp->s_size, sp->st_size); + (void)printf("%*s%*lld ", + 8 - dp->s_size, "", dp->s_size, (long long)sp->st_size); else - (void)printf("%*qd ", dp->s_size, sp->st_size); + (void)printf("%*lld ", dp->s_size, (long long)sp->st_size); if (f_accesstime) printtime(sp->st_atime); else if (f_statustime) printtime(sp->st_ctime); else printtime(sp->st_mtime); + if (f_color) + (void)colortype(sp->st_mode); (void)printf("%s", p->fts_name); if (f_type) (void)printtype(sp->st_mode); + if (f_color) + (void)printf("\033[m"); if (S_ISLNK(sp->st_mode)) printlink(p); (void)putchar('\n'); @@ -190,7 +222,19 @@ printcol(dp) dp->s_block); if ((base += numrows) >= num) break; - while ((cnt = ((chcnt + TAB) & ~(TAB - 1))) <= endcol){ + + /* + * some terminals get confused if we mix tabs + * with color sequences + */ + if (f_color) + while ((cnt = (chcnt + 1)) <= endcol) { + (void)putchar(' '); + chcnt = cnt; + } + else + while ((cnt = ((chcnt + TAB) & ~(TAB - 1))) + <= endcol) { (void)putchar('\t'); chcnt = cnt; } @@ -217,11 +261,15 @@ printaname(p, inodefield, sizefield) if (f_inode) chcnt += printf("%*lu ", (int)inodefield, (u_long)sp->st_ino); if (f_size) - chcnt += printf("%*qd ", - (int)sizefield, howmany(sp->st_blocks, blocksize)); + chcnt += printf("%*lld ", + (int)sizefield, (long long)howmany(sp->st_blocks, blocksize)); + if (f_color) + (void)colortype(sp->st_mode); chcnt += printf("%s", p->fts_name); if (f_type) chcnt += printtype(sp->st_mode); + if (f_color) + printf("\033[m"); return (chcnt); } @@ -232,7 +280,7 @@ printtime(ftime) int i; char longstring[80]; - strftime(longstring, sizeof(longstring), "%c", localtime(&ftime)); + snprintf(longstring, sizeof(longstring), "%s", ctime(&ftime)); for (i = 4; i < 11; ++i) (void)putchar(longstring[i]); @@ -281,6 +329,96 @@ printtype(mode) return (0); } +void +printcolor(c) + Colors c; +{ + printf("\033["); + if (colors[c][0] != -1) { + printf("3%d", colors[c][0]); + if (colors[c][1] != -1) + printf(";"); + } + if (colors[c][1] != -1) + printf("4%d", colors[c][1]); + printf("m"); +} + +int +colortype(mode) + mode_t mode; +{ + switch(mode & S_IFMT) { + case S_IFDIR: + if (mode & S_IWOTH) + if (mode & S_ISTXT) + printcolor(C_WSDIR); + else + printcolor(C_WDIR); + else + printcolor(C_DIR); + return(1); + case S_IFLNK: + printcolor(C_LNK); + return(1); + case S_IFSOCK: + printcolor(C_SOCK); + return(1); + case S_IFIFO: + printcolor(C_FIFO); + return(1); + case S_IFBLK: + printcolor(C_BLK); + return(1); + case S_IFCHR: + printcolor(C_CHR); + return(1); + } + if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { + if (mode & S_ISUID) + printcolor(C_SUID); + else if (mode & S_ISGID) + printcolor(C_SGID); + else + printcolor(C_EXEC); + return(1); + } + return(0); +} + +void +parsecolors(cs) +char *cs; +{ + int i, j, len; + char c[2]; + if (cs == NULL) cs = ""; /* LSCOLORS not set */ + len = strlen(cs); + for (i = 0 ; i < C_NUMCOLORS ; i++) { + if (len <= 2*i) { + c[0] = defcolors[2*i]; + c[1] = defcolors[2*i+1]; + } + else { + c[0] = cs[2*i]; + c[1] = cs[2*i+1]; + } + for (j = 0 ; j < 2 ; j++) { + if ((c[j] < '0' || c[j] > '7') && + tolower(c[j]) != 'x') { + fprintf(stderr, + "error: invalid character '%c' in LSCOLORS env var\n", + c[j]); + c[j] = defcolors[2*i+j]; + } + if (c[j] == 'x') + colors[i][j] = -1; + else + colors[i][j] = c[j]-'0'; + } + } +} + static void printlink(p) FTSENT *p;