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