19ef1f84bSDavid du Colombier #include "u.h"
29ef1f84bSDavid du Colombier #include "../port/lib.h"
39ef1f84bSDavid du Colombier #include "mem.h"
49ef1f84bSDavid du Colombier #include "dat.h"
59ef1f84bSDavid du Colombier #include "fns.h"
69ef1f84bSDavid du Colombier #include "../port/error.h"
79ef1f84bSDavid du Colombier
89ef1f84bSDavid du Colombier /* Qid is (2*fd + (file is ctl))+1 */
99ef1f84bSDavid du Colombier
109ef1f84bSDavid du Colombier static int
dupgen(Chan * c,char *,Dirtab *,int,int s,Dir * dp)119ef1f84bSDavid du Colombier dupgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp)
129ef1f84bSDavid du Colombier {
139ef1f84bSDavid du Colombier Fgrp *fgrp = up->fgrp;
149ef1f84bSDavid du Colombier Chan *f;
159ef1f84bSDavid du Colombier static int perm[] = { 0400, 0200, 0600, 0 };
169ef1f84bSDavid du Colombier int p;
179ef1f84bSDavid du Colombier Qid q;
189ef1f84bSDavid du Colombier
199ef1f84bSDavid du Colombier if(s == DEVDOTDOT){
209ef1f84bSDavid du Colombier devdir(c, c->qid, ".", 0, eve, DMDIR|0555, dp);
219ef1f84bSDavid du Colombier return 1;
229ef1f84bSDavid du Colombier }
239ef1f84bSDavid du Colombier if(s == 0)
249ef1f84bSDavid du Colombier return 0;
259ef1f84bSDavid du Colombier s--;
269ef1f84bSDavid du Colombier if(s/2 > fgrp->maxfd)
279ef1f84bSDavid du Colombier return -1;
289ef1f84bSDavid du Colombier if((f=fgrp->fd[s/2]) == nil)
299ef1f84bSDavid du Colombier return 0;
309ef1f84bSDavid du Colombier if(s & 1){
319ef1f84bSDavid du Colombier p = 0400;
32*406c76faSDavid du Colombier snprint(up->genbuf, sizeof up->genbuf, "%dctl", s/2);
339ef1f84bSDavid du Colombier }else{
349ef1f84bSDavid du Colombier p = perm[f->mode&3];
35*406c76faSDavid du Colombier snprint(up->genbuf, sizeof up->genbuf, "%d", s/2);
369ef1f84bSDavid du Colombier }
379ef1f84bSDavid du Colombier mkqid(&q, s+1, 0, QTFILE);
389ef1f84bSDavid du Colombier devdir(c, q, up->genbuf, 0, eve, p, dp);
399ef1f84bSDavid du Colombier return 1;
409ef1f84bSDavid du Colombier }
419ef1f84bSDavid du Colombier
429ef1f84bSDavid du Colombier static Chan*
dupattach(char * spec)439ef1f84bSDavid du Colombier dupattach(char *spec)
449ef1f84bSDavid du Colombier {
459ef1f84bSDavid du Colombier return devattach('d', spec);
469ef1f84bSDavid du Colombier }
479ef1f84bSDavid du Colombier
489ef1f84bSDavid du Colombier static Walkqid*
dupwalk(Chan * c,Chan * nc,char ** name,int nname)499ef1f84bSDavid du Colombier dupwalk(Chan *c, Chan *nc, char **name, int nname)
509ef1f84bSDavid du Colombier {
519ef1f84bSDavid du Colombier return devwalk(c, nc, name, nname, (Dirtab *)0, 0, dupgen);
529ef1f84bSDavid du Colombier }
539ef1f84bSDavid du Colombier
549ef1f84bSDavid du Colombier static long
dupstat(Chan * c,uchar * db,long n)559ef1f84bSDavid du Colombier dupstat(Chan *c, uchar *db, long n)
569ef1f84bSDavid du Colombier {
579ef1f84bSDavid du Colombier return devstat(c, db, n, (Dirtab *)0, 0L, dupgen);
589ef1f84bSDavid du Colombier }
599ef1f84bSDavid du Colombier
609ef1f84bSDavid du Colombier static Chan*
dupopen(Chan * c,int omode)619ef1f84bSDavid du Colombier dupopen(Chan *c, int omode)
629ef1f84bSDavid du Colombier {
639ef1f84bSDavid du Colombier Chan *f;
649ef1f84bSDavid du Colombier int fd, twicefd;
659ef1f84bSDavid du Colombier
669ef1f84bSDavid du Colombier if(c->qid.type & QTDIR){
679ef1f84bSDavid du Colombier if(omode != 0)
689ef1f84bSDavid du Colombier error(Eisdir);
699ef1f84bSDavid du Colombier c->mode = 0;
709ef1f84bSDavid du Colombier c->flag |= COPEN;
719ef1f84bSDavid du Colombier c->offset = 0;
729ef1f84bSDavid du Colombier return c;
739ef1f84bSDavid du Colombier }
749ef1f84bSDavid du Colombier if(c->qid.type & QTAUTH)
759ef1f84bSDavid du Colombier error(Eperm);
769ef1f84bSDavid du Colombier twicefd = c->qid.path - 1;
779ef1f84bSDavid du Colombier fd = twicefd/2;
789ef1f84bSDavid du Colombier if((twicefd & 1)){
799ef1f84bSDavid du Colombier /* ctl file */
809ef1f84bSDavid du Colombier f = c;
819ef1f84bSDavid du Colombier f->mode = openmode(omode);
829ef1f84bSDavid du Colombier f->flag |= COPEN;
839ef1f84bSDavid du Colombier f->offset = 0;
849ef1f84bSDavid du Colombier }else{
859ef1f84bSDavid du Colombier /* fd file */
869ef1f84bSDavid du Colombier f = fdtochan(fd, openmode(omode), 0, 1);
879ef1f84bSDavid du Colombier cclose(c);
889ef1f84bSDavid du Colombier }
899ef1f84bSDavid du Colombier if(omode & OCEXEC)
909ef1f84bSDavid du Colombier f->flag |= CCEXEC;
919ef1f84bSDavid du Colombier return f;
929ef1f84bSDavid du Colombier }
939ef1f84bSDavid du Colombier
949ef1f84bSDavid du Colombier static void
dupclose(Chan *)959ef1f84bSDavid du Colombier dupclose(Chan*)
969ef1f84bSDavid du Colombier {
979ef1f84bSDavid du Colombier }
989ef1f84bSDavid du Colombier
999ef1f84bSDavid du Colombier static long
dupread(Chan * c,void * va,long n,vlong off)1009ef1f84bSDavid du Colombier dupread(Chan *c, void *va, long n, vlong off)
1019ef1f84bSDavid du Colombier {
1029ef1f84bSDavid du Colombier char buf[256];
1039ef1f84bSDavid du Colombier int fd, twicefd;
1049ef1f84bSDavid du Colombier
1059ef1f84bSDavid du Colombier if(c->qid.type & QTDIR)
1069ef1f84bSDavid du Colombier return devdirread(c, va, n, (Dirtab *)0, 0L, dupgen);
1079ef1f84bSDavid du Colombier twicefd = c->qid.path - 1;
1089ef1f84bSDavid du Colombier fd = twicefd/2;
1099ef1f84bSDavid du Colombier if(twicefd & 1){
1109ef1f84bSDavid du Colombier c = fdtochan(fd, -1, 0, 1);
1119ef1f84bSDavid du Colombier procfdprint(c, fd, 0, buf, sizeof buf);
1129ef1f84bSDavid du Colombier cclose(c);
1139ef1f84bSDavid du Colombier return readstr(off, va, n, buf);
1149ef1f84bSDavid du Colombier }
1159ef1f84bSDavid du Colombier panic("dupread");
1169ef1f84bSDavid du Colombier return 0;
1179ef1f84bSDavid du Colombier }
1189ef1f84bSDavid du Colombier
1199ef1f84bSDavid du Colombier static long
dupwrite(Chan *,void *,long,vlong)1209ef1f84bSDavid du Colombier dupwrite(Chan*, void*, long, vlong)
1219ef1f84bSDavid du Colombier {
1229ef1f84bSDavid du Colombier error(Eperm);
1239ef1f84bSDavid du Colombier return 0; /* not reached */
1249ef1f84bSDavid du Colombier }
1259ef1f84bSDavid du Colombier
1269ef1f84bSDavid du Colombier Dev dupdevtab = {
1279ef1f84bSDavid du Colombier 'd',
1289ef1f84bSDavid du Colombier "dup",
1299ef1f84bSDavid du Colombier
1309ef1f84bSDavid du Colombier devreset,
1319ef1f84bSDavid du Colombier devinit,
1329ef1f84bSDavid du Colombier devshutdown,
1339ef1f84bSDavid du Colombier dupattach,
1349ef1f84bSDavid du Colombier dupwalk,
1359ef1f84bSDavid du Colombier dupstat,
1369ef1f84bSDavid du Colombier dupopen,
1379ef1f84bSDavid du Colombier devcreate,
1389ef1f84bSDavid du Colombier dupclose,
1399ef1f84bSDavid du Colombier dupread,
1409ef1f84bSDavid du Colombier devbread,
1419ef1f84bSDavid du Colombier dupwrite,
1429ef1f84bSDavid du Colombier devbwrite,
1439ef1f84bSDavid du Colombier devremove,
1449ef1f84bSDavid du Colombier devwstat,
1459ef1f84bSDavid du Colombier };
146