ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/src/vendor/FreeBSD/dist/bin/chmod/chmod.c
(Generate patch)

Comparing vendor/FreeBSD/dist/bin/chmod/chmod.c (file contents):
Revision 9656 by laffer1, Sun Oct 22 21:03:47 2017 UTC vs.
Revision 9657 by laffer1, Sun Oct 22 21:36:58 2017 UTC

# Line 39 | Line 39 | static char sccsid[] = "@(#)chmod.c    8.8 (Berkeley) 4/1
39   #endif /* not lint */
40   #endif
41   #include <sys/cdefs.h>
42 < __FBSDID("$FreeBSD: release/7.0.0/bin/chmod/chmod.c 139969 2005-01-10 08:39:26Z imp $");
42 > __FBSDID("$FreeBSD$");
43  
44 < #include <sys/types.h>
44 > #include <sys/param.h>
45   #include <sys/stat.h>
46  
47   #include <err.h>
# Line 53 | Line 53 | __FBSDID("$FreeBSD: release/7.0.0/bin/chmod/chmod.c 13
53   #include <string.h>
54   #include <unistd.h>
55  
56 < void usage(void);
56 > static void usage(void);
57 > static int may_have_nfs4acl(const FTSENT *ent, int hflag);
58  
59   int
60   main(int argc, char *argv[])
# Line 61 | Line 62 | main(int argc, char *argv[])
62          FTS *ftsp;
63          FTSENT *p;
64          mode_t *set;
65 <        int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval;
65 >        int Hflag, Lflag, Rflag, ch, error, fflag, fts_options, hflag, rval;
66          int vflag;
67          char *mode;
68          mode_t newmode;
68        int (*change_mode)(const char *, mode_t);
69  
70          set = NULL;
71          Hflag = Lflag = Rflag = fflag = hflag = vflag = 0;
# Line 139 | Line 139 | done:  argv += optind;
139          } else
140                  fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL;
141  
142        if (hflag)
143                change_mode = lchmod;
144        else
145                change_mode = chmod;
146
142          mode = *argv;
143          if ((set = setmode(mode)) == NULL)
144                  errx(1, "invalid file mode: %s", mode);
# Line 174 | Line 169 | done:  argv += optind;
169                           */
170                          if (!hflag)
171                                  continue;
177                        /* else */
172                          /* FALLTHROUGH */
173                  default:
174                          break;
175                  }
176                  newmode = getmode(set, p->fts_statp->st_mode);
177 <                if ((newmode & ALLPERMS) == (p->fts_statp->st_mode & ALLPERMS))
178 <                        continue;
179 <                if ((*change_mode)(p->fts_accpath, newmode) && !fflag) {
180 <                        warn("%s", p->fts_path);
181 <                        rval = 1;
177 >                /*
178 >                 * With NFSv4 ACLs, it is possible that applying a mode
179 >                 * identical to the one computed from an ACL will change
180 >                 * that ACL.
181 >                 */
182 >                if (may_have_nfs4acl(p, hflag) == 0 &&
183 >                    (newmode & ALLPERMS) == (p->fts_statp->st_mode & ALLPERMS))
184 >                                continue;
185 >                if (hflag)
186 >                        error = lchmod(p->fts_accpath, newmode);
187 >                else
188 >                        error = chmod(p->fts_accpath, newmode);
189 >                if (error) {
190 >                        if (!fflag) {
191 >                                warn("%s", p->fts_path);
192 >                                rval = 1;
193 >                        }
194                  } else {
195                          if (vflag) {
196                                  (void)printf("%s", p->fts_path);
# Line 195 | Line 201 | done:  argv += optind;
201                                          strmode(p->fts_statp->st_mode, m1);
202                                          strmode((p->fts_statp->st_mode &
203                                              S_IFMT) | newmode, m2);
198
204                                          (void)printf(": 0%o [%s] -> 0%o [%s]",
205                                              p->fts_statp->st_mode, m1,
206                                              (p->fts_statp->st_mode & S_IFMT) |
# Line 203 | Line 208 | done:  argv += optind;
208                                  }
209                                  (void)printf("\n");
210                          }
206
211                  }
212          }
213          if (errno)
214                  err(1, "fts_read");
211        free(set);
215          exit(rval);
216   }
217  
218 < void
218 > static void
219   usage(void)
220   {
221          (void)fprintf(stderr,
222              "usage: chmod [-fhv] [-R [-H | -L | -P]] mode file ...\n");
223          exit(1);
224 + }
225 +
226 + static int
227 + may_have_nfs4acl(const FTSENT *ent, int hflag)
228 + {
229 +        int ret;
230 +        static dev_t previous_dev = NODEV;
231 +        static int supports_acls = -1;
232 +
233 +        if (previous_dev != ent->fts_statp->st_dev) {
234 +                previous_dev = ent->fts_statp->st_dev;
235 +                supports_acls = 0;
236 +
237 +                if (hflag)
238 +                        ret = lpathconf(ent->fts_accpath, _PC_ACL_NFS4);
239 +                else
240 +                        ret = pathconf(ent->fts_accpath, _PC_ACL_NFS4);
241 +                if (ret > 0)
242 +                        supports_acls = 1;
243 +                else if (ret < 0 && errno != EINVAL)
244 +                        warn("%s", ent->fts_path);
245 +        }
246 +
247 +        return (supports_acls);
248   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines