[BACK]Return to print.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / bin / ls

Annotation of src/bin/ls/print.c, Revision 1.57

1.57    ! christos    1: /*     $NetBSD: print.c,v 1.56 2020/05/16 18:31:45 christos Exp $      */
1.13      cgd         2:
1.1       cgd         3: /*
1.11      mycroft     4:  * Copyright (c) 1989, 1993, 1994
                      5:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd         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.
1.35      agc        18:  * 3. Neither the name of the University nor the names of its contributors
1.1       cgd        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:
1.16      christos   35: #include <sys/cdefs.h>
1.1       cgd        36: #ifndef lint
1.13      cgd        37: #if 0
1.14      jtc        38: static char sccsid[] = "@(#)print.c    8.5 (Berkeley) 7/28/94";
1.13      cgd        39: #else
1.57    ! christos   40: __RCSID("$NetBSD: print.c,v 1.56 2020/05/16 18:31:45 christos Exp $");
1.13      cgd        41: #endif
1.1       cgd        42: #endif /* not lint */
                     43:
                     44: #include <sys/param.h>
                     45: #include <sys/stat.h>
1.57    ! christos   46: #ifndef SMALL
1.56      christos   47: #include <sys/acl.h>
1.57    ! christos   48: #endif
1.11      mycroft    49:
                     50: #include <err.h>
                     51: #include <errno.h>
1.55      martin     52: #include <inttypes.h>
1.5       mycroft    53: #include <fts.h>
1.1       cgd        54: #include <grp.h>
                     55: #include <pwd.h>
1.11      mycroft    56: #include <stdio.h>
1.5       mycroft    57: #include <stdlib.h>
                     58: #include <string.h>
1.11      mycroft    59: #include <time.h>
                     60: #include <tzfile.h>
                     61: #include <unistd.h>
1.38      grant      62: #include <util.h>
1.11      mycroft    63:
1.1       cgd        64: #include "ls.h"
1.5       mycroft    65: #include "extern.h"
1.1       cgd        66:
1.31      christos   67: extern int termwidth;
                     68:
1.30      lukem      69: static int     printaname(FTSENT *, int, int);
                     70: static void    printlink(FTSENT *);
                     71: static void    printtime(time_t);
1.43      ahoka      72: static void    printtotal(DISPLAY *dp);
1.30      lukem      73: static int     printtype(u_int);
1.57    ! christos   74: #ifndef SMALL
1.56      christos   75: static void    aclmode(char *, const FTSENT *);
1.57    ! christos   76: #endif
1.5       mycroft    77:
1.20      mycroft    78: static time_t  now;
                     79:
1.5       mycroft    80: #define        IS_NOPRINT(p)   ((p)->fts_number == NO_PRINT)
                     81:
1.53      christos   82: static int
                     83: safe_printpath(const FTSENT *p) {
                     84:        int chcnt;
                     85:
                     86:        if (f_fullpath) {
                     87:                chcnt = safe_print(p->fts_path);
                     88:                chcnt += safe_print("/");
                     89:        } else
                     90:                chcnt = 0;
                     91:        return chcnt + safe_print(p->fts_name);
                     92: }
                     93:
                     94: static int
                     95: printescapedpath(const FTSENT *p) {
                     96:        int chcnt;
                     97:
                     98:        if (f_fullpath) {
                     99:                chcnt = printescaped(p->fts_path);
                    100:                chcnt += printescaped("/");
                    101:        } else
                    102:                chcnt = 0;
                    103:
                    104:        return chcnt + printescaped(p->fts_name);
                    105: }
                    106:
                    107: static int
                    108: printpath(const FTSENT *p) {
                    109:        if (f_fullpath)
                    110:                return printf("%s/%s", p->fts_path, p->fts_name);
                    111:        else
1.54      mlelstv   112:                return printf("%s", p->fts_name);
1.53      christos  113: }
                    114:
1.5       mycroft   115: void
1.30      lukem     116: printscol(DISPLAY *dp)
1.1       cgd       117: {
1.11      mycroft   118:        FTSENT *p;
1.5       mycroft   119:
                    120:        for (p = dp->list; p; p = p->fts_link) {
                    121:                if (IS_NOPRINT(p))
                    122:                        continue;
                    123:                (void)printaname(p, dp->s_inode, dp->s_block);
1.1       cgd       124:                (void)putchar('\n');
                    125:        }
                    126: }
                    127:
1.5       mycroft   128: void
1.30      lukem     129: printlong(DISPLAY *dp)
1.5       mycroft   130: {
1.11      mycroft   131:        struct stat *sp;
                    132:        FTSENT *p;
1.5       mycroft   133:        NAMES *np;
1.38      grant     134:        char buf[20], szbuf[5];
1.5       mycroft   135:
1.22      mycroft   136:        now = time(NULL);
1.20      mycroft   137:
1.53      christos  138:        if (!f_leafonly)
                    139:                printtotal(dp);         /* "total: %u\n" */
1.43      ahoka     140:
1.5       mycroft   141:        for (p = dp->list; p; p = p->fts_link) {
                    142:                if (IS_NOPRINT(p))
                    143:                        continue;
                    144:                sp = p->fts_statp;
1.1       cgd       145:                if (f_inode)
1.55      martin    146:                        (void)printf("%*"PRIu64" ", dp->s_inode, sp->st_ino);
1.41      jschauma  147:                if (f_size) {
                    148:                        if (f_humanize) {
                    149:                                if ((humanize_number(szbuf, sizeof(szbuf),
1.48      enami     150:                                    sp->st_blocks * S_BLKSIZE,
                    151:                                    "", HN_AUTOSCALE,
                    152:                                    (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
                    153:                                        err(1, "humanize_number");
                    154:                                (void)printf("%*s ", dp->s_block, szbuf);
1.41      jschauma  155:                        } else {
1.50      christos  156:                                (void)printf(f_commas ? "%'*llu " : "%*llu ",
                    157:                                    dp->s_block,
                    158:                                    (unsigned long long)howmany(sp->st_blocks,
1.48      enami     159:                                    blocksize));
1.41      jschauma  160:                        }
1.38      grant     161:                }
1.5       mycroft   162:                (void)strmode(sp->st_mode, buf);
1.57    ! christos  163: #ifndef SMALL
1.56      christos  164:                aclmode(buf, p);
1.57    ! christos  165: #endif
1.5       mycroft   166:                np = p->fts_pointer;
1.34      grant     167:                (void)printf("%s %*lu ", buf, dp->s_nlink,
                    168:                    (unsigned long)sp->st_nlink);
                    169:                if (!f_grouponly)
                    170:                        (void)printf("%-*s  ", dp->s_user, np->user);
                    171:                (void)printf("%-*s  ", dp->s_group, np->group);
1.5       mycroft   172:                if (f_flags)
                    173:                        (void)printf("%-*s ", dp->s_flags, np->flags);
                    174:                if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
1.44      christos  175:                        (void)printf("%*lld, %*lld ",
                    176:                            dp->s_major, (long long)major(sp->st_rdev),
                    177:                            dp->s_minor, (long long)minor(sp->st_rdev));
1.1       cgd       178:                else
1.38      grant     179:                        if (f_humanize) {
                    180:                                if ((humanize_number(szbuf, sizeof(szbuf),
                    181:                                    sp->st_size, "", HN_AUTOSCALE,
                    182:                                    (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
                    183:                                        err(1, "humanize_number");
                    184:                                (void)printf("%*s ", dp->s_size, szbuf);
                    185:                        } else {
1.50      christos  186:                                (void)printf(f_commas ? "%'*llu " : "%*llu ",
                    187:                                    dp->s_size, (unsigned long long)
                    188:                                    sp->st_size);
1.38      grant     189:                        }
1.1       cgd       190:                if (f_accesstime)
1.5       mycroft   191:                        printtime(sp->st_atime);
1.1       cgd       192:                else if (f_statustime)
1.5       mycroft   193:                        printtime(sp->st_ctime);
1.1       cgd       194:                else
1.5       mycroft   195:                        printtime(sp->st_mtime);
1.37      jschauma  196:                if (f_octal || f_octal_escape)
1.53      christos  197:                        (void)safe_printpath(p);
1.36      jschauma  198:                else if (f_nonprint)
1.53      christos  199:                        (void)printescapedpath(p);
1.28      assar     200:                else
1.53      christos  201:                        (void)printpath(p);
1.28      assar     202:
1.26      kleink    203:                if (f_type || (f_typedir && S_ISDIR(sp->st_mode)))
1.5       mycroft   204:                        (void)printtype(sp->st_mode);
                    205:                if (S_ISLNK(sp->st_mode))
                    206:                        printlink(p);
1.1       cgd       207:                (void)putchar('\n');
                    208:        }
                    209: }
                    210:
1.5       mycroft   211: void
1.30      lukem     212: printcol(DISPLAY *dp)
1.1       cgd       213: {
1.5       mycroft   214:        static FTSENT **array;
                    215:        static int lastentries = -1;
1.11      mycroft   216:        FTSENT *p;
1.16      christos  217:        int base, chcnt, col, colwidth, num;
1.15      thorpej   218:        int numcols, numrows, row;
1.1       cgd       219:
1.19      lukem     220:        colwidth = dp->maxlen;
                    221:        if (f_inode)
                    222:                colwidth += dp->s_inode + 1;
1.38      grant     223:        if (f_size) {
                    224:                if (f_humanize)
                    225:                        colwidth += dp->s_size + 1;
                    226:                else
                    227:                        colwidth += dp->s_block + 1;
                    228:        }
1.26      kleink    229:        if (f_type || f_typedir)
1.19      lukem     230:                colwidth += 1;
                    231:
                    232:        colwidth += 1;
                    233:
                    234:        if (termwidth < 2 * colwidth) {
                    235:                printscol(dp);
                    236:                return;
                    237:        }
                    238:
1.5       mycroft   239:        /*
                    240:         * Have to do random access in the linked list -- build a table
                    241:         * of pointers.
                    242:         */
                    243:        if (dp->entries > lastentries) {
1.51      yamt      244:                FTSENT **newarray;
                    245:
                    246:                newarray = realloc(array, dp->entries * sizeof(FTSENT *));
                    247:                if (newarray == NULL) {
1.27      drochner  248:                        warn(NULL);
1.5       mycroft   249:                        printscol(dp);
1.51      yamt      250:                        return;
1.5       mycroft   251:                }
1.51      yamt      252:                lastentries = dp->entries;
                    253:                array = newarray;
1.5       mycroft   254:        }
                    255:        for (p = dp->list, num = 0; p; p = p->fts_link)
                    256:                if (p->fts_number != NO_PRINT)
                    257:                        array[num++] = p;
                    258:
1.19      lukem     259:        numcols = termwidth / colwidth;
                    260:        colwidth = termwidth / numcols;         /* spread out if possible */
                    261:        numrows = num / numcols;
                    262:        if (num % numcols)
                    263:                ++numrows;
                    264:
1.43      ahoka     265:        printtotal(dp);                         /* "total: %u\n" */
                    266:
1.19      lukem     267:        for (row = 0; row < numrows; ++row) {
                    268:                for (base = row, chcnt = col = 0; col < numcols; ++col) {
                    269:                        chcnt = printaname(array[base], dp->s_inode,
1.38      grant     270:                            f_humanize ? dp->s_size : dp->s_block);
1.19      lukem     271:                        if ((base += numrows) >= num)
                    272:                                break;
                    273:                        while (chcnt++ < colwidth)
1.22      mycroft   274:                                (void)putchar(' ');
1.19      lukem     275:                }
                    276:                (void)putchar('\n');
                    277:        }
                    278: }
                    279:
                    280: void
1.30      lukem     281: printacol(DISPLAY *dp)
1.19      lukem     282: {
                    283:        FTSENT *p;
                    284:        int chcnt, col, colwidth;
                    285:        int numcols;
                    286:
1.5       mycroft   287:        colwidth = dp->maxlen;
1.1       cgd       288:        if (f_inode)
1.5       mycroft   289:                colwidth += dp->s_inode + 1;
1.38      grant     290:        if (f_size) {
                    291:                if (f_humanize)
                    292:                        colwidth += dp->s_size + 1;
                    293:                else
                    294:                        colwidth += dp->s_block + 1;
                    295:        }
1.26      kleink    296:        if (f_type || f_typedir)
1.1       cgd       297:                colwidth += 1;
                    298:
1.15      thorpej   299:        colwidth += 1;
                    300:
1.1       cgd       301:        if (termwidth < 2 * colwidth) {
1.5       mycroft   302:                printscol(dp);
1.1       cgd       303:                return;
                    304:        }
                    305:
                    306:        numcols = termwidth / colwidth;
1.15      thorpej   307:        colwidth = termwidth / numcols;         /* spread out if possible */
1.1       cgd       308:
1.43      ahoka     309:        printtotal(dp);                         /* "total: %u\n" */
                    310:
1.19      lukem     311:        chcnt = col = 0;
                    312:        for (p = dp->list; p; p = p->fts_link) {
                    313:                if (IS_NOPRINT(p))
                    314:                        continue;
                    315:                if (col >= numcols) {
                    316:                        chcnt = col = 0;
1.22      mycroft   317:                        (void)putchar('\n');
1.1       cgd       318:                }
1.38      grant     319:                chcnt = printaname(p, dp->s_inode,
                    320:                    f_humanize ? dp->s_size : dp->s_block);
1.19      lukem     321:                while (chcnt++ < colwidth)
1.22      mycroft   322:                        (void)putchar(' ');
1.19      lukem     323:                col++;
1.25      kleink    324:        }
                    325:        (void)putchar('\n');
                    326: }
                    327:
                    328: void
1.30      lukem     329: printstream(DISPLAY *dp)
1.25      kleink    330: {
                    331:        FTSENT *p;
                    332:        int col;
                    333:        int extwidth;
                    334:
                    335:        extwidth = 0;
                    336:        if (f_inode)
                    337:                extwidth += dp->s_inode + 1;
1.38      grant     338:        if (f_size) {
                    339:                if (f_humanize)
                    340:                        extwidth += dp->s_size + 1;
                    341:                else
                    342:                        extwidth += dp->s_block + 1;
                    343:        }
1.25      kleink    344:        if (f_type)
                    345:                extwidth += 1;
                    346:
                    347:        for (col = 0, p = dp->list; p != NULL; p = p->fts_link) {
                    348:                if (IS_NOPRINT(p))
                    349:                        continue;
                    350:                if (col > 0) {
                    351:                        (void)putchar(','), col++;
1.45      lukem     352:                        if (col + 1 + extwidth + (int)p->fts_namelen >= termwidth)
1.25      kleink    353:                                (void)putchar('\n'), col = 0;
                    354:                        else
                    355:                                (void)putchar(' '), col++;
                    356:                }
1.38      grant     357:                col += printaname(p, dp->s_inode,
                    358:                    f_humanize ? dp->s_size : dp->s_block);
1.1       cgd       359:        }
1.22      mycroft   360:        (void)putchar('\n');
1.1       cgd       361: }
                    362:
                    363: /*
                    364:  * print [inode] [size] name
1.5       mycroft   365:  * return # of characters printed, no trailing characters.
1.1       cgd       366:  */
1.5       mycroft   367: static int
1.30      lukem     368: printaname(FTSENT *p, int inodefield, int sizefield)
1.1       cgd       369: {
1.5       mycroft   370:        struct stat *sp;
1.1       cgd       371:        int chcnt;
1.38      grant     372:        char szbuf[5];
1.1       cgd       373:
1.5       mycroft   374:        sp = p->fts_statp;
1.1       cgd       375:        chcnt = 0;
                    376:        if (f_inode)
1.55      martin    377:                chcnt += printf("%*"PRIu64" ", inodefield, sp->st_ino);
1.38      grant     378:        if (f_size) {
                    379:                if (f_humanize) {
                    380:                        if ((humanize_number(szbuf, sizeof(szbuf), sp->st_size,
                    381:                            "", HN_AUTOSCALE,
                    382:                            (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
                    383:                                err(1, "humanize_number");
                    384:                        chcnt += printf("%*s ", sizefield, szbuf);
                    385:                } else {
1.50      christos  386:                        chcnt += printf(f_commas ? "%'*llu " : "%*llu ",
                    387:                            sizefield, (unsigned long long)
                    388:                            howmany(sp->st_blocks, blocksize));
1.38      grant     389:                }
                    390:        }
1.37      jschauma  391:        if (f_octal || f_octal_escape)
1.53      christos  392:                chcnt += safe_printpath(p);
1.36      jschauma  393:        else if (f_nonprint)
1.53      christos  394:                chcnt += printescapedpath(p);
1.29      assar     395:        else
1.53      christos  396:                chcnt += printpath(p);
1.26      kleink    397:        if (f_type || (f_typedir && S_ISDIR(sp->st_mode)))
1.5       mycroft   398:                chcnt += printtype(sp->st_mode);
                    399:        return (chcnt);
1.1       cgd       400: }
                    401:
1.5       mycroft   402: static void
1.30      lukem     403: printtime(time_t ftime)
1.1       cgd       404: {
                    405:        int i;
1.46      christos  406:        const char *longstring;
1.1       cgd       407:
1.47      christos  408:        if ((longstring = ctime(&ftime)) == NULL) {
1.46      christos  409:                           /* 012345678901234567890123 */
                    410:                longstring = "????????????????????????";
                    411:        }
1.1       cgd       412:        for (i = 4; i < 11; ++i)
                    413:                (void)putchar(longstring[i]);
                    414:
                    415: #define        SIXMONTHS       ((DAYSPERNYEAR / 2) * SECSPERDAY)
                    416:        if (f_sectime)
                    417:                for (i = 11; i < 24; i++)
                    418:                        (void)putchar(longstring[i]);
1.40      mycroft   419:        else if (ftime + SIXMONTHS > now && ftime - SIXMONTHS < now)
1.1       cgd       420:                for (i = 11; i < 16; ++i)
                    421:                        (void)putchar(longstring[i]);
                    422:        else {
                    423:                (void)putchar(' ');
                    424:                for (i = 20; i < 24; ++i)
                    425:                        (void)putchar(longstring[i]);
                    426:        }
                    427:        (void)putchar(' ');
                    428: }
                    429:
1.43      ahoka     430: /*
                    431:  * Display total used disk space in the form "total: %u\n".
                    432:  * Note: POSIX (IEEE Std 1003.1-2001) says this should be always in 512 blocks,
1.49      erh       433:  * but we humanise it with -h, or separate it with commas with -M, and use 1024
                    434:  * with -k.
1.43      ahoka     435:  */
                    436: static void
                    437: printtotal(DISPLAY *dp)
                    438: {
                    439:        char szbuf[5];
                    440:
                    441:        if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
                    442:                if (f_humanize) {
                    443:                        if ((humanize_number(szbuf, sizeof(szbuf), (int64_t)dp->stotal,
                    444:                            "", HN_AUTOSCALE,
                    445:                            (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
                    446:                                err(1, "humanize_number");
                    447:                        (void)printf("total %s\n", szbuf);
                    448:                } else {
1.50      christos  449:                        (void)printf(f_commas ? "total %'llu\n" :
                    450:                            "total %llu\n", (unsigned long long)
                    451:                            howmany(dp->btotal, blocksize));
1.43      ahoka     452:                }
                    453:        }
                    454: }
                    455:
1.5       mycroft   456: static int
1.30      lukem     457: printtype(u_int mode)
1.1       cgd       458: {
1.11      mycroft   459:        switch (mode & S_IFMT) {
1.1       cgd       460:        case S_IFDIR:
                    461:                (void)putchar('/');
1.5       mycroft   462:                return (1);
1.11      mycroft   463:        case S_IFIFO:
                    464:                (void)putchar('|');
                    465:                return (1);
1.1       cgd       466:        case S_IFLNK:
                    467:                (void)putchar('@');
1.5       mycroft   468:                return (1);
1.1       cgd       469:        case S_IFSOCK:
                    470:                (void)putchar('=');
1.12      mycroft   471:                return (1);
                    472:        case S_IFWHT:
                    473:                (void)putchar('%');
1.6       jtc       474:                return (1);
1.1       cgd       475:        }
                    476:        if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
                    477:                (void)putchar('*');
1.5       mycroft   478:                return (1);
1.1       cgd       479:        }
1.5       mycroft   480:        return (0);
1.1       cgd       481: }
                    482:
1.5       mycroft   483: static void
1.30      lukem     484: printlink(FTSENT *p)
1.1       cgd       485: {
                    486:        int lnklen;
1.5       mycroft   487:        char name[MAXPATHLEN + 1], path[MAXPATHLEN + 1];
                    488:
                    489:        if (p->fts_level == FTS_ROOTLEVEL)
                    490:                (void)snprintf(name, sizeof(name), "%s", p->fts_name);
1.33      enami     491:        else
1.11      mycroft   492:                (void)snprintf(name, sizeof(name),
                    493:                    "%s/%s", p->fts_parent->fts_accpath, p->fts_name);
                    494:        if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
1.1       cgd       495:                (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
                    496:                return;
                    497:        }
                    498:        path[lnklen] = '\0';
1.28      assar     499:        (void)printf(" -> ");
1.37      jschauma  500:        if (f_octal || f_octal_escape)
1.36      jschauma  501:                (void)safe_print(path);
                    502:        else if (f_nonprint)
                    503:                (void)printescaped(path);
1.28      assar     504:        else
                    505:                (void)printf("%s", path);
1.1       cgd       506: }
1.56      christos  507:
1.57    ! christos  508: #ifndef SMALL
1.56      christos  509: /*
                    510:  * Add a + after the standard rwxrwxrwx mode if the file has an
                    511:  * ACL. strmode() reserves space at the end of the string.
                    512:  */
                    513: static void
                    514: aclmode(char *buf, const FTSENT *p)
                    515: {
                    516:        char name[MAXPATHLEN + 1];
                    517:        int ret, trivial;
                    518:        static dev_t previous_dev = NODEV;
                    519:        static int supports_acls = -1;
                    520:        static int type = ACL_TYPE_ACCESS;
                    521:        acl_t facl;
                    522:
                    523:        /*
                    524:         * XXX: ACLs are not supported on whiteouts and device files
                    525:         * residing on UFS.
                    526:         */
                    527:        if (S_ISCHR(p->fts_statp->st_mode) || S_ISBLK(p->fts_statp->st_mode) ||
                    528:            S_ISWHT(p->fts_statp->st_mode))
                    529:                return;
                    530:
                    531:        if (previous_dev == p->fts_statp->st_dev && supports_acls == 0)
                    532:                return;
                    533:
                    534:        if (p->fts_level == FTS_ROOTLEVEL)
                    535:                snprintf(name, sizeof(name), "%s", p->fts_name);
                    536:        else
                    537:                snprintf(name, sizeof(name), "%s/%s",
                    538:                    p->fts_parent->fts_accpath, p->fts_name);
                    539:
                    540:        if (supports_acls == -1 || previous_dev != p->fts_statp->st_dev) {
                    541:                previous_dev = p->fts_statp->st_dev;
                    542:                supports_acls = 0;
                    543:
                    544:                ret = lpathconf(name, _PC_ACL_NFS4);
                    545:                if (ret > 0) {
                    546:                        type = ACL_TYPE_NFS4;
                    547:                        supports_acls = 1;
                    548:                } else if (ret < 0 && errno != EINVAL) {
                    549:                        warn("%s", name);
                    550:                        return;
                    551:                }
                    552:                if (supports_acls == 0) {
                    553:                        ret = lpathconf(name, _PC_ACL_EXTENDED);
                    554:                        if (ret > 0) {
                    555:                                type = ACL_TYPE_ACCESS;
                    556:                                supports_acls = 1;
                    557:                        } else if (ret < 0 && errno != EINVAL) {
                    558:                                warn("%s", name);
                    559:                                return;
                    560:                        }
                    561:                }
                    562:        }
                    563:        if (supports_acls == 0)
                    564:                return;
                    565:        facl = acl_get_link_np(name, type);
                    566:        if (facl == NULL) {
                    567:                warn("%s", name);
                    568:                return;
                    569:        }
                    570:        if (acl_is_trivial_np(facl, &trivial)) {
                    571:                acl_free(facl);
                    572:                warn("%s", name);
                    573:                return;
                    574:        }
                    575:        if (!trivial)
                    576:                buf[10] = '+';
                    577:        acl_free(facl);
                    578: }
1.57    ! christos  579: #endif

CVSweb <webmaster@jp.NetBSD.org>