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