Plan 9 from Bell Labs’s /usr/web/sources/patch/sorry/find/find.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <String.h>

void	find(char*, Dir*);
void	err(char*);
void	warn(char*);
int	seen(Dir*);

char	*fmt = "%q\n";
int fflag;

void
main(int argc, char *argv[])
{
	int i;

	doquote = needsrcquote;
	quotefmtinstall();

	ARGBEGIN {
	case 'f':	/* ignore errors */
		fflag = 1;
		break;
	} ARGEND
	if(argc==0)
		find(".", dirstat("."));
	else
		for(i=0; i<argc; i++) {
			find(argv[i], dirstat(argv[i]));
			print(fmt, argv[i]);
		}

	exits(0);
}

void
find(char *name, Dir *dir)
{
	int fd, i, n;
	Dir *buf, *d;
	String *file;

	if(dir == nil) {
		warn(name);
		return;
	}

	fd = open(name, OREAD);
	if(fd < 0) {
		warn(name);
		return;
	}

	while((n=dirread(fd, &buf)) > 0) {
		d = buf;
		for(i=0; i<n; i++, d++) {
			if((d->qid.type&QTDIR) == 0) {
				file = s_copy(name);
				if(file == nil)
					err("s_copy");
				s_append(file, "/");
				s_append(file, d->name);
				print(fmt, s_to_c(file));
				s_free(file);
				continue;
			}
			if(strcmp(d->name, ".") == 0 ||
			   strcmp(d->name, "..") == 0 ||
			   seen(d))
				continue;
			file = s_copy(name);
			s_append(file, "/");
			s_append(file, d->name);
			find(s_to_c(file), d);
			if(file == nil)
				err("s_copy");
			print(fmt, s_to_c(file));
			s_free(file);
		}
		free(buf);
	}
	if(n < 0)
		warn(name);
	close(fd);
}

#define	NCACHE	128	/* must be power of two */
typedef	struct	Cache	Cache;
struct	Cache
{
	Dir*	cache;
	int	n;
	int	max;
} cache[NCACHE];

int
seen(Dir *dir)
{
	Dir *dp;
	int i;
	Cache *c;

	c = &cache[dir->qid.path&(NCACHE-1)];
	dp = c->cache;
	for(i=0; i<c->n; i++, dp++)
		if(dir->qid.path == dp->qid.path &&
		   dir->type == dp->type &&
		   dir->dev == dp->dev)
			return 1;
	if(c->n == c->max){
		c->cache = realloc(c->cache, (c->max+=20)*sizeof(Dir));
		if(cache == 0)
			err("malloc failure");
	}
	c->cache[c->n++] = *dir;
	return 0;
}

void
err(char *s)
{
	fprint(2, "find: %s: %r\n", s);
	exits(s);
}

void
warn(char *s)
{
	if(fflag == 0)
		fprint(2, "find: %s: %r\n", s);
	return;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.