xref: /original-bsd/bin/rm/rm.c (revision d25e1985)
1 static char *sccsid = "@(#)rm.c	4.1 (Berkeley) 10/01/80";
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 		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 
52 rm(arg, fflg, rflg, iflg, level)
53 char 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) {
76 				printf("directory %s: ", arg);
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) {
100 		printf("%s: ", arg);
101 		if(!yes())
102 			return;
103 	}
104 	else if(!fflg) {
105 		if (access(arg, 02)<0) {
106 			printf("rm: %s %o mode ", arg, buf.st_mode&0777);
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 
117 dotname(s)
118 char *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 
131 rmdir(f, iflg)
132 char *f;
133 {
134 	int status, i;
135 
136 	if(dotname(f))
137 		return(0);
138 	if(iflg) {
139 		printf("%s: ", f);
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 
155 yes()
156 {
157 	int i, b;
158 
159 	i = b = getchar();
160 	while(b != '\n' && b != EOF)
161 		b = getchar();
162 	return(i == 'y');
163 }
164