Blame


1 478ee963 2003-11-23 devnull #include <u.h>
2 478ee963 2003-11-23 devnull #define NOPLAN9DEFINES
3 478ee963 2003-11-23 devnull #include <libc.h>
4 478ee963 2003-11-23 devnull #include <sys/types.h>
5 fd04aace 2003-11-23 devnull #include <sys/stat.h>
6 fd04aace 2003-11-23 devnull #include <dirent.h>
7 fd04aace 2003-11-23 devnull #include <pwd.h>
8 fd04aace 2003-11-23 devnull #include <grp.h>
9 fd04aace 2003-11-23 devnull
10 2c82cd6f 2008-07-03 rsc #if defined(__APPLE__)
11 2c82cd6f 2008-07-03 rsc #define _HAVESTGEN
12 97529508 2007-05-15 devnull #include <sys/disk.h>
13 2c82cd6f 2008-07-03 rsc static vlong
14 427abd1e 2008-07-09 rsc disksize(int fd, struct stat *st)
15 2c82cd6f 2008-07-03 rsc {
16 2c82cd6f 2008-07-03 rsc u64int bc;
17 2c82cd6f 2008-07-03 rsc u32int bs;
18 69bdb78d 2007-05-11 devnull
19 2c82cd6f 2008-07-03 rsc bs = 0;
20 2c82cd6f 2008-07-03 rsc bc = 0;
21 2c82cd6f 2008-07-03 rsc ioctl(fd, DKIOCGETBLOCKSIZE, &bs);
22 2c82cd6f 2008-07-03 rsc ioctl(fd, DKIOCGETBLOCKCOUNT, &bc);
23 2c82cd6f 2008-07-03 rsc if(bs >0 && bc > 0)
24 2c82cd6f 2008-07-03 rsc return bc*bs;
25 2c82cd6f 2008-07-03 rsc return 0;
26 2c82cd6f 2008-07-03 rsc }
27 2c82cd6f 2008-07-03 rsc
28 2c82cd6f 2008-07-03 rsc #elif defined(__FreeBSD__)
29 2c82cd6f 2008-07-03 rsc #define _HAVESTGEN
30 2c82cd6f 2008-07-03 rsc #include <sys/disk.h>
31 97529508 2007-05-15 devnull #include <sys/disklabel.h>
32 97529508 2007-05-15 devnull #include <sys/ioctl.h>
33 2c82cd6f 2008-07-03 rsc static vlong
34 2c82cd6f 2008-07-03 rsc disksize(int fd, struct stat *st)
35 669250d1 2003-12-03 devnull {
36 2c82cd6f 2008-07-03 rsc off_t mediasize;
37 fa325e9b 2020-01-10 cross
38 2c82cd6f 2008-07-03 rsc if(ioctl(fd, DIOCGMEDIASIZE, &mediasize) >= 0)
39 2c82cd6f 2008-07-03 rsc return mediasize;
40 669250d1 2003-12-03 devnull return 0;
41 669250d1 2003-12-03 devnull }
42 64bcfff3 2003-11-25 devnull
43 2c82cd6f 2008-07-03 rsc #elif defined(__OpenBSD__)
44 2c82cd6f 2008-07-03 rsc #define _HAVESTGEN
45 2c82cd6f 2008-07-03 rsc #include <sys/disklabel.h>
46 2c82cd6f 2008-07-03 rsc #include <sys/ioctl.h>
47 efe48aa6 2010-07-11 rsc #include <sys/dkio.h>
48 2c82cd6f 2008-07-03 rsc static vlong
49 2c82cd6f 2008-07-03 rsc disksize(int fd, struct stat *st)
50 69bdb78d 2007-05-11 devnull {
51 2c82cd6f 2008-07-03 rsc struct disklabel lab;
52 dd9d5927 2008-07-05 rsc int n;
53 dd9d5927 2008-07-05 rsc
54 69bdb78d 2007-05-11 devnull if(!S_ISCHR(st->st_mode))
55 69bdb78d 2007-05-11 devnull return 0;
56 2c82cd6f 2008-07-03 rsc if(ioctl(fd, DIOCGDINFO, &lab) < 0)
57 2c82cd6f 2008-07-03 rsc return 0;
58 2c82cd6f 2008-07-03 rsc n = minor(st->st_rdev)&7;
59 2c82cd6f 2008-07-03 rsc if(n >= lab.d_npartitions)
60 2c82cd6f 2008-07-03 rsc return 0;
61 2c82cd6f 2008-07-03 rsc return (vlong)lab.d_partitions[n].p_size * lab.d_secsize;
62 69bdb78d 2007-05-11 devnull }
63 69bdb78d 2007-05-11 devnull
64 2c82cd6f 2008-07-03 rsc #elif defined(__linux__)
65 7317e77d 2004-04-25 devnull #include <linux/hdreg.h>
66 7317e77d 2004-04-25 devnull #include <linux/fs.h>
67 7317e77d 2004-04-25 devnull #include <sys/ioctl.h>
68 a3e9d893 2005-08-10 devnull #undef major
69 a3e9d893 2005-08-10 devnull #define major(dev) ((int)(((dev) >> 8) & 0xff))
70 7317e77d 2004-04-25 devnull static vlong
71 2c82cd6f 2008-07-03 rsc disksize(int fd, struct stat *st)
72 7317e77d 2004-04-25 devnull {
73 7317e77d 2004-04-25 devnull u64int u64;
74 7317e77d 2004-04-25 devnull long l;
75 7317e77d 2004-04-25 devnull struct hd_geometry geo;
76 7317e77d 2004-04-25 devnull
77 ceecb313 2004-06-09 devnull memset(&geo, 0, sizeof geo);
78 ceecb313 2004-06-09 devnull l = 0;
79 ceecb313 2004-06-09 devnull u64 = 0;
80 76e6aca8 2004-05-15 devnull #ifdef BLKGETSIZE64
81 7317e77d 2004-04-25 devnull if(ioctl(fd, BLKGETSIZE64, &u64) >= 0)
82 7317e77d 2004-04-25 devnull return u64;
83 76e6aca8 2004-05-15 devnull #endif
84 7317e77d 2004-04-25 devnull if(ioctl(fd, BLKGETSIZE, &l) >= 0)
85 3d484b0d 2005-12-29 devnull return l*512;
86 7317e77d 2004-04-25 devnull if(ioctl(fd, HDIO_GETGEO, &geo) >= 0)
87 7317e77d 2004-04-25 devnull return (vlong)geo.heads*geo.sectors*geo.cylinders*512;
88 7317e77d 2004-04-25 devnull return 0;
89 7317e77d 2004-04-25 devnull }
90 7317e77d 2004-04-25 devnull
91 2c82cd6f 2008-07-03 rsc #else
92 2c82cd6f 2008-07-03 rsc static vlong
93 2c82cd6f 2008-07-03 rsc disksize(int fd, struct stat *st)
94 2c82cd6f 2008-07-03 rsc {
95 2c82cd6f 2008-07-03 rsc return 0;
96 2c82cd6f 2008-07-03 rsc }
97 64bcfff3 2003-11-25 devnull #endif
98 64bcfff3 2003-11-25 devnull
99 63fcc2bc 2006-06-12 devnull int _p9usepwlibrary = 1;
100 6f6553df 2004-04-08 devnull /*
101 6f6553df 2004-04-08 devnull * Caching the last group and passwd looked up is
102 6f6553df 2004-04-08 devnull * a significant win (stupidly enough) on most systems.
103 6f6553df 2004-04-08 devnull * It's not safe for threaded programs, but neither is using
104 6f6553df 2004-04-08 devnull * getpwnam in the first place, so I'm not too worried.
105 6f6553df 2004-04-08 devnull */
106 fd04aace 2003-11-23 devnull int
107 0a229052 2005-02-08 devnull _p9dir(struct stat *lst, struct stat *st, char *name, Dir *d, char **str, char *estr)
108 fd04aace 2003-11-23 devnull {
109 fd04aace 2003-11-23 devnull char *s;
110 fd04aace 2003-11-23 devnull char tmp[20];
111 6f6553df 2004-04-08 devnull static struct group *g;
112 6f6553df 2004-04-08 devnull static struct passwd *p;
113 6f6553df 2004-04-08 devnull static int gid, uid;
114 7317e77d 2004-04-25 devnull int sz, fd;
115 fd04aace 2003-11-23 devnull
116 631fe87f 2004-05-14 devnull fd = -1;
117 631fe87f 2004-05-14 devnull USED(fd);
118 fd04aace 2003-11-23 devnull sz = 0;
119 fd04aace 2003-11-23 devnull if(d)
120 fd04aace 2003-11-23 devnull memset(d, 0, sizeof *d);
121 fd04aace 2003-11-23 devnull
122 fd04aace 2003-11-23 devnull /* name */
123 fd04aace 2003-11-23 devnull s = strrchr(name, '/');
124 fd04aace 2003-11-23 devnull if(s)
125 fd04aace 2003-11-23 devnull s++;
126 fd04aace 2003-11-23 devnull if(!s || !*s)
127 fd04aace 2003-11-23 devnull s = name;
128 fd04aace 2003-11-23 devnull if(*s == '/')
129 fd04aace 2003-11-23 devnull s++;
130 fd04aace 2003-11-23 devnull if(*s == 0)
131 fd04aace 2003-11-23 devnull s = "/";
132 fd04aace 2003-11-23 devnull if(d){
133 fd04aace 2003-11-23 devnull if(*str + strlen(s)+1 > estr)
134 fd04aace 2003-11-23 devnull d->name = "oops";
135 fd04aace 2003-11-23 devnull else{
136 fd04aace 2003-11-23 devnull strcpy(*str, s);
137 fd04aace 2003-11-23 devnull d->name = *str;
138 fd04aace 2003-11-23 devnull *str += strlen(*str)+1;
139 fd04aace 2003-11-23 devnull }
140 fd04aace 2003-11-23 devnull }
141 fd04aace 2003-11-23 devnull sz += strlen(s)+1;
142 fd04aace 2003-11-23 devnull
143 fd04aace 2003-11-23 devnull /* user */
144 6f6553df 2004-04-08 devnull if(p && st->st_uid == uid && p->pw_uid == uid)
145 6f6553df 2004-04-08 devnull ;
146 63fcc2bc 2006-06-12 devnull else if(_p9usepwlibrary){
147 6f6553df 2004-04-08 devnull p = getpwuid(st->st_uid);
148 6f6553df 2004-04-08 devnull uid = st->st_uid;
149 6f6553df 2004-04-08 devnull }
150 63fcc2bc 2006-06-12 devnull if(p == nil || st->st_uid != uid || p->pw_uid != uid){
151 fd04aace 2003-11-23 devnull snprint(tmp, sizeof tmp, "%d", (int)st->st_uid);
152 fd04aace 2003-11-23 devnull s = tmp;
153 fd04aace 2003-11-23 devnull }else
154 fd04aace 2003-11-23 devnull s = p->pw_name;
155 fd04aace 2003-11-23 devnull sz += strlen(s)+1;
156 fd04aace 2003-11-23 devnull if(d){
157 fd04aace 2003-11-23 devnull if(*str+strlen(s)+1 > estr)
158 fa325e9b 2020-01-10 cross d->uid = "oops";
159 fd04aace 2003-11-23 devnull else{
160 fd04aace 2003-11-23 devnull strcpy(*str, s);
161 fd04aace 2003-11-23 devnull d->uid = *str;
162 fd04aace 2003-11-23 devnull *str += strlen(*str)+1;
163 fd04aace 2003-11-23 devnull }
164 fd04aace 2003-11-23 devnull }
165 fd04aace 2003-11-23 devnull
166 fd04aace 2003-11-23 devnull /* group */
167 6f6553df 2004-04-08 devnull if(g && st->st_gid == gid && g->gr_gid == gid)
168 6f6553df 2004-04-08 devnull ;
169 63fcc2bc 2006-06-12 devnull else if(_p9usepwlibrary){
170 6f6553df 2004-04-08 devnull g = getgrgid(st->st_gid);
171 6f6553df 2004-04-08 devnull gid = st->st_gid;
172 6f6553df 2004-04-08 devnull }
173 63fcc2bc 2006-06-12 devnull if(g == nil || st->st_gid != gid || g->gr_gid != gid){
174 fd04aace 2003-11-23 devnull snprint(tmp, sizeof tmp, "%d", (int)st->st_gid);
175 fd04aace 2003-11-23 devnull s = tmp;
176 fd04aace 2003-11-23 devnull }else
177 fd04aace 2003-11-23 devnull s = g->gr_name;
178 fd04aace 2003-11-23 devnull sz += strlen(s)+1;
179 fd04aace 2003-11-23 devnull if(d){
180 fd04aace 2003-11-23 devnull if(*str + strlen(s)+1 > estr)
181 fa325e9b 2020-01-10 cross d->gid = "oops";
182 fd04aace 2003-11-23 devnull else{
183 fd04aace 2003-11-23 devnull strcpy(*str, s);
184 fd04aace 2003-11-23 devnull d->gid = *str;
185 fd04aace 2003-11-23 devnull *str += strlen(*str)+1;
186 fd04aace 2003-11-23 devnull }
187 fd04aace 2003-11-23 devnull }
188 fd04aace 2003-11-23 devnull
189 fd04aace 2003-11-23 devnull if(d){
190 fd04aace 2003-11-23 devnull d->type = 'M';
191 fd04aace 2003-11-23 devnull
192 fd04aace 2003-11-23 devnull d->muid = "";
193 1961ee82 2009-09-25 russcox d->qid.path = st->st_ino;
194 1961ee82 2009-09-25 russcox /*
195 1961ee82 2009-09-25 russcox * do not include st->st_dev in path, because
196 1961ee82 2009-09-25 russcox * automounters give the same file system different
197 1961ee82 2009-09-25 russcox * st_dev values for successive mounts, causing
198 1961ee82 2009-09-25 russcox * spurious write warnings in acme and sam.
199 1961ee82 2009-09-25 russcox d->qid.path |= (uvlong)st->st_dev<<32;
200 1961ee82 2009-09-25 russcox */
201 1c253ceb 2003-11-23 devnull #ifdef _HAVESTGEN
202 fd04aace 2003-11-23 devnull d->qid.vers = st->st_gen;
203 1c253ceb 2003-11-23 devnull #endif
204 3d484b0d 2005-12-29 devnull if(d->qid.vers == 0)
205 3d484b0d 2005-12-29 devnull d->qid.vers = st->st_mtime + st->st_ctime;
206 fd04aace 2003-11-23 devnull d->mode = st->st_mode&0777;
207 fd04aace 2003-11-23 devnull d->atime = st->st_atime;
208 fd04aace 2003-11-23 devnull d->mtime = st->st_mtime;
209 fd04aace 2003-11-23 devnull d->length = st->st_size;
210 fd04aace 2003-11-23 devnull
211 4712e223 2008-07-04 rsc if(S_ISLNK(lst->st_mode)){ /* yes, lst not st */
212 2acd6fa6 2005-02-08 devnull d->mode |= DMSYMLINK;
213 4712e223 2008-07-04 rsc d->length = lst->st_size;
214 4712e223 2008-07-04 rsc }
215 9a939d5f 2008-07-04 rsc else if(S_ISDIR(st->st_mode)){
216 9a939d5f 2008-07-04 rsc d->length = 0;
217 9a939d5f 2008-07-04 rsc d->mode |= DMDIR;
218 9a939d5f 2008-07-04 rsc d->qid.type = QTDIR;
219 9a939d5f 2008-07-04 rsc }
220 9a939d5f 2008-07-04 rsc else if(S_ISFIFO(st->st_mode))
221 2acd6fa6 2005-02-08 devnull d->mode |= DMNAMEDPIPE;
222 9a939d5f 2008-07-04 rsc else if(S_ISSOCK(st->st_mode))
223 2acd6fa6 2005-02-08 devnull d->mode |= DMSOCKET;
224 9a939d5f 2008-07-04 rsc else if(S_ISBLK(st->st_mode)){
225 2acd6fa6 2005-02-08 devnull d->mode |= DMDEVICE;
226 2acd6fa6 2005-02-08 devnull d->qid.path = ('b'<<16)|st->st_rdev;
227 2acd6fa6 2005-02-08 devnull }
228 9a939d5f 2008-07-04 rsc else if(S_ISCHR(st->st_mode)){
229 2acd6fa6 2005-02-08 devnull d->mode |= DMDEVICE;
230 2acd6fa6 2005-02-08 devnull d->qid.path = ('c'<<16)|st->st_rdev;
231 2acd6fa6 2005-02-08 devnull }
232 fd04aace 2003-11-23 devnull /* fetch real size for disks */
233 3a62e563 2020-01-14 rsc if(S_ISBLK(lst->st_mode)){
234 9a939d5f 2008-07-04 rsc if((fd = open(name, O_RDONLY)) >= 0){
235 9a939d5f 2008-07-04 rsc d->length = disksize(fd, st);
236 9a939d5f 2008-07-04 rsc close(fd);
237 9a939d5f 2008-07-04 rsc }
238 7317e77d 2004-04-25 devnull }
239 fd04aace 2003-11-23 devnull }
240 fd04aace 2003-11-23 devnull
241 fd04aace 2003-11-23 devnull return sz;
242 fd04aace 2003-11-23 devnull }