Blame


1 9b4a2324 2009-07-09 rsc #include <u.h>
2 9b4a2324 2009-07-09 rsc #include <libc.h>
3 9b4a2324 2009-07-09 rsc #include <draw.h>
4 9b4a2324 2009-07-09 rsc #include <memdraw.h>
5 9b4a2324 2009-07-09 rsc #include <thread.h>
6 9b4a2324 2009-07-09 rsc #include <fcall.h>
7 9b4a2324 2009-07-09 rsc #include <9p.h>
8 9b4a2324 2009-07-09 rsc /*
9 9b4a2324 2009-07-09 rsc * we included thread.h in order to include 9p.h,
10 9b4a2324 2009-07-09 rsc * but we don't use threads, so exits is ok.
11 9b4a2324 2009-07-09 rsc */
12 9b4a2324 2009-07-09 rsc #undef exits
13 9b4a2324 2009-07-09 rsc
14 9b4a2324 2009-07-09 rsc #include "a.h"
15 9b4a2324 2009-07-09 rsc
16 9b4a2324 2009-07-09 rsc Memsubfont *defont;
17 9b4a2324 2009-07-09 rsc
18 9b4a2324 2009-07-09 rsc void
19 9b4a2324 2009-07-09 rsc usage(void)
20 9b4a2324 2009-07-09 rsc {
21 9b4a2324 2009-07-09 rsc fprint(2, "usage: fontsrv [-m mtpt]\n");
22 9b4a2324 2009-07-09 rsc fprint(2, "or fontsrv -p path\n");
23 9b4a2324 2009-07-09 rsc exits("usage");
24 9b4a2324 2009-07-09 rsc }
25 9b4a2324 2009-07-09 rsc
26 9b4a2324 2009-07-09 rsc static
27 9b4a2324 2009-07-09 rsc void
28 9b4a2324 2009-07-09 rsc packinfo(Fontchar *fc, uchar *p, int n)
29 9b4a2324 2009-07-09 rsc {
30 9b4a2324 2009-07-09 rsc int j;
31 9b4a2324 2009-07-09 rsc
32 9b4a2324 2009-07-09 rsc for(j=0; j<=n; j++){
33 9b4a2324 2009-07-09 rsc p[0] = fc->x;
34 9b4a2324 2009-07-09 rsc p[1] = fc->x>>8;
35 9b4a2324 2009-07-09 rsc p[2] = fc->top;
36 9b4a2324 2009-07-09 rsc p[3] = fc->bottom;
37 9b4a2324 2009-07-09 rsc p[4] = fc->left;
38 9b4a2324 2009-07-09 rsc p[5] = fc->width;
39 9b4a2324 2009-07-09 rsc fc++;
40 9b4a2324 2009-07-09 rsc p += 6;
41 9b4a2324 2009-07-09 rsc }
42 9b4a2324 2009-07-09 rsc }
43 9b4a2324 2009-07-09 rsc
44 9b4a2324 2009-07-09 rsc enum
45 9b4a2324 2009-07-09 rsc {
46 9b4a2324 2009-07-09 rsc Qroot = 0,
47 9b4a2324 2009-07-09 rsc Qfontdir,
48 9b4a2324 2009-07-09 rsc Qsizedir,
49 9b4a2324 2009-07-09 rsc Qfontfile,
50 9b4a2324 2009-07-09 rsc Qsubfontfile,
51 9b4a2324 2009-07-09 rsc };
52 9b4a2324 2009-07-09 rsc
53 9b4a2324 2009-07-09 rsc #define QTYPE(p) ((p) & 0xF)
54 9b4a2324 2009-07-09 rsc #define QFONT(p) (((p) >> 4) & 0xFFFF)
55 9b4a2324 2009-07-09 rsc #define QSIZE(p) (((p) >> 20) & 0xFF)
56 9b4a2324 2009-07-09 rsc #define QANTIALIAS(p) (((p) >> 28) & 0x1)
57 9b4a2324 2009-07-09 rsc #define QRANGE(p) (((p) >> 29) & 0xFF)
58 9b4a2324 2009-07-09 rsc static int sizes[] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 24, 28 };
59 9b4a2324 2009-07-09 rsc
60 9b4a2324 2009-07-09 rsc static vlong
61 9b4a2324 2009-07-09 rsc qpath(int type, int font, int size, int antialias, int range)
62 9b4a2324 2009-07-09 rsc {
63 9b4a2324 2009-07-09 rsc return type | (font << 4) | (size << 20) | (antialias << 28) | ((vlong)range << 29);
64 9b4a2324 2009-07-09 rsc }
65 9b4a2324 2009-07-09 rsc
66 9b4a2324 2009-07-09 rsc static void
67 9b4a2324 2009-07-09 rsc dostat(vlong path, Qid *qid, Dir *dir)
68 9b4a2324 2009-07-09 rsc {
69 9b4a2324 2009-07-09 rsc char *name;
70 9b4a2324 2009-07-09 rsc Qid q;
71 9b4a2324 2009-07-09 rsc ulong mode;
72 9b4a2324 2009-07-09 rsc vlong length;
73 9b4a2324 2009-07-09 rsc XFont *f;
74 9b4a2324 2009-07-09 rsc char buf[100];
75 9b4a2324 2009-07-09 rsc
76 9b4a2324 2009-07-09 rsc q.type = 0;
77 9b4a2324 2009-07-09 rsc q.vers = 0;
78 9b4a2324 2009-07-09 rsc q.path = path;
79 9b4a2324 2009-07-09 rsc mode = 0444;
80 9b4a2324 2009-07-09 rsc length = 0;
81 9b4a2324 2009-07-09 rsc name = "???";
82 9b4a2324 2009-07-09 rsc
83 9b4a2324 2009-07-09 rsc switch(QTYPE(path)) {
84 9b4a2324 2009-07-09 rsc default:
85 9b4a2324 2009-07-09 rsc sysfatal("dostat %#llux", path);
86 9b4a2324 2009-07-09 rsc
87 9b4a2324 2009-07-09 rsc case Qroot:
88 9b4a2324 2009-07-09 rsc q.type = QTDIR;
89 9b4a2324 2009-07-09 rsc name = "/";
90 9b4a2324 2009-07-09 rsc break;
91 9b4a2324 2009-07-09 rsc
92 9b4a2324 2009-07-09 rsc case Qfontdir:
93 9b4a2324 2009-07-09 rsc q.type = QTDIR;
94 9b4a2324 2009-07-09 rsc f = &xfont[QFONT(path)];
95 9b4a2324 2009-07-09 rsc name = f->name;
96 9b4a2324 2009-07-09 rsc break;
97 9b4a2324 2009-07-09 rsc
98 9b4a2324 2009-07-09 rsc case Qsizedir:
99 9b4a2324 2009-07-09 rsc q.type = QTDIR;
100 9b4a2324 2009-07-09 rsc snprint(buf, sizeof buf, "%lld%s", QSIZE(path), QANTIALIAS(path) ? "a" : "");
101 9b4a2324 2009-07-09 rsc name = buf;
102 9b4a2324 2009-07-09 rsc break;
103 9b4a2324 2009-07-09 rsc
104 9b4a2324 2009-07-09 rsc case Qfontfile:
105 9b4a2324 2009-07-09 rsc f = &xfont[QFONT(path)];
106 9b4a2324 2009-07-09 rsc load(f);
107 9b4a2324 2009-07-09 rsc length = 11+1+11+1+f->nrange*(6+1+6+1+9+1);
108 9b4a2324 2009-07-09 rsc name = "font";
109 9b4a2324 2009-07-09 rsc break;
110 9b4a2324 2009-07-09 rsc
111 9b4a2324 2009-07-09 rsc case Qsubfontfile:
112 9b4a2324 2009-07-09 rsc snprint(buf, sizeof buf, "x%02llx00.bit", QRANGE(path));
113 9b4a2324 2009-07-09 rsc name = buf;
114 9b4a2324 2009-07-09 rsc break;
115 9b4a2324 2009-07-09 rsc }
116 9b4a2324 2009-07-09 rsc
117 9b4a2324 2009-07-09 rsc if(qid)
118 9b4a2324 2009-07-09 rsc *qid = q;
119 9b4a2324 2009-07-09 rsc if(dir) {
120 9b4a2324 2009-07-09 rsc memset(dir, 0, sizeof *dir);
121 9b4a2324 2009-07-09 rsc dir->name = estrdup9p(name);
122 9b4a2324 2009-07-09 rsc dir->muid = estrdup9p("");
123 9b4a2324 2009-07-09 rsc dir->uid = estrdup9p("font");
124 9b4a2324 2009-07-09 rsc dir->gid = estrdup9p("font");
125 9b4a2324 2009-07-09 rsc dir->qid = q;
126 9b4a2324 2009-07-09 rsc if(q.type == QTDIR)
127 9b4a2324 2009-07-09 rsc mode |= DMDIR | 0111;
128 9b4a2324 2009-07-09 rsc dir->mode = mode;
129 9b4a2324 2009-07-09 rsc dir->length = length;
130 9b4a2324 2009-07-09 rsc }
131 9b4a2324 2009-07-09 rsc }
132 9b4a2324 2009-07-09 rsc
133 9b4a2324 2009-07-09 rsc static char*
134 9b4a2324 2009-07-09 rsc xwalk1(Fid *fid, char *name, Qid *qid)
135 9b4a2324 2009-07-09 rsc {
136 9b4a2324 2009-07-09 rsc int i, dotdot;
137 9b4a2324 2009-07-09 rsc vlong path;
138 9b4a2324 2009-07-09 rsc char *p;
139 9b4a2324 2009-07-09 rsc int a, n;
140 9b4a2324 2009-07-09 rsc XFont *f;
141 9b4a2324 2009-07-09 rsc
142 9b4a2324 2009-07-09 rsc path = fid->qid.path;
143 9b4a2324 2009-07-09 rsc dotdot = strcmp(name, "..") == 0;
144 9b4a2324 2009-07-09 rsc switch(QTYPE(path)) {
145 9b4a2324 2009-07-09 rsc default:
146 9b4a2324 2009-07-09 rsc NotFound:
147 9b4a2324 2009-07-09 rsc return "file not found";
148 9b4a2324 2009-07-09 rsc
149 9b4a2324 2009-07-09 rsc case Qroot:
150 9b4a2324 2009-07-09 rsc if(dotdot)
151 9b4a2324 2009-07-09 rsc break;
152 9b4a2324 2009-07-09 rsc for(i=0; i<nxfont; i++) {
153 9b4a2324 2009-07-09 rsc if(strcmp(xfont[i].name, name) == 0) {
154 9b4a2324 2009-07-09 rsc path = qpath(Qfontdir, i, 0, 0, 0);
155 9b4a2324 2009-07-09 rsc goto Found;
156 9b4a2324 2009-07-09 rsc }
157 9b4a2324 2009-07-09 rsc }
158 9b4a2324 2009-07-09 rsc goto NotFound;
159 9b4a2324 2009-07-09 rsc
160 9b4a2324 2009-07-09 rsc case Qfontdir:
161 9b4a2324 2009-07-09 rsc if(dotdot) {
162 9b4a2324 2009-07-09 rsc path = Qroot;
163 9b4a2324 2009-07-09 rsc break;
164 9b4a2324 2009-07-09 rsc }
165 9b4a2324 2009-07-09 rsc n = strtol(name, &p, 10);
166 9b4a2324 2009-07-09 rsc if(n == 0)
167 9b4a2324 2009-07-09 rsc goto NotFound;
168 9b4a2324 2009-07-09 rsc a = 0;
169 9b4a2324 2009-07-09 rsc if(*p == 'a') {
170 9b4a2324 2009-07-09 rsc a = 1;
171 9b4a2324 2009-07-09 rsc p++;
172 9b4a2324 2009-07-09 rsc }
173 9b4a2324 2009-07-09 rsc if(*p != 0)
174 9b4a2324 2009-07-09 rsc goto NotFound;
175 9b4a2324 2009-07-09 rsc path += Qsizedir - Qfontdir + qpath(0, 0, n, a, 0);
176 9b4a2324 2009-07-09 rsc break;
177 9b4a2324 2009-07-09 rsc
178 9b4a2324 2009-07-09 rsc case Qsizedir:
179 9b4a2324 2009-07-09 rsc if(dotdot) {
180 9b4a2324 2009-07-09 rsc path = qpath(Qfontdir, QFONT(path), 0, 0, 0);
181 9b4a2324 2009-07-09 rsc break;
182 9b4a2324 2009-07-09 rsc }
183 9b4a2324 2009-07-09 rsc if(strcmp(name, "font") == 0) {
184 9b4a2324 2009-07-09 rsc path += Qfontfile - Qsizedir;
185 9b4a2324 2009-07-09 rsc break;
186 9b4a2324 2009-07-09 rsc }
187 9b4a2324 2009-07-09 rsc f = &xfont[QFONT(path)];
188 9b4a2324 2009-07-09 rsc load(f);
189 9b4a2324 2009-07-09 rsc p = name;
190 9b4a2324 2009-07-09 rsc if(*p != 'x')
191 9b4a2324 2009-07-09 rsc goto NotFound;
192 9b4a2324 2009-07-09 rsc p++;
193 9b4a2324 2009-07-09 rsc n = strtoul(p, &p, 16);
194 9b4a2324 2009-07-09 rsc if(p != name+5 || (n&0xFF) != 0 || strcmp(p, ".bit") != 0 || !f->range[(n>>8) & 0xFF])
195 9b4a2324 2009-07-09 rsc goto NotFound;
196 9b4a2324 2009-07-09 rsc path += Qsubfontfile - Qsizedir + qpath(0, 0, 0, 0, (n>>8) & 0xFF);
197 9b4a2324 2009-07-09 rsc break;
198 9b4a2324 2009-07-09 rsc }
199 9b4a2324 2009-07-09 rsc Found:
200 9b4a2324 2009-07-09 rsc dostat(path, qid, nil);
201 9b4a2324 2009-07-09 rsc fid->qid = *qid;
202 9b4a2324 2009-07-09 rsc return nil;
203 9b4a2324 2009-07-09 rsc }
204 9b4a2324 2009-07-09 rsc
205 9b4a2324 2009-07-09 rsc static int
206 9b4a2324 2009-07-09 rsc rootgen(int i, Dir *d, void *v)
207 9b4a2324 2009-07-09 rsc {
208 9b4a2324 2009-07-09 rsc if(i >= nxfont)
209 9b4a2324 2009-07-09 rsc return -1;
210 9b4a2324 2009-07-09 rsc dostat(qpath(Qfontdir, i, 0, 0, 0), nil, d);
211 9b4a2324 2009-07-09 rsc return 0;
212 9b4a2324 2009-07-09 rsc }
213 9b4a2324 2009-07-09 rsc
214 9b4a2324 2009-07-09 rsc static int
215 9b4a2324 2009-07-09 rsc fontgen(int i, Dir *d, void *v)
216 9b4a2324 2009-07-09 rsc {
217 9b4a2324 2009-07-09 rsc vlong path;
218 9b4a2324 2009-07-09 rsc Fid *f;
219 9b4a2324 2009-07-09 rsc
220 9b4a2324 2009-07-09 rsc f = v;
221 9b4a2324 2009-07-09 rsc path = f->qid.path;
222 9b4a2324 2009-07-09 rsc if(i >= 2*nelem(sizes))
223 9b4a2324 2009-07-09 rsc return -1;
224 9b4a2324 2009-07-09 rsc dostat(qpath(Qsizedir, QFONT(path), sizes[i/2], i&1, 0), nil, d);
225 9b4a2324 2009-07-09 rsc return 0;
226 9b4a2324 2009-07-09 rsc }
227 9b4a2324 2009-07-09 rsc
228 9b4a2324 2009-07-09 rsc static int
229 9b4a2324 2009-07-09 rsc sizegen(int i, Dir *d, void *v)
230 9b4a2324 2009-07-09 rsc {
231 9b4a2324 2009-07-09 rsc vlong path;
232 9b4a2324 2009-07-09 rsc Fid *fid;
233 9b4a2324 2009-07-09 rsc XFont *f;
234 9b4a2324 2009-07-09 rsc int j;
235 9b4a2324 2009-07-09 rsc
236 9b4a2324 2009-07-09 rsc fid = v;
237 9b4a2324 2009-07-09 rsc path = fid->qid.path;
238 9b4a2324 2009-07-09 rsc if(i == 0) {
239 9b4a2324 2009-07-09 rsc path += Qfontfile - Qsizedir;
240 9b4a2324 2009-07-09 rsc goto Done;
241 9b4a2324 2009-07-09 rsc }
242 9b4a2324 2009-07-09 rsc i--;
243 9b4a2324 2009-07-09 rsc f = &xfont[QFONT(path)];
244 9b4a2324 2009-07-09 rsc load(f);
245 9b4a2324 2009-07-09 rsc for(j=0; j<nelem(f->range); j++) {
246 9b4a2324 2009-07-09 rsc if(f->range[j] == 0)
247 9b4a2324 2009-07-09 rsc continue;
248 9b4a2324 2009-07-09 rsc if(i == 0) {
249 9b4a2324 2009-07-09 rsc path += Qsubfontfile - Qsizedir;
250 9b4a2324 2009-07-09 rsc path += qpath(0, 0, 0, 0, j);
251 9b4a2324 2009-07-09 rsc goto Done;
252 9b4a2324 2009-07-09 rsc }
253 9b4a2324 2009-07-09 rsc i--;
254 9b4a2324 2009-07-09 rsc }
255 9b4a2324 2009-07-09 rsc return -1;
256 9b4a2324 2009-07-09 rsc
257 9b4a2324 2009-07-09 rsc Done:
258 9b4a2324 2009-07-09 rsc dostat(path, nil, d);
259 9b4a2324 2009-07-09 rsc return 0;
260 9b4a2324 2009-07-09 rsc }
261 9b4a2324 2009-07-09 rsc
262 9b4a2324 2009-07-09 rsc static void
263 9b4a2324 2009-07-09 rsc xattach(Req *r)
264 9b4a2324 2009-07-09 rsc {
265 9b4a2324 2009-07-09 rsc dostat(0, &r->ofcall.qid, nil);
266 9b4a2324 2009-07-09 rsc r->fid->qid = r->ofcall.qid;
267 9b4a2324 2009-07-09 rsc respond(r, nil);
268 9b4a2324 2009-07-09 rsc }
269 9b4a2324 2009-07-09 rsc
270 9b4a2324 2009-07-09 rsc static void
271 9b4a2324 2009-07-09 rsc xopen(Req *r)
272 9b4a2324 2009-07-09 rsc {
273 9b4a2324 2009-07-09 rsc if(r->ifcall.mode != OREAD) {
274 9b4a2324 2009-07-09 rsc respond(r, "permission denied");
275 9b4a2324 2009-07-09 rsc return;
276 9b4a2324 2009-07-09 rsc }
277 9b4a2324 2009-07-09 rsc r->ofcall.qid = r->fid->qid;
278 9b4a2324 2009-07-09 rsc respond(r, nil);
279 9b4a2324 2009-07-09 rsc }
280 9b4a2324 2009-07-09 rsc
281 9b4a2324 2009-07-09 rsc void
282 9b4a2324 2009-07-09 rsc responderrstr(Req *r)
283 9b4a2324 2009-07-09 rsc {
284 9b4a2324 2009-07-09 rsc char err[ERRMAX];
285 9b4a2324 2009-07-09 rsc
286 9b4a2324 2009-07-09 rsc rerrstr(err, sizeof err);
287 9b4a2324 2009-07-09 rsc respond(r, err);
288 9b4a2324 2009-07-09 rsc }
289 9b4a2324 2009-07-09 rsc
290 9b4a2324 2009-07-09 rsc static void
291 9b4a2324 2009-07-09 rsc xread(Req *r)
292 9b4a2324 2009-07-09 rsc {
293 9b4a2324 2009-07-09 rsc int i, size, height, ascent;
294 9b4a2324 2009-07-09 rsc vlong path;
295 9b4a2324 2009-07-09 rsc Fmt fmt;
296 9b4a2324 2009-07-09 rsc XFont *f;
297 9b4a2324 2009-07-09 rsc char *data;
298 9b4a2324 2009-07-09 rsc Memsubfont *sf;
299 9b4a2324 2009-07-09 rsc Memimage *m;
300 9b4a2324 2009-07-09 rsc
301 9b4a2324 2009-07-09 rsc path = r->fid->qid.path;
302 9b4a2324 2009-07-09 rsc switch(QTYPE(path)) {
303 9b4a2324 2009-07-09 rsc case Qroot:
304 9b4a2324 2009-07-09 rsc dirread9p(r, rootgen, nil);
305 9b4a2324 2009-07-09 rsc break;
306 9b4a2324 2009-07-09 rsc case Qfontdir:
307 9b4a2324 2009-07-09 rsc dirread9p(r, fontgen, r->fid);
308 9b4a2324 2009-07-09 rsc break;
309 9b4a2324 2009-07-09 rsc case Qsizedir:
310 9b4a2324 2009-07-09 rsc dirread9p(r, sizegen, r->fid);
311 9b4a2324 2009-07-09 rsc break;
312 9b4a2324 2009-07-09 rsc case Qfontfile:
313 9b4a2324 2009-07-09 rsc fmtstrinit(&fmt);
314 9b4a2324 2009-07-09 rsc f = &xfont[QFONT(path)];
315 9b4a2324 2009-07-09 rsc load(f);
316 9b4a2324 2009-07-09 rsc if(f->unit == 0)
317 9b4a2324 2009-07-09 rsc break;
318 9b4a2324 2009-07-09 rsc height = f->height * (int)QSIZE(path)/f->unit + 0.99999999;
319 9b4a2324 2009-07-09 rsc ascent = height - (int)(-f->originy * (int)QSIZE(path)/f->unit + 0.99999999);
320 9b4a2324 2009-07-09 rsc fmtprint(&fmt, "%11d %11d\n", height, ascent);
321 9b4a2324 2009-07-09 rsc for(i=0; i<nelem(f->range); i++) {
322 9b4a2324 2009-07-09 rsc if(f->range[i] == 0)
323 9b4a2324 2009-07-09 rsc continue;
324 9b4a2324 2009-07-09 rsc fmtprint(&fmt, "0x%04x 0x%04x x%04x.bit\n", i<<8, (i<<8) + 0xFF, i<<8);
325 9b4a2324 2009-07-09 rsc }
326 9b4a2324 2009-07-09 rsc data = fmtstrflush(&fmt);
327 9b4a2324 2009-07-09 rsc readstr(r, data);
328 9b4a2324 2009-07-09 rsc free(data);
329 9b4a2324 2009-07-09 rsc break;
330 9b4a2324 2009-07-09 rsc case Qsubfontfile:
331 9b4a2324 2009-07-09 rsc f = &xfont[QFONT(path)];
332 9b4a2324 2009-07-09 rsc load(f);
333 9b4a2324 2009-07-09 rsc if(r->fid->aux == nil) {
334 9b4a2324 2009-07-09 rsc r->fid->aux = mksubfont(f->name, QRANGE(path)<<8, (QRANGE(path)<<8)+0xFF, QSIZE(path), QANTIALIAS(path));
335 9b4a2324 2009-07-09 rsc if(r->fid->aux == nil) {
336 9b4a2324 2009-07-09 rsc responderrstr(r);
337 9b4a2324 2009-07-09 rsc return;
338 9b4a2324 2009-07-09 rsc }
339 9b4a2324 2009-07-09 rsc }
340 9b4a2324 2009-07-09 rsc sf = r->fid->aux;
341 9b4a2324 2009-07-09 rsc m = sf->bits;
342 9b4a2324 2009-07-09 rsc if(r->ifcall.offset < 5*12) {
343 9b4a2324 2009-07-09 rsc char *chan;
344 9b4a2324 2009-07-09 rsc if(QANTIALIAS(path))
345 9b4a2324 2009-07-09 rsc chan = "k8";
346 9b4a2324 2009-07-09 rsc else
347 9b4a2324 2009-07-09 rsc chan = "k1";
348 9b4a2324 2009-07-09 rsc data = smprint("%11s %11d %11d %11d %11d ", chan, m->r.min.x, m->r.min.y, m->r.max.x, m->r.max.y);
349 9b4a2324 2009-07-09 rsc readstr(r, data);
350 9b4a2324 2009-07-09 rsc free(data);
351 9b4a2324 2009-07-09 rsc break;
352 9b4a2324 2009-07-09 rsc }
353 9b4a2324 2009-07-09 rsc r->ifcall.offset -= 5*12;
354 9b4a2324 2009-07-09 rsc size = bytesperline(m->r, chantodepth(m->chan)) * Dy(m->r);
355 9b4a2324 2009-07-09 rsc if(r->ifcall.offset < size) {
356 9b4a2324 2009-07-09 rsc readbuf(r, byteaddr(m, m->r.min), size);
357 9b4a2324 2009-07-09 rsc break;
358 9b4a2324 2009-07-09 rsc }
359 9b4a2324 2009-07-09 rsc r->ifcall.offset -= size;
360 9b4a2324 2009-07-09 rsc data = emalloc9p(3*12+6*(sf->n+1));
361 9b4a2324 2009-07-09 rsc sprint(data, "%11d %11d %11d ", sf->n, sf->height, sf->ascent);
362 9b4a2324 2009-07-09 rsc packinfo(sf->info, (uchar*)data+3*12, sf->n);
363 9b4a2324 2009-07-09 rsc readbuf(r, data, 3*12+6*(sf->n+1));
364 9b4a2324 2009-07-09 rsc free(data);
365 9b4a2324 2009-07-09 rsc break;
366 9b4a2324 2009-07-09 rsc }
367 9b4a2324 2009-07-09 rsc respond(r, nil);
368 9b4a2324 2009-07-09 rsc }
369 9b4a2324 2009-07-09 rsc
370 9b4a2324 2009-07-09 rsc static void
371 9b4a2324 2009-07-09 rsc xdestroyfid(Fid *fid)
372 9b4a2324 2009-07-09 rsc {
373 9b4a2324 2009-07-09 rsc Memsubfont *sf;
374 9b4a2324 2009-07-09 rsc
375 9b4a2324 2009-07-09 rsc sf = fid->aux;
376 9b4a2324 2009-07-09 rsc if(sf == nil)
377 9b4a2324 2009-07-09 rsc return;
378 9b4a2324 2009-07-09 rsc
379 9b4a2324 2009-07-09 rsc freememimage(sf->bits);
380 9b4a2324 2009-07-09 rsc free(sf->info);
381 9b4a2324 2009-07-09 rsc free(sf);
382 9b4a2324 2009-07-09 rsc fid->aux = nil;
383 9b4a2324 2009-07-09 rsc }
384 9b4a2324 2009-07-09 rsc
385 9b4a2324 2009-07-09 rsc static void
386 9b4a2324 2009-07-09 rsc xstat(Req *r)
387 9b4a2324 2009-07-09 rsc {
388 9b4a2324 2009-07-09 rsc dostat(r->fid->qid.path, nil, &r->d);
389 9b4a2324 2009-07-09 rsc respond(r, nil);
390 9b4a2324 2009-07-09 rsc }
391 9b4a2324 2009-07-09 rsc
392 9b4a2324 2009-07-09 rsc Srv xsrv;
393 9b4a2324 2009-07-09 rsc
394 9b4a2324 2009-07-09 rsc int
395 9b4a2324 2009-07-09 rsc proccreate(void (*f)(void*), void *a, unsigned i)
396 9b4a2324 2009-07-09 rsc {
397 9b4a2324 2009-07-09 rsc abort();
398 9b4a2324 2009-07-09 rsc }
399 9b4a2324 2009-07-09 rsc
400 9b4a2324 2009-07-09 rsc int pflag;
401 9b4a2324 2009-07-09 rsc
402 9b4a2324 2009-07-09 rsc static long dirpackage(uchar*, long, Dir**);
403 9b4a2324 2009-07-09 rsc
404 9b4a2324 2009-07-09 rsc void
405 9b4a2324 2009-07-09 rsc dump(char *path)
406 9b4a2324 2009-07-09 rsc {
407 9b4a2324 2009-07-09 rsc char *elem, *p, *path0, *err;
408 9b4a2324 2009-07-09 rsc uchar buf[4096];
409 9b4a2324 2009-07-09 rsc Fid fid;
410 9b4a2324 2009-07-09 rsc Qid qid;
411 9b4a2324 2009-07-09 rsc Dir *d;
412 9b4a2324 2009-07-09 rsc Req r;
413 9b4a2324 2009-07-09 rsc int off, i, n;
414 9b4a2324 2009-07-09 rsc
415 9b4a2324 2009-07-09 rsc // root
416 9b4a2324 2009-07-09 rsc memset(&fid, 0, sizeof fid);
417 9b4a2324 2009-07-09 rsc dostat(0, &fid.qid, nil);
418 9b4a2324 2009-07-09 rsc qid = fid.qid;
419 9b4a2324 2009-07-09 rsc
420 9b4a2324 2009-07-09 rsc path0 = path;
421 9b4a2324 2009-07-09 rsc while(path != nil) {
422 9b4a2324 2009-07-09 rsc p = strchr(path, '/');
423 9b4a2324 2009-07-09 rsc if(p != nil)
424 9b4a2324 2009-07-09 rsc *p = '\0';
425 9b4a2324 2009-07-09 rsc elem = path;
426 9b4a2324 2009-07-09 rsc if(strcmp(elem, "") != 0 && strcmp(elem, ".") != 0) {
427 9b4a2324 2009-07-09 rsc err = xwalk1(&fid, elem, &qid);
428 9b4a2324 2009-07-09 rsc if(err != nil) {
429 9b4a2324 2009-07-09 rsc fprint(2, "%s: %s\n", path0, err);
430 9b4a2324 2009-07-09 rsc exits(err);
431 9b4a2324 2009-07-09 rsc }
432 9b4a2324 2009-07-09 rsc }
433 9b4a2324 2009-07-09 rsc if(p)
434 9b4a2324 2009-07-09 rsc *p++ = '/';
435 9b4a2324 2009-07-09 rsc path = p;
436 9b4a2324 2009-07-09 rsc }
437 9b4a2324 2009-07-09 rsc
438 9b4a2324 2009-07-09 rsc memset(&r, 0, sizeof r);
439 9b4a2324 2009-07-09 rsc xsrv.fake = 1;
440 9b4a2324 2009-07-09 rsc
441 9b4a2324 2009-07-09 rsc // read and display
442 9b4a2324 2009-07-09 rsc off = 0;
443 9b4a2324 2009-07-09 rsc for(;;) {
444 9b4a2324 2009-07-09 rsc r.srv = &xsrv;
445 9b4a2324 2009-07-09 rsc r.fid = &fid;
446 9b4a2324 2009-07-09 rsc r.ifcall.type = Tread;
447 9b4a2324 2009-07-09 rsc r.ifcall.count = sizeof buf;
448 9b4a2324 2009-07-09 rsc r.ifcall.offset = off;
449 9b4a2324 2009-07-09 rsc r.ofcall.data = (char*)buf;
450 9b4a2324 2009-07-09 rsc r.ofcall.count = 0;
451 9b4a2324 2009-07-09 rsc xread(&r);
452 9b4a2324 2009-07-09 rsc if(r.ofcall.type != Rread) {
453 9b4a2324 2009-07-09 rsc fprint(2, "reading %s: %s\n", path0, r.ofcall.ename);
454 9b4a2324 2009-07-09 rsc exits(r.ofcall.ename);
455 9b4a2324 2009-07-09 rsc }
456 9b4a2324 2009-07-09 rsc n = r.ofcall.count;
457 9b4a2324 2009-07-09 rsc if(n == 0)
458 9b4a2324 2009-07-09 rsc break;
459 9b4a2324 2009-07-09 rsc if(off == 0 && pflag > 1) {
460 9b4a2324 2009-07-09 rsc print("\001");
461 9b4a2324 2009-07-09 rsc }
462 9b4a2324 2009-07-09 rsc off += n;
463 9b4a2324 2009-07-09 rsc if(qid.type & QTDIR) {
464 9b4a2324 2009-07-09 rsc n = dirpackage(buf, n, &d);
465 9b4a2324 2009-07-09 rsc for(i=0; i<n; i++)
466 9b4a2324 2009-07-09 rsc print("%s%s\n", d[i].name, (d[i].mode&DMDIR) ? "/" : "");
467 9b4a2324 2009-07-09 rsc free(d);
468 9b4a2324 2009-07-09 rsc } else
469 9b4a2324 2009-07-09 rsc write(1, buf, n);
470 9b4a2324 2009-07-09 rsc }
471 9b4a2324 2009-07-09 rsc }
472 9b4a2324 2009-07-09 rsc
473 9b4a2324 2009-07-09 rsc int
474 9b4a2324 2009-07-09 rsc fontcmp(const void *va, const void *vb)
475 9b4a2324 2009-07-09 rsc {
476 9b4a2324 2009-07-09 rsc XFont *a, *b;
477 9b4a2324 2009-07-09 rsc
478 9b4a2324 2009-07-09 rsc a = (XFont*)va;
479 9b4a2324 2009-07-09 rsc b = (XFont*)vb;
480 9b4a2324 2009-07-09 rsc return strcmp(a->name, b->name);
481 9b4a2324 2009-07-09 rsc }
482 9b4a2324 2009-07-09 rsc
483 9b4a2324 2009-07-09 rsc void
484 9b4a2324 2009-07-09 rsc main(int argc, char **argv)
485 9b4a2324 2009-07-09 rsc {
486 76f90e51 2009-07-09 rsc char *mtpt, *srvname;
487 76f90e51 2009-07-09 rsc
488 76f90e51 2009-07-09 rsc mtpt = nil;
489 76f90e51 2009-07-09 rsc srvname = "font";
490 9b4a2324 2009-07-09 rsc
491 9b4a2324 2009-07-09 rsc ARGBEGIN{
492 9b4a2324 2009-07-09 rsc case 'D':
493 9b4a2324 2009-07-09 rsc chatty9p++;
494 9b4a2324 2009-07-09 rsc break;
495 9b4a2324 2009-07-09 rsc case 'F':
496 9b4a2324 2009-07-09 rsc chattyfuse++;
497 9b4a2324 2009-07-09 rsc break;
498 9b4a2324 2009-07-09 rsc case 'm':
499 9b4a2324 2009-07-09 rsc mtpt = EARGF(usage());
500 9b4a2324 2009-07-09 rsc break;
501 76f90e51 2009-07-09 rsc case 's':
502 76f90e51 2009-07-09 rsc srvname = EARGF(usage());
503 76f90e51 2009-07-09 rsc break;
504 9b4a2324 2009-07-09 rsc case 'p':
505 9b4a2324 2009-07-09 rsc pflag++;
506 9b4a2324 2009-07-09 rsc break;
507 9b4a2324 2009-07-09 rsc default:
508 9b4a2324 2009-07-09 rsc usage();
509 9b4a2324 2009-07-09 rsc }ARGEND
510 9b4a2324 2009-07-09 rsc
511 9b4a2324 2009-07-09 rsc xsrv.attach = xattach;
512 9b4a2324 2009-07-09 rsc xsrv.open = xopen;
513 9b4a2324 2009-07-09 rsc xsrv.read = xread;
514 9b4a2324 2009-07-09 rsc xsrv.stat = xstat;
515 9b4a2324 2009-07-09 rsc xsrv.walk1 = xwalk1;
516 9b4a2324 2009-07-09 rsc xsrv.destroyfid = xdestroyfid;
517 9b4a2324 2009-07-09 rsc
518 9b4a2324 2009-07-09 rsc fmtinstall('R', Rfmt);
519 9b4a2324 2009-07-09 rsc fmtinstall('P', Pfmt);
520 9b4a2324 2009-07-09 rsc memimageinit();
521 9b4a2324 2009-07-09 rsc defont = getmemdefont();
522 9b4a2324 2009-07-09 rsc loadfonts();
523 9b4a2324 2009-07-09 rsc qsort(xfont, nxfont, sizeof xfont[0], fontcmp);
524 9b4a2324 2009-07-09 rsc
525 9b4a2324 2009-07-09 rsc if(pflag) {
526 9b4a2324 2009-07-09 rsc if(argc != 1 || chatty9p || chattyfuse)
527 9b4a2324 2009-07-09 rsc usage();
528 9b4a2324 2009-07-09 rsc dump(argv[0]);
529 9b4a2324 2009-07-09 rsc exits(0);
530 9b4a2324 2009-07-09 rsc }
531 9b4a2324 2009-07-09 rsc
532 9b4a2324 2009-07-09 rsc if(pflag || argc != 0)
533 9b4a2324 2009-07-09 rsc usage();
534 9b4a2324 2009-07-09 rsc
535 9b4a2324 2009-07-09 rsc /*
536 9b4a2324 2009-07-09 rsc * Check twice -- if there is an exited instance
537 9b4a2324 2009-07-09 rsc * mounted there, the first access will fail but unmount it.
538 9b4a2324 2009-07-09 rsc */
539 9b4a2324 2009-07-09 rsc if(mtpt && access(mtpt, AEXIST) < 0 && access(mtpt, AEXIST) < 0)
540 9b4a2324 2009-07-09 rsc sysfatal("mountpoint %s does not exist", mtpt);
541 9b4a2324 2009-07-09 rsc
542 9b4a2324 2009-07-09 rsc xsrv.foreground = 1;
543 76f90e51 2009-07-09 rsc threadpostmountsrv(&xsrv, srvname, mtpt, 0);
544 9b4a2324 2009-07-09 rsc }
545 9b4a2324 2009-07-09 rsc
546 9b4a2324 2009-07-09 rsc /*
547 9b4a2324 2009-07-09 rsc /sys/src/libc/9sys/dirread.c
548 9b4a2324 2009-07-09 rsc */
549 9b4a2324 2009-07-09 rsc static
550 9b4a2324 2009-07-09 rsc long
551 9b4a2324 2009-07-09 rsc dirpackage(uchar *buf, long ts, Dir **d)
552 9b4a2324 2009-07-09 rsc {
553 9b4a2324 2009-07-09 rsc char *s;
554 9b4a2324 2009-07-09 rsc long ss, i, n, nn, m;
555 9b4a2324 2009-07-09 rsc
556 9b4a2324 2009-07-09 rsc *d = nil;
557 9b4a2324 2009-07-09 rsc if(ts <= 0)
558 9b4a2324 2009-07-09 rsc return 0;
559 9b4a2324 2009-07-09 rsc
560 9b4a2324 2009-07-09 rsc /*
561 9b4a2324 2009-07-09 rsc * first find number of all stats, check they look like stats, & size all associated strings
562 9b4a2324 2009-07-09 rsc */
563 9b4a2324 2009-07-09 rsc ss = 0;
564 9b4a2324 2009-07-09 rsc n = 0;
565 9b4a2324 2009-07-09 rsc for(i = 0; i < ts; i += m){
566 9b4a2324 2009-07-09 rsc m = BIT16SZ + GBIT16(&buf[i]);
567 9b4a2324 2009-07-09 rsc if(statcheck(&buf[i], m) < 0)
568 9b4a2324 2009-07-09 rsc break;
569 9b4a2324 2009-07-09 rsc ss += m;
570 9b4a2324 2009-07-09 rsc n++;
571 9b4a2324 2009-07-09 rsc }
572 9b4a2324 2009-07-09 rsc
573 9b4a2324 2009-07-09 rsc if(i != ts)
574 9b4a2324 2009-07-09 rsc return -1;
575 9b4a2324 2009-07-09 rsc
576 9b4a2324 2009-07-09 rsc *d = malloc(n * sizeof(Dir) + ss);
577 9b4a2324 2009-07-09 rsc if(*d == nil)
578 9b4a2324 2009-07-09 rsc return -1;
579 9b4a2324 2009-07-09 rsc
580 9b4a2324 2009-07-09 rsc /*
581 9b4a2324 2009-07-09 rsc * then convert all buffers
582 9b4a2324 2009-07-09 rsc */
583 9b4a2324 2009-07-09 rsc s = (char*)*d + n * sizeof(Dir);
584 9b4a2324 2009-07-09 rsc nn = 0;
585 9b4a2324 2009-07-09 rsc for(i = 0; i < ts; i += m){
586 9b4a2324 2009-07-09 rsc m = BIT16SZ + GBIT16((uchar*)&buf[i]);
587 9b4a2324 2009-07-09 rsc if(nn >= n || convM2D(&buf[i], m, *d + nn, s) != m){
588 9b4a2324 2009-07-09 rsc free(*d);
589 9b4a2324 2009-07-09 rsc *d = nil;
590 9b4a2324 2009-07-09 rsc return -1;
591 9b4a2324 2009-07-09 rsc }
592 9b4a2324 2009-07-09 rsc nn++;
593 9b4a2324 2009-07-09 rsc s += m;
594 9b4a2324 2009-07-09 rsc }
595 9b4a2324 2009-07-09 rsc
596 9b4a2324 2009-07-09 rsc return nn;
597 9b4a2324 2009-07-09 rsc }
598 9b4a2324 2009-07-09 rsc