1 #include "all.h"
2
3 #include "9p1.h"
4
5 void
fcall9p1(Chan * cp,Fcall * in,Fcall * ou)6 fcall9p1(Chan *cp, Fcall *in, Fcall *ou)
7 {
8 int t;
9
10 rlock(&mainlock);
11 t = in->type;
12 if(t < 0 || t >= MAXSYSCALL || (t&1) || !call9p1[t]) {
13 print("bad message type %d\n", t);
14 panic("");
15 }
16 ou->type = t+1;
17 ou->err = 0;
18
19 rlock(&cp->reflock);
20 (*call9p1[t])(cp, in, ou);
21 runlock(&cp->reflock);
22
23 if(ou->err && CHAT(cp))
24 print("\terror: %s\n", errstr9p[ou->err]);
25 runlock(&mainlock);
26 }
27
28 int
con_session(void)29 con_session(void)
30 {
31 Fcall in, ou;
32
33 in.type = Tsession;
34 fcall9p1(cons.chan, &in, &ou);
35 return ou.err;
36 }
37
38 int
con_attach(int fid,char * uid,char * arg)39 con_attach(int fid, char *uid, char *arg)
40 {
41 Fcall in, ou;
42
43 in.type = Tattach;
44 in.fid = fid;
45 strncpy(in.uname, uid, NAMELEN);
46 strncpy(in.aname, arg, NAMELEN);
47 fcall9p1(cons.chan, &in, &ou);
48 return ou.err;
49 }
50
51 int
con_clone(int fid1,int fid2)52 con_clone(int fid1, int fid2)
53 {
54 Fcall in, ou;
55
56 in.type = Tclone;
57 in.fid = fid1;
58 in.newfid = fid2;
59 fcall9p1(cons.chan, &in, &ou);
60 return ou.err;
61 }
62
63 int
con_walk(int fid,char * name)64 con_walk(int fid, char *name)
65 {
66 Fcall in, ou;
67
68 in.type = Twalk;
69 in.fid = fid;
70 strncpy(in.name, name, NAMELEN);
71 fcall9p1(cons.chan, &in, &ou);
72 return ou.err;
73 }
74
75 int
con_open(int fid,int mode)76 con_open(int fid, int mode)
77 {
78 Fcall in, ou;
79
80 in.type = Topen;
81 in.fid = fid;
82 in.mode = mode;
83 fcall9p1(cons.chan, &in, &ou);
84 return ou.err;
85 }
86
87 int
con_read(int fid,char * data,Off offset,int count)88 con_read(int fid, char *data, Off offset, int count)
89 {
90 Fcall in, ou;
91
92 in.type = Tread;
93 in.fid = fid;
94 in.offset = offset;
95 in.count = count;
96 ou.data = data;
97 fcall9p1(cons.chan, &in, &ou);
98 if(ou.err)
99 return 0;
100 return ou.count;
101 }
102
103 int
con_write(int fid,char * data,Off offset,int count)104 con_write(int fid, char *data, Off offset, int count)
105 {
106 Fcall in, ou;
107
108 in.type = Twrite;
109 in.fid = fid;
110 in.data = data;
111 in.offset = offset;
112 in.count = count;
113 fcall9p1(cons.chan, &in, &ou);
114 if(ou.err)
115 return 0;
116 return ou.count;
117 }
118
119 int
con_remove(int fid)120 con_remove(int fid)
121 {
122 Fcall in, ou;
123
124 in.type = Tremove;
125 in.fid = fid;
126 fcall9p1(cons.chan, &in, &ou);
127 return ou.err;
128 }
129
130 int
con_create(int fid,char * name,int uid,int gid,long perm,int mode)131 con_create(int fid, char *name, int uid, int gid, long perm, int mode)
132 {
133 Fcall in, ou;
134
135 in.type = Tcreate;
136 in.fid = fid;
137 strncpy(in.name, name, NAMELEN);
138 in.perm = perm;
139 in.mode = mode;
140 cons.uid = uid; /* beyond ugly */
141 cons.gid = gid;
142 fcall9p1(cons.chan, &in, &ou);
143 return ou.err;
144 }
145
146 int
doclri(File * f)147 doclri(File *f)
148 {
149 Iobuf *p, *p1;
150 Dentry *d, *d1;
151 int err;
152
153 err = 0;
154 p = 0;
155 p1 = 0;
156 if(f->fs->dev->type == Devro) {
157 err = Eronly;
158 goto out;
159 }
160 /*
161 * check on parent directory of file to be deleted
162 */
163 if(f->wpath == 0 || f->wpath->addr == f->addr) {
164 err = Ephase;
165 goto out;
166 }
167 p1 = getbuf(f->fs->dev, f->wpath->addr, Brd);
168 d1 = getdir(p1, f->wpath->slot);
169 if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
170 err = Ephase;
171 goto out;
172 }
173
174 accessdir(p1, d1, FWRITE, 0);
175 putbuf(p1);
176 p1 = 0;
177
178 /*
179 * check on file to be deleted
180 */
181 p = getbuf(f->fs->dev, f->addr, Brd);
182 d = getdir(p, f->slot);
183
184 /*
185 * do it
186 */
187 memset(d, 0, sizeof(Dentry));
188 settag(p, Tdir, QPNONE);
189 freewp(f->wpath);
190 freefp(f);
191
192 out:
193 if(p1)
194 putbuf(p1);
195 if(p)
196 putbuf(p);
197 return err;
198 }
199
200 void
f_fstat(Chan * cp,Fcall * in,Fcall * ou)201 f_fstat(Chan *cp, Fcall *in, Fcall *ou)
202 {
203 File *f;
204 Iobuf *p;
205 Dentry *d;
206 int i;
207
208 if(CHAT(cp)) {
209 print("c_fstat %d\n", cp->chan);
210 print("\tfid = %d\n", in->fid);
211 }
212
213 p = 0;
214 f = filep(cp, in->fid, 0);
215 if(!f) {
216 ou->err = Efid;
217 goto out;
218 }
219 p = getbuf(f->fs->dev, f->addr, Brd);
220 d = getdir(p, f->slot);
221 if(d == 0)
222 goto out;
223
224 print("name = %.*s\n", NAMELEN, d->name);
225 print("uid = %d; gid = %d; muid = %d\n", d->uid, d->gid, d->muid);
226 print("size = %lld; qid = %llux/%lux\n", (Wideoff)d->size,
227 (Wideoff)d->qid.path, d->qid.version);
228 print("atime = %ld; mtime = %ld\n", d->atime, d->mtime);
229 print("dblock =");
230 for(i=0; i<NDBLOCK; i++)
231 print(" %lld", (Wideoff)d->dblock[i]);
232 for (i = 0; i < NIBLOCK; i++)
233 print("; iblocks[%d] = %lld", i, (Wideoff)d->iblocks[i]);
234 print("\n\n");
235
236 out:
237 if(p)
238 putbuf(p);
239 ou->fid = in->fid;
240 if(f)
241 qunlock(f);
242 }
243
244 void
f_clri(Chan * cp,Fcall * in,Fcall * ou)245 f_clri(Chan *cp, Fcall *in, Fcall *ou)
246 {
247 File *f;
248
249 if(CHAT(cp)) {
250 print("c_clri %d\n", cp->chan);
251 print("\tfid = %d\n", in->fid);
252 }
253
254 f = filep(cp, in->fid, 0);
255 if(!f) {
256 ou->err = Efid;
257 goto out;
258 }
259 ou->err = doclri(f);
260
261 out:
262 ou->fid = in->fid;
263 if(f)
264 qunlock(f);
265 }
266
267 int
con_clri(int fid)268 con_clri(int fid)
269 {
270 Fcall in, ou;
271 Chan *cp;
272
273 in.type = Tremove;
274 in.fid = fid;
275 cp = cons.chan;
276
277 rlock(&mainlock);
278 ou.type = Tremove+1;
279 ou.err = 0;
280
281 rlock(&cp->reflock);
282 f_clri(cp, &in, &ou);
283 runlock(&cp->reflock);
284
285 runlock(&mainlock);
286 return ou.err;
287 }
288
289 int
con_fstat(int fid)290 con_fstat(int fid)
291 {
292 Fcall in, ou;
293 Chan *cp;
294
295 in.type = Tstat;
296 in.fid = fid;
297 cp = cons.chan;
298
299 rlock(&mainlock);
300 ou.type = Tstat+1;
301 ou.err = 0;
302
303 rlock(&cp->reflock);
304 f_fstat(cp, &in, &ou);
305 runlock(&cp->reflock);
306
307 runlock(&mainlock);
308 return ou.err;
309 }
310