diff options
author | rsc <devnull@localhost> | 2003-11-23 18:04:47 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2003-11-23 18:04:47 +0000 |
commit | bc7cb1a15a67c859c8c71c4b52bb35fe9425a63d (patch) | |
tree | 8ca0fe4e2418e6aa18dc74a236c577a719f6c6ed /src/cmd/rm.c | |
parent | f08fdedcee12c06e3ce9ac9bec363915978e8289 (diff) | |
download | plan9port-bc7cb1a15a67c859c8c71c4b52bb35fe9425a63d.tar.gz plan9port-bc7cb1a15a67c859c8c71c4b52bb35fe9425a63d.tar.bz2 plan9port-bc7cb1a15a67c859c8c71c4b52bb35fe9425a63d.zip |
new utilities.
the .C files compile but are renamed to avoid building automatically.
Diffstat (limited to 'src/cmd/rm.c')
-rw-r--r-- | src/cmd/rm.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/cmd/rm.c b/src/cmd/rm.c new file mode 100644 index 00000000..6066543e --- /dev/null +++ b/src/cmd/rm.c @@ -0,0 +1,104 @@ +#include <u.h> +#include <libc.h> + +#define rmdir p9rmdir + +char errbuf[ERRMAX]; +int ignerr = 0; + +void +err(char *f) +{ + if(!ignerr){ + errbuf[0] = '\0'; + errstr(errbuf, sizeof errbuf); + fprint(2, "rm: %s: %s\n", f, errbuf); + } +} + +/* + * f is a non-empty directory. Remove its contents and then it. + */ +void +rmdir(char *f) +{ + char *name; + int fd, i, j, n, ndir, nname; + Dir *dirbuf; + + fd = open(f, OREAD); + if(fd < 0){ + err(f); + return; + } + n = dirreadall(fd, &dirbuf); + close(fd); + if(n < 0){ + err("dirreadall"); + return; + } + + nname = strlen(f)+1+STATMAX+1; /* plenty! */ + name = malloc(nname); + if(name == 0){ + err("memory allocation"); + return; + } + + ndir = 0; + for(i=0; i<n; i++){ + snprint(name, nname, "%s/%s", f, dirbuf[i].name); + if(remove(name) != -1) + dirbuf[i].qid.type = QTFILE; /* so we won't recurse */ + else{ + if(dirbuf[i].qid.type & QTDIR) + ndir++; + else + err(name); + } + } + if(ndir) + for(j=0; j<n; j++) + if(dirbuf[j].qid.type & QTDIR){ + snprint(name, nname, "%s/%s", f, dirbuf[j].name); + rmdir(name); + } + if(remove(f) == -1) + err(f); + free(name); + free(dirbuf); +} +void +main(int argc, char *argv[]) +{ + int i; + int recurse; + char *f; + Dir *db; + + ignerr = 0; + recurse = 0; + ARGBEGIN{ + case 'r': + recurse = 1; + break; + case 'f': + ignerr = 1; + break; + default: + fprint(2, "usage: rm [-fr] file ...\n"); + exits("usage"); + }ARGEND + for(i=0; i<argc; i++){ + f = argv[i]; + if(remove(f) != -1) + continue; + db = nil; + if(recurse && (db=dirstat(f))!=nil && (db->qid.type&QTDIR)) + rmdir(f); + else + err(f); + free(db); + } + exits(errbuf); +} |