diff options
author | H. Peter Anvin <hpa@zytor.com> | 2004-06-07 19:57:29 +0000 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2004-06-07 19:57:29 +0000 |
commit | 0b2f8a06771c57475178910d3bc8d891b3ddce91 (patch) | |
tree | a466fd2a328c8c16202ed31b792df24be3fbd8fe | |
parent | 0386dda2b9e6e6f8b901d56ec9be08c8404f52dd (diff) | |
download | klibc-0b2f8a06771c57475178910d3bc8d891b3ddce91.tar.gz |
Add "nuke" program; save non-stripped versions in .g directoriesklibc-0.122
-rw-r--r-- | utils/Makefile | 11 | ||||
-rw-r--r-- | utils/nuke.c | 128 |
2 files changed, 135 insertions, 4 deletions
diff --git a/utils/Makefile b/utils/Makefile index 98953e9f2e9a8..486da70dceaba 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -6,7 +6,7 @@ MAKEDEPS = -Wp,-MD,.$(subst /,-,$*).d CFLAGS = $(MAKEDEPS) $(OPTFLAGS) $(REQFLAGS) -W -Wall LIBS = $(KLIBC) $(LIBGCC) PROGS := chroot dd fstype mkdir mkfifo mount pivot_root umount \ - true false sleep ln + true false sleep ln nuke STATICPROGS := $(patsubst %,static/%,$(PROGS)) SHAREDPROGS := $(patsubst %,shared/%,$(PROGS)) LIBOBJS = file_mode.o @@ -15,14 +15,16 @@ LIBUTILS = libutils.a all: $(STATICPROGS) $(SHAREDPROGS) static/%: %.o $(CRT0) $(LIBS) $(LIBUTILS) - mkdir -p static + mkdir -p static static.g $(LD) $(LDFLAGS) -o $@ $(CRT0) $< $(LIBUTILS) $(LIBS) + cp -f $@ static.g $(STRIP) $@ shared/%: %.o $(CRTSHARED) $(LIBSHARED) $(LIBUTILS) - mkdir -p shared + mkdir -p shared shared.g $(LD) $(LDFLAGS) -o $@ -e main $(CRTSHARED) $< $(LIBUTILS) \ -R $(LIBSHARED) $(LIBGCC) + cp -f $@ shared.g $(STRIP) $@ # Programs that consist of more than one file @@ -38,7 +40,8 @@ $(CRT0) $(LIBS): @echo '*** error: $@ not up to date' || exit 1 clean: - $(RM) *.o core $(PROGS) .*.d shared/* static/* + $(RM) *.o core $(PROGS) .*.d + $(RM) -rf static static.g shared shared.g spotless: clean $(RM) *~ diff --git a/utils/nuke.c b/utils/nuke.c new file mode 100644 index 0000000000000..c85fc094c026a --- /dev/null +++ b/utils/nuke.c @@ -0,0 +1,128 @@ +#ident "$Id: nuke.c,v 1.1 2004/06/07 20:40:32 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * Copyright 2004 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * nuke.c + * + * Simple program which does the same thing as rm -rf, except it takes + * no options and can therefore not get confused by filenames starting + * with -. Similarly, an empty list of inputs is assumed to mean don't + * do anything. + */ + +#include <alloca.h> +#include <assert.h> +#include <dirent.h> +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> + +static const char *program; + +static int nuke(const char *what); + +static int nuke_dirent(int len, const char *dir, const char *name) +{ + int bytes = len+strlen(name)+2; + char path[bytes]; + int xlen; + + xlen = snprintf(path, bytes, "%s/%s", dir, name); + assert(xlen < bytes); + + return nuke(path); +} + +static int nuke(const char *what) +{ + int rv; + int err; + + rv = unlink(what); + if ( rv < 0 && errno == EISDIR ) { + /* It's a directory. */ + int len = strlen(what); + DIR *dir; + struct dirent *d; + + if ( !(dir = opendir(what)) ) { + err = errno; + if ( err == EACCES ) { + /* Can't read it. Might be empty and removable */ + if ( rmdir(what) == 0 ) + return 0; + } + fprintf(stderr, "%s: %s: %s\n", program, what, strerror(err)); + return err; + } + + err = 0; + + while ( (d = readdir(dir)) ) { + /* Skip . and .. */ + if ( d->d_name[0] == '.' && + (d->d_name[1] == '\0' || + (d->d_name[1] == '.' && d->d_name[2] == '\0')) ) + continue; + + err = nuke_dirent(len, what, d->d_name); + if ( err ) { + closedir(dir); + return err; + } + } + + closedir(dir); + + rv = rmdir(what); + } + + if ( rv ) { + err = errno; + fprintf(stderr, "%s: %s: %s\n", program, what, strerror(err)); + return err; + } else { + return 0; + } +} + +int main(int argc, char *argv[]) +{ + int i; + int err = 0; + + for ( i = 1 ; i < argc ; i++ ) { + err = nuke(argv[i]); + if ( err ) + break; + } + + return !!err; +} |