changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > plan9front / sys/src/games/blit/telnet.c

changeset 6228: f4fa0b9d0397
parent: 84a6cae21f1f
author: cinap_lenrek@felloff.net
date: Sun, 26 Nov 2017 17:11:01 +0100
permissions: -rw-r--r--
description: cga: capture cga console contents on boot, make sure cgapos is in range

to capture bios and bootloader messages, convert the contents
on the screen to kmesg.

on machines without legacy cga, the cga registers read out as
0xFF, resuting in out of bounds cgapos. so set cgapos to 0 in
that case.
1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include "dat.h"
5 #include "fns.h"
6 
7 Channel *telnetrxch, *telnettxch;
8 extern Channel *uartrxch, *uarttxch;
9 int teldebug;
10 
11 enum {
12  SE = 240,
13  NOP = 241,
14  BRK = 243,
15  IP = 244,
16  AO = 245,
17  AYT = 246,
18  EC = 247,
19  EL = 248,
20  GA = 249,
21  SB = 250,
22  WILL = 251,
23  WONT = 252,
24  DO = 253,
25  DONT = 254,
26  IAC = 255,
27 
28  XMITBIN = 0,
29  ECHO = 1,
30  SUPRGA = 3,
31  LINEEDIT = 34,
32 
33 };
34 
35 int telfd;
36 
37 static void
38 netrproc(void *)
39 {
40  static uchar buf[512];
41  int n, c;
42  uchar *p;
43 
44  for(;;){
45  n = read(telfd, buf, sizeof(buf));
46  if(n < 0) sysfatal("read: %r");
47  for(p = buf; p < buf + n; p++){
48  c = *p;
49  send(telnetrxch, &c);
50  }
51  }
52 }
53 
54 static void
55 netwproc(void *)
56 {
57  static uchar buf[512];
58  int c;
59  uchar *p;
60 
61  for(;;){
62  recv(telnettxch, &c);
63  p = buf;
64  do
65  *p++ = c;
66  while(nbrecv(telnettxch, &c) > 0);
67  if(write(telfd, buf, p - buf) < p - buf)
68  sysfatal("write: %r");
69  }
70 }
71 
72 static void
73 telnetrthread(void *)
74 {
75  int c;
76 
77  for(;;){
78  recv(telnetrxch, &c);
79  if(c != IAC){
80  send(uartrxch, &c);
81  continue;
82  }
83  recv(telnetrxch, &c);
84  switch(c){
85  case NOP: break;
86  case WILL:
87  recv(telnetrxch, &c);
88  if(teldebug) fprint(2, "WILL %d\n", c);
89  break;
90  case WONT:
91  recv(telnetrxch, &c);
92  if(teldebug) fprint(2, "WONT %d\n", c);
93  break;
94  case DO:
95  recv(telnetrxch, &c);
96  if(teldebug) fprint(2, "DO %d\n", c);
97  break;
98  case DONT:
99  recv(telnetrxch, &c);
100  if(teldebug) fprint(2, "DONT %d\n", c);
101  break;
102  case IAC:
103  send(uartrxch, &c);
104  break;
105  default:
106  fprint(2, "unknown telnet command %d\n", c);
107  }
108  }
109 }
110 
111 static void
112 cmd(int a, int b)
113 {
114  send(telnettxch, &a);
115  if(b >= 0) send(telnettxch, &b);
116 }
117 
118 static void
119 telnetwthread(void *)
120 {
121  int c;
122 
123  for(;;){
124  recv(uarttxch, &c);
125  send(telnettxch, &c);
126  if(c == 0xff)
127  send(telnettxch, &c);
128  }
129 }
130 
131 void
132 telnetinit(char *dialstr)
133 {
134  telfd = dial(netmkaddr(dialstr, nil, "telnet"), nil, nil, nil);
135  if(telfd < 0) sysfatal("dial: %r");
136  telnetrxch = chancreate(sizeof(int), 128);
137  telnettxch = chancreate(sizeof(int), 128);
138  cmd(WILL, XMITBIN);
139  cmd(DO, XMITBIN);
140  cmd(DONT, ECHO);
141  cmd(DO, SUPRGA);
142  cmd(WILL, SUPRGA);
143  cmd(WONT, LINEEDIT);
144  cmd(DONT, LINEEDIT);
145  proccreate(netrproc, nil, mainstacksize);
146  proccreate(netwproc, nil, mainstacksize);
147  threadcreate(telnetrthread, nil, mainstacksize);
148  threadcreate(telnetwthread, nil, mainstacksize);
149 }