source: rtems/cpukit/libmisc/shell/print-ls.c @ 6cdaa85

5
Last change on this file since 6cdaa85 was 6cdaa85, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 4, 2018 at 6:16:45 PM

shell: Use #include "..." for local header files

Update #3375.

  • Property mode set to 100644
File size: 11.9 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/libio.h>
54
55#include <sys/param.h>
56#include <sys/stat.h>
57
58#include "err.h"
59#include <errno.h>
60#include "fts.h"
61#include <grp.h>
62#include <pwd.h>
63#include <stdio.h>
64#include <stdlib.h>
65#include <string.h>
66#include <time.h>
67//#include <tzfile.h>
68#include <unistd.h>
69//#include <util.h>
70
71#include "internal.h"
72#include "extern-ls.h"
73
74#define DAYSPERNYEAR ((time_t)365)
75#define SECSPERDAY   ((time_t)60 * (time_t)60 * (time_t)24)
76
77
78#if RTEMS_REMOVED
79extern int termwidth;
80#endif
81
82static int      printaname(rtems_shell_ls_globals* globals, FTSENT *, int, int);
83static void     printlink(rtems_shell_ls_globals* globals, FTSENT *);
84static void     printtime(rtems_shell_ls_globals* globals, time_t);
85static int      printtype(u_int);
86
87#if RTEMS_REMOVED
88static time_t   now;
89#endif
90
91#define IS_NOPRINT(p)   ((p)->fts_number == NO_PRINT)
92
93void
94printscol(rtems_shell_ls_globals* globals, DISPLAY *dp)
95{
96        FTSENT *p;
97
98        for (p = dp->list; p; p = p->fts_link) {
99                if (IS_NOPRINT(p))
100                        continue;
101                (void)printaname(globals, p, dp->s_inode, dp->s_block);
102                (void)putchar('\n');
103        }
104}
105
106void
107printlong(rtems_shell_ls_globals* globals, DISPLAY *dp)
108{
109        struct stat *sp;
110        FTSENT *p;
111        NAMES *np;
112        char buf[20]; //, szbuf[5];
113
114        now = time(NULL);
115
116        if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
117#if RTEMS_REMOVED
118                if (f_humanize) {
119                        if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
120                            "", HN_AUTOSCALE,
121                            (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
122                                err(exit_jump, 1, "humanize_number");
123                        (void)printf("total %s\n", szbuf);
124                } else {
125#endif
126                        (void)printf("total %llu\n",
127                            (unsigned long long)(howmany(dp->btotal, blocksize)));
128#if RTEMS_REMOVED
129                }
130#endif
131        }
132
133        for (p = dp->list; p; p = p->fts_link) {
134                if (IS_NOPRINT(p))
135                        continue;
136                sp = p->fts_statp;
137                if (f_inode)
138                        (void)printf("%*lu ", dp->s_inode, sp->st_ino);
139                if (f_size && !f_humanize) {
140                        (void)printf("%*llu ", dp->s_block,
141                            (unsigned long long)howmany(sp->st_blocks, blocksize));
142                }
143                (void)strmode(sp->st_mode, buf);
144                np = p->fts_pointer;
145                (void)printf("%s %*lu ", buf, dp->s_nlink,
146                    (unsigned long)sp->st_nlink);
147                if (!f_grouponly)
148                        (void)printf("%-*s  ", dp->s_user, np->user);
149                (void)printf("%-*s  ", dp->s_group, np->group);
150                if (f_flags)
151                        (void)printf("%-*s ", dp->s_flags, np->flags);
152                if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
153                        (void)printf("%*"PRIu32", %*"PRIu32" ",
154                            dp->s_major, major(sp->st_rdev), dp->s_minor,
155                            minor(sp->st_rdev));
156                else
157#if RTEMS_REMOVED
158                        if (f_humanize) {
159                                if ((humanize_number(szbuf, sizeof(szbuf),
160                                    sp->st_size, "", HN_AUTOSCALE,
161                                    (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
162                                        err(1, "humanize_number");
163                                (void)printf("%*s ", dp->s_size, szbuf);
164                        } else {
165#endif
166      {
167        unsigned long long size;
168        if (sp->st_size < 0)
169          size = sp->st_size * -1;
170        else
171          size = sp->st_size;
172                                (void)printf("%*llu ", dp->s_size, size);
173                }
174                if (f_accesstime)
175                        printtime(globals, sp->st_atime);
176                else if (f_statustime)
177                        printtime(globals, sp->st_ctime);
178                else
179                        printtime(globals, sp->st_mtime);
180                if (f_octal || f_octal_escape)
181                        (void)safe_print(globals, p->fts_name);
182                else if (f_nonprint)
183                        (void)printescaped(globals, p->fts_name);
184                else
185                        (void)printf("%s", p->fts_name);
186
187                if (f_type || (f_typedir && S_ISDIR(sp->st_mode)))
188                        (void)printtype(sp->st_mode);
189                if (S_ISLNK(sp->st_mode))
190                        printlink(globals, p);
191                (void)putchar('\n');
192        }
193}
194
195void
196printcol(rtems_shell_ls_globals* globals, DISPLAY *dp)
197{
198        static FTSENT **array;
199        static int lastentries = -1;
200        FTSENT *p;
201        int base, chcnt, col, colwidth, num;
202        int numcols, numrows, row;
203        //char szbuf[5];
204
205        colwidth = dp->maxlen;
206        if (f_inode)
207                colwidth += dp->s_inode + 1;
208        if (f_size) {
209                if (f_humanize)
210                        colwidth += dp->s_size + 1;
211                else
212                        colwidth += dp->s_block + 1;
213        }
214        if (f_type || f_typedir)
215                colwidth += 1;
216
217        colwidth += 1;
218
219        if (termwidth < 2 * colwidth) {
220                printscol(globals, dp);
221                return;
222        }
223
224        /*
225         * Have to do random access in the linked list -- build a table
226         * of pointers.
227         */
228        if (dp->entries > lastentries) {
229                lastentries = dp->entries;
230                if ((array =
231                    realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
232                        warn(NULL);
233                        printscol(globals, dp);
234                }
235        }
236        for (p = dp->list, num = 0; p; p = p->fts_link)
237                if (p->fts_number != NO_PRINT)
238                        array[num++] = p;
239
240        numcols = termwidth / colwidth;
241        colwidth = termwidth / numcols;         /* spread out if possible */
242        numrows = num / numcols;
243        if (num % numcols)
244                ++numrows;
245
246        if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
247#if RTEMS_REMOVED
248                if (f_humanize) {
249                        if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
250                            "", HN_AUTOSCALE,
251                            (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
252                                err(1, "humanize_number");
253                        (void)printf("total %s\n", szbuf);
254                } else {
255#endif
256                        (void)printf("total %llu\n",
257                            (unsigned long long)(howmany(dp->btotal, blocksize)));
258#if RTEMS_REMOVED
259                }
260#endif
261        }
262        for (row = 0; row < numrows; ++row) {
263                for (base = row, chcnt = col = 0; col < numcols; ++col) {
264                        chcnt = printaname(globals, array[base], dp->s_inode,
265                            f_humanize && 0 ? dp->s_size : dp->s_block);
266                        if ((base += numrows) >= num)
267                                break;
268                        while (chcnt++ < colwidth)
269                                (void)putchar(' ');
270                }
271                (void)putchar('\n');
272        }
273}
274
275void
276printacol(rtems_shell_ls_globals* globals, DISPLAY *dp)
277{
278        FTSENT *p;
279        int chcnt, col, colwidth;
280        int numcols;
281        //char szbuf[5];
282
283        colwidth = dp->maxlen;
284        if (f_inode)
285                colwidth += dp->s_inode + 1;
286        if (f_size) {
287                if (f_humanize)
288                        colwidth += dp->s_size + 1;
289                else
290                        colwidth += dp->s_block + 1;
291        }
292        if (f_type || f_typedir)
293                colwidth += 1;
294
295        colwidth += 1;
296
297        if (termwidth < 2 * colwidth) {
298                printscol(globals, dp);
299                return;
300        }
301
302        numcols = termwidth / colwidth;
303        colwidth = termwidth / numcols;         /* spread out if possible */
304
305        if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
306#if RTEMS_REMOVED
307                if (f_humanize) {
308                        if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
309                            "", HN_AUTOSCALE,
310                            (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
311                                err(1, "humanize_number");
312                        (void)printf("total %s\n", szbuf);
313                } else {
314#endif
315                        (void)printf("total %llu\n",
316                            (unsigned long long)(howmany(dp->btotal, blocksize)));
317#if RTEMS_REMOVED
318                }
319#endif
320        }
321        chcnt = col = 0;
322        for (p = dp->list; p; p = p->fts_link) {
323                if (IS_NOPRINT(p))
324                        continue;
325                if (col >= numcols) {
326                        chcnt = col = 0;
327                        (void)putchar('\n');
328                }
329                chcnt = printaname(globals, p, dp->s_inode,
330                    f_humanize && 0 ? dp->s_size : dp->s_block);
331                while (chcnt++ < colwidth)
332                        (void)putchar(' ');
333                col++;
334        }
335        (void)putchar('\n');
336}
337
338void
339printstream(rtems_shell_ls_globals* globals, DISPLAY *dp)
340{
341        FTSENT *p;
342        int col;
343        int extwidth;
344
345        extwidth = 0;
346        if (f_inode)
347                extwidth += dp->s_inode + 1;
348        if (f_size) {
349                if (f_humanize)
350                        extwidth += dp->s_size + 1;
351                else
352                        extwidth += dp->s_block + 1;
353        }
354        if (f_type)
355                extwidth += 1;
356
357        for (col = 0, p = dp->list; p != NULL; p = p->fts_link) {
358                if (IS_NOPRINT(p))
359                        continue;
360                if (col > 0) {
361                        (void)putchar(','), col++;
362                        if (col + 1 + extwidth + p->fts_namelen >= termwidth)
363                                (void)putchar('\n'), col = 0;
364                        else
365                                (void)putchar(' '), col++;
366                }
367                col += printaname(globals, p, dp->s_inode,
368                    f_humanize && 0 ? dp->s_size : dp->s_block);
369        }
370        (void)putchar('\n');
371}
372
373/*
374 * print [inode] [size] name
375 * return # of characters printed, no trailing characters.
376 */
377static int
378printaname(rtems_shell_ls_globals* globals,
379           FTSENT *p, int inodefield, int sizefield)
380{
381        struct stat *sp;
382        int chcnt;
383        //char szbuf[5];
384
385        sp = p->fts_statp;
386        chcnt = 0;
387        if (f_inode)
388                chcnt += printf("%*lu ", inodefield, sp->st_ino);
389        if (f_size) {
390#if RTEMS_REMOVED
391                if (f_humanize) {
392                        if ((humanize_number(szbuf, sizeof(szbuf), sp->st_size,
393                            "", HN_AUTOSCALE,
394                            (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
395                                err(1, "humanize_number");
396                        chcnt += printf("%*s ", sizefield, szbuf);
397                } else {
398#endif
399                        chcnt += printf("%*llu ", sizefield,
400                            (unsigned long long)howmany(sp->st_blocks, blocksize));
401#if RTEMS_REMOVED
402                }
403#endif
404        }
405        if (f_octal || f_octal_escape)
406                chcnt += safe_print(globals, p->fts_name);
407        else if (f_nonprint)
408                chcnt += printescaped(globals, p->fts_name);
409        else
410                chcnt += printf("%s", p->fts_name);
411        if (f_type || (f_typedir && S_ISDIR(sp->st_mode)))
412                chcnt += printtype(sp->st_mode);
413        return (chcnt);
414}
415
416static void
417printtime(rtems_shell_ls_globals* globals, time_t ftime)
418{
419        int i;
420        char *longstring;
421
422        longstring = ctime(&ftime);
423        for (i = 4; i < 11; ++i)
424                (void)putchar(longstring[i]);
425
426#define SIXMONTHS       ((DAYSPERNYEAR / 2) * SECSPERDAY)
427        if (f_sectime)
428                for (i = 11; i < 24; i++)
429                        (void)putchar(longstring[i]);
430        else if (ftime + SIXMONTHS > now && ftime - SIXMONTHS < now)
431                for (i = 11; i < 16; ++i)
432                        (void)putchar(longstring[i]);
433        else {
434                (void)putchar(' ');
435                for (i = 20; i < 24; ++i)
436                        (void)putchar(longstring[i]);
437        }
438        (void)putchar(' ');
439}
440
441static int
442printtype(u_int mode)
443{
444        switch (mode & S_IFMT) {
445        case S_IFDIR:
446                (void)putchar('/');
447                return (1);
448        case S_IFIFO:
449                (void)putchar('|');
450                return (1);
451        case S_IFLNK:
452                (void)putchar('@');
453                return (1);
454        case S_IFSOCK:
455                (void)putchar('=');
456                return (1);
457#if RTEMS_REMOVED
458        case S_IFWHT:
459                (void)putchar('%');
460                return (1);
461#endif
462        }
463        if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
464                (void)putchar('*');
465                return (1);
466        }
467        return (0);
468}
469
470static void
471printlink(rtems_shell_ls_globals* globals, FTSENT *p)
472{
473        int lnklen;
474        char name[MAXPATHLEN + 1], path[MAXPATHLEN + 1];
475
476        if (p->fts_level == FTS_ROOTLEVEL)
477                (void)snprintf(name, sizeof(name), "%s", p->fts_name);
478        else
479                (void)snprintf(name, sizeof(name),
480                    "%s/%s", p->fts_parent->fts_accpath, p->fts_name);
481        if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
482                (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
483                return;
484        }
485        path[lnklen] = '\0';
486        (void)printf(" -> ");
487        if (f_octal || f_octal_escape)
488                (void)safe_print(globals, path);
489        else if (f_nonprint)
490                (void)printescaped(globals, path);
491        else
492                (void)printf("%s", path);
493}
Note: See TracBrowser for help on using the repository browser.