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