1*37da2899SCharles.Forsyth #include "dat.h"
2*37da2899SCharles.Forsyth #include "fns.h"
3*37da2899SCharles.Forsyth #include "error.h"
4*37da2899SCharles.Forsyth #include "interp.h"
5*37da2899SCharles.Forsyth
6*37da2899SCharles.Forsyth /* Qid is (2*fd + (file is ctl))+1 */
7*37da2899SCharles.Forsyth
8*37da2899SCharles.Forsyth static int
dupgen(Chan * c,char * name,Dirtab * tab,int ntab,int s,Dir * dp)9*37da2899SCharles.Forsyth dupgen(Chan *c, char *name, Dirtab *tab, int ntab, int s, Dir *dp)
10*37da2899SCharles.Forsyth {
11*37da2899SCharles.Forsyth Fgrp *fgrp = up->env->fgrp;
12*37da2899SCharles.Forsyth Chan *f;
13*37da2899SCharles.Forsyth static int perm[] = { 0400, 0200, 0600, 0 };
14*37da2899SCharles.Forsyth int p;
15*37da2899SCharles.Forsyth Qid q;
16*37da2899SCharles.Forsyth
17*37da2899SCharles.Forsyth USED(name); USED(tab); USED(ntab);
18*37da2899SCharles.Forsyth if(s == DEVDOTDOT){
19*37da2899SCharles.Forsyth devdir(c, c->qid, ".", 0, eve, DMDIR|0555, dp);
20*37da2899SCharles.Forsyth return 1;
21*37da2899SCharles.Forsyth }
22*37da2899SCharles.Forsyth if(s == 0)
23*37da2899SCharles.Forsyth return 0;
24*37da2899SCharles.Forsyth s--;
25*37da2899SCharles.Forsyth if(s/2 > fgrp->maxfd)
26*37da2899SCharles.Forsyth return -1;
27*37da2899SCharles.Forsyth if((f=fgrp->fd[s/2]) == nil)
28*37da2899SCharles.Forsyth return 0;
29*37da2899SCharles.Forsyth if(s & 1){
30*37da2899SCharles.Forsyth p = 0400;
31*37da2899SCharles.Forsyth sprint(up->genbuf, "%dctl", s/2);
32*37da2899SCharles.Forsyth }else{
33*37da2899SCharles.Forsyth p = perm[f->mode&3];
34*37da2899SCharles.Forsyth sprint(up->genbuf, "%d", s/2);
35*37da2899SCharles.Forsyth }
36*37da2899SCharles.Forsyth mkqid(&q, s+1, 0, QTFILE);
37*37da2899SCharles.Forsyth devdir(c, q, up->genbuf, 0, eve, p, dp);
38*37da2899SCharles.Forsyth return 1;
39*37da2899SCharles.Forsyth }
40*37da2899SCharles.Forsyth
41*37da2899SCharles.Forsyth static Chan*
dupattach(char * spec)42*37da2899SCharles.Forsyth dupattach(char *spec)
43*37da2899SCharles.Forsyth {
44*37da2899SCharles.Forsyth return devattach('d', spec);
45*37da2899SCharles.Forsyth }
46*37da2899SCharles.Forsyth
47*37da2899SCharles.Forsyth static Walkqid*
dupwalk(Chan * c,Chan * nc,char ** name,int nname)48*37da2899SCharles.Forsyth dupwalk(Chan *c, Chan *nc, char **name, int nname)
49*37da2899SCharles.Forsyth {
50*37da2899SCharles.Forsyth return devwalk(c, nc, name, nname, nil, 0, dupgen);
51*37da2899SCharles.Forsyth }
52*37da2899SCharles.Forsyth
53*37da2899SCharles.Forsyth static int
dupstat(Chan * c,uchar * db,int n)54*37da2899SCharles.Forsyth dupstat(Chan *c, uchar *db, int n)
55*37da2899SCharles.Forsyth {
56*37da2899SCharles.Forsyth return devstat(c, db, n, nil, 0, dupgen);
57*37da2899SCharles.Forsyth }
58*37da2899SCharles.Forsyth
59*37da2899SCharles.Forsyth static Chan*
dupopen(Chan * c,int omode)60*37da2899SCharles.Forsyth dupopen(Chan *c, int omode)
61*37da2899SCharles.Forsyth {
62*37da2899SCharles.Forsyth Chan *f;
63*37da2899SCharles.Forsyth int fd, twicefd;
64*37da2899SCharles.Forsyth
65*37da2899SCharles.Forsyth if(c->qid.type & QTDIR){
66*37da2899SCharles.Forsyth if(omode != 0)
67*37da2899SCharles.Forsyth error(Eisdir);
68*37da2899SCharles.Forsyth c->mode = 0;
69*37da2899SCharles.Forsyth c->flag |= COPEN;
70*37da2899SCharles.Forsyth c->offset = 0;
71*37da2899SCharles.Forsyth return c;
72*37da2899SCharles.Forsyth }
73*37da2899SCharles.Forsyth if(c->qid.type & QTAUTH)
74*37da2899SCharles.Forsyth error(Eperm);
75*37da2899SCharles.Forsyth twicefd = c->qid.path - 1;
76*37da2899SCharles.Forsyth fd = twicefd/2;
77*37da2899SCharles.Forsyth if((twicefd & 1)){
78*37da2899SCharles.Forsyth /* ctl file */
79*37da2899SCharles.Forsyth f = c;
80*37da2899SCharles.Forsyth f->mode = openmode(omode);
81*37da2899SCharles.Forsyth f->flag |= COPEN;
82*37da2899SCharles.Forsyth f->offset = 0;
83*37da2899SCharles.Forsyth }else{
84*37da2899SCharles.Forsyth /* fd file */
85*37da2899SCharles.Forsyth f = fdtochan(up->env->fgrp, fd, openmode(omode), 0, 1);
86*37da2899SCharles.Forsyth cclose(c);
87*37da2899SCharles.Forsyth }
88*37da2899SCharles.Forsyth if(omode & OCEXEC)
89*37da2899SCharles.Forsyth f->flag |= CCEXEC;
90*37da2899SCharles.Forsyth return f;
91*37da2899SCharles.Forsyth }
92*37da2899SCharles.Forsyth
93*37da2899SCharles.Forsyth static void
dupclose(Chan * c)94*37da2899SCharles.Forsyth dupclose(Chan *c)
95*37da2899SCharles.Forsyth {
96*37da2899SCharles.Forsyth USED(c);
97*37da2899SCharles.Forsyth }
98*37da2899SCharles.Forsyth
99*37da2899SCharles.Forsyth static long
dupread(Chan * c,void * va,long n,vlong offset)100*37da2899SCharles.Forsyth dupread(Chan *c, void *va, long n, vlong offset)
101*37da2899SCharles.Forsyth {
102*37da2899SCharles.Forsyth char *a = va;
103*37da2899SCharles.Forsyth char buf[256];
104*37da2899SCharles.Forsyth int fd, twicefd;
105*37da2899SCharles.Forsyth
106*37da2899SCharles.Forsyth if(c->qid.type == QTDIR)
107*37da2899SCharles.Forsyth return devdirread(c, a, n, nil, 0, dupgen);
108*37da2899SCharles.Forsyth twicefd = c->qid.path - 1;
109*37da2899SCharles.Forsyth fd = twicefd/2;
110*37da2899SCharles.Forsyth if(twicefd & 1){
111*37da2899SCharles.Forsyth c = fdtochan(up->env->fgrp, fd, -1, 0, 1);
112*37da2899SCharles.Forsyth if(waserror()){
113*37da2899SCharles.Forsyth cclose(c);
114*37da2899SCharles.Forsyth nexterror();
115*37da2899SCharles.Forsyth }
116*37da2899SCharles.Forsyth progfdprint(c, fd, 0, buf, sizeof buf);
117*37da2899SCharles.Forsyth poperror();
118*37da2899SCharles.Forsyth cclose(c);
119*37da2899SCharles.Forsyth return readstr((ulong)offset, va, n, buf);
120*37da2899SCharles.Forsyth }
121*37da2899SCharles.Forsyth panic("dupread");
122*37da2899SCharles.Forsyth return 0;
123*37da2899SCharles.Forsyth }
124*37da2899SCharles.Forsyth
125*37da2899SCharles.Forsyth static long
dupwrite(Chan * c,void * a,long n,vlong o)126*37da2899SCharles.Forsyth dupwrite(Chan *c, void *a, long n, vlong o)
127*37da2899SCharles.Forsyth {
128*37da2899SCharles.Forsyth USED(c); USED(a); USED(n); USED(o);
129*37da2899SCharles.Forsyth panic("dupwrite");
130*37da2899SCharles.Forsyth return 0; /* not reached */
131*37da2899SCharles.Forsyth }
132*37da2899SCharles.Forsyth
133*37da2899SCharles.Forsyth Dev dupdevtab = {
134*37da2899SCharles.Forsyth 'd',
135*37da2899SCharles.Forsyth "dup",
136*37da2899SCharles.Forsyth
137*37da2899SCharles.Forsyth devinit,
138*37da2899SCharles.Forsyth dupattach,
139*37da2899SCharles.Forsyth dupwalk,
140*37da2899SCharles.Forsyth dupstat,
141*37da2899SCharles.Forsyth dupopen,
142*37da2899SCharles.Forsyth devcreate,
143*37da2899SCharles.Forsyth dupclose,
144*37da2899SCharles.Forsyth dupread,
145*37da2899SCharles.Forsyth devbread,
146*37da2899SCharles.Forsyth dupwrite,
147*37da2899SCharles.Forsyth devbwrite,
148*37da2899SCharles.Forsyth devremove,
149*37da2899SCharles.Forsyth devwstat,
150*37da2899SCharles.Forsyth };
151