* Copyright (c) 1989 The Regents of the University of California.
* %sccs.include.redist.c%
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid
[] = "@(#)setmode.c 5.3 (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
newmode
= omode
& clrbits
;
if (omode
& (S_IFDIR
|S_IXUSR
|S_IXGRP
|S_IXOTH
))
#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
#define CLR(a) { clrbits |= a; setbits &= ~(a); Xbits &= ~(a); }
* get a copy of the mask for the permissions that are mask
* relative. Flip the bits, we want what's not set.
(void)umask(mask
= umask(0));
if (!(set
= (mode_t
*)malloc((u_int
)(sizeof(mode_t
) * 3)))) {
setbits
= clrbits
= Xbits
= 0;
* if an absolute number, get it and return; disallow non-octal
* digits or illegal bits.
setbits
= (mode_t
)strtol(p
, (char **)0, 8);
clrbits
= ~(STANDARD_BITS
|S_ISTXT
);
if (*p
< '0' || *p
> '7')
* accumulate bits to add and subtract from each clause of
getop
: if ((op
= *p
++) != '+' && op
!= '-' && op
!= '=')
perm
|= S_IRUSR
|S_IRGRP
|S_IROTH
;
/* if only "other" bits ignore set-id */
/* if only "other" bits ignore sticky */
perm
|= S_IWUSR
|S_IWGRP
|S_IWOTH
;
permXbits
= S_IXUSR
|S_IXGRP
|S_IXOTH
;
perm
|= S_IXUSR
|S_IXGRP
|S_IXOTH
;
* If no perm value, skip. If no who value, use umask
* bits. Don't bother clearing any bits, getmode
* clears first, then sets.
Xbits
|= who
& permXbits
;
* If no perm value, skip. If no who value, use
* owner, group, and other.
who
= S_IRWXU
|S_IRWXG
|S_IRWXO
;
* If no who value, clear all the bits. Otherwise,
* clear the bits specified by who.