File indexing completed on 2025-05-11 08:24:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #ifdef HAVE_CONFIG_H
0036 #include "config.h"
0037 #endif
0038
0039 #if 0
0040 #include <sys/cdefs.h>
0041 #ifndef lint
0042 #if 0
0043 static char sccsid[] = "@(#)print.c 8.5 (Berkeley) 7/28/94";
0044 #else
0045 __RCSID("$NetBSD: print.c,v 1.40 2004/11/17 17:00:00 mycroft Exp $");
0046 #endif
0047 #endif
0048 #endif
0049
0050 #include <inttypes.h>
0051
0052 #include <rtems.h>
0053 #include <rtems/inttypes.h>
0054 #include <rtems/libio.h>
0055
0056 #include <sys/param.h>
0057 #include <sys/stat.h>
0058
0059 #include "err.h"
0060 #include <errno.h>
0061 #include "fts.h"
0062 #include <grp.h>
0063 #include <pwd.h>
0064 #include <stdio.h>
0065 #include <stdlib.h>
0066 #include <string.h>
0067 #include <time.h>
0068
0069 #include <unistd.h>
0070
0071
0072 #include "internal.h"
0073 #include "extern-ls.h"
0074
0075 #define DAYSPERNYEAR ((time_t)365)
0076 #define SECSPERDAY ((time_t)60 * (time_t)60 * (time_t)24)
0077
0078
0079 #if RTEMS_REMOVED
0080 extern int termwidth;
0081 #endif
0082
0083 static int printaname(rtems_shell_ls_globals* globals, FTSENT *, int, int);
0084 static void printlink(rtems_shell_ls_globals* globals, FTSENT *);
0085 static void printtime(rtems_shell_ls_globals* globals, time_t);
0086 static int printtype(u_int);
0087
0088 #if RTEMS_REMOVED
0089 static time_t now;
0090 #endif
0091
0092 #define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT)
0093
0094 void
0095 printscol(rtems_shell_ls_globals* globals, DISPLAY *dp)
0096 {
0097 FTSENT *p;
0098
0099 for (p = dp->list; p; p = p->fts_link) {
0100 if (IS_NOPRINT(p))
0101 continue;
0102 (void)printaname(globals, p, dp->s_inode, dp->s_block);
0103 (void)putchar('\n');
0104 }
0105 }
0106
0107 void
0108 printlong(rtems_shell_ls_globals* globals, DISPLAY *dp)
0109 {
0110 struct stat *sp;
0111 FTSENT *p;
0112 NAMES *np;
0113 char buf[20];
0114
0115 now = time(NULL);
0116
0117 if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
0118 #if RTEMS_REMOVED
0119 if (f_humanize) {
0120 if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
0121 "", HN_AUTOSCALE,
0122 (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
0123 err(exit_jump, 1, "humanize_number");
0124 (void)printf("total %s\n", szbuf);
0125 } else {
0126 #endif
0127 (void)printf("total %llu\n",
0128 (unsigned long long)(howmany(dp->btotal, blocksize)));
0129 #if RTEMS_REMOVED
0130 }
0131 #endif
0132 }
0133
0134 for (p = dp->list; p; p = p->fts_link) {
0135 if (IS_NOPRINT(p))
0136 continue;
0137 sp = p->fts_statp;
0138 if (f_inode)
0139 (void)printf("%*" PRIuino_t " ", dp->s_inode,
0140 sp->st_ino);
0141 if (f_size && !f_humanize) {
0142 (void)printf("%*llu ", dp->s_block,
0143 (unsigned long long)howmany(sp->st_blocks, blocksize));
0144 }
0145 (void)strmode(sp->st_mode, buf);
0146 np = p->fts_pointer;
0147 (void)printf("%s %*lu ", buf, dp->s_nlink,
0148 (unsigned long)sp->st_nlink);
0149 if (!f_grouponly)
0150 (void)printf("%-*s ", dp->s_user, np->user);
0151 (void)printf("%-*s ", dp->s_group, np->group);
0152 if (f_flags)
0153 (void)printf("%-*s ", dp->s_flags, np->flags);
0154 if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
0155 (void)printf("%*"PRIu32", %*"PRIu32" ",
0156 dp->s_major, major(sp->st_rdev), dp->s_minor,
0157 minor(sp->st_rdev));
0158 else
0159 #if RTEMS_REMOVED
0160 if (f_humanize) {
0161 if ((humanize_number(szbuf, sizeof(szbuf),
0162 sp->st_size, "", HN_AUTOSCALE,
0163 (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
0164 err(1, "humanize_number");
0165 (void)printf("%*s ", dp->s_size, szbuf);
0166 } else {
0167 #endif
0168 {
0169 unsigned long long size;
0170 if (sp->st_size < 0)
0171 size = sp->st_size * -1;
0172 else
0173 size = sp->st_size;
0174 (void)printf("%*llu ", dp->s_size, size);
0175 }
0176 if (f_accesstime)
0177 printtime(globals, sp->st_atime);
0178 else if (f_statustime)
0179 printtime(globals, sp->st_ctime);
0180 else
0181 printtime(globals, sp->st_mtime);
0182 if (f_octal || f_octal_escape)
0183 (void)safe_print(globals, p->fts_name);
0184 else if (f_nonprint)
0185 (void)printescaped(globals, p->fts_name);
0186 else
0187 (void)printf("%s", p->fts_name);
0188
0189 if (f_type || (f_typedir && S_ISDIR(sp->st_mode)))
0190 (void)printtype(sp->st_mode);
0191 if (S_ISLNK(sp->st_mode))
0192 printlink(globals, p);
0193 (void)putchar('\n');
0194 }
0195 }
0196
0197 void
0198 printcol(rtems_shell_ls_globals* globals, DISPLAY *dp)
0199 {
0200 static FTSENT **array;
0201 static int lastentries = -1;
0202 FTSENT *p;
0203 int base, chcnt, col, colwidth, num;
0204 int numcols, numrows, row;
0205
0206
0207 colwidth = dp->maxlen;
0208 if (f_inode)
0209 colwidth += dp->s_inode + 1;
0210 if (f_size) {
0211 if (f_humanize)
0212 colwidth += dp->s_size + 1;
0213 else
0214 colwidth += dp->s_block + 1;
0215 }
0216 if (f_type || f_typedir)
0217 colwidth += 1;
0218
0219 colwidth += 1;
0220
0221 if (termwidth < 2 * colwidth) {
0222 printscol(globals, dp);
0223 return;
0224 }
0225
0226
0227
0228
0229
0230 if (dp->entries > lastentries) {
0231 lastentries = dp->entries;
0232 if ((array =
0233 realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
0234 warn(NULL);
0235 printscol(globals, dp);
0236 }
0237 }
0238 for (p = dp->list, num = 0; p; p = p->fts_link)
0239 if (p->fts_number != NO_PRINT)
0240 array[num++] = p;
0241
0242 numcols = termwidth / colwidth;
0243 colwidth = termwidth / numcols;
0244 numrows = num / numcols;
0245 if (num % numcols)
0246 ++numrows;
0247
0248 if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
0249 #if RTEMS_REMOVED
0250 if (f_humanize) {
0251 if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
0252 "", HN_AUTOSCALE,
0253 (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
0254 err(1, "humanize_number");
0255 (void)printf("total %s\n", szbuf);
0256 } else {
0257 #endif
0258 (void)printf("total %llu\n",
0259 (unsigned long long)(howmany(dp->btotal, blocksize)));
0260 #if RTEMS_REMOVED
0261 }
0262 #endif
0263 }
0264 for (row = 0; row < numrows; ++row) {
0265 for (base = row, chcnt = col = 0; col < numcols; ++col) {
0266 chcnt = printaname(globals, array[base], dp->s_inode,
0267 f_humanize && 0 ? dp->s_size : dp->s_block);
0268 if ((base += numrows) >= num)
0269 break;
0270 while (chcnt++ < colwidth)
0271 (void)putchar(' ');
0272 }
0273 (void)putchar('\n');
0274 }
0275 }
0276
0277 void
0278 printacol(rtems_shell_ls_globals* globals, DISPLAY *dp)
0279 {
0280 FTSENT *p;
0281 int chcnt, col, colwidth;
0282 int numcols;
0283
0284
0285 colwidth = dp->maxlen;
0286 if (f_inode)
0287 colwidth += dp->s_inode + 1;
0288 if (f_size) {
0289 if (f_humanize)
0290 colwidth += dp->s_size + 1;
0291 else
0292 colwidth += dp->s_block + 1;
0293 }
0294 if (f_type || f_typedir)
0295 colwidth += 1;
0296
0297 colwidth += 1;
0298
0299 if (termwidth < 2 * colwidth) {
0300 printscol(globals, dp);
0301 return;
0302 }
0303
0304 numcols = termwidth / colwidth;
0305 colwidth = termwidth / numcols;
0306
0307 if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
0308 #if RTEMS_REMOVED
0309 if (f_humanize) {
0310 if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
0311 "", HN_AUTOSCALE,
0312 (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
0313 err(1, "humanize_number");
0314 (void)printf("total %s\n", szbuf);
0315 } else {
0316 #endif
0317 (void)printf("total %llu\n",
0318 (unsigned long long)(howmany(dp->btotal, blocksize)));
0319 #if RTEMS_REMOVED
0320 }
0321 #endif
0322 }
0323 chcnt = col = 0;
0324 for (p = dp->list; p; p = p->fts_link) {
0325 if (IS_NOPRINT(p))
0326 continue;
0327 if (col >= numcols) {
0328 #ifdef __rtems__
0329
0330
0331
0332
0333
0334 col = 0;
0335 #else
0336 chcnt = col = 0;
0337 #endif
0338 (void)putchar('\n');
0339 }
0340 chcnt = printaname(globals, p, dp->s_inode,
0341 f_humanize && 0 ? dp->s_size : dp->s_block);
0342 while (chcnt++ < colwidth)
0343 (void)putchar(' ');
0344 col++;
0345 }
0346 (void)putchar('\n');
0347 }
0348
0349 void
0350 printstream(rtems_shell_ls_globals* globals, DISPLAY *dp)
0351 {
0352 FTSENT *p;
0353 int col;
0354 int extwidth;
0355
0356 extwidth = 0;
0357 if (f_inode)
0358 extwidth += dp->s_inode + 1;
0359 if (f_size) {
0360 if (f_humanize)
0361 extwidth += dp->s_size + 1;
0362 else
0363 extwidth += dp->s_block + 1;
0364 }
0365 if (f_type)
0366 extwidth += 1;
0367
0368 for (col = 0, p = dp->list; p != NULL; p = p->fts_link) {
0369 if (IS_NOPRINT(p))
0370 continue;
0371 if (col > 0) {
0372 (void)putchar(','), col++;
0373 if (col + 1 + extwidth + p->fts_namelen >= termwidth)
0374 (void)putchar('\n'), col = 0;
0375 else
0376 (void)putchar(' '), col++;
0377 }
0378 col += printaname(globals, p, dp->s_inode,
0379 f_humanize && 0 ? dp->s_size : dp->s_block);
0380 }
0381 (void)putchar('\n');
0382 }
0383
0384
0385
0386
0387
0388 static int
0389 printaname(rtems_shell_ls_globals* globals,
0390 FTSENT *p, int inodefield, int sizefield)
0391 {
0392 struct stat *sp;
0393 int chcnt;
0394
0395
0396 sp = p->fts_statp;
0397 chcnt = 0;
0398 if (f_inode)
0399 chcnt += printf("%*" PRIuino_t " ", inodefield, sp->st_ino);
0400 if (f_size) {
0401 #if RTEMS_REMOVED
0402 if (f_humanize) {
0403 if ((humanize_number(szbuf, sizeof(szbuf), sp->st_size,
0404 "", HN_AUTOSCALE,
0405 (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
0406 err(1, "humanize_number");
0407 chcnt += printf("%*s ", sizefield, szbuf);
0408 } else {
0409 #endif
0410 chcnt += printf("%*llu ", sizefield,
0411 (unsigned long long)howmany(sp->st_blocks, blocksize));
0412 #if RTEMS_REMOVED
0413 }
0414 #endif
0415 }
0416 if (f_octal || f_octal_escape)
0417 chcnt += safe_print(globals, p->fts_name);
0418 else if (f_nonprint)
0419 chcnt += printescaped(globals, p->fts_name);
0420 else
0421 chcnt += printf("%s", p->fts_name);
0422 if (f_type || (f_typedir && S_ISDIR(sp->st_mode)))
0423 chcnt += printtype(sp->st_mode);
0424 return (chcnt);
0425 }
0426
0427 static void
0428 printtime(rtems_shell_ls_globals* globals, time_t ftime)
0429 {
0430 int i;
0431 char *longstring;
0432
0433 longstring = ctime(&ftime);
0434 for (i = 4; i < 11; ++i)
0435 (void)putchar(longstring[i]);
0436
0437 #define SIXMONTHS ((DAYSPERNYEAR / 2) * SECSPERDAY)
0438 if (f_sectime)
0439 for (i = 11; i < 24; i++)
0440 (void)putchar(longstring[i]);
0441 else if (ftime + SIXMONTHS > now && ftime - SIXMONTHS < now)
0442 for (i = 11; i < 16; ++i)
0443 (void)putchar(longstring[i]);
0444 else {
0445 (void)putchar(' ');
0446 for (i = 20; i < 24; ++i)
0447 (void)putchar(longstring[i]);
0448 }
0449 (void)putchar(' ');
0450 }
0451
0452 static int
0453 printtype(u_int mode)
0454 {
0455 switch (mode & S_IFMT) {
0456 case S_IFDIR:
0457 (void)putchar('/');
0458 return (1);
0459 case S_IFIFO:
0460 (void)putchar('|');
0461 return (1);
0462 case S_IFLNK:
0463 (void)putchar('@');
0464 return (1);
0465 case S_IFSOCK:
0466 (void)putchar('=');
0467 return (1);
0468 #if RTEMS_REMOVED
0469 case S_IFWHT:
0470 (void)putchar('%');
0471 return (1);
0472 #endif
0473 }
0474 if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
0475 (void)putchar('*');
0476 return (1);
0477 }
0478 return (0);
0479 }
0480
0481 static void
0482 printlink(rtems_shell_ls_globals* globals, FTSENT *p)
0483 {
0484 int lnklen;
0485 char name[MAXPATHLEN + 1], path[MAXPATHLEN + 1];
0486
0487 if (p->fts_level == FTS_ROOTLEVEL)
0488 (void)snprintf(name, sizeof(name), "%s", p->fts_name);
0489 else
0490 (void)snprintf(name, sizeof(name),
0491 "%s/%s", p->fts_parent->fts_accpath, p->fts_name);
0492 if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
0493 (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
0494 return;
0495 }
0496 path[lnklen] = '\0';
0497 (void)printf(" -> ");
0498 if (f_octal || f_octal_escape)
0499 (void)safe_print(globals, path);
0500 else if (f_nonprint)
0501 (void)printescaped(globals, path);
0502 else
0503 (void)printf("%s", path);
0504 }