plan9port/src/cmd/rm.c
rsc 912fba95e7 Changes for Mac OS X. Most important is stack sizes in samterm,
which were completely bogus.  (Libthread used to ignore them but
not anymore.  Maybe we really should ignore them, but that breaks
Venti, which needs *really* big stacks.)
2003-11-24 22:39:06 +00:00

104 lines
1.6 KiB
C

#include <u.h>
#include <libc.h>
#define rmdir p9rmdir
char errbuf[ERRMAX];
int ignerr = 0;
static 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);
}