xref: /original-bsd/bin/rm/rm.c (revision 0b685140)
1 static char *sccsid = "@(#)rm.c	4.6 (Berkeley) 02/28/82";
2 int	errcode;
3 
4 #include <stdio.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <ndir.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 *dp;
63 	DIR *dirp;
64 	char name[BUFSIZ];
65 	int d;
66 
67 	if(stat(arg, &buf)) {
68 		if (fflg==0) {
69 			printf("rm: %s nonexistent\n", arg);
70 			++errcode;
71 		}
72 		return;
73 	}
74 	if ((buf.st_mode&S_IFMT) == S_IFDIR) {
75 		if(rflg) {
76 			if (access(arg, 02) < 0) {
77 				if (fflg==0)
78 					printf("%s not changed\n", arg);
79 				errcode++;
80 				return;
81 			}
82 			if(iflg && level!=0) {
83 				printf("remove directory %s? ", arg);
84 				if(!yes())
85 					return;
86 			}
87 			if((dirp = opendir(arg)) == NULL) {
88 				printf("rm: cannot read %s?\n", arg);
89 				exit(1);
90 			}
91 			while((dp = readdir(dirp)) != NULL) {
92 				if(dp->d_ino != 0 && !dotname(dp->d_name)) {
93 					sprintf(name, "%s/%s", arg, dp->d_name);
94 					rm(name, fflg, rflg, iflg, level+1);
95 				}
96 			}
97 			closedir(dirp);
98 			errcode += rmdir(arg, iflg);
99 			return;
100 		}
101 		printf("rm: %s directory\n", arg);
102 		++errcode;
103 		return;
104 	}
105 
106 	if(iflg) {
107 		printf("rm: remove %s? ", arg);
108 		if(!yes())
109 			return;
110 	}
111 	else if(!fflg) {
112 		if (access(arg, 02)<0) {
113 			printf("rm: override protection %o for %s? ", buf.st_mode&0777, arg);
114 			if(!yes())
115 				return;
116 		}
117 	}
118 	if(unlink(arg) && (fflg==0 || iflg)) {
119 		printf("rm: %s not removed\n", arg);
120 		++errcode;
121 	}
122 }
123 
124 dotname(s)
125 char *s;
126 {
127 	if(s[0] == '.')
128 		if(s[1] == '.')
129 			if(s[2] == '\0')
130 				return(1);
131 			else
132 				return(0);
133 		else if(s[1] == '\0')
134 			return(1);
135 	return(0);
136 }
137 
138 rmdir(f, iflg)
139 char *f;
140 {
141 	int status, i;
142 
143 	if(dotname(f))
144 		return(0);
145 	if(iflg) {
146 		printf("rm: remove %s? ", f);
147 		if(!yes())
148 			return(0);
149 	}
150 	while((i=fork()) == -1)
151 		sleep(3);
152 	if(i) {
153 		wait(&status);
154 		return(status);
155 	}
156 	execl("/bin/rmdir", "rmdir", f, 0);
157 	execl("/usr/bin/rmdir", "rmdir", f, 0);
158 	printf("rm: can't find rmdir\n");
159 	exit(1);
160 }
161 
162 yes()
163 {
164 	int i, b;
165 
166 	i = b = getchar();
167 	while(b != '\n' && b != EOF)
168 		b = getchar();
169 	return(i == 'y');
170 }
171