sbase

suckless unix tools
git clone git://git.2f30.org/sbase
Log | Files | Refs | README | LICENSE

commit 8c76381e9199137db0a1cdc7e49cfa92f1863ea8
parent 9714d7b1d32f97e63ea99ba614673e1e39c051c0
Author: Connor Lane Smith <cls@lubutu.com>
Date:   Tue, 24 May 2011 01:52:28 +0100

add rm, thanks rob
Diffstat:
MLICENSE | 1+
MMakefile | 2+-
Arm.1 | 17+++++++++++++++++
Arm.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtouch.c | 4++--
5 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -3,6 +3,7 @@ MIT/X Consortium License © 2011 Connor Lane Smith <cls@lubutu.com> © 2011 Kamil Cholewiński <harry666t@gmail.com> © 2011 stateless <stateless@archlinux.us> +© 2011 Rob Pilling <robpilling@gmail.com> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/Makefile b/Makefile @@ -1,6 +1,6 @@ include config.mk -SRC = basename.c cat.c date.c echo.c false.c grep.c pwd.c sleep.c tee.c touch.c true.c wc.c +SRC = basename.c cat.c date.c echo.c false.c grep.c pwd.c rm.c sleep.c tee.c touch.c true.c wc.c OBJ = $(SRC:.c=.o) util.o BIN = $(SRC:.c=) MAN = $(SRC:.c=.1) diff --git a/rm.1 b/rm.1 @@ -0,0 +1,17 @@ +.TH RM 1 sbase\-VERSION +.SH NAME +rm \- remove files and directories +.SH SYNOPSIS +.B rm +.RB [ \-fr ] +.RI [ files ...] +.SH DESCRIPTION +.B rm +removes the given files and directories. +.SH OPTIONS +.TP +.B \-f +ignored, for compatibility. +.TP +.B \-r +remove directories recursively. diff --git a/rm.c b/rm.c @@ -0,0 +1,58 @@ +/* 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" + +static void rm(const char *); + +static bool rflag = 0; + +int +main(int argc, char *argv[]) +{ + char c; + + while((c = getopt(argc, argv, "fr")) != -1) + switch(c) { + case 'f': + break; + case 'r': + rflag = true; + break; + default: + exit(EXIT_FAILURE); + } + for(; optind < argc; optind++) + rm(argv[optind]); + return EXIT_SUCCESS; +} + +void rm(const char *path) +{ + if(remove(path) == 0) + return; + if(errno == ENOTEMPTY && rflag) { + struct dirent *d; + DIR *dp; + + 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("..") != 0) + eprintf("chdir:"); + if(remove(path) == 0) + return; + } + eprintf("remove %s:", path); +} diff --git a/touch.c b/touch.c @@ -43,7 +43,7 @@ touch(const char *str) struct stat st; struct utimbuf ut; - if(stat(str, &st) < 0) { + if(stat(str, &st) != 0) { if(errno != ENOENT) eprintf("stat %s:", str); if(cflag) @@ -54,6 +54,6 @@ touch(const char *str) } ut.actime = st.st_atime; ut.modtime = t; - if(utime(str, &ut) < 0) + if(utime(str, &ut) != 0) eprintf("utime %s:", str); }