static char *rcsid
= "$Header: gaptelnet.c,v 2.2 86/05/16 11:03:33 jqj Exp $";
* XNS User telnet program.
* Revision 2.2 86/05/16 11:03:33 jqj
* fix to correspond to new semantics for enumerations (global)
* Revision 2.1 86/03/01 09:26:04 jqj
* Accept data with datastream=0 for the sake of incorrectly implemented
* servers (e.g. InterLisp-D). If unrecognized inband controls arrive,
* Revision 2.0 85/11/21 07:23:04 jqj
* 4.3BSD standard release
* Revision 1.3 85/11/20 14:00:08 jqj
* added symbolic entries for Gap connection types
* Revision 1.2 85/05/22 09:46:37 jqj
* VAX 4.3beta baseline version
* Revision 1.2 85/05/22 09:46:37 jqj
* static char *rcsid = "$Header: gaptelnet.c,v 2.2 86/05/16 11:03:33 jqj Exp $";
* static char sccsid[] = "@(#)telnet.c 4.24 (Berkeley) 7/20/83";
#include <netns/sp.h> /* for spphdr */
#include <xnscourier/Clearinghouse2.h>
#include <xnscourier/except.h>
#include <xnscourier/CH.h>
#define strip(x) ((x)&0177)
char ttyobuf
[BUFSIZ
], *tfrontp
= ttyobuf
, *tbackp
= ttyobuf
;
char netobuf
[BUFSIZ
], *nfrontp
= netobuf
, *nbackp
= netobuf
;
CourierConnection
*cconn
;
int tn(), quit(), suspend(), bye(), help();
int setescape(), status(), toggle(), setoptions();
int setcrmod(), setdebug(), setlog();
#define HELPINDENT (sizeof ("connect"))
char *name
; /* command name */
char *help
; /* help string */
int (*handler
)(); /* routine which executes command */
char openhelp
[] = "connect to a site";
char closehelp
[] = "close current connection";
char quithelp
[] = "exit telnet";
char zhelp
[] = "suspend telnet";
char debughelp
[] = "toggle debugging";
char escapehelp
[] = "set escape character";
char statushelp
[] = "print status information";
char helphelp
[] = "print help information";
char crmodhelp
[] = "toggle mapping of received carriage returns";
char loghelp
[] = "toggle logging of session";
{ "open", openhelp
, tn
},
{ "close", closehelp
, bye
},
{ "quit", quithelp
, quit
},
{ "escape", escapehelp
, setescape
},
{ "status", statushelp
, status
},
/* { "crmod", crmodhelp, setcrmod }, */
{ "debug", debughelp
, setdebug
},
{ "log", loghelp
, setlog
},
ioctl(0, TIOCGETP
, (char *)&ottyb
);
ioctl(0, TIOCGETC
, (char *)&otc
);
ioctl(0, TIOCGLTC
, (char *)&oltc
);
if (argc
> 1 && !strcmp(argv
[1], "-d"))
debug
= SO_DEBUG
, argv
++, argc
--;
if (setjmp(toplevel
) != 0)
register struct ns_addr
*host
;
extern struct ns_addr
*getXNSaddr();
Clearinghouse2_ObjectName hostoname
, hdefault
;
LongCardinal servicetype
;
printf("?Already connected to %s\n", hostname
);
strcpy(line
, "Connect ");
gets(&line
[strlen(line
)]);
printf("usage: %s host-name [service-type]\n", argv
[0]);
if (argc
== 2) servicetype
= TTYService_sa
; /* default to 1 */
else if (strcmp(argv
[2],"sa") == 0) servicetype
= TTYService_sa
;
else if (strncmp(argv
[2],"re",2) == 0 ||
strcmp(argv
[2],"exec") == 0) servicetype
= TTYService_exec
;
else if (strcmp(argv
[2],"its") == 0) servicetype
= TTYService_its
;
else servicetype
= atoi(argv
[2]);
CH_NameDefault(&hdefault
);
hostoname
= CH_StringToName(argv
[1], &hdefault
);
if ((host
= CH_LookupAddrDN(hostoname
,0,hnamebuf
,sizeof(hnamebuf
)))) {
host
->x_port
= htons(IDPPORT_COURIER
);
bcopy(host
, (caddr_t
)&sin
.sns_addr
, sizeof(host
));
/* hnamebuf is filled in by CH_LookupAddrDN */
} else if ((host
= getXNSaddr(argv
[1]))) {
bcopy(host
, (caddr_t
)&sin
.sns_addr
, sizeof(host
));
strcpy(hnamebuf
, argv
[1]);
printf("%s: unknown host\n", argv
[1]);
cconn
= CourierOpen(host
);
fprintf(stderr
,"Courier connection failed\n");
signal(SIGPIPE
, deadpeer
);
if (createsession(cconn
,servicetype
) < 0)
call(status
, "status", 0);
if (setjmp(peerdied
) == 0)
fprintf(stderr
, "\nConnection closed by foreign host.\n");
createsession(cconn
, servicetype
)
CourierConnection
*cconn
;
LongCardinal servicetype
;
GAP3_SessionParameterObject pobj
;
GAP3_TransportObject tobjs
[2];
GAP3_CommParamObject
*cp
;
GAP3_TransportObject
*sequence
;
Authentication1_Credentials creds
;
Authentication1_Verifier verifier
;
pobj
.designator
= GAP3_oldTtyHost
; /* 11 */
pobj
.GAP3_oldTtyHost_case
.charLength
= GAP3_seven
;
pobj
.GAP3_oldTtyHost_case
.parity
= GAP3_none
;
pobj
.GAP3_oldTtyHost_case
.stopBits
= GAP3_oneStopBit
;
pobj
.GAP3_oldTtyHost_case
.frameTimeout
= 20;
tobjs[0].designator = GAP3_rs232c;
cp = &tobjs[0].GAP3_rs232c_case.commParams;
cp->accessDetail.designator = GAP3_directConn;
cp->accessDetail.directConn_case.duplex = GAP3_fullduplex;
cp->accessDetail.directConn_case.lineType = GAP3_asynchronous;
cp->accessDetail.directConn_case.lineSpeed = GAP3_bps300;
tobjs[0].rs232c_case.preemptOthers = GAP3_preemptInactive;
tobjs[0].rs232c_case.preemptMe = GAP3_preemptInactive;
tobjs[0].rs232c_case.phoneNumber = "";
tobjs[0].rs232c_case.line.designator = GAP3_reserveNeeded;
tobjs[0].rs232c_case.line.reserveNeeded_case.lineNumber = 1;
tobjs
[0].designator
= GAP3_service
;
tobjs
[0].GAP3_service_case
.id
= servicetype
; /* 1 == SA */
tobjs
[1].designator
= GAP3_teletype
;
tobjlist
.sequence
= tobjs
;
MakeSimpleCredsAndVerifier(0, 0, &creds
, &verifier
);
(void) GAP3_Create(cconn
, NULL
, pobj
, tobjlist
, 0, creds
, verifier
);
switch (Exception
.Code
) {
case GAP3_mediumConnectFailed
:
msg
= "medium connect failed";
case GAP3_illegalTransport
:
msg
= "illegal transport type";
case GAP3_tooManyGateStreams
:
case GAP3_serviceTooBusy
:
msg
= "insufficient resources";
case GAP3_serviceNotFound
:
msg
= "service type not found";
case GAP3_userNotAuthenticated
:
case GAP3_userNotAuthorized
:
msg
= "authentication problem";
switch (CourierErrArgs(rejectionDetails
,designator
)){
case noSuchProgramNumber
:
msg
= "server does not support GAP";
case noSuchVersionNumber
:
msg
= "server does not support our GAP version";
msg
= "connection rejected";
msg
= "protocol violation by remote server";
msg
= "some random error";
fprintf(stderr
,"Error creating connection, %s\n",
* Print status about the connection.
printf("Connected to %s.\n", hostname
);
printf("No connection.\n");
printf("Escape character is '%s'.\n", control(escape
));
register char **argp
= margv
;
while (*cp
!= '\0' && !isspace(*cp
))
/* reget parameters in case they were changed */
ioctl(0, TIOCGETP
, (char *)&ottyb
);
ioctl(0, TIOCGETC
, (char *)&otc
);
ioctl(0, TIOCGLTC
, (char *)&oltc
);
sendoobdata(GAPCTLcleanup
);
setsockopt(net
, NSPROTO_SPP
, SO_HEADERS_ON_OUTPUT
, &on
,
printf("Connection closed.\n");
printf("Syntax: %s [filename]\n",argv
[0]);
else if (logfile
!= (FILE*) 0) {
printf("Log file closed\n");
if (argc
== 2 && (logfile
= fopen(argv
[1],"a")) != (FILE*)0)
printf("Logging to %s\n",argv
[1]);
/* not currently logging */
printf("Logging already disabled\n");
(logfile
= fopen(argv
[1],"a")) != (FILE*)0 )
printf("Logging to %s\n",argv
[1]);
printf("Commands may be abbreviated. Commands are:\n\n");
for (c
= cmdtab
; c
->name
; c
++)
printf("%-*s\t%s\n", HELPINDENT
, c
->name
, c
->help
);
if (c
== (struct cmd
*)-1)
printf("?Ambiguous help command %s\n", arg
);
else if (c
== (struct cmd
*)0)
printf("?Invalid help command %s\n", arg
);
* Call routine with argc, argv set from args (terminated by 0).
for (argc
= 0, argp
= &args
; *argp
++ != 0; argc
++)
struct tchars notc
= { -1, -1, -1, -1, -1, -1 };
struct ltchars noltc
= { -1, -1, -1, -1, -1, -1 };
sb
.sg_flags
&= ~(ECHO
|CRMOD
);
sb
.sg_flags
|= ECHO
|CRMOD
;
sb
.sg_erase
= sb
.sg_kill
= -1;
ioctl(fileno(stdin
), TIOCSLTC
, (char *)ltc
);
ioctl(fileno(stdin
), TIOCSETC
, (char *)tc
);
ioctl(fileno(stdin
), TIOCSETP
, (char *)&sb
);
ioctl(fileno(stdin
), FIONBIO
, &onoff
);
ioctl(fileno(stdout
), FIONBIO
, &onoff
);
struct {struct sphdr hdr
;
char tibuf
[BUFSIZ
], *tbp
;
* Select from tty and network...
int tin
= fileno(stdin
), tout
= fileno(stdout
);
changeSPPopts(net
, GAPCTLnone
, 1); /* datastream "normal", eom */
select(16, &ibits
, &obits
, 0, 0);
if (ibits
== 0 && obits
== 0) {
* Something to read from the network...
scc
= read(s
, &sibuf
, sizeof (sibuf
))
printf("reading %d bytes from net\n", scc
);
if (scc
< 0 && errno
== EWOULDBLOCK
)
break; /* protocol violation? */
else if (sibuf
.hdr
.sp_cc
& SP_OB
) {
/* status or OOB control */
switch ((u_char
) *sibuf
.data
) {
sendoobdata(GAPCTLiAmHere
);
else if (sibuf
.hdr
.sp_dt
== GAPCTLnone
||
/* normal case, plus Lisp bogosity */
else if(sibuf
.hdr
.sp_dt
== GAPCTLcleanup
){
sendoobdata(GAPCTLcleanup
);
/* should get an END next */
else if(sibuf
.hdr
.sp_dt
== SPPSST_END
) {
setsockopt(net
, NSPROTO_SPP
,
else scc
= 0; /* ignore other inband controls */
* Something to read from the tty...
if (ibits
& (1 << tin
)) {
tcc
= read(tin
, tibuf
, sizeof (tibuf
));
if (tcc
< 0 && errno
== EWOULDBLOCK
)
if ((&netobuf
[BUFSIZ
] - nfrontp
) < 2)
c
= *tbp
++ & 0377, tcc
--;
if (strip(c
) == escape
) {
/* We don't do any input translation at the moment */
if ((obits
& (1 << s
)) && (nfrontp
- nbackp
) > 0)
/* nor do we do any output translation */
if ((obits
& (1 << tout
)) && (tfrontp
- tbackp
) > 0)
if (c
== (struct cmd
*)-1) {
printf("?Ambiguous command\n");
printf("?Invalid command\n");
(*c
->handler
)(margc
, margv
);
* Set the escape character.
printf("new escape character: ");
printf("Escape character is '%s'.\n", control(escape
));
* Construct a control character sequence
* for a special character.
register struct cmd
*c
, *found
;
register int nmatches
, longest
;
for (c
= cmdtab
; p
= c
->name
; c
++) {
for (q
= name
; *q
== *p
++; q
++)
if (*q
== 0) /* exact match? */
if (!*q
) { /* the name was a prefix */
if (q
- name
> longest
) {
} else if (q
- name
== longest
)
return ((struct cmd
*)-1);
if ((n
= tfrontp
- tbackp
) > 0) {
fwrite(tbackp
, 1, n
, logfile
);
n
= write(fd
, tbackp
, n
);
tbackp
= tfrontp
= ttyobuf
;
if ((n
= nfrontp
- nbackp
) > 0)
n
= write(fd
, nbackp
, n
);
printf("writing %d of %d bytes to net\n", n
, nfrontp
-nbackp
);
if (errno
!= ENOBUFS
&& errno
!= EWOULDBLOCK
) {
nbackp
= nfrontp
= netobuf
;
* Send out of band data to other end of network
send(net
, &value
, 1, MSG_OOB
);
changeSPPopts(s
, stream
, eom
)
u_char stream
; /* datastream type */
char eom
; /* Boolean EOM */
sphdr
.sp_cc
= (eom
? SP_EM
: 0);
setsockopt(s
, NSPROTO_SPP
, SO_HEADERS_ON_OUTPUT
, &off
, sizeof(off
));
setsockopt(s
, NSPROTO_SPP
, SO_DEFAULT_HEADERS
, &sphdr
, sizeof(sphdr
));