133965Sjdp/* filemode.c -- make a string describing file modes
2218822Sdim   Copyright 1985, 1990, 1991, 1994, 1995, 1997, 1999, 2002, 2003, 2005,
3218822Sdim   2007 Free Software Foundation, Inc.
433965Sjdp
533965Sjdp   This program is free software; you can redistribute it and/or modify
633965Sjdp   it under the terms of the GNU General Public License as published by
733965Sjdp   the Free Software Foundation; either version 2, or (at your option)
833965Sjdp   any later version.
933965Sjdp
1033965Sjdp   This program is distributed in the hope that it will be useful,
1133965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1233965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1333965Sjdp   GNU General Public License for more details.
1433965Sjdp
1533965Sjdp   You should have received a copy of the GNU General Public License
1633965Sjdp   along with this program; if not, write to the Free Software
17218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
18218822Sdim   02110-1301, USA.  */
1933965Sjdp
20218822Sdim#include "sysdep.h"
2133965Sjdp#include "bfd.h"
2233965Sjdp#include "bucomm.h"
2333965Sjdp
24130561Sobrienstatic char ftypelet (unsigned long);
25130561Sobrienstatic void setst (unsigned long, char *);
2633965Sjdp
2733965Sjdp/* filemodestring - fill in string STR with an ls-style ASCII
2833965Sjdp   representation of the st_mode field of file stats block STATP.
2933965Sjdp   10 characters are stored in STR; no terminating null is added.
3033965Sjdp   The characters stored in STR are:
3133965Sjdp
3233965Sjdp   0	File type.  'd' for directory, 'c' for character
3333965Sjdp	special, 'b' for block special, 'm' for multiplex,
3433965Sjdp	'l' for symbolic link, 's' for socket, 'p' for fifo,
3533965Sjdp	'-' for any other file type
3633965Sjdp
3733965Sjdp   1	'r' if the owner may read, '-' otherwise.
3833965Sjdp
3933965Sjdp   2	'w' if the owner may write, '-' otherwise.
4033965Sjdp
4133965Sjdp   3	'x' if the owner may execute, 's' if the file is
4233965Sjdp	set-user-id, '-' otherwise.
4333965Sjdp	'S' if the file is set-user-id, but the execute
4433965Sjdp	bit isn't set.
4533965Sjdp
4633965Sjdp   4	'r' if group members may read, '-' otherwise.
4733965Sjdp
4833965Sjdp   5	'w' if group members may write, '-' otherwise.
4933965Sjdp
5033965Sjdp   6	'x' if group members may execute, 's' if the file is
5133965Sjdp	set-group-id, '-' otherwise.
5233965Sjdp	'S' if it is set-group-id but not executable.
5333965Sjdp
5433965Sjdp   7	'r' if any user may read, '-' otherwise.
5533965Sjdp
5633965Sjdp   8	'w' if any user may write, '-' otherwise.
5733965Sjdp
5833965Sjdp   9	'x' if any user may execute, 't' if the file is "sticky"
5933965Sjdp	(will be retained in swap space after execution), '-'
6033965Sjdp	otherwise.
61104834Sobrien	'T' if the file is sticky but not executable.  */
6233965Sjdp
6333965Sjdp/* Get definitions for the file permission bits.  */
6433965Sjdp
6533965Sjdp#ifndef S_IRWXU
6633965Sjdp#define S_IRWXU 0700
6733965Sjdp#endif
6833965Sjdp#ifndef S_IRUSR
6933965Sjdp#define S_IRUSR 0400
7033965Sjdp#endif
7133965Sjdp#ifndef S_IWUSR
7233965Sjdp#define S_IWUSR 0200
7333965Sjdp#endif
7433965Sjdp#ifndef S_IXUSR
7533965Sjdp#define S_IXUSR 0100
7633965Sjdp#endif
7733965Sjdp
7833965Sjdp#ifndef S_IRWXG
7933965Sjdp#define S_IRWXG 0070
8033965Sjdp#endif
8133965Sjdp#ifndef S_IRGRP
8233965Sjdp#define S_IRGRP 0040
8333965Sjdp#endif
8433965Sjdp#ifndef S_IWGRP
8533965Sjdp#define S_IWGRP 0020
8633965Sjdp#endif
8733965Sjdp#ifndef S_IXGRP
8833965Sjdp#define S_IXGRP 0010
8933965Sjdp#endif
9033965Sjdp
9133965Sjdp#ifndef S_IRWXO
9233965Sjdp#define S_IRWXO 0007
9333965Sjdp#endif
9433965Sjdp#ifndef S_IROTH
9533965Sjdp#define S_IROTH 0004
9633965Sjdp#endif
9733965Sjdp#ifndef S_IWOTH
9833965Sjdp#define S_IWOTH 0002
9933965Sjdp#endif
10033965Sjdp#ifndef S_IXOTH
10133965Sjdp#define S_IXOTH 0001
10233965Sjdp#endif
10333965Sjdp
10433965Sjdp/* Like filemodestring, but only the relevant part of the `struct stat'
105104834Sobrien   is given as an argument.  */
10633965Sjdp
10733965Sjdpvoid
108130561Sobrienmode_string (unsigned long mode, char *str)
10933965Sjdp{
11033965Sjdp  str[0] = ftypelet ((unsigned long) mode);
11133965Sjdp  str[1] = (mode & S_IRUSR) != 0 ? 'r' : '-';
11233965Sjdp  str[2] = (mode & S_IWUSR) != 0 ? 'w' : '-';
11333965Sjdp  str[3] = (mode & S_IXUSR) != 0 ? 'x' : '-';
11433965Sjdp  str[4] = (mode & S_IRGRP) != 0 ? 'r' : '-';
11533965Sjdp  str[5] = (mode & S_IWGRP) != 0 ? 'w' : '-';
11633965Sjdp  str[6] = (mode & S_IXGRP) != 0 ? 'x' : '-';
11733965Sjdp  str[7] = (mode & S_IROTH) != 0 ? 'r' : '-';
11833965Sjdp  str[8] = (mode & S_IWOTH) != 0 ? 'w' : '-';
11933965Sjdp  str[9] = (mode & S_IXOTH) != 0 ? 'x' : '-';
12033965Sjdp  setst ((unsigned long) mode, str);
12133965Sjdp}
12233965Sjdp
12333965Sjdp/* Return a character indicating the type of file described by
12433965Sjdp   file mode BITS:
12533965Sjdp   'd' for directories
12633965Sjdp   'b' for block special files
12733965Sjdp   'c' for character special files
128130561Sobrien   'm' for multiplexer files
12933965Sjdp   'l' for symbolic links
13033965Sjdp   's' for sockets
13133965Sjdp   'p' for fifos
132104834Sobrien   '-' for any other file type.  */
13333965Sjdp
13433965Sjdp#ifndef S_ISDIR
13533965Sjdp#ifdef S_IFDIR
13633965Sjdp#define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR)
13733965Sjdp#else /* ! defined (S_IFDIR) */
13833965Sjdp#define S_ISDIR(i) (((i) & 0170000) == 040000)
13933965Sjdp#endif /* ! defined (S_IFDIR) */
14033965Sjdp#endif /* ! defined (S_ISDIR) */
14133965Sjdp
14233965Sjdp#ifndef S_ISBLK
14333965Sjdp#ifdef S_IFBLK
14433965Sjdp#define S_ISBLK(i) (((i) & S_IFMT) == S_IFBLK)
14533965Sjdp#else /* ! defined (S_IFBLK) */
14633965Sjdp#define S_ISBLK(i) 0
14733965Sjdp#endif /* ! defined (S_IFBLK) */
14833965Sjdp#endif /* ! defined (S_ISBLK) */
14933965Sjdp
15033965Sjdp#ifndef S_ISCHR
15133965Sjdp#ifdef S_IFCHR
15233965Sjdp#define S_ISCHR(i) (((i) & S_IFMT) == S_IFCHR)
15333965Sjdp#else /* ! defined (S_IFCHR) */
15433965Sjdp#define S_ISCHR(i) 0
15533965Sjdp#endif /* ! defined (S_IFCHR) */
15633965Sjdp#endif /* ! defined (S_ISCHR) */
15733965Sjdp
15833965Sjdp#ifndef S_ISFIFO
15933965Sjdp#ifdef S_IFIFO
16033965Sjdp#define S_ISFIFO(i) (((i) & S_IFMT) == S_IFIFO)
16133965Sjdp#else /* ! defined (S_IFIFO) */
16233965Sjdp#define S_ISFIFO(i) 0
16333965Sjdp#endif /* ! defined (S_IFIFO) */
16433965Sjdp#endif /* ! defined (S_ISFIFO) */
16533965Sjdp
16633965Sjdp#ifndef S_ISSOCK
16733965Sjdp#ifdef S_IFSOCK
16833965Sjdp#define S_ISSOCK(i) (((i) & S_IFMT) == S_IFSOCK)
16933965Sjdp#else /* ! defined (S_IFSOCK) */
17033965Sjdp#define S_ISSOCK(i) 0
17133965Sjdp#endif /* ! defined (S_IFSOCK) */
17233965Sjdp#endif /* ! defined (S_ISSOCK) */
17333965Sjdp
17433965Sjdp#ifndef S_ISLNK
17533965Sjdp#ifdef S_IFLNK
17633965Sjdp#define S_ISLNK(i) (((i) & S_IFMT) == S_IFLNK)
17733965Sjdp#else /* ! defined (S_IFLNK) */
17833965Sjdp#define S_ISLNK(i) 0
17933965Sjdp#endif /* ! defined (S_IFLNK) */
18033965Sjdp#endif /* ! defined (S_ISLNK) */
18133965Sjdp
18233965Sjdpstatic char
183130561Sobrienftypelet (unsigned long bits)
18433965Sjdp{
18533965Sjdp  if (S_ISDIR (bits))
18633965Sjdp    return 'd';
18733965Sjdp  if (S_ISLNK (bits))
18833965Sjdp    return 'l';
18933965Sjdp  if (S_ISBLK (bits))
19033965Sjdp    return 'b';
19133965Sjdp  if (S_ISCHR (bits))
19233965Sjdp    return 'c';
19333965Sjdp  if (S_ISSOCK (bits))
19433965Sjdp    return 's';
19533965Sjdp  if (S_ISFIFO (bits))
19633965Sjdp    return 'p';
19733965Sjdp
19833965Sjdp#ifdef S_IFMT
19933965Sjdp#ifdef S_IFMPC
20033965Sjdp  if ((bits & S_IFMT) == S_IFMPC
20133965Sjdp      || (bits & S_IFMT) == S_IFMPB)
20233965Sjdp    return 'm';
20333965Sjdp#endif
20433965Sjdp#ifdef S_IFNWK
20533965Sjdp  if ((bits & S_IFMT) == S_IFNWK)
20633965Sjdp    return 'n';
20733965Sjdp#endif
20833965Sjdp#endif
20933965Sjdp
21033965Sjdp  return '-';
21133965Sjdp}
21233965Sjdp
21333965Sjdp/* Set the 's' and 't' flags in file attributes string CHARS,
214104834Sobrien   according to the file mode BITS.  */
21533965Sjdp
21633965Sjdpstatic void
217130561Sobriensetst (unsigned long bits ATTRIBUTE_UNUSED, char *chars ATTRIBUTE_UNUSED)
21833965Sjdp{
21933965Sjdp#ifdef S_ISUID
22033965Sjdp  if (bits & S_ISUID)
22133965Sjdp    {
22233965Sjdp      if (chars[3] != 'x')
223104834Sobrien	/* Set-uid, but not executable by owner.  */
22433965Sjdp	chars[3] = 'S';
22533965Sjdp      else
22633965Sjdp	chars[3] = 's';
22733965Sjdp    }
22833965Sjdp#endif
22933965Sjdp#ifdef S_ISGID
23033965Sjdp  if (bits & S_ISGID)
23133965Sjdp    {
23233965Sjdp      if (chars[6] != 'x')
233104834Sobrien	/* Set-gid, but not executable by group.  */
23433965Sjdp	chars[6] = 'S';
23533965Sjdp      else
23633965Sjdp	chars[6] = 's';
23733965Sjdp    }
23833965Sjdp#endif
23933965Sjdp#ifdef S_ISVTX
24033965Sjdp  if (bits & S_ISVTX)
24133965Sjdp    {
24233965Sjdp      if (chars[9] != 'x')
243104834Sobrien	/* Sticky, but not executable by others.  */
24433965Sjdp	chars[9] = 'T';
24533965Sjdp      else
24633965Sjdp	chars[9] = 't';
24733965Sjdp    }
24833965Sjdp#endif
24933965Sjdp}
250