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