xref: /original-bsd/bin/rm/rm.c (revision 6c57d260)
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