b55de3d1a2
and mark it as finished in README. One small rationale on the way the manpage is set up: Looking at the coreutils manpage, it does not invite to be a quick reference guide, whereas I wrote this manpage to be short and concise in regard to the information the advanced user needs. No one needs to explain what an octal number is. That's not part of the scope of this manpage. Also, nobody wants to read a block of text just to find out how to build an octal mode string.
75 lines
1.2 KiB
C
75 lines
1.2 KiB
C
/* See LICENSE file for copyright and license details. */
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
#include "util.h"
|
|
|
|
static int rflag = 0;
|
|
static char *modestr = "";
|
|
static mode_t mask = 0;
|
|
static int ret = 0;
|
|
|
|
void
|
|
chmodr(const char *path)
|
|
{
|
|
struct stat st;
|
|
mode_t m;
|
|
|
|
if (stat(path, &st) < 0) {
|
|
weprintf("stat %s:", path);
|
|
ret = 1;
|
|
return;
|
|
}
|
|
|
|
m = parsemode(modestr, st.st_mode, mask);
|
|
if (chmod(path, m) < 0) {
|
|
weprintf("chmod %s:", path);
|
|
ret = 1;
|
|
}
|
|
if (rflag)
|
|
recurse(path, chmodr);
|
|
}
|
|
|
|
static void
|
|
usage(void)
|
|
{
|
|
eprintf("usage: %s [-R] mode [file ...]\n", argv0);
|
|
}
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
size_t i;
|
|
|
|
argv0 = argv[0];
|
|
for (i = 1; i < argc && argv[i][0] == '-'; i++) {
|
|
switch (argv[i][1]) {
|
|
case 'R':
|
|
rflag = 1;
|
|
break;
|
|
case 'r': case 'w': case 'x': case 's': case 't':
|
|
/*
|
|
* -[rwxst] are valid modes so do not interpret
|
|
* them as options - in any case we are done if
|
|
* we hit this case
|
|
*/
|
|
goto done;
|
|
default:
|
|
usage();
|
|
}
|
|
}
|
|
done:
|
|
mask = getumask();
|
|
modestr = argv[i];
|
|
|
|
if (argc - i - 1 < 1)
|
|
usage();
|
|
|
|
for (++i; i < argc; i++)
|
|
chmodr(argv[i]);
|
|
|
|
return ret;
|
|
}
|