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