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.20 (Berkeley) 04/08/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 char *user_from_uid(), *group_from_gid(); 39 40 if (f_total) 41 (void)printf("total %lu\n", f_kblocks ? 42 howmany(stats[0].lstat.st_btotal, 2) : 43 stats[0].lstat.st_btotal); 44 for (; num--; ++stats) { 45 if (f_inode) 46 (void)printf("%6lu ", stats->lstat.st_ino); 47 if (f_size) 48 (void)printf("%4ld ", f_kblocks ? 49 howmany(stats->lstat.st_blocks, 2) : 50 stats->lstat.st_blocks); 51 printperms(stats->lstat.st_mode); 52 (void)printf("%3u %-*s ", stats->lstat.st_nlink, UT_NAMESIZE, 53 user_from_uid(stats->lstat.st_uid, 0)); 54 if (f_group) 55 (void)printf("%-*s ", UT_NAMESIZE, 56 group_from_gid(stats->lstat.st_gid, 0)); 57 if (S_ISCHR(stats->lstat.st_mode) || 58 S_ISBLK(stats->lstat.st_mode)) 59 (void)printf("%3d, %3d ", major(stats->lstat.st_rdev), 60 minor(stats->lstat.st_rdev)); 61 else 62 (void)printf("%8ld ", stats->lstat.st_size); 63 if (f_accesstime) 64 printtime(stats->lstat.st_atime); 65 else if (f_statustime) 66 printtime(stats->lstat.st_ctime); 67 else 68 printtime(stats->lstat.st_mtime); 69 (void)printf("%s", stats->name); 70 if (f_type) 71 (void)printtype(stats->lstat.st_mode); 72 if (S_ISLNK(stats->lstat.st_mode)) 73 printlink(stats->name); 74 (void)putchar('\n'); 75 } 76 } 77 78 #define TAB 8 79 80 printcol(stats, num) 81 LS *stats; 82 int num; 83 { 84 extern int termwidth; 85 register int base, chcnt, cnt, col, colwidth; 86 int endcol, numcols, numrows, row; 87 88 colwidth = stats[0].lstat.st_maxlen; 89 if (f_inode) 90 colwidth += 6; 91 if (f_size) 92 colwidth += 5; 93 if (f_type) 94 colwidth += 1; 95 96 colwidth = (colwidth + TAB) & ~(TAB - 1); 97 if (termwidth < 2 * colwidth) { 98 printscol(stats, num); 99 return; 100 } 101 102 numcols = termwidth / colwidth; 103 numrows = num / numcols; 104 if (num % numcols) 105 ++numrows; 106 107 if (f_size && f_total) 108 (void)printf("total %lu\n", f_kblocks ? 109 howmany(stats[0].lstat.st_btotal, 2) : 110 stats[0].lstat.st_btotal); 111 for (row = 0; row < numrows; ++row) { 112 endcol = colwidth; 113 for (base = row, chcnt = col = 0; col < numcols; ++col) { 114 chcnt += printaname(stats + base); 115 if ((base += numrows) >= num) 116 break; 117 while ((cnt = (chcnt + TAB & ~(TAB - 1))) <= endcol) { 118 (void)putchar('\t'); 119 chcnt = cnt; 120 } 121 endcol += colwidth; 122 } 123 putchar('\n'); 124 } 125 } 126 127 /* 128 * print [inode] [size] name 129 * return # of characters printed, no trailing characters 130 */ 131 printaname(lp) 132 LS *lp; 133 { 134 int chcnt; 135 136 chcnt = 0; 137 if (f_inode) 138 chcnt += printf("%5lu ", lp->lstat.st_ino); 139 if (f_size) 140 chcnt += printf("%4ld ", f_kblocks ? 141 howmany(lp->lstat.st_blocks, 2) : lp->lstat.st_blocks); 142 chcnt += printf("%s", lp->name); 143 if (f_type) 144 chcnt += printtype(lp->lstat.st_mode); 145 return(chcnt); 146 } 147 148 printtime(ftime) 149 time_t ftime; 150 { 151 int i; 152 char *longstring, *ctime(); 153 time_t time(); 154 155 longstring = ctime((long *)&ftime); 156 for (i = 4; i < 11; ++i) 157 (void)putchar(longstring[i]); 158 159 #define SIXMONTHS ((DAYSPERNYEAR / 2) * SECSPERDAY) 160 if (ftime + SIXMONTHS > time((time_t *)NULL)) 161 for (i = 11; i < 16; ++i) 162 (void)putchar(longstring[i]); 163 else { 164 (void)putchar(' '); 165 for (i = 20; i < 24; ++i) 166 (void)putchar(longstring[i]); 167 } 168 (void)putchar(' '); 169 } 170 171 /* 172 * do the permissions printing, passed the mode 173 */ 174 printperms(mode) 175 mode_t mode; 176 { 177 /* print type */ 178 switch (mode & S_IFMT) { 179 case S_IFDIR: /* directory */ 180 (void)putchar('d'); 181 break; 182 case S_IFCHR: /* character special */ 183 (void)putchar('c'); 184 break; 185 case S_IFBLK: /* block special */ 186 (void)putchar('b'); 187 break; 188 case S_IFREG: /* regular */ 189 (void)putchar('-'); 190 break; 191 case S_IFLNK: /* symbolic link */ 192 (void)putchar('l'); 193 break; 194 case S_IFSOCK: /* socket */ 195 (void)putchar('s'); 196 break; 197 #ifdef S_IFIFO 198 case S_IFIFO: /* fifo */ 199 (void)putchar('p'); 200 break; 201 #endif 202 default: /* unknown */ 203 (void)putchar('?'); 204 break; 205 } 206 /* usr */ 207 if (mode & S_IRUSR) 208 (void)putchar('r'); 209 else 210 (void)putchar('-'); 211 if (mode & S_IWUSR) 212 (void)putchar('w'); 213 else 214 (void)putchar('-'); 215 switch (mode & (S_IXUSR | S_ISUID)) { 216 case 0: 217 (void)putchar('-'); 218 break; 219 case S_IXUSR: 220 (void)putchar('x'); 221 break; 222 case S_ISUID: 223 (void)putchar('S'); 224 break; 225 case S_IXUSR | S_ISUID: 226 (void)putchar('s'); 227 break; 228 } 229 /* group */ 230 if (mode & S_IRGRP) 231 (void)putchar('r'); 232 else 233 (void)putchar('-'); 234 if (mode & S_IWGRP) 235 (void)putchar('w'); 236 else 237 (void)putchar('-'); 238 switch (mode & (S_IXGRP | S_ISGID)) { 239 case 0: 240 (void)putchar('-'); 241 break; 242 case S_IXGRP: 243 (void)putchar('x'); 244 break; 245 case S_ISGID: 246 (void)putchar('S'); 247 break; 248 case S_IXGRP | S_ISGID: 249 (void)putchar('s'); 250 break; 251 } 252 /* other */ 253 if (mode & S_IROTH) 254 (void)putchar('r'); 255 else 256 (void)putchar('-'); 257 if (mode & S_IWOTH) 258 (void)putchar('w'); 259 else 260 (void)putchar('-'); 261 switch (mode & (S_IXOTH | S_ISVTX)) { 262 case 0: 263 (void)putchar('-'); 264 break; 265 case S_IXOTH: 266 (void)putchar('x'); 267 break; 268 case S_ISVTX: 269 (void)putchar('T'); 270 break; 271 case S_IXOTH | S_ISVTX: 272 (void)putchar('t'); 273 break; 274 } 275 (void)putchar(' '); 276 } 277 278 printtype(mode) 279 mode_t mode; 280 { 281 switch(mode & S_IFMT) { 282 case S_IFDIR: 283 (void)putchar('/'); 284 return(1); 285 case S_IFLNK: 286 (void)putchar('@'); 287 return(1); 288 case S_IFSOCK: 289 (void)putchar('='); 290 return(1); 291 } 292 if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { 293 (void)putchar('*'); 294 return(1); 295 } 296 return(0); 297 } 298 299 printlink(name) 300 char *name; 301 { 302 int lnklen; 303 char path[MAXPATHLEN + 1], *strerror(); 304 305 if ((lnklen = readlink(name, path, MAXPATHLEN)) == -1) { 306 (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno)); 307 return; 308 } 309 path[lnklen] = '\0'; 310 (void)printf(" -> %s", path); 311 } 312