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 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 #ifndef lint 38 static char sccsid[] = "@(#)print.c 5.24 (Berkeley) 10/19/90"; 39 static char rcsid[] = "$Header: /cvsroot/src/bin/ls/print.c,v 1.3 1993/03/23 00:26:10 cgd Exp $"; 40 #endif /* not lint */ 41 42 #include <sys/param.h> 43 #include <sys/stat.h> 44 #include <stdio.h> 45 #include <grp.h> 46 #include <pwd.h> 47 #include <utmp.h> 48 #include <tzfile.h> 49 #include "ls.h" 50 51 printscol(stats, num) 52 register LS *stats; 53 register int num; 54 { 55 for (; num--; ++stats) { 56 (void)printaname(stats); 57 (void)putchar('\n'); 58 } 59 } 60 61 printlong(stats, num) 62 LS *stats; 63 register int num; 64 { 65 extern int errno; 66 char modep[15], *user_from_uid(), *group_from_gid(), *strerror(); 67 68 if (f_total) 69 (void)printf("total %lu\n", f_kblocks ? 70 howmany(stats[0].lstat.st_btotal, 2) : 71 stats[0].lstat.st_btotal); 72 for (; num--; ++stats) { 73 if (f_inode) 74 (void)printf("%6lu ", stats->lstat.st_ino); 75 if (f_size) 76 (void)printf("%4ld ", f_kblocks ? 77 howmany(stats->lstat.st_blocks, 2) : 78 stats->lstat.st_blocks); 79 (void)strmode(stats->lstat.st_mode, modep); 80 (void)printf("%s %3u %-*s ", modep, stats->lstat.st_nlink, 81 UT_NAMESIZE, user_from_uid(stats->lstat.st_uid, 0)); 82 if (f_group) 83 (void)printf("%-*s ", UT_NAMESIZE, 84 group_from_gid(stats->lstat.st_gid, 0)); 85 if (S_ISCHR(stats->lstat.st_mode) || 86 S_ISBLK(stats->lstat.st_mode)) 87 (void)printf("%3d, %3d ", major(stats->lstat.st_rdev), 88 minor(stats->lstat.st_rdev)); 89 else 90 (void)printf("%8ld ", stats->lstat.st_size); 91 if (f_accesstime) 92 printtime(stats->lstat.st_atime); 93 else if (f_statustime) 94 printtime(stats->lstat.st_ctime); 95 else 96 printtime(stats->lstat.st_mtime); 97 (void)printf("%s", stats->name); 98 if (f_type) 99 (void)printtype(stats->lstat.st_mode); 100 if (S_ISLNK(stats->lstat.st_mode)) 101 printlink(stats->name); 102 (void)putchar('\n'); 103 } 104 } 105 106 #define TAB 8 107 108 printcol(stats, num) 109 LS *stats; 110 int num; 111 { 112 extern int termwidth; 113 register int base, chcnt, cnt, col, colwidth; 114 int endcol, numcols, numrows, row; 115 116 colwidth = stats[0].lstat.st_maxlen; 117 if (f_inode) 118 colwidth += 6; 119 if (f_size) 120 colwidth += 5; 121 if (f_type) 122 colwidth += 1; 123 124 colwidth = (colwidth + TAB) & ~(TAB - 1); 125 if (termwidth < 2 * colwidth) { 126 printscol(stats, num); 127 return; 128 } 129 130 numcols = termwidth / colwidth; 131 numrows = num / numcols; 132 if (num % numcols) 133 ++numrows; 134 135 if (f_size && f_total) 136 (void)printf("total %lu\n", f_kblocks ? 137 howmany(stats[0].lstat.st_btotal, 2) : 138 stats[0].lstat.st_btotal); 139 for (row = 0; row < numrows; ++row) { 140 endcol = colwidth; 141 for (base = row, chcnt = col = 0; col < numcols; ++col) { 142 chcnt += printaname(stats + base); 143 if ((base += numrows) >= num) 144 break; 145 while ((cnt = (chcnt + TAB & ~(TAB - 1))) <= endcol) { 146 (void)putchar('\t'); 147 chcnt = cnt; 148 } 149 endcol += colwidth; 150 } 151 putchar('\n'); 152 } 153 } 154 155 /* 156 * print [inode] [size] name 157 * return # of characters printed, no trailing characters 158 */ 159 printaname(lp) 160 LS *lp; 161 { 162 int chcnt; 163 164 chcnt = 0; 165 if (f_inode) 166 chcnt += printf("%5lu ", lp->lstat.st_ino); 167 if (f_size) 168 chcnt += printf("%4ld ", f_kblocks ? 169 howmany(lp->lstat.st_blocks, 2) : lp->lstat.st_blocks); 170 chcnt += printf("%s", lp->name); 171 if (f_type) 172 chcnt += printtype(lp->lstat.st_mode); 173 return(chcnt); 174 } 175 176 printtime(ftime) 177 time_t ftime; 178 { 179 int i; 180 char *longstring, *ctime(); 181 time_t time(); 182 183 longstring = ctime((long *)&ftime); 184 for (i = 4; i < 11; ++i) 185 (void)putchar(longstring[i]); 186 187 #define SIXMONTHS ((DAYSPERNYEAR / 2) * SECSPERDAY) 188 if (f_sectime) 189 for (i = 11; i < 24; i++) 190 (void)putchar(longstring[i]); 191 else if (ftime + SIXMONTHS > time((time_t *)NULL)) 192 for (i = 11; i < 16; ++i) 193 (void)putchar(longstring[i]); 194 else { 195 (void)putchar(' '); 196 for (i = 20; i < 24; ++i) 197 (void)putchar(longstring[i]); 198 } 199 (void)putchar(' '); 200 } 201 202 printtype(mode) 203 mode_t mode; 204 { 205 switch(mode & S_IFMT) { 206 case S_IFDIR: 207 (void)putchar('/'); 208 return(1); 209 case S_IFLNK: 210 (void)putchar('@'); 211 return(1); 212 case S_IFSOCK: 213 (void)putchar('='); 214 return(1); 215 } 216 if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { 217 (void)putchar('*'); 218 return(1); 219 } 220 return(0); 221 } 222 223 printlink(name) 224 char *name; 225 { 226 int lnklen; 227 char path[MAXPATHLEN + 1], *strerror(); 228 229 if ((lnklen = readlink(name, path, MAXPATHLEN)) == -1) { 230 (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno)); 231 return; 232 } 233 path[lnklen] = '\0'; 234 (void)printf(" -> %s", path); 235 } 236