xref: /original-bsd/bin/rm/rm.c (revision fb7939e6)
1 static char *sccsid = "@(#)rm.c	4.12 (Berkeley) 06/30/83";
2 int	errcode;
3 
4 #include <stdio.h>
5 #include <sys/param.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 *dp;
63 	DIR *dirp;
64 	char name[BUFSIZ];
65 	int d;
66 
67 	if(lstat(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 			if (dotname(arg))
99 				return;
100 			if (iflg) {
101 				printf("rm: remove %s? ", arg);
102 				if (!yes())
103 					return;
104 			}
105 			if (rmdir(arg) < 0) {
106 				fprintf(stderr, "rm: ");
107 				perror(arg);
108 				errcode++;
109 			}
110 			return;
111 		}
112 		printf("rm: %s directory\n", arg);
113 		++errcode;
114 		return;
115 	}
116 
117 	if(iflg) {
118 		printf("rm: remove %s? ", arg);
119 		if(!yes())
120 			return;
121 	}
122 	else if(!fflg) {
123 		if ((buf.st_mode&S_IFMT) != S_IFLNK && access(arg, 02) < 0) {
124 			printf("rm: override protection %o for %s? ", buf.st_mode&0777, arg);
125 			if(!yes())
126 				return;
127 		}
128 	}
129 	if(unlink(arg) && (fflg==0 || iflg)) {
130 		printf("rm: %s not removed\n", arg);
131 		++errcode;
132 	}
133 }
134 
135 dotname(s)
136 char *s;
137 {
138 	if(s[0] == '.')
139 		if(s[1] == '.')
140 			if(s[2] == '\0')
141 				return(1);
142 			else
143 				return(0);
144 		else if(s[1] == '\0')
145 			return(1);
146 	return(0);
147 }
148 
149 yes()
150 {
151 	int i, b;
152 
153 	i = b = getchar();
154 	while(b != '\n' && b != EOF)
155 		b = getchar();
156 	return(i == 'y');
157 }
158