add chown

This commit is contained in:
Connor Lane Smith 2011-05-25 00:24:33 +01:00
parent c367d4d05f
commit da757ff7d1
6 changed files with 130 additions and 36 deletions

View File

@ -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
View 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
View 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
View File

@ -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
View File

@ -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
View 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);
}