xref: /original-bsd/bin/rmdir/rmdir.c (revision c7de680c)
1 static char *sccsid = "@(#)rmdir.c	4.5 (Berkeley) 05/07/82";
2 /*
3  * Remove directory
4  */
5 
6 #include <sys/param.h>
7 #include <sys/stat.h>
8 #include <dir.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 	char	*np, name[BUFSIZ];
34 	struct	stat	st, cst;
35 	struct	direct	*dp;
36 	DIR	*dirp;
37 
38 	strcpy(name, d);
39 
40 	/* eat trailing slashes */
41 	np = &(name[strlen(name)-1]);
42 	while (*np == '/' && np != name) {
43 		*np = '\0';
44 		np--;
45 	}
46 
47 	/* point after last slash */
48 	if((np = rindex(name, '/')) == NULL)
49 		np = name;
50 	else
51 		np++;
52 
53 	if(!strcmp(np, ".") || !strcmp(np, "..")) {
54 		fprintf(stderr, "rmdir: cannot remove . or ..\n");
55 		++Errors;
56 		return;
57 	}
58 	if(stat(name,&st) < 0) {
59 		fprintf(stderr, "rmdir: %s non-existent\n", name);
60 		++Errors;
61 		return;
62 	}
63 	if (stat("", &cst) < 0) {
64 		fprintf(stderr, "rmdir: cannot stat \"\"");
65 		++Errors;
66 		exit(1);
67 	}
68 	if((st.st_mode & S_IFMT) != S_IFDIR) {
69 		fprintf(stderr, "rmdir: %s not a directory\n", name);
70 		++Errors;
71 		return;
72 	}
73 	if(st.st_ino==cst.st_ino &&st.st_dev==cst.st_dev) {
74 		fprintf(stderr, "rmdir: cannot remove current directory\n");
75 		++Errors;
76 		return;
77 	}
78 	if((dirp = opendir(name)) == NULL) {
79 		fprintf(stderr, "rmdir: %s unreadable\n", name);
80 		++Errors;
81 		return;
82 	}
83 	while((dp = readdir(dirp)) != NULL) {
84 		if(dp->d_ino == 0) continue;
85 		if(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
86 			continue;
87 		fprintf(stderr, "rmdir: %s not empty\n", name);
88 		++Errors;
89 		closedir(dirp);
90 		return;
91 	}
92 	closedir(dirp);
93 	strcat(name, "/.");
94 	if((access(name, 0)) < 0) {		/* name/. non-existent */
95 		strcat(name, ".");
96 		goto unl;
97 	}
98 	strcat(name, ".");
99 	if((access(name, 0)) < 0)		/* name/.. non-existent */
100 		goto unl2;
101 	if(access(name, 02)) {
102 		name[strlen(name)-3] = '\0';
103 		fprintf(stderr, "rmdir: %s: no permission\n", name);
104 		++Errors;
105 		return;
106 	}
107 unl:
108 	unlink(name);	/* unlink name/.. */
109 unl2:
110 	name[strlen(name)-1] = '\0';
111 	unlink(name);	/* unlink name/.  */
112 	name[strlen(name)-2] = '\0';
113 	if (unlink(name) < 0) {
114 		fprintf(stderr, "rmdir: %s not removed\n", name);
115 		++Errors;
116 	}
117 }
118