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