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