Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/coreutils/src/gnulib/lib/modechange.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* modechange.c -- file mode manipulation | - | ||||||||||||||||||
2 | - | |||||||||||||||||||
3 | Copyright (C) 1989-1990, 1997-1999, 2001, 2003-2006, 2009-2018 Free Software | - | ||||||||||||||||||
4 | Foundation, Inc. | - | ||||||||||||||||||
5 | - | |||||||||||||||||||
6 | This program is free software: you can redistribute it and/or modify | - | ||||||||||||||||||
7 | it under the terms of the GNU General Public License as published by | - | ||||||||||||||||||
8 | the Free Software Foundation; either version 3 of the License, or | - | ||||||||||||||||||
9 | (at your option) any later version. | - | ||||||||||||||||||
10 | - | |||||||||||||||||||
11 | This program is distributed in the hope that it will be useful, | - | ||||||||||||||||||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | ||||||||||||||||||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | ||||||||||||||||||
14 | GNU General Public License for more details. | - | ||||||||||||||||||
15 | - | |||||||||||||||||||
16 | You should have received a copy of the GNU General Public License | - | ||||||||||||||||||
17 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | - | ||||||||||||||||||
18 | - | |||||||||||||||||||
19 | /* Written by David MacKenzie <djm@ai.mit.edu> */ | - | ||||||||||||||||||
20 | - | |||||||||||||||||||
21 | /* The ASCII mode string is compiled into an array of 'struct | - | ||||||||||||||||||
22 | modechange', which can then be applied to each file to be changed. | - | ||||||||||||||||||
23 | We do this instead of re-parsing the ASCII string for each file | - | ||||||||||||||||||
24 | because the compiled form requires less computation to use; when | - | ||||||||||||||||||
25 | changing the mode of many files, this probably results in a | - | ||||||||||||||||||
26 | performance gain. */ | - | ||||||||||||||||||
27 | - | |||||||||||||||||||
28 | #include <config.h> | - | ||||||||||||||||||
29 | - | |||||||||||||||||||
30 | #include "modechange.h" | - | ||||||||||||||||||
31 | #include <sys/stat.h> | - | ||||||||||||||||||
32 | #include "stat-macros.h" | - | ||||||||||||||||||
33 | #include "xalloc.h" | - | ||||||||||||||||||
34 | #include <stdlib.h> | - | ||||||||||||||||||
35 | - | |||||||||||||||||||
36 | /* The traditional octal values corresponding to each mode bit. */ | - | ||||||||||||||||||
37 | #define SUID 04000 | - | ||||||||||||||||||
38 | #define SGID 02000 | - | ||||||||||||||||||
39 | #define SVTX 01000 | - | ||||||||||||||||||
40 | #define RUSR 00400 | - | ||||||||||||||||||
41 | #define WUSR 00200 | - | ||||||||||||||||||
42 | #define XUSR 00100 | - | ||||||||||||||||||
43 | #define RGRP 00040 | - | ||||||||||||||||||
44 | #define WGRP 00020 | - | ||||||||||||||||||
45 | #define XGRP 00010 | - | ||||||||||||||||||
46 | #define ROTH 00004 | - | ||||||||||||||||||
47 | #define WOTH 00002 | - | ||||||||||||||||||
48 | #define XOTH 00001 | - | ||||||||||||||||||
49 | #define ALLM 07777 /* all octal mode bits */ | - | ||||||||||||||||||
50 | - | |||||||||||||||||||
51 | /* Convert OCTAL, which uses one of the traditional octal values, to | - | ||||||||||||||||||
52 | an internal mode_t value. */ | - | ||||||||||||||||||
53 | static mode_t | - | ||||||||||||||||||
54 | octal_to_mode (unsigned int octal) | - | ||||||||||||||||||
55 | { | - | ||||||||||||||||||
56 | /* Help the compiler optimize the usual case where mode_t uses | - | ||||||||||||||||||
57 | the traditional octal representation. */ | - | ||||||||||||||||||
58 | return ((S_ISUID == SUID && S_ISGID == SGID && S_ISVTX == SVTX executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
59 | && S_IRUSR == RUSR && S_IWUSR == WUSR && S_IXUSR == XUSR executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
60 | && S_IRGRP == RGRP && S_IWGRP == WGRP && S_IXGRP == XGRP executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
61 | && S_IROTH == ROTH && S_IWOTH == WOTH && S_IXOTH == XOTH) executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
62 | ? octal executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
63 | : (mode_t) ((octal & SUID ? S_ISUID : 0) executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
64 | | (octal & SGID ? S_ISGID : 0) executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
65 | | (octal & SVTX ? S_ISVTX : 0) executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
66 | | (octal & RUSR ? S_IRUSR : 0) executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
67 | | (octal & WUSR ? S_IWUSR : 0) executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
68 | | (octal & XUSR ? S_IXUSR : 0) executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
69 | | (octal & RGRP ? S_IRGRP : 0) executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
70 | | (octal & WGRP ? S_IWGRP : 0) executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
71 | | (octal & XGRP ? S_IXGRP : 0) executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
72 | | (octal & ROTH ? S_IROTH : 0) executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
73 | | (octal & WOTH ? S_IWOTH : 0) executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
74 | | (octal & XOTH ? S_IXOTH : 0))); executed 89 times by 3 tests: return (( 04000 == 04000 && 02000 == 02000 && 01000 == 01000 && 0400 == 00400 && 0200 == 00200 && 0100 == 00100 && (0400 >> 3) == 00040 && (0200 >> 3) == 00020 && (0100 >> 3) == 00010 && ((0400 >> 3) >> 3) == 00004 && ((0200 >> 3) >> 3) == 00002 && ((0100...100 ? 0100 : 0) | (octal & 00040 ? (0400 >> 3) : 0) | (octal & 00020 ? (0200 >> 3) : 0) | (octal & 00010 ? (0100 >> 3) : 0) | (octal & 00004 ? ((0400 >> 3) >> 3) : 0) | (octal & 00002 ? ((0200 >> 3) >> 3) : 0) | (octal & 00001 ? ((0100 >> 3) >> 3) : 0))); Executed by:
| 89 | ||||||||||||||||||
75 | } | - | ||||||||||||||||||
76 | - | |||||||||||||||||||
77 | /* Special operations flags. */ | - | ||||||||||||||||||
78 | enum | - | ||||||||||||||||||
79 | { | - | ||||||||||||||||||
80 | /* For the sentinel at the end of the mode changes array. */ | - | ||||||||||||||||||
81 | MODE_DONE, | - | ||||||||||||||||||
82 | - | |||||||||||||||||||
83 | /* The typical case. */ | - | ||||||||||||||||||
84 | MODE_ORDINARY_CHANGE, | - | ||||||||||||||||||
85 | - | |||||||||||||||||||
86 | /* In addition to the typical case, affect the execute bits if at | - | ||||||||||||||||||
87 | least one execute bit is set already, or if the file is a | - | ||||||||||||||||||
88 | directory. */ | - | ||||||||||||||||||
89 | MODE_X_IF_ANY_X, | - | ||||||||||||||||||
90 | - | |||||||||||||||||||
91 | /* Instead of the typical case, copy some existing permissions for | - | ||||||||||||||||||
92 | u, g, or o onto the other two. Which of u, g, or o is copied | - | ||||||||||||||||||
93 | is determined by which bits are set in the 'value' field. */ | - | ||||||||||||||||||
94 | MODE_COPY_EXISTING | - | ||||||||||||||||||
95 | }; | - | ||||||||||||||||||
96 | - | |||||||||||||||||||
97 | /* Description of a mode change. */ | - | ||||||||||||||||||
98 | struct mode_change | - | ||||||||||||||||||
99 | { | - | ||||||||||||||||||
100 | char op; /* One of "=+-". */ | - | ||||||||||||||||||
101 | char flag; /* Special operations flag. */ | - | ||||||||||||||||||
102 | mode_t affected; /* Set for u, g, o, or a. */ | - | ||||||||||||||||||
103 | mode_t value; /* Bits to add/remove. */ | - | ||||||||||||||||||
104 | mode_t mentioned; /* Bits explicitly mentioned. */ | - | ||||||||||||||||||
105 | }; | - | ||||||||||||||||||
106 | - | |||||||||||||||||||
107 | /* Return a mode_change array with the specified "=ddd"-style | - | ||||||||||||||||||
108 | mode change operation, where NEW_MODE is "ddd" and MENTIONED | - | ||||||||||||||||||
109 | contains the bits explicitly mentioned in the mode are MENTIONED. */ | - | ||||||||||||||||||
110 | - | |||||||||||||||||||
111 | static struct mode_change * | - | ||||||||||||||||||
112 | make_node_op_equals (mode_t new_mode, mode_t mentioned) | - | ||||||||||||||||||
113 | { | - | ||||||||||||||||||
114 | struct mode_change *p = xmalloc (2 * sizeof *p); | - | ||||||||||||||||||
115 | p->op = '='; | - | ||||||||||||||||||
116 | p->flag = MODE_ORDINARY_CHANGE; | - | ||||||||||||||||||
117 | p->affected = CHMOD_MODE_BITS; | - | ||||||||||||||||||
118 | p->value = new_mode; | - | ||||||||||||||||||
119 | p->mentioned = mentioned; | - | ||||||||||||||||||
120 | p[1].flag = MODE_DONE; | - | ||||||||||||||||||
121 | return p; executed 69 times by 3 tests: return p; Executed by:
| 69 | ||||||||||||||||||
122 | } | - | ||||||||||||||||||
123 | - | |||||||||||||||||||
124 | /* Return a pointer to an array of file mode change operations created from | - | ||||||||||||||||||
125 | MODE_STRING, an ASCII string that contains either an octal number | - | ||||||||||||||||||
126 | specifying an absolute mode, or symbolic mode change operations with | - | ||||||||||||||||||
127 | the form: | - | ||||||||||||||||||
128 | [ugoa...][[+-=][rwxXstugo...]...][,...] | - | ||||||||||||||||||
129 | - | |||||||||||||||||||
130 | Return NULL if 'mode_string' does not contain a valid | - | ||||||||||||||||||
131 | representation of file mode change operations. */ | - | ||||||||||||||||||
132 | - | |||||||||||||||||||
133 | struct mode_change * | - | ||||||||||||||||||
134 | mode_compile (char const *mode_string) | - | ||||||||||||||||||
135 | { | - | ||||||||||||||||||
136 | /* The array of mode-change directives to be returned. */ | - | ||||||||||||||||||
137 | struct mode_change *mc; | - | ||||||||||||||||||
138 | size_t used = 0; | - | ||||||||||||||||||
139 | char const *p; | - | ||||||||||||||||||
140 | - | |||||||||||||||||||
141 | if ('0' <= *mode_string && *mode_string < '8')
| 49-737 | ||||||||||||||||||
142 | { | - | ||||||||||||||||||
143 | unsigned int octal_mode = 0; | - | ||||||||||||||||||
144 | mode_t mode; | - | ||||||||||||||||||
145 | mode_t mentioned; | - | ||||||||||||||||||
146 | - | |||||||||||||||||||
147 | p = mode_string; | - | ||||||||||||||||||
148 | do | - | ||||||||||||||||||
149 | { | - | ||||||||||||||||||
150 | octal_mode = 8 * octal_mode + *p++ - '0'; | - | ||||||||||||||||||
151 | if (ALLM < octal_mode)
| 0-186 | ||||||||||||||||||
152 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
153 | } executed 186 times by 3 tests: end of block Executed by:
| 186 | ||||||||||||||||||
154 | while ('0' <= *p && *p < '8');
| 0-115 | ||||||||||||||||||
155 | - | |||||||||||||||||||
156 | if (*p)
| 2-69 | ||||||||||||||||||
157 | return NULL; executed 2 times by 1 test: return ((void *)0) ; Executed by:
| 2 | ||||||||||||||||||
158 | - | |||||||||||||||||||
159 | mode = octal_to_mode (octal_mode); | - | ||||||||||||||||||
160 | mentioned = (p - mode_string < 5
| 2-67 | ||||||||||||||||||
161 | ? (mode & (S_ISUID | S_ISGID)) | S_ISVTX | S_IRWXUGO | - | ||||||||||||||||||
162 | : CHMOD_MODE_BITS); | - | ||||||||||||||||||
163 | return make_node_op_equals (mode, mentioned); executed 69 times by 3 tests: return make_node_op_equals (mode, mentioned); Executed by:
| 69 | ||||||||||||||||||
164 | } | - | ||||||||||||||||||
165 | - | |||||||||||||||||||
166 | /* Allocate enough space to hold the result. */ | - | ||||||||||||||||||
167 | { | - | ||||||||||||||||||
168 | size_t needed = 1; | - | ||||||||||||||||||
169 | for (p = mode_string; *p; p++)
| 715-3432 | ||||||||||||||||||
170 | needed += (*p == '=' || *p == '+' || *p == '-'); executed 3432 times by 2 tests: needed += (*p == '=' || *p == '+' || *p == '-'); Executed by:
| 68-3432 | ||||||||||||||||||
171 | mc = xnmalloc (needed, sizeof *mc); | - | ||||||||||||||||||
172 | } | - | ||||||||||||||||||
173 | - | |||||||||||||||||||
174 | /* One loop iteration for each | - | ||||||||||||||||||
175 | '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+'. */ | - | ||||||||||||||||||
176 | for (p = mode_string; ; p++) | - | ||||||||||||||||||
177 | { | - | ||||||||||||||||||
178 | /* Which bits in the mode are operated on. */ | - | ||||||||||||||||||
179 | mode_t affected = 0; | - | ||||||||||||||||||
180 | - | |||||||||||||||||||
181 | /* Turn on all the bits in 'affected' for each group given. */ | - | ||||||||||||||||||
182 | for (;; p++) | - | ||||||||||||||||||
183 | switch (*p) | - | ||||||||||||||||||
184 | { | - | ||||||||||||||||||
185 | default: executed 3 times by 1 test: default: Executed by:
| 3 | ||||||||||||||||||
186 | goto invalid; executed 3 times by 1 test: goto invalid; Executed by:
| 3 | ||||||||||||||||||
187 | case 'u': executed 591 times by 1 test: case 'u': Executed by:
| 591 | ||||||||||||||||||
188 | affected |= S_ISUID | S_IRWXU; | - | ||||||||||||||||||
189 | break; executed 591 times by 1 test: break; Executed by:
| 591 | ||||||||||||||||||
190 | case 'g': executed 25 times by 1 test: case 'g': Executed by:
| 25 | ||||||||||||||||||
191 | affected |= S_ISGID | S_IRWXG; | - | ||||||||||||||||||
192 | break; executed 25 times by 1 test: break; Executed by:
| 25 | ||||||||||||||||||
193 | case 'o': executed 17 times by 1 test: case 'o': Executed by:
| 17 | ||||||||||||||||||
194 | affected |= S_ISVTX | S_IRWXO; | - | ||||||||||||||||||
195 | break; executed 17 times by 1 test: break; Executed by:
| 17 | ||||||||||||||||||
196 | case 'a': executed 46 times by 2 tests: case 'a': Executed by:
| 46 | ||||||||||||||||||
197 | affected |= CHMOD_MODE_BITS; | - | ||||||||||||||||||
198 | break; executed 46 times by 2 tests: break; Executed by:
| 46 | ||||||||||||||||||
199 | case '=': case '+': case '-': executed 68 times by 1 test: case '=': Executed by:
executed 602 times by 1 test: case '+': Executed by:
executed 83 times by 2 tests: case '-': Executed by:
| 68-602 | ||||||||||||||||||
200 | goto no_more_affected; executed 753 times by 2 tests: goto no_more_affected; Executed by:
| 753 | ||||||||||||||||||
201 | } | - | ||||||||||||||||||
202 | no_more_affected:; code before this statement never executed: no_more_affected: | 0 | ||||||||||||||||||
203 | - | |||||||||||||||||||
204 | do | - | ||||||||||||||||||
205 | { | - | ||||||||||||||||||
206 | char op = *p++; | - | ||||||||||||||||||
207 | mode_t value; | - | ||||||||||||||||||
208 | mode_t mentioned = 0; | - | ||||||||||||||||||
209 | char flag = MODE_COPY_EXISTING; | - | ||||||||||||||||||
210 | struct mode_change *change; | - | ||||||||||||||||||
211 | - | |||||||||||||||||||
212 | switch (*p) | - | ||||||||||||||||||
213 | { | - | ||||||||||||||||||
214 | case '0': case '1': case '2': case '3': never executed: case '0': never executed: case '1': executed 15 times by 1 test: case '2': Executed by:
never executed: case '3': | 0-15 | ||||||||||||||||||
215 | case '4': case '5': case '6': case '7': never executed: case '4': executed 2 times by 1 test: case '5': Executed by:
never executed: case '6': executed 3 times by 1 test: case '7': Executed by:
| 0-3 | ||||||||||||||||||
216 | { | - | ||||||||||||||||||
217 | unsigned int octal_mode = 0; | - | ||||||||||||||||||
218 | - | |||||||||||||||||||
219 | do | - | ||||||||||||||||||
220 | { | - | ||||||||||||||||||
221 | octal_mode = 8 * octal_mode + *p++ - '0'; | - | ||||||||||||||||||
222 | if (ALLM < octal_mode)
| 0-79 | ||||||||||||||||||
223 | goto invalid; never executed: goto invalid; | 0 | ||||||||||||||||||
224 | } executed 79 times by 1 test: end of block Executed by:
| 79 | ||||||||||||||||||
225 | while ('0' <= *p && *p < '8');
| 0-59 | ||||||||||||||||||
226 | - | |||||||||||||||||||
227 | if (affected || (*p && *p != ','))
| 0-20 | ||||||||||||||||||
228 | goto invalid; never executed: goto invalid; | 0 | ||||||||||||||||||
229 | affected = mentioned = CHMOD_MODE_BITS; | - | ||||||||||||||||||
230 | value = octal_to_mode (octal_mode); | - | ||||||||||||||||||
231 | flag = MODE_ORDINARY_CHANGE; | - | ||||||||||||||||||
232 | break; executed 20 times by 1 test: break; Executed by:
| 20 | ||||||||||||||||||
233 | } | - | ||||||||||||||||||
234 | - | |||||||||||||||||||
235 | case 'u': executed 3 times by 1 test: case 'u': Executed by:
| 3 | ||||||||||||||||||
236 | /* Set the affected bits to the value of the "u" bits | - | ||||||||||||||||||
237 | on the same file. */ | - | ||||||||||||||||||
238 | value = S_IRWXU; | - | ||||||||||||||||||
239 | p++; | - | ||||||||||||||||||
240 | break; executed 3 times by 1 test: break; Executed by:
| 3 | ||||||||||||||||||
241 | case 'g': executed 3 times by 1 test: case 'g': Executed by:
| 3 | ||||||||||||||||||
242 | /* Set the affected bits to the value of the "g" bits | - | ||||||||||||||||||
243 | on the same file. */ | - | ||||||||||||||||||
244 | value = S_IRWXG; | - | ||||||||||||||||||
245 | p++; | - | ||||||||||||||||||
246 | break; executed 3 times by 1 test: break; Executed by:
| 3 | ||||||||||||||||||
247 | case 'o': executed 2 times by 1 test: case 'o': Executed by:
| 2 | ||||||||||||||||||
248 | /* Set the affected bits to the value of the "o" bits | - | ||||||||||||||||||
249 | on the same file. */ | - | ||||||||||||||||||
250 | value = S_IRWXO; | - | ||||||||||||||||||
251 | p++; | - | ||||||||||||||||||
252 | break; executed 2 times by 1 test: break; Executed by:
| 2 | ||||||||||||||||||
253 | - | |||||||||||||||||||
254 | default: executed 733 times by 2 tests: default: Executed by:
| 733 | ||||||||||||||||||
255 | value = 0; | - | ||||||||||||||||||
256 | flag = MODE_ORDINARY_CHANGE; | - | ||||||||||||||||||
257 | - | |||||||||||||||||||
258 | for (;; p++) | - | ||||||||||||||||||
259 | switch (*p) | - | ||||||||||||||||||
260 | { | - | ||||||||||||||||||
261 | case 'r': executed 597 times by 2 tests: case 'r': Executed by:
| 597 | ||||||||||||||||||
262 | value |= S_IRUSR | S_IRGRP | S_IROTH; | - | ||||||||||||||||||
263 | break; executed 597 times by 2 tests: break; Executed by:
| 597 | ||||||||||||||||||
264 | case 'w': executed 634 times by 1 test: case 'w': Executed by:
| 634 | ||||||||||||||||||
265 | value |= S_IWUSR | S_IWGRP | S_IWOTH; | - | ||||||||||||||||||
266 | break; executed 634 times by 1 test: break; Executed by:
| 634 | ||||||||||||||||||
267 | case 'x': executed 607 times by 1 test: case 'x': Executed by:
| 607 | ||||||||||||||||||
268 | value |= S_IXUSR | S_IXGRP | S_IXOTH; | - | ||||||||||||||||||
269 | break; executed 607 times by 1 test: break; Executed by:
| 607 | ||||||||||||||||||
270 | case 'X': executed 4 times by 1 test: case 'X': Executed by:
| 4 | ||||||||||||||||||
271 | flag = MODE_X_IF_ANY_X; | - | ||||||||||||||||||
272 | break; executed 4 times by 1 test: break; Executed by:
| 4 | ||||||||||||||||||
273 | case 's': executed 10 times by 1 test: case 's': Executed by:
| 10 | ||||||||||||||||||
274 | /* Set the setuid/gid bits if 'u' or 'g' is selected. */ | - | ||||||||||||||||||
275 | value |= S_ISUID | S_ISGID; | - | ||||||||||||||||||
276 | break; executed 10 times by 1 test: break; Executed by:
| 10 | ||||||||||||||||||
277 | case 't': executed 6 times by 1 test: case 't': Executed by:
| 6 | ||||||||||||||||||
278 | /* Set the "save text image" bit if 'o' is selected. */ | - | ||||||||||||||||||
279 | value |= S_ISVTX; | - | ||||||||||||||||||
280 | break; executed 6 times by 1 test: break; Executed by:
| 6 | ||||||||||||||||||
281 | default: executed 733 times by 2 tests: default: Executed by:
| 733 | ||||||||||||||||||
282 | goto no_more_values; executed 733 times by 2 tests: goto no_more_values; Executed by:
| 733 | ||||||||||||||||||
283 | } | - | ||||||||||||||||||
284 | no_more_values:; code before this statement never executed: no_more_values: | 0 | ||||||||||||||||||
285 | } executed 733 times by 2 tests: end of block Executed by:
| 733 | ||||||||||||||||||
286 | - | |||||||||||||||||||
287 | change = &mc[used++]; | - | ||||||||||||||||||
288 | change->op = op; | - | ||||||||||||||||||
289 | change->flag = flag; | - | ||||||||||||||||||
290 | change->affected = affected; | - | ||||||||||||||||||
291 | change->value = value; | - | ||||||||||||||||||
292 | change->mentioned = | - | ||||||||||||||||||
293 | (mentioned ? mentioned : affected ? affected & value : value);
| 20-741 | ||||||||||||||||||
294 | } executed 761 times by 2 tests: end of block Executed by:
| 761 | ||||||||||||||||||
295 | while (*p == '=' || *p == '+' || *p == '-');
| 0-761 | ||||||||||||||||||
296 | - | |||||||||||||||||||
297 | if (*p != ',')
| 41-712 | ||||||||||||||||||
298 | break; executed 712 times by 2 tests: break; Executed by:
| 712 | ||||||||||||||||||
299 | } executed 41 times by 1 test: end of block Executed by:
| 41 | ||||||||||||||||||
300 | - | |||||||||||||||||||
301 | if (*p == 0)
| 1-711 | ||||||||||||||||||
302 | { | - | ||||||||||||||||||
303 | mc[used].flag = MODE_DONE; | - | ||||||||||||||||||
304 | return mc; executed 711 times by 2 tests: return mc; Executed by:
| 711 | ||||||||||||||||||
305 | } | - | ||||||||||||||||||
306 | - | |||||||||||||||||||
307 | invalid: code before this statement executed 1 time by 1 test: invalid: Executed by:
| 1 | ||||||||||||||||||
308 | free (mc); | - | ||||||||||||||||||
309 | return NULL; executed 4 times by 1 test: return ((void *)0) ; Executed by:
| 4 | ||||||||||||||||||
310 | } | - | ||||||||||||||||||
311 | - | |||||||||||||||||||
312 | /* Return a file mode change operation that sets permissions to match those | - | ||||||||||||||||||
313 | of REF_FILE. Return NULL (setting errno) if REF_FILE can't be accessed. */ | - | ||||||||||||||||||
314 | - | |||||||||||||||||||
315 | struct mode_change * | - | ||||||||||||||||||
316 | mode_create_from_ref (const char *ref_file) | - | ||||||||||||||||||
317 | { | - | ||||||||||||||||||
318 | struct stat ref_stats; | - | ||||||||||||||||||
319 | - | |||||||||||||||||||
320 | if (stat (ref_file, &ref_stats) != 0)
| 0 | ||||||||||||||||||
321 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
322 | return make_node_op_equals (ref_stats.st_mode, CHMOD_MODE_BITS); never executed: return make_node_op_equals (ref_stats.st_mode, ( 04000 | 02000 | 01000 | (0400|0200|0100) | ((0400|0200|0100) >> 3) | (((0400|0200|0100) >> 3) >> 3) )); | 0 | ||||||||||||||||||
323 | } | - | ||||||||||||||||||
324 | - | |||||||||||||||||||
325 | /* Return the file mode bits of OLDMODE (which is the mode of a | - | ||||||||||||||||||
326 | directory if DIR), assuming the umask is UMASK_VALUE, adjusted as | - | ||||||||||||||||||
327 | indicated by the list of change operations CHANGES. If DIR, the | - | ||||||||||||||||||
328 | type 'X' change affects the returned value even if no execute bits | - | ||||||||||||||||||
329 | were set in OLDMODE, and set user and group ID bits are preserved | - | ||||||||||||||||||
330 | unless CHANGES mentioned them. If PMODE_BITS is not null, store into | - | ||||||||||||||||||
331 | *PMODE_BITS a mask denoting file mode bits that are affected by | - | ||||||||||||||||||
332 | CHANGES. | - | ||||||||||||||||||
333 | - | |||||||||||||||||||
334 | The returned value and *PMODE_BITS contain only file mode bits. | - | ||||||||||||||||||
335 | For example, they have the S_IFMT bits cleared on a standard | - | ||||||||||||||||||
336 | Unix-like host. */ | - | ||||||||||||||||||
337 | - | |||||||||||||||||||
338 | mode_t | - | ||||||||||||||||||
339 | mode_adjust (mode_t oldmode, bool dir, mode_t umask_value, | - | ||||||||||||||||||
340 | struct mode_change const *changes, mode_t *pmode_bits) | - | ||||||||||||||||||
341 | { | - | ||||||||||||||||||
342 | /* The adjusted mode. */ | - | ||||||||||||||||||
343 | mode_t newmode = oldmode & CHMOD_MODE_BITS; | - | ||||||||||||||||||
344 | - | |||||||||||||||||||
345 | /* File mode bits that CHANGES cares about. */ | - | ||||||||||||||||||
346 | mode_t mode_bits = 0; | - | ||||||||||||||||||
347 | - | |||||||||||||||||||
348 | for (; changes->flag != MODE_DONE; changes++)
| 291017-291067 | ||||||||||||||||||
349 | { | - | ||||||||||||||||||
350 | mode_t affected = changes->affected; | - | ||||||||||||||||||
351 | mode_t omit_change = | - | ||||||||||||||||||
352 | (dir ? S_ISUID | S_ISGID : 0) & ~ changes->mentioned;
| 43014-248053 | ||||||||||||||||||
353 | mode_t value = changes->value; | - | ||||||||||||||||||
354 | - | |||||||||||||||||||
355 | switch (changes->flag) | - | ||||||||||||||||||
356 | { | - | ||||||||||||||||||
357 | case MODE_ORDINARY_CHANGE: executed 291056 times by 3 tests: case MODE_ORDINARY_CHANGE: Executed by:
| 291056 | ||||||||||||||||||
358 | break; executed 291056 times by 3 tests: break; Executed by:
| 291056 | ||||||||||||||||||
359 | - | |||||||||||||||||||
360 | case MODE_COPY_EXISTING: executed 7 times by 1 test: case MODE_COPY_EXISTING: Executed by:
| 7 | ||||||||||||||||||
361 | /* Isolate in 'value' the bits in 'newmode' to copy. */ | - | ||||||||||||||||||
362 | value &= newmode; | - | ||||||||||||||||||
363 | - | |||||||||||||||||||
364 | /* Copy the isolated bits to the other two parts. */ | - | ||||||||||||||||||
365 | value |= ((value & (S_IRUSR | S_IRGRP | S_IROTH)
| 0-7 | ||||||||||||||||||
366 | ? S_IRUSR | S_IRGRP | S_IROTH : 0) | - | ||||||||||||||||||
367 | | (value & (S_IWUSR | S_IWGRP | S_IWOTH) | - | ||||||||||||||||||
368 | ? S_IWUSR | S_IWGRP | S_IWOTH : 0) | - | ||||||||||||||||||
369 | | (value & (S_IXUSR | S_IXGRP | S_IXOTH) | - | ||||||||||||||||||
370 | ? S_IXUSR | S_IXGRP | S_IXOTH : 0)); | - | ||||||||||||||||||
371 | break; executed 7 times by 1 test: break; Executed by:
| 7 | ||||||||||||||||||
372 | - | |||||||||||||||||||
373 | case MODE_X_IF_ANY_X: executed 4 times by 1 test: case MODE_X_IF_ANY_X: Executed by:
| 4 | ||||||||||||||||||
374 | /* Affect the execute bits if execute bits are already set | - | ||||||||||||||||||
375 | or if the file is a directory. */ | - | ||||||||||||||||||
376 | if ((newmode & (S_IXUSR | S_IXGRP | S_IXOTH)) | dir)
| 1-3 | ||||||||||||||||||
377 | value |= S_IXUSR | S_IXGRP | S_IXOTH; executed 1 time by 1 test: value |= 0100 | (0100 >> 3) | ((0100 >> 3) >> 3) ; Executed by:
| 1 | ||||||||||||||||||
378 | break; executed 4 times by 1 test: break; Executed by:
| 4 | ||||||||||||||||||
379 | } | - | ||||||||||||||||||
380 | - | |||||||||||||||||||
381 | /* If WHO was specified, limit the change to the affected bits. | - | ||||||||||||||||||
382 | Otherwise, apply the umask. Either way, omit changes as | - | ||||||||||||||||||
383 | requested. */ | - | ||||||||||||||||||
384 | value &= (affected ? affected : ~umask_value) & ~ omit_change;
| 84-290983 | ||||||||||||||||||
385 | - | |||||||||||||||||||
386 | switch (changes->op) | - | ||||||||||||||||||
387 | { | - | ||||||||||||||||||
388 | case '=': executed 200160 times by 3 tests: case '=': Executed by:
| 200160 | ||||||||||||||||||
389 | /* If WHO was specified, preserve the previous values of | - | ||||||||||||||||||
390 | bits that are not affected by this change operation. | - | ||||||||||||||||||
391 | Otherwise, clear all the bits. */ | - | ||||||||||||||||||
392 | { | - | ||||||||||||||||||
393 | mode_t preserved = (affected ? ~affected : 0) | omit_change;
| 8-200152 | ||||||||||||||||||
394 | mode_bits |= CHMOD_MODE_BITS & ~preserved; | - | ||||||||||||||||||
395 | newmode = (newmode & preserved) | value; | - | ||||||||||||||||||
396 | break; executed 200160 times by 3 tests: break; Executed by:
| 200160 | ||||||||||||||||||
397 | } | - | ||||||||||||||||||
398 | - | |||||||||||||||||||
399 | case '+': executed 90795 times by 1 test: case '+': Executed by:
| 90795 | ||||||||||||||||||
400 | mode_bits |= value; | - | ||||||||||||||||||
401 | newmode |= value; | - | ||||||||||||||||||
402 | break; executed 90795 times by 1 test: break; Executed by:
| 90795 | ||||||||||||||||||
403 | - | |||||||||||||||||||
404 | case '-': executed 112 times by 2 tests: case '-': Executed by:
| 112 | ||||||||||||||||||
405 | mode_bits |= value; | - | ||||||||||||||||||
406 | newmode &= ~value; | - | ||||||||||||||||||
407 | break; executed 112 times by 2 tests: break; Executed by:
| 112 | ||||||||||||||||||
408 | } | - | ||||||||||||||||||
409 | } executed 291067 times by 3 tests: end of block Executed by:
| 291067 | ||||||||||||||||||
410 | - | |||||||||||||||||||
411 | if (pmode_bits)
| 17-291000 | ||||||||||||||||||
412 | *pmode_bits = mode_bits; executed 17 times by 2 tests: *pmode_bits = mode_bits; Executed by:
| 17 | ||||||||||||||||||
413 | return newmode; executed 291017 times by 3 tests: return newmode; Executed by:
| 291017 | ||||||||||||||||||
414 | } | - | ||||||||||||||||||
Source code | Switch to Preprocessed file |