Charles.Forsyth20060303644188019 years agoHistory
151 lines · 2.3 KB · C
RawDownload
#include <lib9.h>#include <windows.h> typedef struct	Direntry{	int	isdir;	char	*name;} Direntry; char	errbuf[ERRMAX];long	ndirbuf = 0;int	ignerr = 0; voiderr(char *f){	if(!ignerr){		errstr(errbuf, sizeof errbuf);		fprint(2, "rm: %s: %s\n", f, errbuf);	}} intbadentry(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. */voidNtrmdir(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);} voidmain(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);}