xref: /csrg-svn/bin/rm/rm.c (revision 5754)
1*5754Sroot static char *sccsid = "@(#)rm.c	4.4 (Berkeley) 02/11/82";
21083Sbill int	errcode;
3*5754Sroot short	uid, euid;
41083Sbill 
51083Sbill #include <stdio.h>
61083Sbill #include <sys/types.h>
71083Sbill #include <sys/stat.h>
81083Sbill #include <sys/dir.h>
91083Sbill 
101083Sbill char	*sprintf();
111083Sbill 
121083Sbill main(argc, argv)
131083Sbill char *argv[];
141083Sbill {
151083Sbill 	register char *arg;
161083Sbill 	int fflg, iflg, rflg;
171083Sbill 
181083Sbill 	fflg = 0;
191083Sbill 	if (isatty(0) == 0)
201083Sbill 		fflg++;
211083Sbill 	iflg = 0;
221083Sbill 	rflg = 0;
23*5754Sroot 	uid = getuid();
24*5754Sroot 	euid = geteuid();
251083Sbill 	while(argc>1 && argv[1][0]=='-') {
261083Sbill 		arg = *++argv;
271083Sbill 		argc--;
281932Sroot 
291932Sroot 		/*
301932Sroot 		 *  all files following a null option are considered file names
311932Sroot 		 */
321932Sroot 		if (*(arg+1) == '\0') break;
331932Sroot 
341083Sbill 		while(*++arg != '\0')
351083Sbill 			switch(*arg) {
361083Sbill 			case 'f':
371083Sbill 				fflg++;
381083Sbill 				break;
391083Sbill 			case 'i':
401083Sbill 				iflg++;
411083Sbill 				break;
421083Sbill 			case 'r':
431083Sbill 				rflg++;
441083Sbill 				break;
451083Sbill 			default:
461083Sbill 				printf("rm: unknown option %s\n", *argv);
471083Sbill 				exit(1);
481083Sbill 			}
491083Sbill 	}
501083Sbill 	while(--argc > 0) {
511083Sbill 		if(!strcmp(*++argv, "..")) {
521083Sbill 			fprintf(stderr, "rm: cannot remove `..'\n");
531083Sbill 			continue;
541083Sbill 		}
551083Sbill 		rm(*argv, fflg, rflg, iflg, 0);
561083Sbill 	}
571083Sbill 
581083Sbill 	exit(errcode);
591083Sbill }
601083Sbill 
611083Sbill rm(arg, fflg, rflg, iflg, level)
621083Sbill char arg[];
631083Sbill {
641083Sbill 	struct stat buf;
651083Sbill 	struct direct direct;
661083Sbill 	char name[100];
671083Sbill 	int d;
681083Sbill 
691083Sbill 	if(stat(arg, &buf)) {
701083Sbill 		if (fflg==0) {
711083Sbill 			printf("rm: %s nonexistent\n", arg);
721083Sbill 			++errcode;
731083Sbill 		}
741083Sbill 		return;
751083Sbill 	}
761083Sbill 	if ((buf.st_mode&S_IFMT) == S_IFDIR) {
771083Sbill 		if(rflg) {
781083Sbill 			if (access(arg, 02) < 0) {
791083Sbill 				if (fflg==0)
801083Sbill 					printf("%s not changed\n", arg);
811083Sbill 				errcode++;
821083Sbill 				return;
831083Sbill 			}
841083Sbill 			if(iflg && level!=0) {
852057Sroot 				printf("remove directory %s? ", arg);
861083Sbill 				if(!yes())
871083Sbill 					return;
881083Sbill 			}
891083Sbill 			if((d=open(arg, 0)) < 0) {
902057Sroot 				printf("rm: cannot read %s?\n", arg);
911083Sbill 				exit(1);
921083Sbill 			}
931083Sbill 			while(read(d, (char *)&direct, sizeof(direct)) == sizeof(direct)) {
941083Sbill 				if(direct.d_ino != 0 && !dotname(direct.d_name)) {
951083Sbill 					sprintf(name, "%s/%.14s", arg, direct.d_name);
961083Sbill 					rm(name, fflg, rflg, iflg, level+1);
971083Sbill 				}
981083Sbill 			}
991083Sbill 			close(d);
1001083Sbill 			errcode += rmdir(arg, iflg);
1011083Sbill 			return;
1021083Sbill 		}
1031083Sbill 		printf("rm: %s directory\n", arg);
1041083Sbill 		++errcode;
1051083Sbill 		return;
1061083Sbill 	}
1071083Sbill 
1081083Sbill 	if(iflg) {
1092057Sroot 		printf("rm: remove %s? ", arg);
1101083Sbill 		if(!yes())
1111083Sbill 			return;
1121083Sbill 	}
1131083Sbill 	else if(!fflg) {
1141083Sbill 		if (access(arg, 02)<0) {
115*5754Sroot 			if (uid == buf.st_uid || euid == buf.st_uid) {
116*5754Sroot 				printf("rm: override protection %o for %s? ",
117*5754Sroot 					buf.st_mode&0777, arg);
118*5754Sroot 				if(!yes())
119*5754Sroot 					return;
120*5754Sroot 			} else {
121*5754Sroot 				printf("rm: %s: not owner.\n", arg);
1221083Sbill 				return;
123*5754Sroot 			}
1241083Sbill 		}
1251083Sbill 	}
1261083Sbill 	if(unlink(arg) && (fflg==0 || iflg)) {
1271083Sbill 		printf("rm: %s not removed\n", arg);
1281083Sbill 		++errcode;
1291083Sbill 	}
1301083Sbill }
1311083Sbill 
1321083Sbill dotname(s)
1331083Sbill char *s;
1341083Sbill {
1351083Sbill 	if(s[0] == '.')
1361083Sbill 		if(s[1] == '.')
1371083Sbill 			if(s[2] == '\0')
1381083Sbill 				return(1);
1391083Sbill 			else
1401083Sbill 				return(0);
1411083Sbill 		else if(s[1] == '\0')
1421083Sbill 			return(1);
1431083Sbill 	return(0);
1441083Sbill }
1451083Sbill 
1461083Sbill rmdir(f, iflg)
1471083Sbill char *f;
1481083Sbill {
1491083Sbill 	int status, i;
1501083Sbill 
1511083Sbill 	if(dotname(f))
1521083Sbill 		return(0);
1531083Sbill 	if(iflg) {
1542057Sroot 		printf("rm: remove %s? ", f);
1551083Sbill 		if(!yes())
1561083Sbill 			return(0);
1571083Sbill 	}
1581083Sbill 	while((i=fork()) == -1)
1591083Sbill 		sleep(3);
1601083Sbill 	if(i) {
1611083Sbill 		wait(&status);
1621083Sbill 		return(status);
1631083Sbill 	}
1641083Sbill 	execl("/bin/rmdir", "rmdir", f, 0);
1651083Sbill 	execl("/usr/bin/rmdir", "rmdir", f, 0);
1661083Sbill 	printf("rm: can't find rmdir\n");
1671083Sbill 	exit(1);
1681083Sbill }
1691083Sbill 
1701083Sbill yes()
1711083Sbill {
1721083Sbill 	int i, b;
1731083Sbill 
1741083Sbill 	i = b = getchar();
1751083Sbill 	while(b != '\n' && b != EOF)
1761083Sbill 		b = getchar();
1771083Sbill 	return(i == 'y');
1781083Sbill }
179