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