xref: /plan9/sys/src/cmd/rm.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier 
4*9a747e4fSDavid du Colombier char	errbuf[ERRMAX];
53e12c5d1SDavid du Colombier int	ignerr = 0;
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier void
err(char * f)83e12c5d1SDavid du Colombier err(char *f)
93e12c5d1SDavid du Colombier {
103e12c5d1SDavid du Colombier 	if(!ignerr){
11*9a747e4fSDavid du Colombier 		errbuf[0] = '\0';
12*9a747e4fSDavid du Colombier 		errstr(errbuf, sizeof errbuf);
133e12c5d1SDavid du Colombier 		fprint(2, "rm: %s: %s\n", f, errbuf);
143e12c5d1SDavid du Colombier 	}
153e12c5d1SDavid du Colombier }
163e12c5d1SDavid du Colombier 
173e12c5d1SDavid du Colombier /*
183e12c5d1SDavid du Colombier  * f is a non-empty directory. Remove its contents and then it.
193e12c5d1SDavid du Colombier  */
203e12c5d1SDavid du Colombier void
rmdir(char * f)213e12c5d1SDavid du Colombier rmdir(char *f)
223e12c5d1SDavid du Colombier {
233e12c5d1SDavid du Colombier 	char *name;
24*9a747e4fSDavid du Colombier 	int fd, i, j, n, ndir, nname;
25*9a747e4fSDavid du Colombier 	Dir *dirbuf;
263e12c5d1SDavid du Colombier 
273e12c5d1SDavid du Colombier 	fd = open(f, OREAD);
283e12c5d1SDavid du Colombier 	if(fd < 0){
293e12c5d1SDavid du Colombier 		err(f);
303e12c5d1SDavid du Colombier 		return;
313e12c5d1SDavid du Colombier 	}
32*9a747e4fSDavid du Colombier 	n = dirreadall(fd, &dirbuf);
333e12c5d1SDavid du Colombier 	close(fd);
34*9a747e4fSDavid du Colombier 	if(n < 0){
35*9a747e4fSDavid du Colombier 		err("dirreadall");
36*9a747e4fSDavid du Colombier 		return;
37*9a747e4fSDavid du Colombier 	}
383e12c5d1SDavid du Colombier 
39*9a747e4fSDavid du Colombier 	nname = strlen(f)+1+STATMAX+1;	/* plenty! */
40*9a747e4fSDavid du Colombier 	name = malloc(nname);
413e12c5d1SDavid du Colombier 	if(name == 0){
423e12c5d1SDavid du Colombier 		err("memory allocation");
433e12c5d1SDavid du Colombier 		return;
443e12c5d1SDavid du Colombier 	}
453e12c5d1SDavid du Colombier 
463e12c5d1SDavid du Colombier 	ndir = 0;
473e12c5d1SDavid du Colombier 	for(i=0; i<n; i++){
48*9a747e4fSDavid du Colombier 		snprint(name, nname, "%s/%s", f, dirbuf[i].name);
493e12c5d1SDavid du Colombier 		if(remove(name) != -1)
50*9a747e4fSDavid du Colombier 			dirbuf[i].qid.type = QTFILE;	/* so we won't recurse */
513e12c5d1SDavid du Colombier 		else{
52*9a747e4fSDavid du Colombier 			if(dirbuf[i].qid.type & QTDIR)
533e12c5d1SDavid du Colombier 				ndir++;
543e12c5d1SDavid du Colombier 			else
553e12c5d1SDavid du Colombier 				err(name);
563e12c5d1SDavid du Colombier 		}
573e12c5d1SDavid du Colombier 	}
58*9a747e4fSDavid du Colombier 	if(ndir)
59*9a747e4fSDavid du Colombier 		for(j=0; j<n; j++)
60*9a747e4fSDavid du Colombier 			if(dirbuf[j].qid.type & QTDIR){
61*9a747e4fSDavid du Colombier 				snprint(name, nname, "%s/%s", f, dirbuf[j].name);
623e12c5d1SDavid du Colombier 				rmdir(name);
633e12c5d1SDavid du Colombier 			}
643e12c5d1SDavid du Colombier 	if(remove(f) == -1)
653e12c5d1SDavid du Colombier 		err(f);
663e12c5d1SDavid du Colombier 	free(name);
67*9a747e4fSDavid du Colombier 	free(dirbuf);
683e12c5d1SDavid du Colombier }
693e12c5d1SDavid du Colombier void
main(int argc,char * argv[])703e12c5d1SDavid du Colombier main(int argc, char *argv[])
713e12c5d1SDavid du Colombier {
723e12c5d1SDavid du Colombier 	int i;
733e12c5d1SDavid du Colombier 	int recurse;
743e12c5d1SDavid du Colombier 	char *f;
75*9a747e4fSDavid du Colombier 	Dir *db;
763e12c5d1SDavid du Colombier 
773e12c5d1SDavid du Colombier 	ignerr = 0;
783e12c5d1SDavid du Colombier 	recurse = 0;
793e12c5d1SDavid du Colombier 	ARGBEGIN{
803e12c5d1SDavid du Colombier 	case 'r':
813e12c5d1SDavid du Colombier 		recurse = 1;
823e12c5d1SDavid du Colombier 		break;
833e12c5d1SDavid du Colombier 	case 'f':
843e12c5d1SDavid du Colombier 		ignerr = 1;
853e12c5d1SDavid du Colombier 		break;
863e12c5d1SDavid du Colombier 	default:
873e12c5d1SDavid du Colombier 		fprint(2, "usage: rm [-fr] file ...\n");
883e12c5d1SDavid du Colombier 		exits("usage");
893e12c5d1SDavid du Colombier 	}ARGEND
903e12c5d1SDavid du Colombier 	for(i=0; i<argc; i++){
913e12c5d1SDavid du Colombier 		f = argv[i];
923e12c5d1SDavid du Colombier 		if(remove(f) != -1)
933e12c5d1SDavid du Colombier 			continue;
94*9a747e4fSDavid du Colombier 		db = nil;
95*9a747e4fSDavid du Colombier 		if(recurse && (db=dirstat(f))!=nil && (db->qid.type&QTDIR))
963e12c5d1SDavid du Colombier 			rmdir(f);
973e12c5d1SDavid du Colombier 		else
983e12c5d1SDavid du Colombier 			err(f);
99*9a747e4fSDavid du Colombier 		free(db);
1003e12c5d1SDavid du Colombier 	}
1013e12c5d1SDavid du Colombier 	exits(errbuf);
1023e12c5d1SDavid du Colombier }
103