13e12c5d1SDavid du Colombier #include "u.h"
23e12c5d1SDavid du Colombier #include "../port/lib.h"
33e12c5d1SDavid du Colombier #include "mem.h"
43e12c5d1SDavid du Colombier #include "dat.h"
53e12c5d1SDavid du Colombier #include "fns.h"
63e12c5d1SDavid du Colombier #include "../port/error.h"
73e12c5d1SDavid du Colombier
89a747e4fSDavid du Colombier /* Qid is (2*fd + (file is ctl))+1 */
99a747e4fSDavid du Colombier
107dd7cddfSDavid du Colombier static int
dupgen(Chan * c,char *,Dirtab *,int,int s,Dir * dp)119a747e4fSDavid du Colombier dupgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp)
123e12c5d1SDavid du Colombier {
137dd7cddfSDavid du Colombier Fgrp *fgrp = up->fgrp;
143e12c5d1SDavid du Colombier Chan *f;
153e12c5d1SDavid du Colombier static int perm[] = { 0400, 0200, 0600, 0 };
169a747e4fSDavid du Colombier int p;
179a747e4fSDavid du Colombier Qid q;
183e12c5d1SDavid du Colombier
197dd7cddfSDavid du Colombier if(s == DEVDOTDOT){
209a747e4fSDavid du Colombier devdir(c, c->qid, ".", 0, eve, DMDIR|0555, dp);
217dd7cddfSDavid du Colombier return 1;
227dd7cddfSDavid du Colombier }
239a747e4fSDavid du Colombier if(s == 0)
243e12c5d1SDavid du Colombier return 0;
259a747e4fSDavid du Colombier s--;
269a747e4fSDavid du Colombier if(s/2 > fgrp->maxfd)
279a747e4fSDavid du Colombier return -1;
289a747e4fSDavid du Colombier if((f=fgrp->fd[s/2]) == nil)
299a747e4fSDavid du Colombier return 0;
309a747e4fSDavid du Colombier if(s & 1){
319a747e4fSDavid du Colombier p = 0400;
32*4e3613abSDavid du Colombier snprint(up->genbuf, sizeof up->genbuf, "%dctl", s/2);
339a747e4fSDavid du Colombier }else{
349a747e4fSDavid du Colombier p = perm[f->mode&3];
35*4e3613abSDavid du Colombier snprint(up->genbuf, sizeof up->genbuf, "%d", s/2);
369a747e4fSDavid du Colombier }
379a747e4fSDavid du Colombier mkqid(&q, s+1, 0, QTFILE);
389a747e4fSDavid du Colombier devdir(c, q, up->genbuf, 0, eve, p, dp);
393e12c5d1SDavid du Colombier return 1;
403e12c5d1SDavid du Colombier }
413e12c5d1SDavid du Colombier
427dd7cddfSDavid du Colombier static Chan*
dupattach(char * spec)433e12c5d1SDavid du Colombier dupattach(char *spec)
443e12c5d1SDavid du Colombier {
453e12c5d1SDavid du Colombier return devattach('d', spec);
463e12c5d1SDavid du Colombier }
473e12c5d1SDavid du Colombier
489a747e4fSDavid du Colombier static Walkqid*
dupwalk(Chan * c,Chan * nc,char ** name,int nname)499a747e4fSDavid du Colombier dupwalk(Chan *c, Chan *nc, char **name, int nname)
503e12c5d1SDavid du Colombier {
519a747e4fSDavid du Colombier return devwalk(c, nc, name, nname, (Dirtab *)0, 0, dupgen);
523e12c5d1SDavid du Colombier }
533e12c5d1SDavid du Colombier
549a747e4fSDavid du Colombier static int
dupstat(Chan * c,uchar * db,int n)559a747e4fSDavid du Colombier dupstat(Chan *c, uchar *db, int n)
563e12c5d1SDavid du Colombier {
579a747e4fSDavid du Colombier return devstat(c, db, n, (Dirtab *)0, 0L, dupgen);
583e12c5d1SDavid du Colombier }
593e12c5d1SDavid du Colombier
607dd7cddfSDavid du Colombier static Chan*
dupopen(Chan * c,int omode)613e12c5d1SDavid du Colombier dupopen(Chan *c, int omode)
623e12c5d1SDavid du Colombier {
633e12c5d1SDavid du Colombier Chan *f;
649a747e4fSDavid du Colombier int fd, twicefd;
653e12c5d1SDavid du Colombier
669a747e4fSDavid du Colombier if(c->qid.type & QTDIR){
673e12c5d1SDavid du Colombier if(omode != 0)
683e12c5d1SDavid du Colombier error(Eisdir);
693e12c5d1SDavid du Colombier c->mode = 0;
703e12c5d1SDavid du Colombier c->flag |= COPEN;
713e12c5d1SDavid du Colombier c->offset = 0;
723e12c5d1SDavid du Colombier return c;
733e12c5d1SDavid du Colombier }
749a747e4fSDavid du Colombier if(c->qid.type & QTAUTH)
759a747e4fSDavid du Colombier error(Eperm);
769a747e4fSDavid du Colombier twicefd = c->qid.path - 1;
779a747e4fSDavid du Colombier fd = twicefd/2;
789a747e4fSDavid du Colombier if((twicefd & 1)){
799a747e4fSDavid du Colombier /* ctl file */
809a747e4fSDavid du Colombier f = c;
819a747e4fSDavid du Colombier f->mode = openmode(omode);
829a747e4fSDavid du Colombier f->flag |= COPEN;
839a747e4fSDavid du Colombier f->offset = 0;
849a747e4fSDavid du Colombier }else{
859a747e4fSDavid du Colombier /* fd file */
869a747e4fSDavid du Colombier f = fdtochan(fd, openmode(omode), 0, 1);
877dd7cddfSDavid du Colombier cclose(c);
889a747e4fSDavid du Colombier }
893e12c5d1SDavid du Colombier if(omode & OCEXEC)
903e12c5d1SDavid du Colombier f->flag |= CCEXEC;
913e12c5d1SDavid du Colombier return f;
923e12c5d1SDavid du Colombier }
933e12c5d1SDavid du Colombier
947dd7cddfSDavid du Colombier static void
dupclose(Chan *)957dd7cddfSDavid du Colombier dupclose(Chan*)
963e12c5d1SDavid du Colombier {
973e12c5d1SDavid du Colombier }
983e12c5d1SDavid du Colombier
997dd7cddfSDavid du Colombier static long
dupread(Chan * c,void * va,long n,vlong offset)1009a747e4fSDavid du Colombier dupread(Chan *c, void *va, long n, vlong offset)
1013e12c5d1SDavid du Colombier {
1023e12c5d1SDavid du Colombier char *a = va;
1039a747e4fSDavid du Colombier char buf[256];
1049a747e4fSDavid du Colombier int fd, twicefd;
1053e12c5d1SDavid du Colombier
1069a747e4fSDavid du Colombier if(c->qid.type == QTDIR)
1073e12c5d1SDavid du Colombier return devdirread(c, a, n, (Dirtab *)0, 0L, dupgen);
1089a747e4fSDavid du Colombier twicefd = c->qid.path - 1;
1099a747e4fSDavid du Colombier fd = twicefd/2;
1109a747e4fSDavid du Colombier if(twicefd & 1){
1119a747e4fSDavid du Colombier c = fdtochan(fd, -1, 0, 1);
1129a747e4fSDavid du Colombier procfdprint(c, fd, 0, buf, sizeof buf);
1139a747e4fSDavid du Colombier cclose(c);
1149a747e4fSDavid du Colombier return readstr((ulong)offset, va, n, buf);
1159a747e4fSDavid du Colombier }
1169a747e4fSDavid du Colombier panic("dupread");
1179a747e4fSDavid du Colombier return 0;
1183e12c5d1SDavid du Colombier }
1193e12c5d1SDavid du Colombier
1207dd7cddfSDavid du Colombier static long
dupwrite(Chan *,void *,long,vlong)1217dd7cddfSDavid du Colombier dupwrite(Chan*, void*, long, vlong)
1223e12c5d1SDavid du Colombier {
1238f5875f3SDavid du Colombier error(Eperm);
1243e12c5d1SDavid du Colombier return 0; /* not reached */
1253e12c5d1SDavid du Colombier }
1267dd7cddfSDavid du Colombier
1277dd7cddfSDavid du Colombier Dev dupdevtab = {
1287dd7cddfSDavid du Colombier 'd',
1297dd7cddfSDavid du Colombier "dup",
1307dd7cddfSDavid du Colombier
1317dd7cddfSDavid du Colombier devreset,
1327dd7cddfSDavid du Colombier devinit,
1339a747e4fSDavid du Colombier devshutdown,
1347dd7cddfSDavid du Colombier dupattach,
1357dd7cddfSDavid du Colombier dupwalk,
1367dd7cddfSDavid du Colombier dupstat,
1377dd7cddfSDavid du Colombier dupopen,
1387dd7cddfSDavid du Colombier devcreate,
1397dd7cddfSDavid du Colombier dupclose,
1407dd7cddfSDavid du Colombier dupread,
1417dd7cddfSDavid du Colombier devbread,
1427dd7cddfSDavid du Colombier dupwrite,
1437dd7cddfSDavid du Colombier devbwrite,
1447dd7cddfSDavid du Colombier devremove,
1457dd7cddfSDavid du Colombier devwstat,
1467dd7cddfSDavid du Colombier };
147