|
|
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: #define DEVTAB
8: #include "devtab.h"
9:
10: extern ulong kerndate;
11:
12: int
13: devno(int c, int user)
14: {
15: Rune *s;
16: int i;
17:
18: s = devchar;
19: i = 0;
20: while(*s){
21: if(c == *s)
22: return i;
23: i++;
24: s++;
25: }
26:
27: if(user)
28: return -1;
29: panic("devno %C 0x%ux", c, c);
30: return 0;
31: }
32:
33: void
34: devdir(Chan *c, Qid qid, char *n, long length, char *user, long perm, Dir *db)
35: {
36: strcpy(db->name, n);
37: db->qid = qid;
38: db->type = devchar[c->type];
39: db->dev = c->dev;
40: if(qid.path & CHDIR)
41: db->mode = CHDIR|perm;
42: else
43: db->mode = perm;
44: if(c->flag&CMSG)
45: db->mode |= CHMOUNT;
46: db->atime = seconds();
47: db->mtime = kerndate;
48: db->hlength = 0;
49: db->length = length;
50: memmove(db->uid, user, NAMELEN);
51: memmove(db->gid, eve, NAMELEN);
52: }
53:
54: int
55: devgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp)
56: {
57: if(tab==0 || i>=ntab)
58: return -1;
59: tab += i;
60: devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
61: return 1;
62: }
63:
64: Chan *
65: devattach(int tc, char *spec)
66: {
67: Chan *c;
68:
69: USED(spec);
70: c = newchan();
71: c->qid = (Qid){CHDIR, 0};
72: c->type = devno(tc, 0);
73: return c;
74: }
75:
76: Chan *
77: devclone(Chan *c, Chan *nc)
78: {
79: if(c->flag & COPEN)
80: panic("clone of open file type %C\n", devchar[c->type]);
81: if(nc == 0)
82: nc = newchan();
83: nc->type = c->type;
84: nc->dev = c->dev;
85: nc->mode = c->mode;
86: nc->qid = c->qid;
87: nc->offset = c->offset;
88: nc->flag = c->flag;
89: nc->mnt = c->mnt;
90: nc->mountid = c->mountid;
91: nc->aux = c->aux;
92: nc->mchan = c->mchan;
93: nc->mqid = c->mqid;
94: return nc;
95: }
96:
97: int
98: devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen)
99: {
100: long i;
101: Dir dir;
102:
103: isdir(c);
104: if(name[0]=='.' && name[1]==0)
105: return 1;
106: for(i=0;; i++)
107: switch((*gen)(c, tab, ntab, i, &dir)){
108: case -1:
109: strncpy(u->error, Enonexist, NAMELEN);
110: return 0;
111: case 0:
112: continue;
113: case 1:
114: if(strcmp(name, dir.name) == 0){
115: c->qid = dir.qid;
116: return 1;
117: }
118: continue;
119: }
120: return 1; /* not reached */
121: }
122:
123: void
124: devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen)
125: {
126: int i;
127: Dir dir;
128:
129: for(i=0;; i++)
130: switch((*gen)(c, tab, ntab, i, &dir)){
131: case -1:
132: /*
133: * given a channel, we cannot derive the directory name
134: * that the channel was generated from since it was lost
135: * by namec.
136: */
137: if(c->qid.path & CHDIR){
138: devdir(c, c->qid, ".", 0L, eve, CHDIR|0775, &dir);
139: convD2M(&dir, db);
140: return;
141: }
142: print("%s %s: devstat %C %lux\n", u->p->text, u->p->user,
143: devchar[c->type], c->qid.path);
144: error(Enonexist);
145: case 0:
146: break;
147: case 1:
148: if(eqqid(c->qid, dir.qid)){
149: if(c->flag&CMSG)
150: dir.mode |= CHMOUNT;
151: convD2M(&dir, db);
152: return;
153: }
154: break;
155: }
156: }
157:
158: long
159: devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen)
160: {
161: long k, m;
162: Dir dir;
163:
164: k = c->offset/DIRLEN;
165: for(m=0; m<n; k++)
166: switch((*gen)(c, tab, ntab, k, &dir)){
167: case -1:
168: return m;
169:
170: case 0:
171: c->offset += DIRLEN;
172: break;
173:
174: case 1:
175: convD2M(&dir, d);
176: m += DIRLEN;
177: d += DIRLEN;
178: break;
179: }
180: return m;
181: }
182:
183: Chan *
184: devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen)
185: {
186: int i;
187: Dir dir;
188: ulong t, mode;
189: static int access[] = { 0400, 0200, 0600, 0100 };
190:
191: for(i=0;; i++)
192: switch((*gen)(c, tab, ntab, i, &dir)){
193: case -1:
194: goto Return;
195: case 0:
196: break;
197: case 1:
198: if(eqqid(c->qid, dir.qid)) {
199: if(strcmp(u->p->user, dir.uid) == 0) /* User */
200: mode = dir.mode;
201: else if(strcmp(u->p->user, eve) == 0) /* eve is group */
202: mode = dir.mode<<3;
203: else
204: mode = dir.mode<<6; /* Other */
205:
206: t = access[omode&3];
207: if((t & mode) == t)
208: goto Return;
209: error(Eperm);
210: }
211: break;
212: }
213: Return:
214: c->offset = 0;
215: if((c->qid.path&CHDIR) && omode!=OREAD)
216: error(Eperm);
217: c->mode = openmode(omode);
218: c->flag |= COPEN;
219: return c;
220: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.