xref: /csrg-svn/bin/rm/rm.c (revision 5898)
1*5898Smckusic static char *sccsid = "@(#)rm.c	4.5 (Berkeley) 02/19/82";
21083Sbill int	errcode;
35754Sroot short	uid, euid;
41083Sbill 
51083Sbill #include <stdio.h>
61083Sbill #include <sys/types.h>
71083Sbill #include <sys/stat.h>
8*5898Smckusic #include <ndir.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;
235754Sroot 	uid = getuid();
245754Sroot 	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;
65*5898Smckusic 	struct direct *dp;
66*5898Smckusic 	DIR *dirp;
67*5898Smckusic 	char name[BUFSIZ];
681083Sbill 	int d;
691083Sbill 
701083Sbill 	if(stat(arg, &buf)) {
711083Sbill 		if (fflg==0) {
721083Sbill 			printf("rm: %s nonexistent\n", arg);
731083Sbill 			++errcode;
741083Sbill 		}
751083Sbill 		return;
761083Sbill 	}
771083Sbill 	if ((buf.st_mode&S_IFMT) == S_IFDIR) {
781083Sbill 		if(rflg) {
791083Sbill 			if (access(arg, 02) < 0) {
801083Sbill 				if (fflg==0)
811083Sbill 					printf("%s not changed\n", arg);
821083Sbill 				errcode++;
831083Sbill 				return;
841083Sbill 			}
851083Sbill 			if(iflg && level!=0) {
862057Sroot 				printf("remove directory %s? ", arg);
871083Sbill 				if(!yes())
881083Sbill 					return;
891083Sbill 			}
90*5898Smckusic 			if((dirp = opendir(arg)) == NULL) {
912057Sroot 				printf("rm: cannot read %s?\n", arg);
921083Sbill 				exit(1);
931083Sbill 			}
94*5898Smckusic 			while((dp = readdir(dirp)) != NULL) {
95*5898Smckusic 				if(dp->d_ino != 0 && !dotname(dp->d_name)) {
96*5898Smckusic 					sprintf(name, "%s/%.14s", arg, dp->d_name);
971083Sbill 					rm(name, fflg, rflg, iflg, level+1);
981083Sbill 				}
991083Sbill 			}
100*5898Smckusic 			closedir(dirp);
1011083Sbill 			errcode += rmdir(arg, iflg);
1021083Sbill 			return;
1031083Sbill 		}
1041083Sbill 		printf("rm: %s directory\n", arg);
1051083Sbill 		++errcode;
1061083Sbill 		return;
1071083Sbill 	}
1081083Sbill 
1091083Sbill 	if(iflg) {
1102057Sroot 		printf("rm: remove %s? ", arg);
1111083Sbill 		if(!yes())
1121083Sbill 			return;
1131083Sbill 	}
1141083Sbill 	else if(!fflg) {
1151083Sbill 		if (access(arg, 02)<0) {
1165754Sroot 			if (uid == buf.st_uid || euid == buf.st_uid) {
1175754Sroot 				printf("rm: override protection %o for %s? ",
1185754Sroot 					buf.st_mode&0777, arg);
1195754Sroot 				if(!yes())
1205754Sroot 					return;
1215754Sroot 			} else {
1225754Sroot 				printf("rm: %s: not owner.\n", arg);
1231083Sbill 				return;
1245754Sroot 			}
1251083Sbill 		}
1261083Sbill 	}
1271083Sbill 	if(unlink(arg) && (fflg==0 || iflg)) {
1281083Sbill 		printf("rm: %s not removed\n", arg);
1291083Sbill 		++errcode;
1301083Sbill 	}
1311083Sbill }
1321083Sbill 
1331083Sbill dotname(s)
1341083Sbill char *s;
1351083Sbill {
1361083Sbill 	if(s[0] == '.')
1371083Sbill 		if(s[1] == '.')
1381083Sbill 			if(s[2] == '\0')
1391083Sbill 				return(1);
1401083Sbill 			else
1411083Sbill 				return(0);
1421083Sbill 		else if(s[1] == '\0')
1431083Sbill 			return(1);
1441083Sbill 	return(0);
1451083Sbill }
1461083Sbill 
1471083Sbill rmdir(f, iflg)
1481083Sbill char *f;
1491083Sbill {
1501083Sbill 	int status, i;
1511083Sbill 
1521083Sbill 	if(dotname(f))
1531083Sbill 		return(0);
1541083Sbill 	if(iflg) {
1552057Sroot 		printf("rm: remove %s? ", f);
1561083Sbill 		if(!yes())
1571083Sbill 			return(0);
1581083Sbill 	}
1591083Sbill 	while((i=fork()) == -1)
1601083Sbill 		sleep(3);
1611083Sbill 	if(i) {
1621083Sbill 		wait(&status);
1631083Sbill 		return(status);
1641083Sbill 	}
1651083Sbill 	execl("/bin/rmdir", "rmdir", f, 0);
1661083Sbill 	execl("/usr/bin/rmdir", "rmdir", f, 0);
1671083Sbill 	printf("rm: can't find rmdir\n");
1681083Sbill 	exit(1);
1691083Sbill }
1701083Sbill 
1711083Sbill yes()
1721083Sbill {
1731083Sbill 	int i, b;
1741083Sbill 
1751083Sbill 	i = b = getchar();
1761083Sbill 	while(b != '\n' && b != EOF)
1771083Sbill 		b = getchar();
1781083Sbill 	return(i == 'y');
1791083Sbill }
180