/*
 *	Remove all binaries from the user file system.
 */

#include <stdio.h>
#include <sys/types.h>	/* for stat.h */
#include <sys/stat.h>	/* for struct stbuf */

char *progname;		/* argv[0] for reror reporting */

int rmbinary();

int doit = 1;		/* should we actually renove things? */

main(argc, argv)
char **argv;
{
	register int i;

	progname = argv[0];

	if (argc < 2) {
		usage();
		exit(1);
	}

	for (i=1; i<argc; i++) {
		if (argv[i][0] == '-') {

			switch(argv[i][1]) {
			case 'n':
				doit = 0;
				break;
			default:
				usage();
				exit(1);
			}
		} else {
			/*
			 * Quit if things go badly.
			 * Descend may end up in a different directory if it 
			 * can't cd back up, so relative filename arguments
			 * would mean different files.
			 */
			if (descend(argv[i], rmbinary) == -1) break;
		}
	}
	exit(0);
}

usage()
{
	fputs("Usage: rmbinaries [-n] <startdir> ...\n", stderr);
}

#include <a.out.h>

int
rmbinary(name, fullname, stbuf)
char *name, *fullname;
struct stat *stbuf;
{
	long magic;
	register int fd;
	register int unlinkit;

	if (stbuf == NULL) return(0);

	/* only regular files can be binaries */
	if ((stbuf->st_mode & S_IFMT) != S_IFREG) return(0);

	unlinkit = 0;

	/* want to zap core files etc as well */
	switch (name[0]) {
	case 'c':
		if (strcmp(name, "core") == 0) unlinkit = 1;
		break;
	case 'g':
		if (strcmp(name, "gmon.out") == 0) unlinkit = 1;
		break;
	case 'm':
		if (strcmp(name, "mon.out") == 0) unlinkit = 1;
		break;
	}


	if (!unlinkit && 
		/* is the file to small to be a binary? (saves system calls) */
		stbuf->st_size >= sizeof(struct exec)) {

		/* Oh well. We are going to have to inspect the magic number */
		if ( (fd = open(name, 0)) < 0 ) {
			fprintf(stderr, "%s: Could not open ", progname);
			perror(fullname);
		} else {
			if (read(fd, (char *)&magic, sizeof(magic)) != sizeof(magic)) {
				fprintf(stderr, "%s: Failed to read magic number from ", progname);
				perror(fullname);
			} else {
				switch (magic) {
				case OMAGIC:
				case NMAGIC:
				case ZMAGIC:
				/* standard magic numbers */
				case 0407:
				case 0410:
				case 0413:
				/* HLH magic numbers */
				case 01407:
				case 01410:
				case 01413:
					unlinkit = 1;
					break;
				}
			}
			close(fd);
		}
	}

	if (unlinkit) {
		if (!doit) {			/* -n switch */
			puts(fullname);
		} else {
			if (unlink(name) == 0) {
				puts(fullname);
				return(1);
			} else {
				fprintf(stderr, "%s: Could not unlink ", progname);
				perror(fullname);
				return(0);	/* carry on with descent */
			}
		}
	}
	return(0);
}
