source: rtems/cpukit/libmisc/shell/print-ls.c @ 7bde91b

5
Last change on this file since 7bde91b was 7bde91b, checked in by Sebastian Huber <sebastian.huber@…>, on 01/10/19 at 08:05:49

Fix format warnings due to ino_t changes

  • Property mode set to 100644
File size: 12.0 KB
Line 
1/*      $NetBSD: print.c,v 1.40 2004/11/17 17:00:00 mycroft Exp $       */
2
3/*
4 * Copyright (c) 1989, 1993, 1994
5 *      The Regents of the University of California.  All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Michael Fischbein.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
39#if 0
40#include <sys/cdefs.h>
41#ifndef lint
42#if 0
43static char sccsid[] = "@(#)print.c     8.5 (Berkeley) 7/28/94";
44#else
45__RCSID("$NetBSD: print.c,v 1.40 2004/11/17 17:00:00 mycroft Exp $");
46#endif
47#endif /* not lint */
48#endif
49
50#include <inttypes.h>
51
52#include <rtems.h>
53#include <rtems/inttypes.h>
54#include <rtems/libio.h>
55
56#include <sys/param.h>
57#include <sys/stat.h>
58
59#include "err.h"
60#include <errno.h>
61#include "fts.h"
62#include <grp.h>
63#include <pwd.h>
64#include <stdio.h>
65#include <stdlib.h>
66#include <string.h>
67#include <time.h>
68//#include <tzfile.h>
69#include <unistd.h>
70//#include <util.h>
71
72#include "internal.h"
73#include "extern-ls.h"
74
75#define DAYSPERNYEAR ((time_t)365)
76#define SECSPERDAY   ((time_t)60 * (time_t)60 * (time_t)24)
77
78
79#if RTEMS_REMOVED
80extern int termwidth;
81#endif
82
83static int      printaname(rtems_shell_ls_globals* globals, FTSENT *, int, int);
84static void     printlink(rtems_shell_ls_globals* globals, FTSENT *);
85static void     printtime(rtems_shell_ls_globals* globals, time_t);
86static int      printtype(u_int);
87
88#if RTEMS_REMOVED
89static time_t   now;
90#endif
91
92#define IS_NOPRINT(p)   ((p)->fts_number == NO_PRINT)
93
94void
95printscol(rtems_shell_ls_globals* globals, DISPLAY *dp)
96{
97        FTSENT *p;
98
99        for (p = dp->list; p; p = p->fts_link) {
100                if (IS_NOPRINT(p))
101                        continue;
102                (void)printaname(globals, p, dp->s_inode, dp->s_block);
103                (void)putchar('\n');
104        }
105}
106
107void
108printlong(rtems_shell_ls_globals* globals, DISPLAY *dp)
109{
110        struct stat *sp;
111        FTSENT *p;
112        NAMES *np;
113        char buf[20]; //, szbuf[5];
114
115        now = time(NULL);
116
117        if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
118#if RTEMS_REMOVED
119                if (f_humanize) {
120                        if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
121                            "", HN_AUTOSCALE,
122                            (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
123                                err(exit_jump, 1, "humanize_number");
124                        (void)printf("total %s\n", szbuf);
125                } else {
126#endif
127                        (void)printf("total %llu\n",
128                            (unsigned long long)(howmany(dp->btotal, blocksize)));
129#if RTEMS_REMOVED
130                }
131#endif
132        }
133
134        for (p = dp->list; p; p = p->fts_link) {
135                if (IS_NOPRINT(p))
136                        continue;
137                sp = p->fts_statp;
138                if (f_inode)
139                        (void)printf("%*" PRIuino_t " ", dp->s_inode,
140                            sp->st_ino);
141                if (f_size && !f_humanize) {
142                        (void)printf("%*llu ", dp->s_block,
143                            (unsigned long long)howmany(sp->st_blocks, blocksize));
144                }
145                (void)strmode(sp->st_mode, buf);
146                np = p->fts_pointer;
147                (void)printf("%s %*lu ", buf, dp->s_nlink,
148                    (unsigned long)sp->st_nlink);
149                if (!f_grouponly)
150                        (void)printf("%-*s  ", dp->s_user, np->user);
151                (void)printf("%-*s  ", dp->s_group, np->group);
152                if (f_flags)
153                        (void)printf("%-*s ", dp->s_flags, np->flags);
154                if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
155                        (void)printf("%*"PRIu32", %*"PRIu32" ",
156                            dp->s_major, major(sp->st_rdev), dp->s_minor,
157                            minor(sp->st_rdev));
158                else
159#if RTEMS_REMOVED
160                        if (f_humanize) {
161                                if ((humanize_number(szbuf, sizeof(szbuf),
162                                    sp->st_size, "", HN_AUTOSCALE,
163                                    (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
164                                        err(1, "humanize_number");
165                                (void)printf("%*s ", dp->s_size, szbuf);
166                        } else {
167#endif
168      {
169        unsigned long long size;
170        if (sp->st_size < 0)
171          size = sp->st_size * -1;
172        else
173          size = sp->st_size;
174                                (void)printf("%*llu ", dp->s_size, size);
175                }
176                if (f_accesstime)
177                        printtime(globals, sp->st_atime);
178                else if (f_statustime)
179                        printtime(globals, sp->st_ctime);
180                else
181                        printtime(globals, sp->st_mtime);
182                if (f_octal || f_octal_escape)
183                        (void)safe_print(globals, p->fts_name);
184                else if (f_nonprint)
185                        (void)printescaped(globals, p->fts_name);
186                else
187                        (void)printf("%s", p->fts_name);
188
189                if (f_type || (f_typedir && S_ISDIR(sp->st_mode)))
190                        (void)printtype(sp->st_mode);
191                if (S_ISLNK(sp->st_mode))
192                        printlink(globals, p);
193                (void)putchar('\n');
194        }
195}
196
197void
198printcol(rtems_shell_ls_globals* globals, DISPLAY *dp)
199{
200        static FTSENT **array;
201        static int lastentries = -1;
202        FTSENT *p;
203        int base, chcnt, col, colwidth, num;
204        int numcols, numrows, row;
205        //char szbuf[5];
206
207        colwidth = dp->maxlen;
208        if (f_inode)
209                colwidth += dp->s_inode + 1;
210        if (f_size) {
211                if (f_humanize)
212                        colwidth += dp->s_size + 1;
213                else
214                        colwidth += dp->s_block + 1;
215        }
216        if (f_type || f_typedir)
217                colwidth += 1;
218
219        colwidth += 1;
220
221        if (termwidth < 2 * colwidth) {
222                printscol(globals, dp);
223                return;
224        }
225
226        /*
227         * Have to do random access in the linked list -- build a table
228         * of pointers.
229         */
230        if (dp->entries > lastentries) {
231                lastentries = dp->entries;
232                if ((array =
233                    realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
234                        warn(NULL);
235                        printscol(globals, dp);
236                }
237        }
238        for (p = dp->list, num = 0; p; p = p->fts_link)
239                if (p->fts_number != NO_PRINT)
240                        array[num++] = p;
241
242        numcols = termwidth / colwidth;
243        colwidth = termwidth / numcols;         /* spread out if possible */
244        numrows = num / numcols;
245        if (num % numcols)
246                ++numrows;
247
248        if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
249#if RTEMS_REMOVED
250                if (f_humanize) {
251                        if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
252                            "", HN_AUTOSCALE,
253                            (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
254                                err(1, "humanize_number");
255                        (void)printf("total %s\n", szbuf);
256                } else {
257#endif
258                        (void)printf("total %llu\n",
259                            (unsigned long long)(howmany(dp->btotal, blocksize)));
260#if RTEMS_REMOVED
261                }
262#endif
263        }
264        for (row = 0; row < numrows; ++row) {
265                for (base = row, chcnt = col = 0; col < numcols; ++col) {
266                        chcnt = printaname(globals, array[base], dp->s_inode,
267                            f_humanize && 0 ? dp->s_size : dp->s_block);
268                        if ((base += numrows) >= num)
269                                break;
270                        while (chcnt++ < colwidth)
271                                (void)putchar(' ');
272                }
273                (void)putchar('\n');
274        }
275}
276
277void
278printacol(rtems_shell_ls_globals* globals, DISPLAY *dp)
279{
280        FTSENT *p;
281        int chcnt, col, colwidth;
282        int numcols;
283        //char szbuf[5];
284
285        colwidth = dp->maxlen;
286        if (f_inode)
287                colwidth += dp->s_inode + 1;
288        if (f_size) {
289                if (f_humanize)
290                        colwidth += dp->s_size + 1;
291                else
292                        colwidth += dp->s_block + 1;
293        }
294        if (f_type || f_typedir)
295                colwidth += 1;
296
297        colwidth += 1;
298
299        if (termwidth < 2 * colwidth) {
300                printscol(globals, dp);
301                return;
302        }
303
304        numcols = termwidth / colwidth;
305        colwidth = termwidth / numcols;         /* spread out if possible */
306
307        if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
308#if RTEMS_REMOVED
309                if (f_humanize) {
310                        if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
311                            "", HN_AUTOSCALE,
312                            (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
313                                err(1, "humanize_number");
314                        (void)printf("total %s\n", szbuf);
315                } else {
316#endif
317                        (void)printf("total %llu\n",
318                            (unsigned long long)(howmany(dp->btotal, blocksize)));
319#if RTEMS_REMOVED
320                }
321#endif
322        }
323        chcnt = col = 0;
324        for (p = dp->list; p; p = p->fts_link) {
325                if (IS_NOPRINT(p))
326                        continue;
327                if (col >= numcols) {
328                        chcnt = col = 0;
329                        (void)putchar('\n');
330                }
331                chcnt = printaname(globals, p, dp->s_inode,
332                    f_humanize && 0 ? dp->s_size : dp->s_block);
333                while (chcnt++ < colwidth)
334                        (void)putchar(' ');
335                col++;
336        }
337        (void)putchar('\n');
338}
339
340void
341printstream(rtems_shell_ls_globals* globals, DISPLAY *dp)
342{
343        FTSENT *p;
344        int col;
345        int extwidth;
346
347        extwidth = 0;
348        if (f_inode)
349                extwidth += dp->s_inode + 1;
350        if (f_size) {
351                if (f_humanize)
352                        extwidth += dp->s_size + 1;
353                else
354                        extwidth += dp->s_block + 1;
355        }
356        if (f_type)
357                extwidth += 1;
358
359        for (col = 0, p = dp->list; p != NULL; p = p->fts_link) {
360                if (IS_NOPRINT(p))
361                        continue;
362                if (col > 0) {
363                        (void)putchar(','), col++;
364                        if (col + 1 + extwidth + p->fts_namelen >= termwidth)
365                                (void)putchar('\n'), col = 0;
366                        else
367                                (void)putchar(' '), col++;
368                }
369                col += printaname(globals, p, dp->s_inode,
370                    f_humanize && 0 ? dp->s_size : dp->s_block);
371        }
372        (void)putchar('\n');
373}
374
375/*
376 * print [inode] [size] name
377 * return # of characters printed, no trailing characters.
378 */
379static int
380printaname(rtems_shell_ls_globals* globals,
381           FTSENT *p, int inodefield, int sizefield)
382{
383        struct stat *sp;
384        int chcnt;
385        //char szbuf[5];
386
387        sp = p->fts_statp;
388        chcnt = 0;
389        if (f_inode)
390                chcnt += printf("%*" PRIuino_t " ", inodefield, sp->st_ino);
391        if (f_size) {
392#if RTEMS_REMOVED
393                if (f_humanize) {
394                        if ((humanize_number(szbuf, sizeof(szbuf), sp->st_size,
395                            "", HN_AUTOSCALE,
396                            (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
397                                err(1, "humanize_number");
398                        chcnt += printf("%*s ", sizefield, szbuf);
399                } else {
400#endif
401                        chcnt += printf("%*llu ", sizefield,
402                            (unsigned long long)howmany(sp->st_blocks, blocksize));
403#if RTEMS_REMOVED
404                }
405#endif
406        }
407        if (f_octal || f_octal_escape)
408                chcnt += safe_print(globals, p->fts_name);
409        else if (f_nonprint)
410                chcnt += printescaped(globals, p->fts_name);
411        else
412                chcnt += printf("%s", p->fts_name);
413        if (f_type || (f_typedir && S_ISDIR(sp->st_mode)))
414                chcnt += printtype(sp->st_mode);
415        return (chcnt);
416}
417
418static void
419printtime(rtems_shell_ls_globals* globals, time_t ftime)
420{
421        int i;
422        char *longstring;
423
424        longstring = ctime(&ftime);
425        for (i = 4; i < 11; ++i)
426                (void)putchar(longstring[i]);
427
428#define SIXMONTHS       ((DAYSPERNYEAR / 2) * SECSPERDAY)
429        if (f_sectime)
430                for (i = 11; i < 24; i++)
431                        (void)putchar(longstring[i]);
432        else if (ftime + SIXMONTHS > now && ftime - SIXMONTHS < now)
433                for (i = 11; i < 16; ++i)
434                        (void)putchar(longstring[i]);
435        else {
436                (void)putchar(' ');
437                for (i = 20; i < 24; ++i)
438                        (void)putchar(longstring[i]);
439        }
440        (void)putchar(' ');
441}
442
443static int
444printtype(u_int mode)
445{
446        switch (mode & S_IFMT) {
447        case S_IFDIR:
448                (void)putchar('/');
449                return (1);
450        case S_IFIFO:
451                (void)putchar('|');
452                return (1);
453        case S_IFLNK:
454                (void)putchar('@');
455                return (1);
456        case S_IFSOCK:
457                (void)putchar('=');
458                return (1);
459#if RTEMS_REMOVED
460        case S_IFWHT:
461                (void)putchar('%');
462                return (1);
463#endif
464        }
465        if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
466                (void)putchar('*');
467                return (1);
468        }
469        return (0);
470}
471
472static void
473printlink(rtems_shell_ls_globals* globals, FTSENT *p)
474{
475        int lnklen;
476        char name[MAXPATHLEN + 1], path[MAXPATHLEN + 1];
477
478        if (p->fts_level == FTS_ROOTLEVEL)
479                (void)snprintf(name, sizeof(name), "%s", p->fts_name);
480        else
481                (void)snprintf(name, sizeof(name),
482                    "%s/%s", p->fts_parent->fts_accpath, p->fts_name);
483        if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
484                (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
485                return;
486        }
487        path[lnklen] = '\0';
488        (void)printf(" -> ");
489        if (f_octal || f_octal_escape)
490                (void)safe_print(globals, path);
491        else if (f_nonprint)
492                (void)printescaped(globals, path);
493        else
494                (void)printf("%s", path);
495}
Note: See TracBrowser for help on using the repository browser.