Blame lib/filemode.c

Packit 8f70b4
/* filemode.c -- make a string describing file modes
Packit 8f70b4
Packit 8f70b4
   Copyright (C) 1985, 1990, 1993, 1998-2000, 2004, 2006, 2009-2018 Free
Packit 8f70b4
   Software Foundation, Inc.
Packit 8f70b4
Packit 8f70b4
   This program is free software: you can redistribute it and/or modify
Packit 8f70b4
   it under the terms of the GNU General Public License as published by
Packit 8f70b4
   the Free Software Foundation; either version 3 of the License, or
Packit 8f70b4
   (at your option) any later version.
Packit 8f70b4
Packit 8f70b4
   This program is distributed in the hope that it will be useful,
Packit 8f70b4
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 8f70b4
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 8f70b4
   GNU General Public License for more details.
Packit 8f70b4
Packit 8f70b4
   You should have received a copy of the GNU General Public License
Packit 8f70b4
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit 8f70b4
Packit 8f70b4
#include <config.h>
Packit 8f70b4
Packit 8f70b4
#include "filemode.h"
Packit 8f70b4
Packit 8f70b4
/* The following is for Cray DMF (Data Migration Facility), which is a
Packit 8f70b4
   HSM file system.  A migrated file has a 'st_dm_mode' that is
Packit 8f70b4
   different from the normal 'st_mode', so any tests for migrated
Packit 8f70b4
   files should use the former.  */
Packit 8f70b4
#if HAVE_ST_DM_MODE
Packit 8f70b4
# define IS_MIGRATED_FILE(statp) \
Packit 8f70b4
    (S_ISOFD (statp->st_dm_mode) || S_ISOFL (statp->st_dm_mode))
Packit 8f70b4
#else
Packit 8f70b4
# define IS_MIGRATED_FILE(statp) 0
Packit 8f70b4
#endif
Packit 8f70b4
Packit 8f70b4
#if ! HAVE_DECL_STRMODE
Packit 8f70b4
Packit 8f70b4
/* Return a character indicating the type of file described by
Packit 8f70b4
   file mode BITS:
Packit 8f70b4
   '-' regular file
Packit 8f70b4
   'b' block special file
Packit 8f70b4
   'c' character special file
Packit 8f70b4
   'C' high performance ("contiguous data") file
Packit 8f70b4
   'd' directory
Packit 8f70b4
   'D' door
Packit 8f70b4
   'l' symbolic link
Packit 8f70b4
   'm' multiplexed file (7th edition Unix; obsolete)
Packit 8f70b4
   'n' network special file (HP-UX)
Packit 8f70b4
   'p' fifo (named pipe)
Packit 8f70b4
   'P' port
Packit 8f70b4
   's' socket
Packit 8f70b4
   'w' whiteout (4.4BSD)
Packit 8f70b4
   '?' some other file type  */
Packit 8f70b4
Packit 8f70b4
static char
Packit 8f70b4
ftypelet (mode_t bits)
Packit 8f70b4
{
Packit 8f70b4
  /* These are the most common, so test for them first.  */
Packit 8f70b4
  if (S_ISREG (bits))
Packit 8f70b4
    return '-';
Packit 8f70b4
  if (S_ISDIR (bits))
Packit 8f70b4
    return 'd';
Packit 8f70b4
Packit 8f70b4
  /* Other letters standardized by POSIX 1003.1-2004.  */
Packit 8f70b4
  if (S_ISBLK (bits))
Packit 8f70b4
    return 'b';
Packit 8f70b4
  if (S_ISCHR (bits))
Packit 8f70b4
    return 'c';
Packit 8f70b4
  if (S_ISLNK (bits))
Packit 8f70b4
    return 'l';
Packit 8f70b4
  if (S_ISFIFO (bits))
Packit 8f70b4
    return 'p';
Packit 8f70b4
Packit 8f70b4
  /* Other file types (though not letters) standardized by POSIX.  */
Packit 8f70b4
  if (S_ISSOCK (bits))
Packit 8f70b4
    return 's';
Packit 8f70b4
Packit 8f70b4
  /* Nonstandard file types.  */
Packit 8f70b4
  if (S_ISCTG (bits))
Packit 8f70b4
    return 'C';
Packit 8f70b4
  if (S_ISDOOR (bits))
Packit 8f70b4
    return 'D';
Packit 8f70b4
  if (S_ISMPB (bits) || S_ISMPC (bits) || S_ISMPX (bits))
Packit 8f70b4
    return 'm';
Packit 8f70b4
  if (S_ISNWK (bits))
Packit 8f70b4
    return 'n';
Packit 8f70b4
  if (S_ISPORT (bits))
Packit 8f70b4
    return 'P';
Packit 8f70b4
  if (S_ISWHT (bits))
Packit 8f70b4
    return 'w';
Packit 8f70b4
Packit 8f70b4
  return '?';
Packit 8f70b4
}
Packit 8f70b4
Packit 8f70b4
/* Like filemodestring, but rely only on MODE.  */
Packit 8f70b4
Packit 8f70b4
void
Packit 8f70b4
strmode (mode_t mode, char *str)
Packit 8f70b4
{
Packit 8f70b4
  str[0] = ftypelet (mode);
Packit 8f70b4
  str[1] = mode & S_IRUSR ? 'r' : '-';
Packit 8f70b4
  str[2] = mode & S_IWUSR ? 'w' : '-';
Packit 8f70b4
  str[3] = (mode & S_ISUID
Packit 8f70b4
            ? (mode & S_IXUSR ? 's' : 'S')
Packit 8f70b4
            : (mode & S_IXUSR ? 'x' : '-'));
Packit 8f70b4
  str[4] = mode & S_IRGRP ? 'r' : '-';
Packit 8f70b4
  str[5] = mode & S_IWGRP ? 'w' : '-';
Packit 8f70b4
  str[6] = (mode & S_ISGID
Packit 8f70b4
            ? (mode & S_IXGRP ? 's' : 'S')
Packit 8f70b4
            : (mode & S_IXGRP ? 'x' : '-'));
Packit 8f70b4
  str[7] = mode & S_IROTH ? 'r' : '-';
Packit 8f70b4
  str[8] = mode & S_IWOTH ? 'w' : '-';
Packit 8f70b4
  str[9] = (mode & S_ISVTX
Packit 8f70b4
            ? (mode & S_IXOTH ? 't' : 'T')
Packit 8f70b4
            : (mode & S_IXOTH ? 'x' : '-'));
Packit 8f70b4
  str[10] = ' ';
Packit 8f70b4
  str[11] = '\0';
Packit 8f70b4
}
Packit 8f70b4
Packit 8f70b4
#endif /* ! HAVE_DECL_STRMODE */
Packit 8f70b4
Packit 8f70b4
/* filemodestring - fill in string STR with an ls-style ASCII
Packit 8f70b4
   representation of the st_mode field of file stats block STATP.
Packit 8f70b4
   12 characters are stored in STR.
Packit 8f70b4
   The characters stored in STR are:
Packit 8f70b4
Packit 8f70b4
   0    File type, as in ftypelet above, except that other letters are used
Packit 8f70b4
        for files whose type cannot be determined solely from st_mode:
Packit 8f70b4
Packit 8f70b4
            'F' semaphore
Packit 8f70b4
            'M' migrated file (Cray DMF)
Packit 8f70b4
            'Q' message queue
Packit 8f70b4
            'S' shared memory object
Packit 8f70b4
            'T' typed memory object
Packit 8f70b4
Packit 8f70b4
   1    'r' if the owner may read, '-' otherwise.
Packit 8f70b4
Packit 8f70b4
   2    'w' if the owner may write, '-' otherwise.
Packit 8f70b4
Packit 8f70b4
   3    'x' if the owner may execute, 's' if the file is
Packit 8f70b4
        set-user-id, '-' otherwise.
Packit 8f70b4
        'S' if the file is set-user-id, but the execute
Packit 8f70b4
        bit isn't set.
Packit 8f70b4
Packit 8f70b4
   4    'r' if group members may read, '-' otherwise.
Packit 8f70b4
Packit 8f70b4
   5    'w' if group members may write, '-' otherwise.
Packit 8f70b4
Packit 8f70b4
   6    'x' if group members may execute, 's' if the file is
Packit 8f70b4
        set-group-id, '-' otherwise.
Packit 8f70b4
        'S' if it is set-group-id but not executable.
Packit 8f70b4
Packit 8f70b4
   7    'r' if any user may read, '-' otherwise.
Packit 8f70b4
Packit 8f70b4
   8    'w' if any user may write, '-' otherwise.
Packit 8f70b4
Packit 8f70b4
   9    'x' if any user may execute, 't' if the file is "sticky"
Packit 8f70b4
        (will be retained in swap space after execution), '-'
Packit 8f70b4
        otherwise.
Packit 8f70b4
        'T' if the file is sticky but not executable.
Packit 8f70b4
Packit 8f70b4
   10   ' ' for compatibility with 4.4BSD strmode,
Packit 8f70b4
        since this interface does not support ACLs.
Packit 8f70b4
Packit 8f70b4
   11   '\0'.  */
Packit 8f70b4
Packit 8f70b4
void
Packit 8f70b4
filemodestring (struct stat const *statp, char *str)
Packit 8f70b4
{
Packit 8f70b4
  strmode (statp->st_mode, str);
Packit 8f70b4
Packit 8f70b4
  if (S_TYPEISSEM (statp))
Packit 8f70b4
    str[0] = 'F';
Packit 8f70b4
  else if (IS_MIGRATED_FILE (statp))
Packit 8f70b4
    str[0] = 'M';
Packit 8f70b4
  else if (S_TYPEISMQ (statp))
Packit 8f70b4
    str[0] = 'Q';
Packit 8f70b4
  else if (S_TYPEISSHM (statp))
Packit 8f70b4
    str[0] = 'S';
Packit 8f70b4
  else if (S_TYPEISTMO (statp))
Packit 8f70b4
    str[0] = 'T';
Packit 8f70b4
}