1: #ifndef lint 2: static char *sccsid = "@(#)rm.c 4.3 (Berkeley) 1/4/81"; 3: #endif 4: int errcode; 5: 6: #include <stdio.h> 7: #include <sys/param.h> 8: #include <sys/stat.h> 9: #include <sys/dir.h> 10: #include <sys/file.h> 11: 12: char *sprintf(); 13: 14: main(argc, argv) 15: char *argv[]; 16: { 17: register char *arg; 18: int fflg, iflg, rflg; 19: 20: fflg = 0; 21: if (isatty(0) == 0) 22: fflg++; 23: iflg = 0; 24: rflg = 0; 25: while(argc>1 && argv[1][0]=='-') { 26: arg = *++argv; 27: argc--; 28: 29: /* 30: * all files following a null option are considered file names 31: */ 32: if (*(arg+1) == '\0') break; 33: 34: while(*++arg != '\0') 35: switch(*arg) { 36: case 'f': 37: fflg++; 38: break; 39: case 'i': 40: iflg++; 41: break; 42: case 'r': 43: rflg++; 44: break; 45: default: 46: printf("rm: unknown option %s\n", *argv); 47: exit(1); 48: } 49: } 50: while(--argc > 0) { 51: if(!strcmp(*++argv, "..")) { 52: fprintf(stderr, "rm: cannot remove `..'\n"); 53: continue; 54: } 55: rm(*argv, fflg, rflg, iflg, 0); 56: } 57: 58: exit(errcode); 59: } 60: 61: rm(arg, fflg, rflg, iflg, level) 62: char arg[]; 63: { 64: struct stat buf; 65: struct direct direct; 66: char name[100]; 67: int d; 68: 69: #ifdef UCB_SYMLINKS 70: if(lstat(arg, &buf)) 71: #else 72: if(stat(arg, &buf)) 73: #endif 74: { 75: if (fflg==0) { 76: printf("rm: %s nonexistent\n", arg); 77: ++errcode; 78: } 79: return; 80: } 81: if ((buf.st_mode&S_IFMT) == S_IFDIR) { 82: if(rflg) { 83: if (access(arg, FACCESS_WRITE) < 0) { 84: if (fflg==0) 85: printf("%s not changed\n", arg); 86: errcode++; 87: return; 88: } 89: if(iflg && level!=0) { 90: printf("remove directory %s? ", arg); 91: if(!yes()) 92: return; 93: } 94: if((d=open(arg, 0)) < 0) { 95: printf("rm: cannot read %s?\n", arg); 96: exit(1); 97: } 98: while(read(d, (char *)&direct, sizeof(direct)) == sizeof(direct)) { 99: if(direct.d_ino != 0 && !dotname(direct.d_name)) { 100: sprintf(name, "%s/%.14s", arg, direct.d_name); 101: rm(name, fflg, rflg, iflg, level+1); 102: } 103: } 104: close(d); 105: errcode += rmdir(arg, iflg); 106: return; 107: } 108: printf("rm: %s directory\n", arg); 109: ++errcode; 110: return; 111: } 112: 113: if(iflg) { 114: printf("rm: remove %s? ", arg); 115: if(!yes()) 116: return; 117: } 118: else if(!fflg) { 119: if ((buf.st_mode&S_IFMT) != S_IFLNK && access(arg, FACCESS_WRITE)<0) { 120: printf("rm: override protection %o for %s? ", buf.st_mode&0777, arg); 121: if(!yes()) 122: return; 123: } 124: } 125: if(unlink(arg) && (fflg==0 || iflg)) { 126: printf("rm: %s not removed\n", arg); 127: ++errcode; 128: } 129: } 130: 131: dotname(s) 132: char *s; 133: { 134: if(s[0] == '.') 135: if(s[1] == '.') 136: if(s[2] == '\0') 137: return(1); 138: else 139: return(0); 140: else if(s[1] == '\0') 141: return(1); 142: return(0); 143: } 144: 145: rmdir(f, iflg) 146: char *f; 147: { 148: int status, i; 149: 150: if(dotname(f)) 151: return(0); 152: if(iflg) { 153: printf("rm: remove %s? ", f); 154: if(!yes()) 155: return(0); 156: } 157: while((i=fork()) == -1) 158: sleep(3); 159: if(i) { 160: wait(&status); 161: return(status); 162: } 163: execl("/bin/rmdir", "rmdir", f, 0); 164: execl("/usr/bin/rmdir", "rmdir", f, 0); 165: printf("rm: can't find rmdir\n"); 166: exit(1); 167: /*NOTREACHED*/ 168: } 169: 170: yes() 171: { 172: int i, b; 173: 174: i = b = getchar(); 175: while(b != '\n' && b != EOF) 176: b = getchar(); 177: return(i == 'y'); 178: }