annotate lib/modechange.c @ 6969:bbdf9204a185

Import from coreutils. * MODULES.html.sh: Add mkancestors. * modules/mkancesdirs: New module. * modules/mkdir-p (Files): Remove lib/chdir-safer.c, lib/chdir-safer.h, lib/same-inode.h, m4/afs.m4, m4/chdir-safer.m4. The chdir-safer and afs files are now orphans; I'll remove them unless someone speaks up. Add lib/dirchownmod.c, lib/dirchownmod.h. (Depends-on): Remove alloca, chown, save-cwd, dirname. Add lchown, mkancesdirs. (Maintainer): Add self. * lib/dirchownmod.c, lib/dirchownmod.h: * lib/mkancesdirs.c, lib/mkancesdirs.h: New files. * lib/mkdir-p.c: Don't include alloca.h, stdio.h, sys/types.h, unistd.h, string.h, chdir-safer.h, dirname.h, lchmod.h, lchown.h, save-cwd.h. Instead, include dirchownmod.h and mkancesdirs.h. (make_dir_parents): New args MAKE_ANCESTOR, OPTIONS, ANNOUNCE, MODE_BITS. Remove options VERBOSE_FMT_STRING, CWD_ERRNO. All callers changed. Revamp internals significantly, by not attempting to create directories that are temporarily more permissive than the final results. Do not attempt to use save_cwd/restore_cwd; it isn't worth it for mkdir and install. This removes some race conditions, fixes some bugs, and simplifies things. Use new dirchownmod function to do owner and mode changes. * lib/mkdir-p.h: Likewise. * lib/modechange.c (octal_to_mode): New function. (struct mode_change): New member mentioned. (make_node_op_equals): New arg mentioned. All callers changed. (mode_compile): Keep track of which mode bits the user has explicitly mentioned. (mode_adjust): New arg DIR, so that we implement the X op correctly. New arg PMODE_BITS, to keep track of which mode bits the user mentioned; it treats S_ISUID and S_ISGID speciall. All callers changed. * lib/modechange.h: Likewise. * mkancesdirs.m4: New file. * mkdir-p.m4 (gl_MKDIR_PARENTS): Mention dirchownmod.c, dirchownmod.h. Don't require AC_FUNC_ALLOCA, gl_AFS, gl_CHDIR_SAFER; no longer needed. Require gl_FUNC_LCHOWN, since dirchownmod.c needs it.
author Paul Eggert <eggert@cs.ucla.edu>
date Mon, 17 Jul 2006 06:06:48 +0000
parents 6b31c8787689
children db9b9e26e735
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
1 /* modechange.c -- file mode manipulation
4360
72f709fb8146 Remove trailing blanks.
Jim Meyering <jim@meyering.net>
parents: 4333
diff changeset
2
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
3 Copyright (C) 1989, 1990, 1997, 1998, 1999, 2001, 2003, 2004, 2005,
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
4 2006 Free Software Foundation, Inc.
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
6 This program is free software; you can redistribute it and/or modify
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
7 it under the terms of the GNU General Public License as published by
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
8 the Free Software Foundation; either version 2, or (at your option)
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
9 any later version.
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
10
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
11 This program is distributed in the hope that it will be useful,
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
14 GNU General Public License for more details.
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
15
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
650
b4ef1c1a0171 update FSF address in copyright
Jim Meyering <jim@meyering.net>
parents: 609
diff changeset
17 along with this program; if not, write to the Free Software Foundation,
5848
a48fb0e98c8c *** empty log message ***
Paul Eggert <eggert@cs.ucla.edu>
parents: 5813
diff changeset
18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
19
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
20 /* Written by David MacKenzie <djm@ai.mit.edu> */
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
21
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
22 /* The ASCII mode string is compiled into an array of `struct
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
23 modechange', which can then be applied to each file to be changed.
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
24 We do this instead of re-parsing the ASCII string for each file
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
25 because the compiled form requires less computation to use; when
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
26 changing the mode of many files, this probably results in a
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
27 performance gain. */
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
28
6259
96c32553b4c6 Use a consistent style for including <config.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
29 #ifdef HAVE_CONFIG_H
702
Jim Meyering <jim@meyering.net>
parents: 650
diff changeset
30 # include <config.h>
229
Jim Meyering <jim@meyering.net>
parents: 5
diff changeset
31 #endif
Jim Meyering <jim@meyering.net>
parents: 5
diff changeset
32
1818
b2644b45e17f (make_node_op_equals, mode_compile, mode_create_from_ref, mode_adjust):
Jim Meyering <jim@meyering.net>
parents: 1769
diff changeset
33 #include "modechange.h"
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
34 #include <sys/stat.h>
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
35 #include "stat-macros.h"
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
36 #include "xalloc.h"
4666
bb2816d0923f Remove K&R cruft.
Paul Eggert <eggert@cs.ucla.edu>
parents: 4360
diff changeset
37 #include <stdlib.h>
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
38
3081
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
39 /* The traditional octal values corresponding to each mode bit. */
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
40 #define SUID 04000
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
41 #define SGID 02000
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
42 #define SVTX 01000
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
43 #define RUSR 00400
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
44 #define WUSR 00200
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
45 #define XUSR 00100
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
46 #define RGRP 00040
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
47 #define WGRP 00020
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
48 #define XGRP 00010
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
49 #define ROTH 00004
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
50 #define WOTH 00002
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
51 #define XOTH 00001
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
52 #define ALLM 07777 /* all octal mode bits */
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
53
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
54 /* Convert OCTAL, which uses one of the traditional octal values, to
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
55 an internal mode_t value. */
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
56 static mode_t
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
57 octal_to_mode (unsigned int octal)
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
58 {
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
59 /* Help the compiler optimize the usual case where mode_t uses
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
60 the traditional octal representation. */
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
61 return ((S_ISUID == SUID && S_ISGID == SGID && S_ISVTX == SVTX
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
62 && S_IRUSR == RUSR && S_IWUSR == WUSR && S_IXUSR == XUSR
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
63 && S_IRGRP == RGRP && S_IWGRP == WGRP && S_IXGRP == XGRP
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
64 && S_IROTH == ROTH && S_IWOTH == WOTH && S_IXOTH == XOTH)
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
65 ? octal
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
66 : (mode_t) ((octal & SUID ? S_ISUID : 0)
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
67 | (octal & SGID ? S_ISGID : 0)
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
68 | (octal & SVTX ? S_ISVTX : 0)
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
69 | (octal & RUSR ? S_IRUSR : 0)
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
70 | (octal & WUSR ? S_IWUSR : 0)
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
71 | (octal & XUSR ? S_IXUSR : 0)
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
72 | (octal & RGRP ? S_IRGRP : 0)
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
73 | (octal & WGRP ? S_IWGRP : 0)
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
74 | (octal & XGRP ? S_IXGRP : 0)
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
75 | (octal & ROTH ? S_IROTH : 0)
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
76 | (octal & WOTH ? S_IWOTH : 0)
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
77 | (octal & XOTH ? S_IXOTH : 0)));
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
78 }
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
79
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
80 /* Special operations flags. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
81 enum
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
82 {
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
83 /* For the sentinel at the end of the mode changes array. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
84 MODE_DONE,
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
85
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
86 /* The typical case. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
87 MODE_ORDINARY_CHANGE,
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
88
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
89 /* In addition to the typical case, affect the execute bits if at
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
90 least one execute bit is set already, or if the file is a
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
91 directory. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
92 MODE_X_IF_ANY_X,
1818
b2644b45e17f (make_node_op_equals, mode_compile, mode_create_from_ref, mode_adjust):
Jim Meyering <jim@meyering.net>
parents: 1769
diff changeset
93
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
94 /* Instead of the typical case, copy some existing permissions for
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
95 u, g, or o onto the other two. Which of u, g, or o is copied
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
96 is determined by which bits are set in the `value' field. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
97 MODE_COPY_EXISTING
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
98 };
1818
b2644b45e17f (make_node_op_equals, mode_compile, mode_create_from_ref, mode_adjust):
Jim Meyering <jim@meyering.net>
parents: 1769
diff changeset
99
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
100 /* Description of a mode change. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
101 struct mode_change
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
102 {
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
103 char op; /* One of "=+-". */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
104 char flag; /* Special operations flag. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
105 mode_t affected; /* Set for u, g, o, or a. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
106 mode_t value; /* Bits to add/remove. */
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
107 mode_t mentioned; /* Bits explicitly mentioned. */
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
108 };
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
109
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
110 /* Return a mode_change array with the specified `=ddd'-style
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
111 mode change operation, where NEW_MODE is `ddd' and MENTIONED
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
112 contains the bits explicitly mentioned in the mode are MENTIONED. */
1769
bc0ac225f0a8 (make_node_op_equals): New function.
Jim Meyering <jim@meyering.net>
parents: 1760
diff changeset
113
bc0ac225f0a8 (make_node_op_equals): New function.
Jim Meyering <jim@meyering.net>
parents: 1760
diff changeset
114 static struct mode_change *
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
115 make_node_op_equals (mode_t new_mode, mode_t mentioned)
1769
bc0ac225f0a8 (make_node_op_equals): New function.
Jim Meyering <jim@meyering.net>
parents: 1760
diff changeset
116 {
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
117 struct mode_change *p = xmalloc (2 * sizeof *p);
1769
bc0ac225f0a8 (make_node_op_equals): New function.
Jim Meyering <jim@meyering.net>
parents: 1760
diff changeset
118 p->op = '=';
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
119 p->flag = MODE_ORDINARY_CHANGE;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
120 p->affected = CHMOD_MODE_BITS;
1769
bc0ac225f0a8 (make_node_op_equals): New function.
Jim Meyering <jim@meyering.net>
parents: 1760
diff changeset
121 p->value = new_mode;
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
122 p->mentioned = mentioned;
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
123 p[1].flag = MODE_DONE;
1769
bc0ac225f0a8 (make_node_op_equals): New function.
Jim Meyering <jim@meyering.net>
parents: 1760
diff changeset
124 return p;
bc0ac225f0a8 (make_node_op_equals): New function.
Jim Meyering <jim@meyering.net>
parents: 1760
diff changeset
125 }
bc0ac225f0a8 (make_node_op_equals): New function.
Jim Meyering <jim@meyering.net>
parents: 1760
diff changeset
126
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
127 /* Return a pointer to an array of file mode change operations created from
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
128 MODE_STRING, an ASCII string that contains either an octal number
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
129 specifying an absolute mode, or symbolic mode change operations with
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
130 the form:
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
131 [ugoa...][[+-=][rwxXstugo...]...][,...]
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
132
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
133 Return NULL if `mode_string' does not contain a valid
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
134 representation of file mode change operations. */
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
135
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
136 struct mode_change *
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
137 mode_compile (char const *mode_string)
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
138 {
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
139 /* The array of mode-change directives to be returned. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
140 struct mode_change *mc;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
141 size_t used = 0;
1769
bc0ac225f0a8 (make_node_op_equals): New function.
Jim Meyering <jim@meyering.net>
parents: 1760
diff changeset
142
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
143 if ('0' <= *mode_string && *mode_string < '8')
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
144 {
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
145 unsigned int octal_mode = 0;
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
146 unsigned int octal_mentioned = 0;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
147
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
148 do
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
149 {
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
150 octal_mode = 8 * octal_mode + *mode_string++ - '0';
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
151 octal_mentioned = 8 * octal_mentioned + 7;
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
152 if (ALLM < octal_mode)
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
153 return NULL;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
154 }
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
155 while ('0' <= *mode_string && *mode_string < '8');
3081
b7402f1afb7b Do not assume that mode_t uses the
Jim Meyering <jim@meyering.net>
parents: 2950
diff changeset
156
6527
6b31c8787689 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6259
diff changeset
157 if (*mode_string)
6b31c8787689 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6259
diff changeset
158 return NULL;
6b31c8787689 Sync from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6259
diff changeset
159
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
160 return make_node_op_equals (octal_to_mode (octal_mode),
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
161 octal_to_mode (octal_mentioned & ALLM));
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
162 }
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
163
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
164 /* Allocate enough space to hold the result. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
165 {
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
166 size_t needed = 1;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
167 char const *p;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
168 for (p = mode_string; *p; p++)
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
169 needed += (*p == '=' || *p == '+' || *p == '-');
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
170 mc = xnmalloc (needed, sizeof *mc);
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
171 }
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
172
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
173 /* One loop iteration for each `[ugoa]*([-+=]([rwxXst]*|[ugo]))+'. */
5304
707482f5c106 (mode_compile): Don't decrement a pointer that
Paul Eggert <eggert@cs.ucla.edu>
parents: 5159
diff changeset
174 for (;; mode_string++)
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
175 {
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
176 /* Which bits in the mode are operated on. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
177 mode_t affected = 0;
1769
bc0ac225f0a8 (make_node_op_equals): New function.
Jim Meyering <jim@meyering.net>
parents: 1760
diff changeset
178
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
179 /* Turn on all the bits in `affected' for each group given. */
5304
707482f5c106 (mode_compile): Don't decrement a pointer that
Paul Eggert <eggert@cs.ucla.edu>
parents: 5159
diff changeset
180 for (;; mode_string++)
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
181 switch (*mode_string)
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
182 {
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
183 default:
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
184 goto invalid;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
185 case 'u':
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
186 affected |= S_ISUID | S_IRWXU;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
187 break;
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
188 case 'g':
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
189 affected |= S_ISGID | S_IRWXG;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
190 break;
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
191 case 'o':
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
192 affected |= S_ISVTX | S_IRWXO;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
193 break;
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
194 case 'a':
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
195 affected |= CHMOD_MODE_BITS;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
196 break;
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
197 case '=': case '+': case '-':
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
198 goto no_more_affected;
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
199 }
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
200 no_more_affected:;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
201
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
202 do
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
203 {
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
204 char op = *mode_string++;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
205 mode_t value;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
206 char flag = MODE_COPY_EXISTING;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
207 struct mode_change *change;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
208
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
209 switch (*mode_string++)
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
210 {
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
211 case 'u':
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
212 /* Set the affected bits to the value of the `u' bits
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
213 on the same file. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
214 value = S_IRWXU;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
215 break;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
216 case 'g':
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
217 /* Set the affected bits to the value of the `g' bits
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
218 on the same file. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
219 value = S_IRWXG;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
220 break;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
221 case 'o':
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
222 /* Set the affected bits to the value of the `o' bits
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
223 on the same file. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
224 value = S_IRWXO;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
225 break;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
226
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
227 default:
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
228 value = 0;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
229 flag = MODE_ORDINARY_CHANGE;
1769
bc0ac225f0a8 (make_node_op_equals): New function.
Jim Meyering <jim@meyering.net>
parents: 1760
diff changeset
230
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
231 for (mode_string--;; mode_string++)
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
232 switch (*mode_string)
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
233 {
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
234 case 'r':
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
235 value |= S_IRUSR | S_IRGRP | S_IROTH;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
236 break;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
237 case 'w':
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
238 value |= S_IWUSR | S_IWGRP | S_IWOTH;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
239 break;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
240 case 'x':
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
241 value |= S_IXUSR | S_IXGRP | S_IXOTH;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
242 break;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
243 case 'X':
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
244 flag = MODE_X_IF_ANY_X;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
245 break;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
246 case 's':
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
247 /* Set the setuid/gid bits if `u' or `g' is selected. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
248 value |= S_ISUID | S_ISGID;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
249 break;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
250 case 't':
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
251 /* Set the "save text image" bit if `o' is selected. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
252 value |= S_ISVTX;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
253 break;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
254 default:
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
255 goto no_more_values;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
256 }
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
257 no_more_values:;
1769
bc0ac225f0a8 (make_node_op_equals): New function.
Jim Meyering <jim@meyering.net>
parents: 1760
diff changeset
258 }
bc0ac225f0a8 (make_node_op_equals): New function.
Jim Meyering <jim@meyering.net>
parents: 1760
diff changeset
259
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
260 change = &mc[used++];
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
261 change->op = op;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
262 change->flag = flag;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
263 change->affected = affected;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
264 change->value = value;
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
265 change->mentioned = (affected ? affected & value : value);
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
266 }
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
267 while (*mode_string == '=' || *mode_string == '+'
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
268 || *mode_string == '-');
5304
707482f5c106 (mode_compile): Don't decrement a pointer that
Paul Eggert <eggert@cs.ucla.edu>
parents: 5159
diff changeset
269
707482f5c106 (mode_compile): Don't decrement a pointer that
Paul Eggert <eggert@cs.ucla.edu>
parents: 5159
diff changeset
270 if (*mode_string != ',')
707482f5c106 (mode_compile): Don't decrement a pointer that
Paul Eggert <eggert@cs.ucla.edu>
parents: 5159
diff changeset
271 break;
707482f5c106 (mode_compile): Don't decrement a pointer that
Paul Eggert <eggert@cs.ucla.edu>
parents: 5159
diff changeset
272 }
707482f5c106 (mode_compile): Don't decrement a pointer that
Paul Eggert <eggert@cs.ucla.edu>
parents: 5159
diff changeset
273
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
274 if (*mode_string == 0)
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
275 {
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
276 mc[used].flag = MODE_DONE;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
277 return mc;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
278 }
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
279
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
280 invalid:
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
281 free (mc);
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
282 return NULL;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
283 }
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
284
989
c68ed1182a64 (mode_create_from_ref): Don't use umask.
Jim Meyering <jim@meyering.net>
parents: 972
diff changeset
285 /* Return a file mode change operation that sets permissions to match those
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
286 of REF_FILE. Return NULL (setting errno) if REF_FILE can't be accessed. */
972
b30f9ff1e92e (mode_create_from_ref): New function.
Jim Meyering <jim@meyering.net>
parents: 761
diff changeset
287
b30f9ff1e92e (mode_create_from_ref): New function.
Jim Meyering <jim@meyering.net>
parents: 761
diff changeset
288 struct mode_change *
1494
8b82518377ef Protoize.
Jim Meyering <jim@meyering.net>
parents: 991
diff changeset
289 mode_create_from_ref (const char *ref_file)
972
b30f9ff1e92e (mode_create_from_ref): New function.
Jim Meyering <jim@meyering.net>
parents: 761
diff changeset
290 {
b30f9ff1e92e (mode_create_from_ref): New function.
Jim Meyering <jim@meyering.net>
parents: 761
diff changeset
291 struct stat ref_stats;
b30f9ff1e92e (mode_create_from_ref): New function.
Jim Meyering <jim@meyering.net>
parents: 761
diff changeset
292
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
293 if (stat (ref_file, &ref_stats) != 0)
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
294 return NULL;
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
295 return make_node_op_equals (ref_stats.st_mode, CHMOD_MODE_BITS);
972
b30f9ff1e92e (mode_create_from_ref): New function.
Jim Meyering <jim@meyering.net>
parents: 761
diff changeset
296 }
b30f9ff1e92e (mode_create_from_ref): New function.
Jim Meyering <jim@meyering.net>
parents: 761
diff changeset
297
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
298 /* Return the file mode bits of OLDMODE (which is the mode of a
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
299 directory if DIR), assuming the umask is UMASK_VALUE, adjusted as
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
300 indicated by the list of change operations CHANGES. If DIR, the
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
301 type 'X' change affects the returned value even if no execute bits
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
302 were set in OLDMODE. If PMODE_BITS is not null, store into
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
303 *PMODE_BITS a mask denoting file mode bits that are affected by
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
304 CHANGES.
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
305
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
306 The returned value and *PMODE_BITS contain only file mode bits.
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
307 For example, they have the S_IFMT bits cleared on a standard
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
308 Unix-like host. */
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
309
1818
b2644b45e17f (make_node_op_equals, mode_compile, mode_create_from_ref, mode_adjust):
Jim Meyering <jim@meyering.net>
parents: 1769
diff changeset
310 mode_t
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
311 mode_adjust (mode_t oldmode, bool dir, mode_t umask_value,
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
312 struct mode_change const *changes, mode_t *pmode_bits)
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
313 {
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
314 /* The adjusted mode. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
315 mode_t newmode = oldmode & CHMOD_MODE_BITS;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
316
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
317 /* File mode bits that CHANGES cares about. */
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
318 mode_t mode_bits = 0;
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
319
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
320 for (; changes->flag != MODE_DONE; changes++)
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
321 {
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
322 mode_t affected = changes->affected;
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
323 mode_t omit_change =
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
324 (dir ? S_ISUID | S_ISGID : 0) & ~ changes->mentioned;
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
325 mode_t value = changes->value;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
326
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
327 switch (changes->flag)
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
328 {
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
329 case MODE_ORDINARY_CHANGE:
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
330 break;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
331
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
332 case MODE_COPY_EXISTING:
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
333 /* Isolate in `value' the bits in `newmode' to copy. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
334 value &= newmode;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
335
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
336 /* Copy the isolated bits to the other two parts. */
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
337 value |= ((value & (S_IRUSR | S_IRGRP | S_IROTH)
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
338 ? S_IRUSR | S_IRGRP | S_IROTH : 0)
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
339 | (value & (S_IWUSR | S_IWGRP | S_IWOTH)
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
340 ? S_IWUSR | S_IWGRP | S_IWOTH : 0)
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
341 | (value & (S_IXUSR | S_IXGRP | S_IXOTH)
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
342 ? S_IXUSR | S_IXGRP | S_IXOTH : 0));
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
343 break;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
344
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
345 case MODE_X_IF_ANY_X:
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
346 /* Affect the execute bits if execute bits are already set
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
347 or if the file is a directory. */
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
348 if ((newmode & (S_IXUSR | S_IXGRP | S_IXOTH)) | dir)
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
349 value |= S_IXUSR | S_IXGRP | S_IXOTH;
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
350 break;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
351 }
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
352
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
353 /* If WHO was specified, limit the change to the affected bits.
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
354 Otherwise, apply the umask. Either way, omit changes as
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
355 requested. */
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
356 value &= (affected ? affected : ~umask_value) & ~ omit_change;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
357
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
358 switch (changes->op)
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
359 {
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
360 case '=':
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
361 /* If WHO was specified, preserve the previous values of
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
362 bits that are not affected by this change operation.
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
363 Otherwise, clear all the bits. */
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
364 {
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
365 mode_t preserved = (affected ? ~affected : 0) | omit_change;
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
366 mode_bits |= CHMOD_MODE_BITS & ~preserved;
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
367 newmode = (newmode & preserved) | value;
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
368 break;
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
369 }
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
370
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
371 case '+':
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
372 mode_bits |= value;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
373 newmode |= value;
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
374 break;
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
375
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
376 case '-':
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
377 mode_bits |= value;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
378 newmode &= ~value;
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
379 break;
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
380 }
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
381 }
5813
6962b5c5069f Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5304
diff changeset
382
6969
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
383 if (pmode_bits)
bbdf9204a185 Import from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6527
diff changeset
384 *pmode_bits = mode_bits;
5
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
385 return newmode;
41c9d08b09d7 Initial revision
Jim Meyering <jim@meyering.net>
parents:
diff changeset
386 }