[net.sources] dsw.c

rusty (06/12/82)

# include <sys/param.h>
# include <sys/dir.h>
# include <stat.h>
# include <stdio.h>

typedef FILE file;

int vflg;

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

	vflg = 0;

	for (i = 1; i < argc; i++) {
		pv = argv[i];
		if (pv[0] != '-')
			break;
		for (j = 1; pv[j] != NULL; j++) {
			switch (pv[j]) {
				case 'v':
					vflg++;
					break;

				default:
					fputs("usage: dsw [-v] [dir]\n", stderr);
					exit(1);
					break;
			}
		}
	}

	if (i == argc)
		dsw(".");
	else
		while (i < argc)
			dsw(argv[i++]);
}

dsw(dir)
char *dir;
{
	register file *fid;
	struct direct ds;
	struct stat stb;
	char fnam[80];

	if ((fid = fopen(dir, "r")) == NULL) {
		fputs("fopen: ", stderr);
		perror(dir);
		return;
	}

	if (fstat(fileno(fid), &stb)) {
		fputs("fstat: ", stderr);
		perror(dir);
		return;
	}
	if ((stb.st_mode & S_IFMT) != S_IFDIR) {
		fprintf(stderr, "not a directory: %s\n", dir);
		return;
	}

	/* skip "." and ".." */
	if (fseek(fid, (long) (sizeof(struct direct) * 2), 0) == -1) {
		fprintf(stderr, "mangled directory: %s (find a guru!)\n", dir);
		exit(1);
	}

	while (fread(&ds, sizeof(struct direct), 1, fid) == 1) {
		if (ds.d_ino == 0)
			continue;
		if (grbg(ds.d_name) || vflg) {
			strcpy(fnam, dir);
			if (fnam[strlen(fnam)-1] != '/')
				strcat(fnam, "/");
			strncat(fnam, ds.d_name, DIRSIZ);
			if (prompt(fnam)) {
				if (unlink(fnam) == -1) {
					if (stat(fnam, &stb)) {
						fputs("stat: ", stderr);
						perror(fnam);
						continue;
					}
					if ((stb.st_mode & S_IFMT) == S_IFDIR) {
						fprintf(stderr, "%s: can't rm directories\n", fnam);
						continue;
					}
					fputs("unlink: ", stderr);
					perror(fnam);
				}
			}
		}
	}
}

/*
 * check for garbaged file
 * name.
 */
grbg(fnam)
register char *fnam;
{
	register int i;

	for (i = 0; i < DIRSIZ; i++) {
		if (fnam[i] == NULL)
			return((i == 0) ? 1 : 0);
		if ((fnam[i] <= ' ') || (fnam[i] > 0177))
			return(1);
		if ((fnam[i] == '-') && (i == 0))
			return(1);
	}

	return(0);
}

/*
 * prompt for removal; print out the
 * file name being sure to print
 * something reasonable for non-
 * printable chars.
 */
prompt(fnam)
register char *fnam;
{
	register char ch;
	register char *bp;
	char buf[40];

	while ((ch = *fnam++) != NULL) {
		if (ch >= 0177)
			putchar('?');
		else if (ch < ' ') {
			putchar('^');
			putchar(ch + '@');
		}
		else
			putchar(ch);
	}

	fputs(" ? ", stdout);
	fflush(stdout);
	fgets(buf, sizeof(buf), stdin);
	if (feof(stdin) || ferror(stdin)) {
		putchar('\n');
		exit(0);
	}

	bp = &buf[0];
	while ((*bp == ' ') || (*bp == '\t')) {
		if (bp++ >= &buf[sizeof(buf)])
			return(0);
	}

	return((*bp == 'y') || (*bp == 'Y'));
}