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