3
/* NetBSD: print.c,v 1.45 2009/02/14 08:02:04 lukem Exp */
6
* Copyright (c) 1989, 1993, 1994
7
* The Regents of the University of California. All rights reserved.
9
* This code is derived from software contributed to Berkeley by
12
* Redistribution and use in source and binary forms, with or without
13
* modification, are permitted provided that the following conditions
15
* 1. Redistributions of source code must retain the above copyright
16
* notice, this list of conditions and the following disclaimer.
17
* 2. Redistributions in binary form must reproduce the above copyright
18
* notice, this list of conditions and the following disclaimer in the
19
* documentation and/or other materials provided with the distribution.
20
* 3. 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.
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
37
#include <sys/cdefs.h>
40
static char sccsid[] = "@(#)print.c 8.5 (Berkeley) 7/28/94";
42
__RCSID("$NetBSD: print.c,v 1.45 2009/02/14 08:02:04 lukem Exp $");
46
#include <sys/param.h>
65
#include <rump/ukfs.h>
68
#define FTSENT FSU_FTSENT
69
#define readlink(n, p, s) ukfs_readlink(ukfs, n ,p, s)
71
extern struct ukfs *ukfs;
79
static int printaname(FTSENT *, int, int);
80
static void printlink(FTSENT *);
81
static void printtime(time_t);
82
static void printtotal(DISPLAY *dp);
83
static int printtype(u_int);
87
#define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT)
90
printscol(DISPLAY *dp)
94
for (p = dp->list; p; p = p->fts_link) {
97
(void)printaname(p, dp->s_inode, dp->s_block);
103
printlong(DISPLAY *dp)
108
char buf[20], szbuf[5];
112
printtotal(dp); /* "total: %u\n" */
114
for (p = dp->list; p; p = p->fts_link) {
119
(void)printf("%*lu ", dp->s_inode,
120
(unsigned long)sp->st_ino);
123
if ((humanize_number(szbuf, sizeof(szbuf),
124
sp->st_blocks * S_BLKSIZE,
126
(HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
127
err(1, "humanize_number");
128
(void)printf("%*s ", dp->s_block, szbuf);
130
(void)printf("%*llu ", dp->s_block,
131
(long long)howmany(sp->st_blocks,
135
(void)strmode(sp->st_mode, buf);
137
(void)printf("%s %*lu ", buf, dp->s_nlink,
138
(unsigned long)sp->st_nlink);
140
(void)printf("%-*s ", dp->s_user, np->user);
141
(void)printf("%-*s ", dp->s_group, np->group);
143
(void)printf("%-*s ", dp->s_flags, np->flags);
144
if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
145
(void)printf("%*lld, %*lld ",
146
dp->s_major, (long long)major(sp->st_rdev),
147
dp->s_minor, (long long)minor(sp->st_rdev));
150
if ((humanize_number(szbuf, sizeof(szbuf),
151
sp->st_size, "", HN_AUTOSCALE,
152
(HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
153
err(1, "humanize_number");
154
(void)printf("%*s ", dp->s_size, szbuf);
156
(void)printf("%*llu ", dp->s_size,
157
(long long)sp->st_size);
160
printtime(sp->st_atime);
161
else if (f_statustime)
162
printtime(sp->st_ctime);
164
printtime(sp->st_mtime);
165
if (f_octal || f_octal_escape)
166
(void)safe_print(p->fts_name);
168
(void)printescaped(p->fts_name);
170
(void)printf("%s", p->fts_name);
172
if (f_type || (f_typedir && S_ISDIR(sp->st_mode)))
173
(void)printtype(sp->st_mode);
174
if (S_ISLNK(sp->st_mode))
181
printcol(DISPLAY *dp)
183
static FTSENT **array;
184
static int lastentries = -1;
186
int base, chcnt, col, colwidth, num;
187
int numcols, numrows, row;
189
colwidth = dp->maxlen;
191
colwidth += dp->s_inode + 1;
194
colwidth += dp->s_size + 1;
196
colwidth += dp->s_block + 1;
198
if (f_type || f_typedir)
203
if (termwidth < 2 * colwidth) {
209
* Have to do random access in the linked list -- build a table
212
if (dp->entries > lastentries) {
213
lastentries = dp->entries;
215
realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
220
for (p = dp->list, num = 0; p; p = p->fts_link)
221
if (p->fts_number != NO_PRINT)
224
numcols = termwidth / colwidth;
225
colwidth = termwidth / numcols; /* spread out if possible */
226
numrows = num / numcols;
230
printtotal(dp); /* "total: %u\n" */
232
for (row = 0; row < numrows; ++row) {
233
for (base = row, chcnt = col = 0; col < numcols; ++col) {
234
chcnt = printaname(array[base], dp->s_inode,
235
f_humanize ? dp->s_size : dp->s_block);
236
if ((base += numrows) >= num)
238
while (chcnt++ < colwidth)
246
printacol(DISPLAY *dp)
249
int chcnt, col, colwidth;
252
colwidth = dp->maxlen;
254
colwidth += dp->s_inode + 1;
257
colwidth += dp->s_size + 1;
259
colwidth += dp->s_block + 1;
261
if (f_type || f_typedir)
266
if (termwidth < 2 * colwidth) {
271
numcols = termwidth / colwidth;
272
colwidth = termwidth / numcols; /* spread out if possible */
274
printtotal(dp); /* "total: %u\n" */
277
for (p = dp->list; p; p = p->fts_link) {
280
if (col >= numcols) {
284
chcnt = printaname(p, dp->s_inode,
285
f_humanize ? dp->s_size : dp->s_block);
286
while (chcnt++ < colwidth)
294
printstream(DISPLAY *dp)
302
extwidth += dp->s_inode + 1;
305
extwidth += dp->s_size + 1;
307
extwidth += dp->s_block + 1;
312
for (col = 0, p = dp->list; p != NULL; p = p->fts_link) {
316
(void)putchar(','), col++;
317
if (col + 1 + extwidth + (int)p->fts_namelen >= termwidth)
318
(void)putchar('\n'), col = 0;
320
(void)putchar(' '), col++;
322
col += printaname(p, dp->s_inode,
323
f_humanize ? dp->s_size : dp->s_block);
329
* print [inode] [size] name
330
* return # of characters printed, no trailing characters.
333
printaname(FTSENT *p, int inodefield, int sizefield)
342
chcnt += printf("%*lu ", inodefield, (unsigned long)sp->st_ino);
345
if ((humanize_number(szbuf, sizeof(szbuf), sp->st_size,
347
(HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
348
err(1, "humanize_number");
349
chcnt += printf("%*s ", sizefield, szbuf);
351
chcnt += printf("%*llu ", sizefield,
352
(long long)howmany(sp->st_blocks, blocksize));
355
if (f_octal || f_octal_escape)
356
chcnt += safe_print(p->fts_name);
358
chcnt += printescaped(p->fts_name);
360
chcnt += printf("%s", p->fts_name);
361
if (f_type || (f_typedir && S_ISDIR(sp->st_mode)))
362
chcnt += printtype(sp->st_mode);
367
printtime(time_t ftime)
372
longstring = ctime(&ftime);
373
for (i = 4; i < 11; ++i)
374
(void)putchar(longstring[i]);
376
#define SIXMONTHS ((DAYSPERNYEAR / 2) * SECSPERDAY)
378
for (i = 11; i < 24; i++)
379
(void)putchar(longstring[i]);
380
else if (ftime + SIXMONTHS > now && ftime - SIXMONTHS < now)
381
for (i = 11; i < 16; ++i)
382
(void)putchar(longstring[i]);
385
for (i = 20; i < 24; ++i)
386
(void)putchar(longstring[i]);
392
* Display total used disk space in the form "total: %u\n".
393
* Note: POSIX (IEEE Std 1003.1-2001) says this should be always in 512 blocks,
394
* but we humanise it with -h and use 1024 with -k.
397
printtotal(DISPLAY *dp)
401
if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
403
if ((humanize_number(szbuf, sizeof(szbuf), (int64_t)dp->stotal,
405
(HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
406
err(1, "humanize_number");
407
(void)printf("total %s\n", szbuf);
409
(void)printf("total %llu\n",
410
(long long)(howmany(dp->btotal, blocksize)));
416
printtype(u_int mode)
418
switch (mode & S_IFMT) {
435
if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
446
char name[MAXPATHLEN + 1], path[MAXPATHLEN + 1];
448
if (p->fts_level == FTS_ROOTLEVEL)
449
(void)snprintf(name, sizeof(name), "%s", p->fts_name);
451
(void)snprintf(name, sizeof(name),
452
"%s/%s", p->fts_parent->fts_accpath, p->fts_name);
453
if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
454
(void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
458
(void)printf(" -> ");
459
if (f_octal || f_octal_escape)
460
(void)safe_print(path);
462
(void)printescaped(path);
464
(void)printf("%s", path);