235 lines · 4.4 KB · C
RawDownload
#include <u.h>#define NOPLAN9DEFINES#include <libc.h>#include <sys/types.h>#include <sys/stat.h>#include <dirent.h>#include <pwd.h>#include <grp.h> #if defined(__APPLE__)#define _HAVESTGEN#include <sys/disk.h>static vlongdisksize(int fd, struct stat *st){	u64int bc;	u32int bs; 	bs = 0;	bc = 0;	ioctl(fd, DKIOCGETBLOCKSIZE, &bs);	ioctl(fd, DKIOCGETBLOCKCOUNT, &bc);	if(bs >0 && bc > 0)		return bc*bs;	return 0;} #elif defined(__FreeBSD__)#define _HAVESTGEN#include <sys/disk.h>#include <sys/disklabel.h>#include <sys/ioctl.h>static vlongdisksize(int fd, struct stat *st){	off_t mediasize;		if(ioctl(fd, DIOCGMEDIASIZE, &mediasize) >= 0)		return mediasize;	return 0;} #elif defined(__OpenBSD__)#define _HAVESTGEN#include <sys/disklabel.h>#include <sys/ioctl.h>static vlongdisksize(int fd, struct stat *st){	struct disklabel lab;	int n; 	if(!S_ISCHR(st->st_mode))		return 0;	if(ioctl(fd, DIOCGDINFO, &lab) < 0)		return 0;	n = minor(st->st_rdev)&7;	if(n >= lab.d_npartitions)		return 0;	return (vlong)lab.d_partitions[n].p_size * lab.d_secsize;} #elif defined(__linux__)#include <linux/hdreg.h>#include <linux/fs.h>#include <sys/ioctl.h>#undef major#define major(dev) ((int)(((dev) >> 8) & 0xff))static vlongdisksize(int fd, struct stat *st){	u64int u64;	long l;	struct hd_geometry geo; 	memset(&geo, 0, sizeof geo);	l = 0;	u64 = 0;#ifdef BLKGETSIZE64	if(ioctl(fd, BLKGETSIZE64, &u64) >= 0)		return u64;#endif	if(ioctl(fd, BLKGETSIZE, &l) >= 0)		return l*512;	if(ioctl(fd, HDIO_GETGEO, &geo) >= 0)		return (vlong)geo.heads*geo.sectors*geo.cylinders*512;	return 0;} #elsestatic vlongdisksize(int fd, struct stat *st){	return 0;}#endif int _p9usepwlibrary = 1;/* * Caching the last group and passwd looked up is * a significant win (stupidly enough) on most systems. * It's not safe for threaded programs, but neither is using * getpwnam in the first place, so I'm not too worried. */int_p9dir(struct stat *lst, struct stat *st, char *name, Dir *d, char **str, char *estr){	char *s;	char tmp[20];	static struct group *g;	static struct passwd *p;	static int gid, uid;	int sz, fd; 	fd = -1;	USED(fd);	sz = 0;	if(d)		memset(d, 0, sizeof *d); 	/* name */	s = strrchr(name, '/');	if(s)		s++;	if(!s || !*s)		s = name;	if(*s == '/')		s++;	if(*s == 0)		s = "/";	if(d){		if(*str + strlen(s)+1 > estr)			d->name = "oops";		else{			strcpy(*str, s);			d->name = *str;			*str += strlen(*str)+1;		}	}	sz += strlen(s)+1; 	/* user */	if(p && st->st_uid == uid && p->pw_uid == uid)		;	else if(_p9usepwlibrary){		p = getpwuid(st->st_uid);		uid = st->st_uid;	}	if(p == nil || st->st_uid != uid || p->pw_uid != uid){		snprint(tmp, sizeof tmp, "%d", (int)st->st_uid);		s = tmp;	}else		s = p->pw_name;	sz += strlen(s)+1;	if(d){		if(*str+strlen(s)+1 > estr)			d->uid = "oops";			else{			strcpy(*str, s);			d->uid = *str;			*str += strlen(*str)+1;		}	} 	/* group */	if(g && st->st_gid == gid && g->gr_gid == gid)		;	else if(_p9usepwlibrary){		g = getgrgid(st->st_gid);		gid = st->st_gid;	}	if(g == nil || st->st_gid != gid || g->gr_gid != gid){		snprint(tmp, sizeof tmp, "%d", (int)st->st_gid);		s = tmp;	}else		s = g->gr_name;	sz += strlen(s)+1;	if(d){		if(*str + strlen(s)+1 > estr)			d->gid = "oops";			else{			strcpy(*str, s);			d->gid = *str;			*str += strlen(*str)+1;		}	} 	if(d){		d->type = 'M'; 		d->muid = "";		d->qid.path = ((uvlong)st->st_dev<<32) | st->st_ino;#ifdef _HAVESTGEN		d->qid.vers = st->st_gen;#endif		if(d->qid.vers == 0)			d->qid.vers = st->st_mtime + st->st_ctime;		d->mode = st->st_mode&0777;		d->atime = st->st_atime;		d->mtime = st->st_mtime;		d->length = st->st_size; 		if(S_ISLNK(lst->st_mode)){	/* yes, lst not st */			d->mode |= DMSYMLINK;			d->length = lst->st_size;		}		else if(S_ISDIR(st->st_mode)){			d->length = 0;			d->mode |= DMDIR;			d->qid.type = QTDIR;		}		else if(S_ISFIFO(st->st_mode))			d->mode |= DMNAMEDPIPE;		else if(S_ISSOCK(st->st_mode))			d->mode |= DMSOCKET;		else if(S_ISBLK(st->st_mode)){			d->mode |= DMDEVICE;			d->qid.path = ('b'<<16)|st->st_rdev;		}		else if(S_ISCHR(st->st_mode)){			d->mode |= DMDEVICE;			d->qid.path = ('c'<<16)|st->st_rdev;		}		/* fetch real size for disks */		if(S_ISBLK(lst->st_mode) || S_ISCHR(lst->st_mode)){			if((fd = open(name, O_RDONLY)) >= 0){				d->length = disksize(fd, st);				close(fd);			}		}	} 	return sz;} 

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t