xref: /csrg-svn/bin/rm/rm.c (revision 17964)
1*17964Sserge static char *sccsid = "@(#)rm.c	4.13 (Berkeley) 02/14/85";
21083Sbill int	errcode;
31083Sbill 
41083Sbill #include <stdio.h>
56413Smckusic #include <sys/param.h>
61083Sbill #include <sys/stat.h>
713491Ssam #include <sys/dir.h>
81083Sbill 
91083Sbill char	*sprintf();
101083Sbill 
111083Sbill main(argc, argv)
121083Sbill char *argv[];
131083Sbill {
141083Sbill 	register char *arg;
151083Sbill 	int fflg, iflg, rflg;
161083Sbill 
171083Sbill 	fflg = 0;
181083Sbill 	if (isatty(0) == 0)
191083Sbill 		fflg++;
201083Sbill 	iflg = 0;
211083Sbill 	rflg = 0;
221083Sbill 	while(argc>1 && argv[1][0]=='-') {
231083Sbill 		arg = *++argv;
241083Sbill 		argc--;
251932Sroot 
261932Sroot 		/*
271932Sroot 		 *  all files following a null option are considered file names
281932Sroot 		 */
291932Sroot 		if (*(arg+1) == '\0') break;
301932Sroot 
311083Sbill 		while(*++arg != '\0')
321083Sbill 			switch(*arg) {
331083Sbill 			case 'f':
341083Sbill 				fflg++;
351083Sbill 				break;
361083Sbill 			case 'i':
371083Sbill 				iflg++;
381083Sbill 				break;
39*17964Sserge 			case 'R':
401083Sbill 			case 'r':
411083Sbill 				rflg++;
421083Sbill 				break;
431083Sbill 			default:
441083Sbill 				printf("rm: unknown option %s\n", *argv);
451083Sbill 				exit(1);
461083Sbill 			}
471083Sbill 	}
48*17964Sserge 
49*17964Sserge 	if (argc < 2) {
50*17964Sserge 		fprintf(stderr, "usage: rm [-rif] file ...\n");
51*17964Sserge 		exit(1);
52*17964Sserge 	}
53*17964Sserge 
541083Sbill 	while(--argc > 0) {
551083Sbill 		if(!strcmp(*++argv, "..")) {
561083Sbill 			fprintf(stderr, "rm: cannot remove `..'\n");
571083Sbill 			continue;
581083Sbill 		}
591083Sbill 		rm(*argv, fflg, rflg, iflg, 0);
601083Sbill 	}
611083Sbill 
621083Sbill 	exit(errcode);
631083Sbill }
641083Sbill 
651083Sbill rm(arg, fflg, rflg, iflg, level)
661083Sbill char arg[];
671083Sbill {
681083Sbill 	struct stat buf;
695898Smckusic 	struct direct *dp;
705898Smckusic 	DIR *dirp;
71*17964Sserge 	char name[MAXPATHLEN + 1];
721083Sbill 	int d;
731083Sbill 
746402Sroot 	if(lstat(arg, &buf)) {
751083Sbill 		if (fflg==0) {
761083Sbill 			printf("rm: %s nonexistent\n", arg);
771083Sbill 			++errcode;
781083Sbill 		}
791083Sbill 		return;
801083Sbill 	}
811083Sbill 	if ((buf.st_mode&S_IFMT) == S_IFDIR) {
821083Sbill 		if(rflg) {
831083Sbill 			if (access(arg, 02) < 0) {
841083Sbill 				if (fflg==0)
851083Sbill 					printf("%s not changed\n", arg);
861083Sbill 				errcode++;
871083Sbill 				return;
881083Sbill 			}
891083Sbill 			if(iflg && level!=0) {
902057Sroot 				printf("remove directory %s? ", arg);
911083Sbill 				if(!yes())
921083Sbill 					return;
931083Sbill 			}
945898Smckusic 			if((dirp = opendir(arg)) == NULL) {
952057Sroot 				printf("rm: cannot read %s?\n", arg);
961083Sbill 				exit(1);
971083Sbill 			}
985898Smckusic 			while((dp = readdir(dirp)) != NULL) {
995898Smckusic 				if(dp->d_ino != 0 && !dotname(dp->d_name)) {
1006003Sroot 					sprintf(name, "%s/%s", arg, dp->d_name);
1011083Sbill 					rm(name, fflg, rflg, iflg, level+1);
1021083Sbill 				}
1031083Sbill 			}
1045898Smckusic 			closedir(dirp);
1059852Ssam 			if (dotname(arg))
1069852Ssam 				return;
1079852Ssam 			if (iflg) {
1089852Ssam 				printf("rm: remove %s? ", arg);
1099852Ssam 				if (!yes())
1109852Ssam 					return;
1119852Ssam 			}
1129852Ssam 			if (rmdir(arg) < 0) {
11313491Ssam 				fprintf(stderr, "rm: ");
1149852Ssam 				perror(arg);
1159852Ssam 				errcode++;
1169852Ssam 			}
1171083Sbill 			return;
1181083Sbill 		}
1191083Sbill 		printf("rm: %s directory\n", arg);
1201083Sbill 		++errcode;
1211083Sbill 		return;
1221083Sbill 	}
1231083Sbill 
1241083Sbill 	if(iflg) {
1252057Sroot 		printf("rm: remove %s? ", arg);
1261083Sbill 		if(!yes())
1271083Sbill 			return;
1281083Sbill 	}
1291083Sbill 	else if(!fflg) {
1307274Ssam 		if ((buf.st_mode&S_IFMT) != S_IFLNK && access(arg, 02) < 0) {
1316003Sroot 			printf("rm: override protection %o for %s? ", buf.st_mode&0777, arg);
1326003Sroot 			if(!yes())
1331083Sbill 				return;
1341083Sbill 		}
1351083Sbill 	}
1361083Sbill 	if(unlink(arg) && (fflg==0 || iflg)) {
1371083Sbill 		printf("rm: %s not removed\n", arg);
1381083Sbill 		++errcode;
1391083Sbill 	}
1401083Sbill }
1411083Sbill 
1421083Sbill dotname(s)
1431083Sbill char *s;
1441083Sbill {
1451083Sbill 	if(s[0] == '.')
1461083Sbill 		if(s[1] == '.')
1471083Sbill 			if(s[2] == '\0')
1481083Sbill 				return(1);
1491083Sbill 			else
1501083Sbill 				return(0);
1511083Sbill 		else if(s[1] == '\0')
1521083Sbill 			return(1);
1531083Sbill 	return(0);
1541083Sbill }
1551083Sbill 
1561083Sbill yes()
1571083Sbill {
1581083Sbill 	int i, b;
1591083Sbill 
1601083Sbill 	i = b = getchar();
1611083Sbill 	while(b != '\n' && b != EOF)
1621083Sbill 		b = getchar();
1631083Sbill 	return(i == 'y');
1641083Sbill }
165