xref: /csrg-svn/bin/rmdir/rmdir.c (revision 1085)
1*1085Sbill static char *sccsid = "@(#)rmdir.c	4.1 (Berkeley) 10/01/80";
2*1085Sbill /*
3*1085Sbill  * Remove directory
4*1085Sbill  */
5*1085Sbill 
6*1085Sbill #include <sys/types.h>
7*1085Sbill #include <sys/dir.h>
8*1085Sbill #include <sys/stat.h>
9*1085Sbill #include <stdio.h>
10*1085Sbill 
11*1085Sbill int	Errors = 0;
12*1085Sbill char	*rindex();
13*1085Sbill char	*strcat();
14*1085Sbill char	*strcpy();
15*1085Sbill 
16*1085Sbill main(argc,argv)
17*1085Sbill int argc;
18*1085Sbill char **argv;
19*1085Sbill {
20*1085Sbill 
21*1085Sbill 	if(argc < 2) {
22*1085Sbill 		fprintf(stderr, "rmdir: arg count\n");
23*1085Sbill 		exit(1);
24*1085Sbill 	}
25*1085Sbill 	while(--argc)
26*1085Sbill 		rmdir(*++argv);
27*1085Sbill 	exit(Errors!=0);
28*1085Sbill }
29*1085Sbill 
30*1085Sbill rmdir(d)
31*1085Sbill char *d;
32*1085Sbill {
33*1085Sbill 	int	fd;
34*1085Sbill 	char	*np, name[500];
35*1085Sbill 	struct	stat	st, cst;
36*1085Sbill 	struct	direct	dir;
37*1085Sbill 
38*1085Sbill 	strcpy(name, d);
39*1085Sbill 	if((np = rindex(name, '/')) == NULL)
40*1085Sbill 		np = name;
41*1085Sbill 	if(stat(name,&st) < 0) {
42*1085Sbill 		fprintf(stderr, "rmdir: %s non-existent\n", name);
43*1085Sbill 		++Errors;
44*1085Sbill 		return;
45*1085Sbill 	}
46*1085Sbill 	if (stat("", &cst) < 0) {
47*1085Sbill 		fprintf(stderr, "rmdir: cannot stat \"\"");
48*1085Sbill 		++Errors;
49*1085Sbill 		exit(1);
50*1085Sbill 	}
51*1085Sbill 	if((st.st_mode & S_IFMT) != S_IFDIR) {
52*1085Sbill 		fprintf(stderr, "rmdir: %s not a directory\n", name);
53*1085Sbill 		++Errors;
54*1085Sbill 		return;
55*1085Sbill 	}
56*1085Sbill 	if(st.st_ino==cst.st_ino &&st.st_dev==cst.st_dev) {
57*1085Sbill 		fprintf(stderr, "rmdir: cannot remove current directory\n");
58*1085Sbill 		++Errors;
59*1085Sbill 		return;
60*1085Sbill 	}
61*1085Sbill 	if((fd = open(name,0)) < 0) {
62*1085Sbill 		fprintf(stderr, "rmdir: %s unreadable\n", name);
63*1085Sbill 		++Errors;
64*1085Sbill 		return;
65*1085Sbill 	}
66*1085Sbill 	while(read(fd, (char *)&dir, sizeof dir) == sizeof dir) {
67*1085Sbill 		if(dir.d_ino == 0) continue;
68*1085Sbill 		if(!strcmp(dir.d_name, ".") || !strcmp(dir.d_name, ".."))
69*1085Sbill 			continue;
70*1085Sbill 		fprintf(stderr, "rmdir: %s not empty\n", name);
71*1085Sbill 		++Errors;
72*1085Sbill 		close(fd);
73*1085Sbill 		return;
74*1085Sbill 	}
75*1085Sbill 	close(fd);
76*1085Sbill 	if(!strcmp(np, ".") || !strcmp(np, "..")) {
77*1085Sbill 		fprintf(stderr, "rmdir: cannot remove . or ..\n");
78*1085Sbill 		++Errors;
79*1085Sbill 		return;
80*1085Sbill 	}
81*1085Sbill 	strcat(name, "/.");
82*1085Sbill 	if((access(name, 0)) < 0) {		/* name/. non-existent */
83*1085Sbill 		strcat(name, ".");
84*1085Sbill 		goto unl;
85*1085Sbill 	}
86*1085Sbill 	strcat(name, ".");
87*1085Sbill 	if((access(name, 0)) < 0)		/* name/.. non-existent */
88*1085Sbill 		goto unl2;
89*1085Sbill 	if(access(name, 02)) {
90*1085Sbill 		name[strlen(name)-3] = '\0';
91*1085Sbill 		fprintf(stderr, "rmdir: %s: no permission\n", name);
92*1085Sbill 		++Errors;
93*1085Sbill 		return;
94*1085Sbill 	}
95*1085Sbill unl:
96*1085Sbill 	unlink(name);	/* unlink name/.. */
97*1085Sbill unl2:
98*1085Sbill 	name[strlen(name)-1] = '\0';
99*1085Sbill 	unlink(name);	/* unlink name/.  */
100*1085Sbill 	name[strlen(name)-2] = '\0';
101*1085Sbill 	if (unlink(name) < 0) {
102*1085Sbill 		fprintf(stderr, "rmdir: %s not removed\n", name);
103*1085Sbill 		++Errors;
104*1085Sbill 	}
105*1085Sbill }
106