10 #if defined(__FreeBSD__)
12 #include <sys/disklabel.h>
13 #include <sys/ioctl.h>
16 #if defined(__OpenBSD__)
17 #include <sys/disklabel.h>
18 #include <sys/ioctl.h>
19 #define _HAVEDISKLABEL
20 static int diskdev[] = {
36 4, /* da on FreeBSD 5 */
39 isdisk(struct stat *st)
43 if(!S_ISCHR(st->st_mode))
45 dev = major(st->st_rdev);
46 for(i=0; i<nelem(diskdev); i++)
53 #if defined(__FreeBSD__) /* maybe OpenBSD too? */
73 isdisk(struct stat *st)
78 if(!S_ISCHR(st->st_mode))
80 name = devname(st->st_rdev, S_IFCHR);
81 for(i=0; i<nelem(diskdev); i++){
82 len = strlen(diskdev[i]);
83 if(strncmp(diskdev[i], name, len) == 0 && isdigit((uchar)name[len]))
91 #if defined(__linux__)
92 #include <linux/hdreg.h>
94 #include <sys/ioctl.h>
96 #define major(dev) ((int)(((dev) >> 8) & 0xff))
98 disksize(int fd, int dev)
102 struct hd_geometry geo;
104 memset(&geo, 0, sizeof geo);
108 if(ioctl(fd, BLKGETSIZE64, &u64) >= 0)
111 if(ioctl(fd, BLKGETSIZE, &l) >= 0)
113 if(ioctl(fd, HDIO_GETGEO, &geo) >= 0)
114 return (vlong)geo.heads*geo.sectors*geo.cylinders*512;
117 #define _HAVEDISKSIZE
120 #if !defined(__linux__) && !defined(__sun__)
124 int _p9usepwlibrary = 1;
126 * Caching the last group and passwd looked up is
127 * a significant win (stupidly enough) on most systems.
128 * It's not safe for threaded programs, but neither is using
129 * getpwnam in the first place, so I'm not too worried.
132 _p9dir(struct stat *lst, struct stat *st, char *name, Dir *d, char **str, char *estr)
136 static struct group *g;
137 static struct passwd *p;
145 memset(d, 0, sizeof *d);
148 s = strrchr(name, '/');
158 if(*str + strlen(s)+1 > estr)
163 *str += strlen(*str)+1;
169 if(p && st->st_uid == uid && p->pw_uid == uid)
171 else if(_p9usepwlibrary){
172 p = getpwuid(st->st_uid);
175 if(p == nil || st->st_uid != uid || p->pw_uid != uid){
176 snprint(tmp, sizeof tmp, "%d", (int)st->st_uid);
182 if(*str+strlen(s)+1 > estr)
187 *str += strlen(*str)+1;
192 if(g && st->st_gid == gid && g->gr_gid == gid)
194 else if(_p9usepwlibrary){
195 g = getgrgid(st->st_gid);
198 if(g == nil || st->st_gid != gid || g->gr_gid != gid){
199 snprint(tmp, sizeof tmp, "%d", (int)st->st_gid);
205 if(*str + strlen(s)+1 > estr)
210 *str += strlen(*str)+1;
218 d->qid.path = ((uvlong)st->st_dev<<32) | st->st_ino;
220 d->qid.vers = st->st_gen;
223 d->qid.vers = st->st_mtime + st->st_ctime;
224 d->mode = st->st_mode&0777;
225 d->atime = st->st_atime;
226 d->mtime = st->st_mtime;
227 d->length = st->st_size;
229 if(S_ISDIR(st->st_mode)){
234 if(S_ISLNK(lst->st_mode)) /* yes, lst not st */
235 d->mode |= DMSYMLINK;
236 if(S_ISFIFO(st->st_mode))
237 d->mode |= DMNAMEDPIPE;
238 if(S_ISSOCK(st->st_mode))
240 if(S_ISBLK(st->st_mode)){
242 d->qid.path = ('b'<<16)|st->st_rdev;
244 if(S_ISCHR(st->st_mode)){
246 d->qid.path = ('c'<<16)|st->st_rdev;
248 /* fetch real size for disks */
250 if(S_ISBLK(st->st_mode) && (fd = open(name, O_RDONLY)) >= 0){
251 d->length = disksize(fd, major(st->st_dev));
255 #if defined(DIOCGMEDIASIZE)
260 if((fd = open(name, O_RDONLY)) >= 0){
261 if(ioctl(fd, DIOCGMEDIASIZE, &mediasize) >= 0)
262 d->length = mediasize;
266 #elif defined(_HAVEDISKLABEL)
269 struct disklabel lab;
271 if((fd = open(name, O_RDONLY)) < 0)
273 if(ioctl(fd, DIOCGDINFO, &lab) < 0)
275 n = minor(st->st_rdev)&7;
276 if(n >= lab.d_npartitions)
279 d->length = (vlong)(lab.d_partitions[n].p_size) * lab.d_secsize;