summaryrefslogtreecommitdiff
path: root/utils/rm/rm-Nt.c
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
commit74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (patch)
treec6e220ba61db3a6ea4052e6841296d829654e664 /utils/rm/rm-Nt.c
parent46439007cf417cbd9ac8049bb4122c890097a0fa (diff)
20060303
Diffstat (limited to 'utils/rm/rm-Nt.c')
-rw-r--r--utils/rm/rm-Nt.c151
1 files changed, 151 insertions, 0 deletions
diff --git a/utils/rm/rm-Nt.c b/utils/rm/rm-Nt.c
new file mode 100644
index 00000000..9c666213
--- /dev/null
+++ b/utils/rm/rm-Nt.c
@@ -0,0 +1,151 @@
+#include <lib9.h>
+#include <windows.h>
+
+typedef struct Direntry
+{
+ int isdir;
+ char *name;
+} Direntry;
+
+char errbuf[ERRMAX];
+long ndirbuf = 0;
+int ignerr = 0;
+
+void
+err(char *f)
+{
+ if(!ignerr){
+ errstr(errbuf, sizeof errbuf);
+ fprint(2, "rm: %s: %s\n", f, errbuf);
+ }
+}
+
+int
+badentry(char *filename)
+{
+ if(*filename == 0)
+ return 1;
+ if(filename[0] == '.'){
+ if(filename[1] == 0)
+ return 1;
+ if(filename[1] == '.' && filename[2] == 0)
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Read a whole directory before removing anything as the holes formed
+ * by removing affect the read offset.
+ */
+Direntry*
+readdirect(char *path)
+{
+ long n;
+ HANDLE h;
+ Direntry *d;
+ char fullpath[MAX_PATH];
+ WIN32_FIND_DATA data;
+
+ snprint(fullpath, MAX_PATH, "%s\\*.*", path);
+ h = FindFirstFile(fullpath, &data);
+ if(h == INVALID_HANDLE_VALUE)
+ err(path);
+
+ n = 0;
+ d = 0;
+ for(;;){
+ if(!badentry(data.cFileName)){
+ d = realloc(d, (n+2)*sizeof(Direntry));
+ if(d == 0){
+ err("memory allocation");
+ exits(errbuf);
+ }
+ d[n].name = malloc(strlen(data.cFileName)+1);
+ if(d[n].name == 0){
+ err("memory allocation");
+ exits(errbuf);
+ }
+ strcpy(d[n].name, data.cFileName);
+ if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ d[n].isdir = 1;
+ else
+ d[n].isdir = 0;
+ n++;
+ }
+ if(FindNextFile(h, &data) == 0)
+ break;
+ }
+ FindClose(h);
+ if(d){
+ d[n].name = 0;
+ d[n].isdir = 0;
+ }
+ return d;
+}
+
+/*
+ * f is a non-empty directory. Remove its contents and then it.
+ */
+void
+Ntrmdir(char *f)
+{
+ Direntry *dp, *dq;
+ char name[MAX_PATH];
+
+ dq = readdirect(f);
+
+ if(dq == 0)
+ return;
+
+ for(dp = dq; dp->name; dp++){
+ snprint(name, MAX_PATH, "%s/%s", f, dp->name);
+ if(remove(name) == -1){
+ if(dp->isdir == 0)
+ err(name);
+ else
+ if(RemoveDirectory(name) == 0)
+ Ntrmdir(name);
+ }
+ free(dp->name);
+ }
+ if(RemoveDirectory(f) == 0)
+ err(f);
+ free(dq);
+}
+
+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;
+ if((db = dirstat(f)) == nil || (db->qid.type&QTDIR) ==0)
+ err(f);
+ else if(RemoveDirectory(f) == 0)
+ if(recurse)
+ Ntrmdir(f);
+ else
+ err(f);
+ }
+ exits(errbuf);
+}