get redist notice from /usr/share/misc
[unix-history] / usr / src / bin / ls / print.c
CommitLineData
62a77e99
KB
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
eeb191cb
KB
5 * This code is derived from software contributed to Berkeley by
6 * Michael Fischbein.
7 *
ff47ce84 8%sccs.include.redist.c%
62a77e99
KB
9 */
10
11#ifndef lint
ff47ce84 12static char sccsid[] = "@(#)print.c 5.20 (Berkeley) %G%";
62a77e99
KB
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>
a1a213d1 20#include <utmp.h>
62a77e99
KB
21#include <tzfile.h>
22#include "ls.h"
23
75a967bb
KB
24printscol(stats, num)
25 register LS *stats;
62a77e99
KB
26 register int num;
27{
75a967bb
KB
28 for (; num--; ++stats) {
29 (void)printaname(stats);
30 (void)putchar('\n');
31 }
32}
33
34printlong(stats, num)
35 LS *stats;
36 register int num;
37{
83ce5973
KB
38 char *user_from_uid(), *group_from_gid();
39
4dfe4db2 40 if (f_total)
a657fc85
KB
41 (void)printf("total %lu\n", f_kblocks ?
42 howmany(stats[0].lstat.st_btotal, 2) :
43 stats[0].lstat.st_btotal);
75a967bb
KB
44 for (; num--; ++stats) {
45 if (f_inode)
46 (void)printf("%6lu ", stats->lstat.st_ino);
47 if (f_size)
a657fc85
KB
48 (void)printf("%4ld ", f_kblocks ?
49 howmany(stats->lstat.st_blocks, 2) :
50 stats->lstat.st_blocks);
75a967bb 51 printperms(stats->lstat.st_mode);
83ce5973 52 (void)printf("%3u %-*s ", stats->lstat.st_nlink, UT_NAMESIZE,
5295572f 53 user_from_uid(stats->lstat.st_uid, 0));
75a967bb 54 if (f_group)
83ce5973 55 (void)printf("%-*s ", UT_NAMESIZE,
5295572f 56 group_from_gid(stats->lstat.st_gid, 0));
75a967bb
KB
57 if (S_ISCHR(stats->lstat.st_mode) ||
58 S_ISBLK(stats->lstat.st_mode))
6aef32a9 59 (void)printf("%3d, %3d ", major(stats->lstat.st_rdev),
75a967bb
KB
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
3cc8e3ba
KB
78#define TAB 8
79
75a967bb
KB
80printcol(stats, num)
81 LS *stats;
67e8527c 82 int num;
75a967bb 83{
eb8c7f67 84 extern int termwidth;
3cc8e3ba
KB
85 register int base, chcnt, cnt, col, colwidth;
86 int endcol, numcols, numrows, row;
62a77e99 87
45e87c19 88 colwidth = stats[0].lstat.st_maxlen;
62a77e99 89 if (f_inode)
9071313b 90 colwidth += 6;
62a77e99 91 if (f_size)
9071313b 92 colwidth += 5;
62a77e99 93 if (f_type)
9071313b 94 colwidth += 1;
299cb8d5 95
3cc8e3ba 96 colwidth = (colwidth + TAB) & ~(TAB - 1);
299cb8d5
KB
97 if (termwidth < 2 * colwidth) {
98 printscol(stats, num);
99 return;
100 }
9071313b
KB
101
102 numcols = termwidth / colwidth;
103 numrows = num / numcols;
104 if (num % numcols)
105 ++numrows;
62a77e99 106
4dfe4db2 107 if (f_size && f_total)
a657fc85
KB
108 (void)printf("total %lu\n", f_kblocks ?
109 howmany(stats[0].lstat.st_btotal, 2) :
110 stats[0].lstat.st_btotal);
9071313b 111 for (row = 0; row < numrows; ++row) {
67e8527c
KB
112 endcol = colwidth;
113 for (base = row, chcnt = col = 0; col < numcols; ++col) {
9071313b
KB
114 chcnt += printaname(stats + base);
115 if ((base += numrows) >= num)
62a77e99 116 break;
67e8527c 117 while ((cnt = (chcnt + TAB & ~(TAB - 1))) <= endcol) {
9071313b 118 (void)putchar('\t');
67e8527c 119 chcnt = cnt;
62a77e99 120 }
67e8527c 121 endcol += colwidth;
62a77e99 122 }
9071313b 123 putchar('\n');
62a77e99
KB
124 }
125}
126
127/*
128 * print [inode] [size] name
129 * return # of characters printed, no trailing characters
130 */
75a967bb
KB
131printaname(lp)
132 LS *lp;
62a77e99 133{
75a967bb 134 int chcnt;
62a77e99 135
75a967bb 136 chcnt = 0;
62a77e99 137 if (f_inode)
75a967bb 138 chcnt += printf("%5lu ", lp->lstat.st_ino);
62a77e99 139 if (f_size)
a657fc85
KB
140 chcnt += printf("%4ld ", f_kblocks ?
141 howmany(lp->lstat.st_blocks, 2) : lp->lstat.st_blocks);
75a967bb 142 chcnt += printf("%s", lp->name);
62a77e99 143 if (f_type)
75a967bb 144 chcnt += printtype(lp->lstat.st_mode);
62a77e99
KB
145 return(chcnt);
146}
147
62a77e99
KB
148printtime(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 */
174printperms(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 }
6aef32a9 275 (void)putchar(' ');
62a77e99
KB
276}
277
278printtype(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
299printlink(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}