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