Switching to GPL 3.
[rsync/rsync.git] / lib / permstring.c
1 /*
2  * A single utility routine.
3  *
4  * Copyright (C) 1996 Andrew Tridgell
5  * Copyright (C) 1996 Paul Mackerras
6  * Copyright (C) 2001 Martin Pool <mbp@samba.org>
7  * Copyright (C) 2003, 2006 Wayne Davison
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 3 as
11  * published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, visit the http://fsf.org website.
20  */
21
22 #include "rsync.h"
23
24 /* Produce a string representation of Unix mode bits like that used by ls(1).
25  * The "buf" buffer must be at least 11 characters. */
26 void permstring(char *perms, mode_t mode)
27 {
28         static const char *perm_map = "rwxrwxrwx";
29         int i;
30
31         strlcpy(perms, "----------", 11);
32
33         for (i = 0; i < 9; i++) {
34                 if (mode & (1 << i))
35                         perms[9-i] = perm_map[8-i];
36         }
37
38         /* Handle setuid/sticky bits.  You might think the indices are
39          * off by one, but remember there's a type char at the
40          * start.  */
41         if (mode & S_ISUID)
42                 perms[3] = (mode & S_IXUSR) ? 's' : 'S';
43
44         if (mode & S_ISGID)
45                 perms[6] = (mode & S_IXGRP) ? 's' : 'S';
46
47 #ifdef S_ISVTX
48         if (mode & S_ISVTX)
49                 perms[9] = (mode & S_IXOTH) ? 't' : 'T';
50 #endif
51
52         if (S_ISDIR(mode))
53                 perms[0] = 'd';
54         else if (S_ISLNK(mode))
55                 perms[0] = 'l';
56         else if (S_ISBLK(mode))
57                 perms[0] = 'b';
58         else if (S_ISCHR(mode))
59                 perms[0] = 'c';
60         else if (S_ISSOCK(mode))
61                 perms[0] = 's';
62         else if (S_ISFIFO(mode))
63                 perms[0] = 'p';
64 }