|
|
1.1 root 1: #include "u.h"
2: #include "../port/lib.h"
3: #include "mem.h"
4: #include "dat.h"
5: #include "fns.h"
6: #include "../port/error.h"
7:
8: #include "devtab.h"
9:
10: typedef struct Srv Srv;
11: struct Srv
12: {
13: char name[NAMELEN];
14: char owner[NAMELEN];
15: ulong perm;
16: Chan *chan;
17: Srv *link;
18: ulong path;
19: };
20:
21: static QLock srvlk;
22: static Srv *srv;
23: static int path;
24:
25: int
26: srvgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
27: {
28: Srv *sp;
29:
30: USED(tab);
31: USED(ntab);
32: qlock(&srvlk);
33: for(sp = srv; sp && s; sp = sp->link)
34: s--;
35:
36: if(sp == 0) {
37: qunlock(&srvlk);
38: return -1;
39: }
40: devdir(c, (Qid){sp->path, 0}, sp->name, 0, sp->owner, sp->perm, dp);
41: qunlock(&srvlk);
42: return 1;
43: }
44:
45: void
46: srvinit(void)
47: {
48: path = 1;
49: }
50:
51: void
52: srvreset(void)
53: {
54: }
55:
56: Chan*
57: srvattach(char *spec)
58: {
59: return devattach('s', spec);
60: }
61:
62: Chan*
63: srvclone(Chan *c, Chan *nc)
64: {
65: return devclone(c, nc);
66: }
67:
68: int
69: srvwalk(Chan *c, char *name)
70: {
71: return devwalk(c, name, 0, 0, srvgen);
72: }
73:
74: void
75: srvstat(Chan *c, char *db)
76: {
77: devstat(c, db, 0, 0, srvgen);
78: }
79:
80: Chan*
81: srvopen(Chan *c, int omode)
82: {
83: Srv *sp;
84:
85: if(c->qid.path == CHDIR){
86: if(omode != OREAD)
87: error(Eisdir);
88: c->mode = omode;
89: c->flag |= COPEN;
90: c->offset = 0;
91: return c;
92: }
93: qlock(&srvlk);
94: if(waserror()){
95: qunlock(&srvlk);
96: nexterror();
97: }
98:
99: for(sp = srv; sp; sp = sp->link)
100: if(sp->path == c->qid.path)
101: break;
102:
103: if(sp == 0 || sp->chan == 0)
104: error(Eshutdown);
105:
106: if(omode&OTRUNC)
107: error(Eperm);
108: if(omode!=sp->chan->mode && sp->chan->mode!=ORDWR)
109: error(Eperm);
110:
111: close(c);
112: incref(sp->chan);
113: qunlock(&srvlk);
114: poperror();
115: return sp->chan;
116: }
117:
118: void
119: srvcreate(Chan *c, char *name, int omode, ulong perm)
120: {
121: Srv *sp;
122:
123: if(omode != OWRITE)
124: error(Eperm);
125:
126: sp = malloc(sizeof(Srv));
127: if(sp == 0)
128: error(Enomem);
129:
130: qlock(&srvlk);
131: if(waserror()){
132: qunlock(&srvlk);
133: nexterror();
134: }
135: sp->path = path++;
136: sp->link = srv;
137: c->qid.path = sp->path;
138: srv = sp;
139: qunlock(&srvlk);
140: poperror();
141:
142: strncpy(sp->name, name, NAMELEN);
143: strncpy(sp->owner, u->p->user, NAMELEN);
144: sp->perm = perm&0777;
145:
146: c->flag |= COPEN;
147: c->mode = OWRITE;
148: }
149:
150: void
151: srvremove(Chan *c)
152: {
153: Srv *sp, **l;
154:
155: if(c->qid.path == CHDIR)
156: error(Eperm);
157:
158: qlock(&srvlk);
159: if(waserror()){
160: qunlock(&srvlk);
161: nexterror();
162: }
163: l = &srv;
164: for(sp = *l; sp; sp = sp->link) {
165: if(sp->path == c->qid.path)
166: break;
167:
168: l = &sp->link;
169: }
170: if(sp == 0)
171: error(Enonexist);
172:
173: if(strcmp(sp->name, "boot") == 0)
174: error(Eperm);
175:
176: *l = sp->link;
177: qunlock(&srvlk);
178: poperror();
179:
180: if(sp->chan)
181: close(sp->chan);
182: free(sp);
183: }
184:
185: void
186: srvwstat(Chan *c, char *dp)
187: {
188: USED(c, dp);
189: error(Egreg);
190: }
191:
192: void
193: srvclose(Chan *c)
194: {
195: USED(c);
196: }
197:
198: long
199: srvread(Chan *c, void *va, long n, ulong offset)
200: {
201: USED(offset);
202: isdir(c);
203: return devdirread(c, va, n, 0, 0, srvgen);
204: }
205:
206: long
207: srvwrite(Chan *c, void *va, long n, ulong offset)
208: {
209: Srv *sp;
210: Chan *c1;
211: int fd;
212: char buf[32];
213:
214: USED(offset);
215: if(n >= sizeof buf)
216: error(Egreg);
217: memmove(buf, va, n); /* so we can NUL-terminate */
218: buf[n] = 0;
219: fd = strtoul(buf, 0, 0);
220:
221: c1 = fdtochan(fd, -1, 0, 1); /* error check only */
222:
223: qlock(&srvlk);
224: if(waserror()) {
225: qunlock(&srvlk);
226: close(c1);
227: nexterror();
228: }
229: for(sp = srv; sp; sp = sp->link)
230: if(sp->path == c->qid.path)
231: break;
232:
233: if(sp == 0)
234: error(Enonexist);
235:
236: if(sp->chan)
237: panic("srvwrite");
238:
239: sp->chan = c1;
240: qunlock(&srvlk);
241: poperror();
242: return n;
243: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.