1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Michael Fischbein. 7 * 8 %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)print.c 5.24 (Berkeley) 10/19/90"; 13 #endif /* not lint */ 14 15 #include <sys/param.h> 16 #include <sys/stat.h> 17 #include <stdio.h> 18 #include <grp.h> 19 #include <pwd.h> 20 #include <utmp.h> 21 #include <tzfile.h> 22 #include "ls.h" 23 24 printscol(stats, num) 25 register LS *stats; 26 register int num; 27 { 28 for (; num--; ++stats) { 29 (void)printaname(stats); 30 (void)putchar('\n'); 31 } 32 } 33 34 printlong(stats, num) 35 LS *stats; 36 register int num; 37 { 38 extern int errno; 39 char modep[15], *user_from_uid(), *group_from_gid(), *strerror(); 40 41 if (f_total) 42 (void)printf("total %lu\n", f_kblocks ? 43 howmany(stats[0].lstat.st_btotal, 2) : 44 stats[0].lstat.st_btotal); 45 for (; num--; ++stats) { 46 if (f_inode) 47 (void)printf("%6lu ", stats->lstat.st_ino); 48 if (f_size) 49 (void)printf("%4ld ", f_kblocks ? 50 howmany(stats->lstat.st_blocks, 2) : 51 stats->lstat.st_blocks); 52 (void)strmode(stats->lstat.st_mode, modep); 53 (void)printf("%s %3u %-*s ", modep, stats->lstat.st_nlink, 54 UT_NAMESIZE, user_from_uid(stats->lstat.st_uid, 0)); 55 if (f_group) 56 (void)printf("%-*s ", UT_NAMESIZE, 57 group_from_gid(stats->lstat.st_gid, 0)); 58 if (S_ISCHR(stats->lstat.st_mode) || 59 S_ISBLK(stats->lstat.st_mode)) 60 (void)printf("%3d, %3d ", major(stats->lstat.st_rdev), 61 minor(stats->lstat.st_rdev)); 62 else 63 (void)printf("%8ld ", stats->lstat.st_size); 64 if (f_accesstime) 65 printtime(stats->lstat.st_atime); 66 else if (f_statustime) 67 printtime(stats->lstat.st_ctime); 68 else 69 printtime(stats->lstat.st_mtime); 70 (void)printf("%s", stats->name); 71 if (f_type) 72 (void)printtype(stats->lstat.st_mode); 73 if (S_ISLNK(stats->lstat.st_mode)) 74 printlink(stats->name); 75 (void)putchar('\n'); 76 } 77 } 78 79 #define TAB 8 80 81 printcol(stats, num) 82 LS *stats; 83 int num; 84 { 85 extern int termwidth; 86 register int base, chcnt, cnt, col, colwidth; 87 int endcol, numcols, numrows, row; 88 89 colwidth = stats[0].lstat.st_maxlen; 90 if (f_inode) 91 colwidth += 6; 92 if (f_size) 93 colwidth += 5; 94 if (f_type) 95 colwidth += 1; 96 97 colwidth = (colwidth + TAB) & ~(TAB - 1); 98 if (termwidth < 2 * colwidth) { 99 printscol(stats, num); 100 return; 101 } 102 103 numcols = termwidth / colwidth; 104 numrows = num / numcols; 105 if (num % numcols) 106 ++numrows; 107 108 if (f_size && f_total) 109 (void)printf("total %lu\n", f_kblocks ? 110 howmany(stats[0].lstat.st_btotal, 2) : 111 stats[0].lstat.st_btotal); 112 for (row = 0; row < numrows; ++row) { 113 endcol = colwidth; 114 for (base = row, chcnt = col = 0; col < numcols; ++col) { 115 chcnt += printaname(stats + base); 116 if ((base += numrows) >= num) 117 break; 118 while ((cnt = (chcnt + TAB & ~(TAB - 1))) <= endcol) { 119 (void)putchar('\t'); 120 chcnt = cnt; 121 } 122 endcol += colwidth; 123 } 124 putchar('\n'); 125 } 126 } 127 128 /* 129 * print [inode] [size] name 130 * return # of characters printed, no trailing characters 131 */ 132 printaname(lp) 133 LS *lp; 134 { 135 int chcnt; 136 137 chcnt = 0; 138 if (f_inode) 139 chcnt += printf("%5lu ", lp->lstat.st_ino); 140 if (f_size) 141 chcnt += printf("%4ld ", f_kblocks ? 142 howmany(lp->lstat.st_blocks, 2) : lp->lstat.st_blocks); 143 chcnt += printf("%s", lp->name); 144 if (f_type) 145 chcnt += printtype(lp->lstat.st_mode); 146 return(chcnt); 147 } 148 149 printtime(ftime) 150 time_t ftime; 151 { 152 int i; 153 char *longstring, *ctime(); 154 time_t time(); 155 156 longstring = ctime((long *)&ftime); 157 for (i = 4; i < 11; ++i) 158 (void)putchar(longstring[i]); 159 160 #define SIXMONTHS ((DAYSPERNYEAR / 2) * SECSPERDAY) 161 if (f_sectime) 162 for (i = 11; i < 24; i++) 163 (void)putchar(longstring[i]); 164 else if (ftime + SIXMONTHS > time((time_t *)NULL)) 165 for (i = 11; i < 16; ++i) 166 (void)putchar(longstring[i]); 167 else { 168 (void)putchar(' '); 169 for (i = 20; i < 24; ++i) 170 (void)putchar(longstring[i]); 171 } 172 (void)putchar(' '); 173 } 174 175 printtype(mode) 176 mode_t mode; 177 { 178 switch(mode & S_IFMT) { 179 case S_IFDIR: 180 (void)putchar('/'); 181 return(1); 182 case S_IFLNK: 183 (void)putchar('@'); 184 return(1); 185 case S_IFSOCK: 186 (void)putchar('='); 187 return(1); 188 } 189 if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { 190 (void)putchar('*'); 191 return(1); 192 } 193 return(0); 194 } 195 196 printlink(name) 197 char *name; 198 { 199 int lnklen; 200 char path[MAXPATHLEN + 1], *strerror(); 201 202 if ((lnklen = readlink(name, path, MAXPATHLEN)) == -1) { 203 (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno)); 204 return; 205 } 206 path[lnklen] = '\0'; 207 (void)printf(" -> %s", path); 208 } 209