]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/vnc/devcons.c
vncv: pick an auth type that we support
[plan9front.git] / sys / src / cmd / vnc / devcons.c
1 #include        <u.h>
2 #include        <libc.h>
3 #include        "compat.h"
4 #include        "kbd.h"
5 #include        "error.h"
6
7 Snarf   snarf = {
8         .vers = 1
9 };
10
11 enum{
12         Qdir,
13         Qcons,
14         Qconsctl,
15         Qsnarf,
16 };
17
18 static Dirtab consdir[]={
19         ".",            {Qdir, 0, QTDIR},       0,              DMDIR|0555,
20         "cons",         {Qcons},        0,              0660,
21         "consctl",      {Qconsctl},     0,              0220,
22         "snarf",        {Qsnarf},       0,              0600,
23 };
24
25 static Chan*
26 consattach(char *spec)
27 {
28         return devattach('c', spec);
29 }
30
31 static Walkqid*
32 conswalk(Chan *c, Chan *nc, char **name, int nname)
33 {
34         return devwalk(c, nc, name,nname, consdir, nelem(consdir), devgen);
35 }
36
37 static int
38 consstat(Chan *c, uchar *dp, int n)
39 {
40         return devstat(c, dp, n, consdir, nelem(consdir), devgen);
41 }
42
43 static Chan*
44 consopen(Chan *c, int omode)
45 {
46         c->aux = nil;
47         c = devopen(c, omode, consdir, nelem(consdir), devgen);
48         switch((ulong)c->qid.path){
49         case Qconsctl:
50                 break;
51         case Qsnarf:
52                 if((c->mode&3) == OWRITE || (c->mode&3) == ORDWR)
53                         c->aux = smalloc(sizeof(Snarf));
54                 break;
55         }
56         return c;
57 }
58
59 void
60 setsnarf(char *buf, int n, int *vers)
61 {
62         int i;
63
64         qlock(&snarf);
65         snarf.vers++;
66         if(vers)
67                 *vers = snarf.vers;     
68         for(i = 0; i < nelem(consdir); i++){
69                 if(consdir[i].qid.type == Qsnarf){
70                         consdir[i].qid.vers = snarf.vers;
71                         break;
72                 }
73         }
74         free(snarf.buf);
75         snarf.n = n;
76         snarf.buf = buf;
77         qunlock(&snarf);
78 }
79
80 static void
81 consclose(Chan *c)
82 {
83         Snarf *t;
84
85         switch((ulong)c->qid.path){
86         /* last close of control file turns off raw */
87         case Qconsctl:
88                 break;
89         /* odd behavior but really ok: replace snarf buffer when /dev/snarf is closed */
90         case Qsnarf:
91                 t = c->aux;
92                 if(t == nil)
93                         break;
94                 setsnarf(t->buf, t->n, 0);
95                 t->buf = nil;   /* setsnarf took it */
96                 free(t);
97                 c->aux = nil;
98                 break;
99         }
100 }
101
102 static long
103 consread(Chan *c, void *buf, long n, vlong off)
104 {
105         if(n <= 0)
106                 return n;
107         switch((ulong)c->qid.path){
108         case Qsnarf:
109                 qlock(&snarf);
110                 if(off < snarf.n){
111                         if(off + n > snarf.n)
112                                 n = snarf.n - off;
113                         memmove(buf, snarf.buf+off, n);
114                 }else
115                         n = 0;
116                 qunlock(&snarf);
117                 return n;
118
119         case Qdir:
120                 return devdirread(c, buf, n, consdir, nelem(consdir), devgen);
121
122         case Qcons:
123                 error(Egreg);
124                 return -1;
125
126         default:
127                 print("consread 0x%llux\n", c->qid.path);
128                 error(Egreg);
129         }
130         return -1;              /* never reached */
131 }
132
133 static long
134 conswrite(Chan *c, void *va, long n, vlong)
135 {
136         Snarf *t;
137         char *a;
138
139         switch((ulong)c->qid.path){
140         case Qcons:
141                 screenputs(va, n);
142                 break;
143
144         case Qconsctl:
145                 error(Egreg);
146                 break;
147
148         case Qsnarf:
149                 t = c->aux;
150                 /* always append only */
151                 if(t->n > MAXSNARF)     /* avoid thrashing when people cut huge text */
152                         error("snarf buffer too big");
153                 a = realloc(t->buf, t->n + n + 1);
154                 if(a == nil)
155                         error("snarf buffer too big");
156                 t->buf = a;
157                 memmove(t->buf+t->n, va, n);
158                 t->n += n;
159                 t->buf[t->n] = '\0';
160                 break;
161         default:
162                 print("conswrite: 0x%llux\n", c->qid.path);
163                 error(Egreg);
164         }
165         return n;
166 }
167
168 Dev consdevtab = {
169         'c',
170         "cons",
171
172         devreset,
173         devinit,
174         consattach,
175         conswalk,
176         consstat,
177         consopen,
178         devcreate,
179         consclose,
180         consread,
181         devbread,
182         conswrite,
183         devbwrite,
184         devremove,
185         devwstat,
186 };