aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/rm.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-11-23 18:04:47 +0000
committerrsc <devnull@localhost>2003-11-23 18:04:47 +0000
commitbc7cb1a15a67c859c8c71c4b52bb35fe9425a63d (patch)
tree8ca0fe4e2418e6aa18dc74a236c577a719f6c6ed /src/cmd/rm.c
parentf08fdedcee12c06e3ce9ac9bec363915978e8289 (diff)
downloadplan9port-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.c104
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);
+}