local version
[unix-history] / usr / src / bin / rm / rm.c
CommitLineData
28c2b1a2 1static char *sccsid = "@(#)rm.c 4.3 (Berkeley) %G%";
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--;
ca02483b
BJ
25
26 /*
27 * all files following a null option are considered file names
28 */
29 if (*(arg+1) == '\0') break;
30
ae80f4a2
BJ
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
58rm(arg, fflg, rflg, iflg, level)
59char 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) {
28c2b1a2 82 printf("remove directory %s? ", arg);
ae80f4a2
BJ
83 if(!yes())
84 return;
85 }
86 if((d=open(arg, 0)) < 0) {
28c2b1a2 87 printf("rm: cannot read %s?\n", arg);
ae80f4a2
BJ
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) {
28c2b1a2 106 printf("rm: remove %s? ", arg);
ae80f4a2
BJ
107 if(!yes())
108 return;
109 }
110 else if(!fflg) {
111 if (access(arg, 02)<0) {
28c2b1a2 112 printf("rm: override protection %o for %s? ", buf.st_mode&0777, arg);
ae80f4a2
BJ
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
123dotname(s)
124char *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
137rmdir(f, iflg)
138char *f;
139{
140 int status, i;
141
142 if(dotname(f))
143 return(0);
144 if(iflg) {
28c2b1a2 145 printf("rm: remove %s? ", f);
ae80f4a2
BJ
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
161yes()
162{
163 int i, b;
164
165 i = b = getchar();
166 while(b != '\n' && b != EOF)
167 b = getchar();
168 return(i == 'y');
169}