add chown
This commit is contained in:
parent
c367d4d05f
commit
da757ff7d1
6
Makefile
6
Makefile
@ -1,8 +1,8 @@
|
||||
include config.mk
|
||||
|
||||
LIB = util/enmasse.o util/eprintf.o
|
||||
SRC = basename.c cat.c date.c dirname.c echo.c false.c grep.c ln.c pwd.c rm.c \
|
||||
sleep.c tee.c touch.c true.c wc.c
|
||||
LIB = util/enmasse.o util/eprintf.o util/recurse.o
|
||||
SRC = basename.c cat.c chown.c date.c dirname.c echo.c false.c grep.c ln.c \
|
||||
pwd.c rm.c sleep.c tee.c touch.c true.c wc.c
|
||||
OBJ = $(SRC:.c=.o) $(LIB)
|
||||
BIN = $(SRC:.c=)
|
||||
MAN = $(SRC:.c=.1)
|
||||
|
15
chown.1
Normal file
15
chown.1
Normal file
@ -0,0 +1,15 @@
|
||||
.TH CHOWN 1 sbase\-VERSION
|
||||
.SH NAME
|
||||
chown \- change file ownership
|
||||
.SH SYNOPSIS
|
||||
.B chown
|
||||
.RB [ -Rr ]
|
||||
.RI [ owner ][: group ]
|
||||
.RI [ files ...]
|
||||
.SH DESCRIPTION
|
||||
.B chown
|
||||
changes the user or group ownership for the given files.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -R, -r
|
||||
change directory ownership recursively.
|
66
chown.c
Normal file
66
chown.c
Normal file
@ -0,0 +1,66 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "util.h"
|
||||
|
||||
static void chownpwgr(const char *);
|
||||
|
||||
static bool rflag = false;
|
||||
static struct passwd *pw = NULL;
|
||||
static struct group *gr = NULL;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char c, *owner, *group;
|
||||
|
||||
while((c = getopt(argc, argv, "Rr")) != -1)
|
||||
switch(c) {
|
||||
case 'R':
|
||||
case 'r':
|
||||
rflag = true;
|
||||
break;
|
||||
default:
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if(optind == argc)
|
||||
eprintf("usage: %s [-Rr] [owner][:group] [file...]\n", argv[0]);
|
||||
owner = argv[optind++];
|
||||
if((group = strchr(owner, ':')))
|
||||
*group++ = '\0';
|
||||
|
||||
if(owner && *owner) {
|
||||
errno = 0;
|
||||
pw = getpwnam(owner);
|
||||
if(errno != 0)
|
||||
eprintf("getpwnam %s:", owner);
|
||||
else if(!pw)
|
||||
eprintf("getpwnam %s: no such user\n", owner);
|
||||
}
|
||||
if(group && *group) {
|
||||
errno = 0;
|
||||
gr = getgrnam(group);
|
||||
if(errno != 0)
|
||||
eprintf("getgrnam %s:", group);
|
||||
else if(!gr)
|
||||
eprintf("getgrnam %s: no such user\n", group);
|
||||
}
|
||||
for(; optind < argc; optind++)
|
||||
chownpwgr(argv[optind]);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
chownpwgr(const char *path)
|
||||
{
|
||||
if(chown(path, pw ? pw->pw_uid : -1, gr ? gr->gr_gid : -1) != 0)
|
||||
eprintf("chown %s:", path);
|
||||
if(rflag)
|
||||
recurse(path, chownpwgr);
|
||||
}
|
38
rm.c
38
rm.c
@ -1,10 +1,7 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "util.h"
|
||||
|
||||
@ -34,36 +31,11 @@ main(int argc, char *argv[])
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void rm(const char *path)
|
||||
void
|
||||
rm(const char *path)
|
||||
{
|
||||
if(remove(path) == 0)
|
||||
return;
|
||||
if(errno == ENOTEMPTY && rflag) {
|
||||
char *buf;
|
||||
long size;
|
||||
struct dirent *d;
|
||||
DIR *dp;
|
||||
|
||||
if((size = pathconf(".", _PC_PATH_MAX)) < 0)
|
||||
size = BUFSIZ;
|
||||
if(!(buf = malloc(size)))
|
||||
eprintf("malloc:");
|
||||
if(!getcwd(buf, size))
|
||||
eprintf("getcwd:");
|
||||
if(!(dp = opendir(path)))
|
||||
eprintf("opendir %s:", path);
|
||||
if(chdir(path) != 0)
|
||||
eprintf("chdir %s:", path);
|
||||
while((d = readdir(dp)))
|
||||
if(strcmp(d->d_name, ".") && strcmp(d->d_name, ".."))
|
||||
rm(d->d_name);
|
||||
|
||||
closedir(dp);
|
||||
if(chdir(buf) != 0)
|
||||
eprintf("chdir %s:", buf);
|
||||
if(remove(path) == 0)
|
||||
return;
|
||||
}
|
||||
if(!fflag)
|
||||
if(rflag)
|
||||
recurse(path, rm);
|
||||
if(remove(path) != 0 && !fflag)
|
||||
eprintf("remove %s:", path);
|
||||
}
|
||||
|
1
util.h
1
util.h
@ -2,3 +2,4 @@
|
||||
|
||||
void enmasse(int, char **, int (*)(const char *, const char *));
|
||||
void eprintf(const char *, ...);
|
||||
void recurse(const char *, void (*)(const char *));
|
||||
|
40
util/recurse.c
Normal file
40
util/recurse.c
Normal file
@ -0,0 +1,40 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "../util.h"
|
||||
|
||||
void
|
||||
recurse(const char *path, void (*fn)(const char *))
|
||||
{
|
||||
char *buf;
|
||||
long size;
|
||||
struct dirent *d;
|
||||
DIR *dp;
|
||||
|
||||
if(!(dp = opendir(path))) {
|
||||
if(errno == ENOTDIR)
|
||||
return;
|
||||
else
|
||||
eprintf("opendir %s:", path);
|
||||
}
|
||||
if((size = pathconf(".", _PC_PATH_MAX)) < 0)
|
||||
size = BUFSIZ;
|
||||
if(!(buf = malloc(size)))
|
||||
eprintf("malloc:");
|
||||
if(!getcwd(buf, size))
|
||||
eprintf("getcwd:");
|
||||
if(chdir(path) != 0)
|
||||
eprintf("chdir %s:", path);
|
||||
while((d = readdir(dp)))
|
||||
if(strcmp(d->d_name, ".") && strcmp(d->d_name, ".."))
|
||||
fn(d->d_name);
|
||||
|
||||
closedir(dp);
|
||||
if(chdir(buf) != 0)
|
||||
eprintf("chdir %s:", buf);
|
||||
free(buf);
|
||||
}
|
Loading…
Reference in New Issue
Block a user