BSD 4 release
[unix-history] / usr / src / cmd / rmdir.c
CommitLineData
31cef89c 1static char *sccsid = "@(#)rmdir.c 4.1 (Berkeley) 10/1/80";
9c79dca0
BJ
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
11int Errors = 0;
12char *rindex();
13char *strcat();
14char *strcpy();
15
16main(argc,argv)
17int argc;
18char **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
30rmdir(d)
31char *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 }
95unl:
96 unlink(name); /* unlink name/.. */
97unl2:
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}