Plan 9 from Bell Labs’s /usr/web/sources/contrib/arisawa/lr/lr.c

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


/*
*	lr: list directories recursively
*	version: 1.1
*	date: 2005/02/18
*	auther: Kenar(Kenji Arisawa)
*	Email: arisawa@aichi-u.ac.jp
*/

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

void
usage(void)
{
	fprint(2,"usage: lr [-lnpw] [-d depth] [path ...]\n");
	exits("usage");
}

enum
{
	LFMT = 1,
	nFMT = 2,
};

char *mods[]={"---","--x","-w-","-wx","r--","r-x","rw-","rwx"};

int mode = 0;
Biobuf	out;
int quit = 0;
int wflag = 0; /* warning for empty files/dirs */

static int
notefun(void *a, char *msg)
{
	USED(a);
	USED(msg);
	quit = 1;
	noted(NCONT);
	return 0;
}


char*
modefmt(ulong m)
{
	static char buf[32];
	char *e, *s;
	s = buf;
	e = s + sizeof buf;
	s[0] = s[1] = '-';
	if(m & DMDIR)
		s[0] = 'd';
	else{
		if(m & DMAPPEND)
			s[0] = 'a';
		if(m & DMEXCL)
			s[1] = 'l';
	}
	s += 2;
	s = seprint(s,e, "%s", mods[(m & 0700) >> 6]);
	s = seprint(s,e, "%s", mods[(m & 070) >> 3]);
	s = seprint(s,e, "%s", mods[m & 07]);
	return buf;
}

char *
datefmt(ulong t)
{
	static char buf[48];
	Tm *tm;

	if(mode & nFMT){
		snprint(buf,sizeof buf, "%lud", t);
		return buf;
	}
	tm = localtime(t);
	snprint(buf,sizeof buf,"%04d/%02d/%02d %02d:%02d:%02d",
		tm->year + 1900,tm->mon + 1,tm->mday, tm->hour, tm->min, tm->sec);
	return buf;
}

/*
*	don't use d->name, the name is in path
*/
void
ls(char *path, Dir *d)
{
	if(mode & LFMT){
		Bprint(&out,"%s %s %s %8llud %s %s\n", modefmt(d->mode),
		d->uid, d->gid, d->length, datefmt(d->mtime), path);
	}
	else
		Bprint(&out,"%s\n", path);
	if(wflag && d->length == 0 && (d->mode & DMDIR) == 0)
		fprint(2, "# empty file: %s\n", path);
}

int
compar(Dir *a, Dir *b)
{
	return strcmp(a->name, b->name);
}


void
list(char *path, char *ep, int depth)
{
	Dir *db;
	int fd, i,n;
	ulong m;
	if(quit)
		return;
	if(path[0] == '.' && path[1] == '/')
		path += 2;
	db = dirstat(path);
	if(db == nil){
		fprint(2, "# %s: non-existent or dead\n", path);	
		return;
	}
	ls(path, db);
	m = db->mode;
	free(db);
	if((m & DMDIR) == 0)
		return;

	if(depth == 0)
		return;
	depth--;

	fd = open(path, OREAD);
	if(fd < 0){
		fprint(2, "# %s: unreadable\n", path);
		return;
	}
	n = dirreadall(fd, &db);
	close(fd);
	if(n < 0){
		fprint(2, "# %s: %r\n", path);
		return;
	}

	/* sort by name */
	qsort(db, n, sizeof(Dir), (int (*)(void*, void*))compar);

	for(i = 0; i < n; i++){
		m = strlen(path);
		seprint(path + m,ep,"/%s", db[i].name);
		list(path, ep, depth);
		path[m] = 0;
	}
	free(db);
	if(wflag && n == 0)
		fprint(2, "# empty dir: %s\n", path);
}


void main(int argc, char *argv[])
{
	char path[4096];
	char wd[512];
	char *ep, *ap;
	int pflag = 0;
	int depth = -1;
	ARGBEGIN{
	case 'd':
		ap = ARGF();
		if(!ap) usage();
		depth = atoi(ap);
		break;
	case 'l':	mode |= LFMT; break;
	case 'n':	mode |= nFMT; break;
	case 'p':	pflag = 1; break;
	case 'w':	wflag = 1; break;
	default: usage();
	}ARGEND

	Binit(&out, 1, OWRITE);
	ep = path + sizeof path;
	if(*argv == nil){
		strcpy(path,".");
		list(path, ep, depth);
		exits(nil);
	}
	if(pflag){
		getwd(wd, sizeof(wd));
		atnotify(notefun,1);
	}
	while(*argv){
		if(pflag){
			chdir(*argv);
			*argv = ".";
		}
		strecpy(path, ep, *argv);
		list(path, ep, depth);
		argv++;
	}
	if(pflag)
		chdir(wd);
}

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.