-# $Id: Makefile.mpw,v 1.1.2.11 1999/04/03 21:53:29 ben Exp $
+# $Id: Makefile.mpw,v 1.1.2.12 1999/04/04 18:23:33 ben Exp $
# This is the Makefile for building PuTTY for the Mac OS.
# Users of non-Mac systems will see some pretty strange characters around.
PPCCOptions = {Includes} {Sym¥PPC} -w 35
Objects¥68K = ¶
+ dnr.c.o ¶
mac.c.o ¶
maccfg.c.o ¶
+ macnet.c.o ¶
macterm.c.o ¶
misc.c.o ¶
# ssh.c.o ¶
# sshrand.c.o ¶
# sshrsa.c.o ¶
# sshsha.c.o ¶
-# telnet.c.o ¶
+ telnet.c.o ¶
terminal.c.o ¶
testback.c.o
Objects¥PPC = ¶
+ dnr.c.x ¶
mac.c.x ¶
maccfg.c.x ¶
+ macnet.c.x ¶
macterm.c.x ¶
misc.c.x ¶
# ssh.c.x ¶
# sshrand.c.x ¶
# sshrsa.c.x ¶
# sshsha.c.x ¶
-# telnet.c.x ¶
+ telnet.c.x ¶
terminal.c.x ¶
testback.c.x
ILink ¶
-o {Targ} {Sym¥68K} ¶
-t 'APPL' -c 'pTTY' ¶
+ -br 68k -model far ¶
-newerdeps {NewerDeps}
ELSE
ILink ¶
-o {Targ} {Sym¥68K} ¶
-t 'APPL' -c 'pTTY' ¶
+ -br 68k -model far¶
{Objects¥68K} ¶
{Libs¥68K}
END
setfile -t XCOF {Targ}
{PPCC} {default}.c -o {Targ} {PPCCOptions}
+dnr.c.o dnr.c.x Ä
mac.c.o mac.c.x Ä putty.h mac.h macresid.h
maccfg.c.o maccfg.c.x Ä putty.h mac.h macresid.h
macnet.c.o macnet.c.x Ä putty.h
-/* $Id: mac.c,v 1.1.2.23 1999/04/02 12:58:02 ben Exp $ */
+/* $Id: mac.c,v 1.1.2.24 1999/04/04 18:23:33 ben Exp $ */
/*
* Copyright (c) 1999 Ben Harris
* All rights reserved.
mac_adjustcursor(cursrgn);
if (gotevent)
mac_event(&event);
+ macnet_eventcheck();
}
DisposeRgn(cursrgn);
}
extern void mac_menuterm(WindowPtr, short, short);
/* from maccfg.c */
extern void mac_loadconfig(Config *);
+/* from macnet.c */
+extern void macnet_eventcheck(void);
#endif
-/* $Id: macnet.c,v 1.1.2.2 1999/04/03 21:53:29 ben Exp $ */
+/* $Id: macnet.c,v 1.1.2.3 1999/04/04 18:23:34 ben Exp $ */
/*
* Copyright (c) 1999 Ben Harris
* All rights reserved.
TCPiopb spareiopb; /* for closing etc */
hostInfo hostinfo;
int port;
-// unsigned char *inbuf;
-// int inbuf_head, inbuf_reap, inbuf_size;
-// unsigned char *outbuf;
-// int outbuf_head, outbuf_reap, outbuf_size;
ProcessSerialNumber psn;
Session *s;
- UInt32 a5;
- qHdr sendq; /* Blocks waiting to be sent */
- qHdr freeq; /* Blocks sent, waiting to be freed */
+ long a5;
+ QHdr sendq; /* Blocks waiting to be sent */
} Socket;
typedef struct {
QElem qelem;
int flags;
- int len;
+ wdsEntry wds;
+ short wdsterm;
} Send_Buffer;
/*
static OSErr macnet_init(void);
static pascal void macnet_resolved(hostInfo *, char *);
-static void macnet_opened(TCPiopb*);
-static void macnet_sent(TCPiopb*);
-static void macnet_closed(TCPiopb*);
+static void macnet_completed_open(TCPiopb*);
+static void macnet_completed_send(TCPiopb*);
+static void macnet_sent(Socket *);
+static void macnet_startsend(Socket *);
+static void macnet_completed_close(TCPiopb*);
static pascal void macnet_asr(StreamPtr, unsigned short, Ptr, unsigned short,
ICMPReport *);
static void macnet_sendevent(Socket *, Net_Event_Type);
#if TARGET_RT_MAC_CFM
static RoutineDescriptor macnet_resolved_upp =
BUILD_ROUTINE_DESCRIPTOR(uppResultProcInfo, (ProcPtr)macnet_resolved);
-static RoutineDescriptor macnet_opened_upp =
+static RoutineDescriptor macnet_completed_open_upp =
BUILD_ROUTINE_DESCRIPTOR(uppTCPIOCompletionProcInfo,
- (ProcPtr)macnet_opened);
-static RoutineDescriptor macnet_sent_upp =
- BUILD_ROUTINE_DESCRIPTOR(uppTCPIOCompletionProcInfo, (ProcPtr)macnet_sent);
-static RoutineDescriptor macnet_closed_upp =
+ (ProcPtr)macnet_completed_open);
+static RoutineDescriptor macnet_complete_send_upp =
BUILD_ROUTINE_DESCRIPTOR(uppTCPIOCompletionProcInfo,
- (ProcPtr)macnet_closed);
+ (ProcPtr)macnet_completed_send);
+static RoutineDescriptor macnet_completed_close_upp =
+ BUILD_ROUTINE_DESCRIPTOR(uppTCPIOCompletionProcInfo,
+ (ProcPtr)macnet_completed_close);
static RoutineDescriptor macnet_asr_upp =
BUILD_ROUTINE_DESCRIPTOR(uppTCPNotifyProcInfo, (ProcPtr)macnet_asr);
#else
#define macnet_resolved_upp macnet_resolved
-#define macnet_opened_upp macnet_opened
-#define macnet_sent_upp macnet_sent
-#define macnet_closed_upp macnet_closed
+#define macnet_completed_open_upp macnet_completed_open
+#define macnet_completed_send_upp macnet_completed_send
+#define macnet_completed_close_upp macnet_completed_close
#define macnet_asr_upp macnet_asr
#endif
NetEvent *eventblock;
int i;
+ /*
+ * FIXME: This is hideously broken, in that we're meant to faff
+ * with unit numbers and stuff, and we blatantly don't.
+ */
err = opendriver(".IPP", &mtcp_refnum);
if (err != noErr)
return err;
err = OpenResolver(NULL);
if (err != noErr)
return err;
- /* Set up the event queues, and fill the free queue with events */
+ /* Set up the event queues, and fill the free queue with events
+ */
macnet_eventq.qFlags = 0;
macnet_eventq.qHead = macnet_eventq.qTail = NULL;
macnet_freeq.qFlags = 0;
for (i = 0; i < NUM_EVENTS; i++)
Enqueue(&eventblock[i].qelem, &macnet_freeq);
mtcp_initted = TRUE;
+ return 0;
}
Socket *net_open(Session *s, char *host, int port) {
static pascal void macnet_resolved(hostInfo *hi, char *cookie) {
Socket *sock = (Socket *)cookie;
OSErr err;
- UInt32 olda5;
+#if !TARGET_RT_CFM
+ long olda5;
olda5 = SetA5(sock->a5);
+#endif
/*
* We've resolved a name, so now we'd like to connect to it (or
* report an error).
switch (sock->hostinfo.rtnCode) {
case noErr:
/* Open a connection */
- sock->iopb.ioCompletion = macnet_opened_upp;
+ sock->iopb.ioCompletion = macnet_completed_open_upp;
sock->iopb.csCode = TCPActiveOpen;
sock->iopb.csParam.open.validityFlags = typeOfService;
sock->iopb.csParam.open.commandTimeoutValue = 0; /* unused */
macnet_sendevent(sock, NE_NOHOST);
break;
}
+#if !TARGET_RT_CFM
SetA5(olda5);
+#endif
}
-static void macnet_opened(TCPiopb *iopb) {
+static void macnet_completed_open(TCPiopb *iopb) {
Socket *sock = (Socket *)iopb->csParam.open.userDataPtr;
- UInt32 olda5;
+#if !TARGET_RT_CFM
+ long olda5;
olda5 = SetA5(sock->a5);
+#endif
switch (iopb->ioResult) {
case noErr:
macnet_sendevent(sock, NE_OPEN);
macnet_sendevent(sock, NE_NOOPEN);
break;
}
+#if !TARGET_RT_CFM
SetA5(olda5);
+#endif
}
static pascal void macnet_asr(StreamPtr tcpstream, unsigned short eventcode,
Ptr cookie, unsigned short terminreason,
ICMPReport *icmpmsg) {
Socket *sock = (Socket *)cookie;
- UInt32 olda5;
+#if !TARGET_RT_CFM
+ long olda5;
olda5 = SetA5(sock->a5);
+#endif
switch (eventcode) {
case TCPClosing:
macnet_sendevent(sock, NE_CLOSING);
}
break;
}
+#if !TARGET_RT_CFM
SetA5(olda5);
+#endif
}
/*
* Send a block of data.
*/
-int net_send(Socket *sock, void *buf, int buflen, int flags) {{
+int net_send(Socket *sock, void *buf, int buflen, int flags) {
OSErr err;
Send_Buffer *buff;
buff = smalloc(sizeof(Send_Buffer) + buflen);
buff->flags = flags;
- buff->len = buflen;
- memcpy(buff + 1, buf, buflen);
+ buff->wds.length = buflen;
+ buff->wds.ptr = (Ptr)&buff[1]; /* after the end of the struct */
+ buff->wdsterm = 0;
+ memcpy(&buff[1], buf, buflen);
Enqueue(&buff->qelem, &sock->sendq);
- macnet_start(sock);
+ /* Kick off the transmit if the queue was empty */
+ if (sock->sendq.qHead == &buff->qelem)
+ macnet_startsend(sock);
+}
+
+/*
+ * This is called once every time round the event loop to check for
+ * network events and handle them.
+ */
+void macnet_eventcheck() {
+ NetEvent *ne;
+
+ if (!mtcp_initted)
+ return;
+ ne = (NetEvent *)macnet_eventq.qHead;
+ if (ne == NULL)
+ return;
+ Dequeue(&ne->qelem, &macnet_eventq);
+ switch (ne->type) {
+ case NE_SENT:
+ macnet_sent(ne->sock);
+ break;
+ default:
+ (ne->sock->s->back->msg)(ne->sock->s, ne->sock, ne->type);
+ break;
+ }
+ Enqueue(&ne->qelem, &macnet_freeq);
+}
+
+/*
+ * The block at the head of the send queue has finished sending, so we
+ * can free it. Kick off the next transmission if there is one.
+ */
+static void macnet_sent(Socket *sock) {
+ Send_Buffer *buff;
+
+ assert(sock->sendq.qHead != NULL);
+ buff = (Send_Buffer *)sock->sendq.qHead;
+ Dequeue(&buff->qelem, &sock->sendq);
+ sfree(buff);
+ if (sock->sendq.qHead != NULL)
+ macnet_startsend(sock);
+}
+
+/*
+ * There's a block on the head of the send queue which needs to be
+ * sent.
+ */
+
+static void macnet_startsend(Socket *sock) {
+ Send_Buffer *buff;
+ OSErr err;
+
+ buff = (Send_Buffer *)sock->sendq.qHead;
+ sock->iopb.csCode = TCPSend;
+ sock->iopb.csParam.send.validityFlags = 0;
+ sock->iopb.csParam.send.pushFlag = buff->flags & SEND_PUSH ? true : false;
+ sock->iopb.csParam.send.urgentFlag = buff->flags & SEND_URG ? true : false;
+ sock->iopb.csParam.send.wdsPtr = (Ptr)&buff->wds;
+ sock->iopb.csParam.send.userDataPtr = (char *)sock;
+ err = PBControlAsync((ParmBlkPtr)&sock->iopb);
}
int net_recv(Socket *sock, void *buf, int buflen, int flags) {
int avail, want, got;
memcpy(&iopb, &sock->iopb, sizeof(TCPiopb));
- /* Work out if there's anything to recieve (we don't want to block) */
+ /* Work out if there's anything to recieve (we don't want to block)
+ */
iopb.csCode = TCPStatus;
err = PBControlSync((ParmBlkPtr)&iopb);
if (err != noErr)
return 0;
want = avail < buflen ? avail : buflen;
iopb.csCode = TCPRcv;
- iopb.csParam.receive.buffPtr = buf;
- iopb.csParam.receive.buffLen = want;
+ iopb.csParam.receive.rcvBuff = buf;
+ iopb.csParam.receive.rcvBuffLen = want;
err = PBControlSync((ParmBlkPtr)&iopb);
if (err != noErr)
return 0;
- return iopb.csParam.receive.buffLen;
+ return iopb.csParam.receive.rcvBuffLen;
}
* free it, which we can't do at interrupt time).
*/
memcpy(&sock->spareiopb, &sock->iopb, sizeof(TCPiopb));
- sock->spareiopb.ioCompletion = macnet_closed_upp;
+ sock->spareiopb.ioCompletion = macnet_completed_close_upp;
sock->spareiopb.csCode = TCPClose;
sock->spareiopb.csParam.close.validityFlags = 0;
sock->spareiopb.csParam.close.userDataPtr = (char *)sock;
}
}
-static void macnet_closed(TCPiopb* iopb) {
+static void macnet_completed_close(TCPiopb* iopb) {
Socket *sock = (Socket *)iopb->csParam.close.userDataPtr;
- UInt32 olda5;
+#if !TARGET_RT_CFM
+ long olda5;
olda5 = SetA5(sock->a5);
+#endif
switch (iopb->ioResult) {
case noErr:
macnet_sendevent(sock, NE_CLOSED);
macnet_sendevent(sock, NE_DIED);
break;
}
+#if !TARGET_RT_CFM
SetA5(olda5);
+#endif
}
/*
-/* $Id: macterm.c,v 1.1.2.33 1999/03/30 19:44:51 ben Exp $ */
+/* $Id: macterm.c,v 1.1.2.34 1999/04/04 18:23:34 ben Exp $ */
/*
* Copyright (c) 1999 Simon Tatham
* Copyright (c) 1999 Ben Harris
s = smalloc(sizeof(*s));
memset(s, 0, sizeof(*s));
mac_loadconfig(&s->cfg);
- s->back = &hexdump_backend;
+ s->back = &telnet_backend;
/* XXX: Own storage management? */
if (mac_gestalts.qdvers == gestaltOriginalQD)
SetPalette(s->window, s->palette, TRUE);
ActivatePalette(s->window);
ShowWindow(s->window);
- starttime = TickCount();
- display_resource(s, 'pTST', 128);
- sprintf(msg, "Elapsed ticks: %d\015\012", TickCount() - starttime);
- inbuf_putstr(s, msg);
- term_out(s);
+ s->back->init(s);
+/* starttime = TickCount(); */
+/* display_resource(s, 'pTST', 128); */
+/* sprintf(msg, "Elapsed ticks: %d\015\012", TickCount() - starttime); */
+/* inbuf_putstr(s, msg); */
+/* term_out(s); */
}
static void mac_initfont(Session *s) {
DisposeRgn(update);
}
+void lognegot(/*Session *s,*/ const char *str) {
+
+ /* XXX Do something */
+}
+
/*
* Emacs magic:
* Local Variables:
NE_NOOPEN, /* Connection failed to open for some other reason */
NE_DATA, /* Incoming normal data */
NE_URGENT, /* Incoming urgent data */
+ NE_SENT, /* Used internally by Mac network stack */
NE_CLOSING, /* Connection closed by remote host */
NE_CLOSED, /* Connection close completed */
NE_TIMEOUT, /* Remote host vanished */
NE_DIED, /* Connection has failed for some other reason */
} Net_Event_Type;
+#ifdef macintosh
+typedef Socket *SOCKET;
+#define INVALID_SOCKET NULL
+#endif
typedef struct {
- char *(*init) (Session *, char *host, int port);
- int (*msg)(Session *, Socket *, Net_Event_Type);
+ char *(*init) (Session *);
+ int (*msg)(Session *, SOCKET, Net_Event_Type);
void (*send) (Session *, char *buf, int len);
void (*size) (Session *);
void (*special) (Session *, Telnet_Special code);
extern void post_paint(Session *);
extern void palette_set(Session *, int, int, int, int);
extern void palette_reset(Session *);
-void write_clip (void *, int);
-void get_clip (void **, int *);
+extern void write_clip (void *, int);
+extern void get_clip (void **, int *);
extern void do_scroll(Session *, int, int, int);
-void fatalbox (const char *, ...);
+extern void fatalbox(const char *, ...);
#ifdef macintosh
#pragma noreturn (fatalbox)
#endif
-extern void beep (Session *s);
+extern void beep(Session *s);
+extern void lognegot(const char *);
/*
* Exports from the network system
extern char *net_realname(Socket *);
extern int net_recv(Socket *, void *, int, int);
extern int net_send(Socket *, void *, int, int);
+#define SEND_PUSH 0x01
+#define SEND_URG 0x02
extern void net_close(Socket *); /* ask the remote end to close */
extern void net_destroy(Socket *); /* Tidy up */
#ifdef macintosh
-#include <mac.h>
#else /* not macintosh */
#include <windows.h>
#include <winsock.h>
#endif /* not macintosh */
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "putty.h"
static SOCKET s = INVALID_SOCKET;
+/* kludge till we decide where to put telnet state */
+static Session *sess;
#define IAC 255 /* interpret as command: */
#define DONT 254 /* you are not to use option */
return "<unknown>";
}
-static void telnet_size(void);
+static void telnet_size(Session *ignored);
struct Opt {
int send; /* what we initially send */
#endif
static int sb_opt, sb_len;
-static char *sb_buf = NULL;
+static unsigned char *sb_buf = NULL;
static int sb_size = 0;
#define SB_DELTA 1024
static void try_write (void) {
- while (outbuf_head != outbuf_reap) {
- int end = (outbuf_reap < outbuf_head ? outbuf_head : OUTBUF_SIZE);
- int len = end - outbuf_reap;
+ while (sess->outbuf_head != sess->outbuf_reap) {
+ int end = (sess->outbuf_reap < sess->outbuf_head ? sess->outbuf_head : OUTBUF_SIZE);
+ int len = end - sess->outbuf_reap;
int ret;
- ret = send (s, outbuf+outbuf_reap, len, 0);
+ ret = net_send (s, sess->outbuf+sess->outbuf_reap, len, 0);
if (ret > 0)
- outbuf_reap = (outbuf_reap + ret) & OUTBUF_MASK;
+ sess->outbuf_reap = (sess->outbuf_reap + ret) & OUTBUF_MASK;
if (ret < len)
return;
}
static void s_write (void *buf, int len) {
unsigned char *p = buf;
while (len--) {
- int new_head = (outbuf_head + 1) & OUTBUF_MASK;
- if (new_head != outbuf_reap) {
- outbuf[outbuf_head] = *p++;
- outbuf_head = new_head;
+ int new_head = (sess->outbuf_head + 1) & OUTBUF_MASK;
+ if (new_head != sess->outbuf_reap) {
+ sess->outbuf[sess->outbuf_head] = *p++;
+ sess->outbuf_head = new_head;
}
}
try_write();
static void c_write (char *buf, int len) {
while (len--) {
- int new_head = (inbuf_head + 1) & INBUF_MASK;
+ int new_head = (sess->inbuf_head + 1) & INBUF_MASK;
int c = (unsigned char) *buf;
- if (new_head != inbuf_reap) {
- inbuf[inbuf_head] = *buf++;
- inbuf_head = new_head;
+ if (new_head != sess->inbuf_reap) {
+ sess->inbuf[sess->inbuf_head] = *buf++;
+ sess->inbuf_head = new_head;
}
}
}
static void activate_option (struct Opt *o) {
if (o->send == WILL && o->option == TELOPT_NAWS)
- telnet_size();
+ telnet_size(sess);
if (o->send == WILL &&
(o->option == TELOPT_NEW_ENVIRON ||
o->option == TELOPT_OLD_ENVIRON)) {
switch (sb_opt) {
case TELOPT_TSPEED:
if (sb_len == 1 && sb_buf[0] == TELQUAL_SEND) {
- char logbuf[sizeof(cfg.termspeed)+80];
+ char logbuf[sizeof(sess->cfg.termspeed)+80];
b[0] = IAC; b[1] = SB; b[2] = TELOPT_TSPEED;
b[3] = TELQUAL_IS;
- strcpy(b+4, cfg.termspeed);
- n = 4 + strlen(cfg.termspeed);
+ strcpy((char *)b+4, sess->cfg.termspeed);
+ n = 4 + strlen(sess->cfg.termspeed);
b[n] = IAC; b[n+1] = SE;
s_write (b, n+2);
lognegot("server:\tSB TSPEED SEND");
- sprintf(logbuf, "client:\tSB TSPEED IS %s", cfg.termspeed);
+ sprintf(logbuf, "client:\tSB TSPEED IS %s", sess->cfg.termspeed);
lognegot (logbuf);
} else
lognegot ("server:\tSB TSPEED <something weird>");
break;
case TELOPT_TTYPE:
if (sb_len == 1 && sb_buf[0] == TELQUAL_SEND) {
- char logbuf[sizeof(cfg.termtype)+80];
+ char logbuf[sizeof(sess->cfg.termtype)+80];
b[0] = IAC; b[1] = SB; b[2] = TELOPT_TTYPE;
b[3] = TELQUAL_IS;
- for (n = 0; cfg.termtype[n]; n++)
- b[n+4] = (cfg.termtype[n] >= 'a' && cfg.termtype[n] <= 'z' ?
- cfg.termtype[n] + 'A'-'a' : cfg.termtype[n]);
+ for (n = 0; sess->cfg.termtype[n]; n++)
+ b[n+4] = (sess->cfg.termtype[n] >= 'a' && sess->cfg.termtype[n] <= 'z' ?
+ sess->cfg.termtype[n] + 'A'-'a' : sess->cfg.termtype[n]);
b[n+4] = IAC; b[n+5] = SE;
s_write (b, n+6);
b[n+4] = 0;
sprintf (logbuf, "server:\tSB %s SEND", telopt(sb_opt));
lognegot (logbuf);
if (sb_opt == TELOPT_OLD_ENVIRON) {
- if (cfg.rfc_environ) {
+ if (sess->cfg.rfc_environ) {
value = RFC_VALUE;
var = RFC_VAR;
} else {
b[0] = IAC; b[1] = SB; b[2] = sb_opt;
b[3] = TELQUAL_IS;
n = 4;
- e = cfg.environmt;
+ e = sess->cfg.environmt;
while (*e) {
b[n++] = var;
while (*e && *e != '\t') b[n++] = *e++;
while (*e) b[n++] = *e++;
e++;
}
- if (*cfg.username) {
+ if (*sess->cfg.username) {
b[n++] = var; b[n++] = 'U'; b[n++] = 'S';
b[n++] = 'E'; b[n++] = 'R'; b[n++] = value;
- e = cfg.username;
+ e = sess->cfg.username;
while (*e) b[n++] = *e++;
}
b[n++] = IAC; b[n++] = SE;
}
static enum {
- TOPLEVEL, SEENIAC, SEENWILL, SEENWONT, SEENDO, SEENDONT,
+ TELNET_TOPLEVEL, SEENIAC, SEENWILL, SEENWONT, SEENDO, SEENDONT,
SEENSB, SUBNEGOT, SUBNEG_IAC, SEENCR
-} telnet_state = TOPLEVEL;
+} telnet_state = TELNET_TOPLEVEL;
static void do_telnet_read (char *buf, int len) {
unsigned char b[10];
int c = (unsigned char) *buf++;
switch (telnet_state) {
- case TOPLEVEL:
+ case TELNET_TOPLEVEL:
case SEENCR:
if (c == NUL && telnet_state == SEENCR)
- telnet_state = TOPLEVEL;
+ telnet_state = TELNET_TOPLEVEL;
else if (c == IAC)
telnet_state = SEENIAC;
else {
#if 0
if (!in_synch)
#endif
- c_write (b, 1);
+ c_write ((char *)b, 1);
if (c == CR)
telnet_state = SEENCR;
else
- telnet_state = TOPLEVEL;
+ telnet_state = TELNET_TOPLEVEL;
}
break;
case SEENIAC:
else if (c == WILL) telnet_state = SEENWILL;
else if (c == WONT) telnet_state = SEENWONT;
else if (c == SB) telnet_state = SEENSB;
- else telnet_state = TOPLEVEL;/* ignore _everything_ else! */
+ else telnet_state = TELNET_TOPLEVEL;/* ignore _everything_ else! */
break;
case SEENWILL:
proc_rec_opt (WILL, c);
- telnet_state = TOPLEVEL;
+ telnet_state = TELNET_TOPLEVEL;
break;
case SEENWONT:
proc_rec_opt (WONT, c);
- telnet_state = TOPLEVEL;
+ telnet_state = TELNET_TOPLEVEL;
break;
case SEENDO:
proc_rec_opt (DO, c);
- telnet_state = TOPLEVEL;
+ telnet_state = TELNET_TOPLEVEL;
break;
case SEENDONT:
proc_rec_opt (DONT, c);
- telnet_state = TOPLEVEL;
+ telnet_state = TELNET_TOPLEVEL;
break;
case SEENSB:
sb_opt = c;
else {
subneg_addchar:
if (sb_len >= sb_size) {
- char *newbuf;
+ unsigned char *newbuf;
sb_size += SB_DELTA;
newbuf = (sb_buf ?
realloc(sb_buf, sb_size) :
goto subneg_addchar; /* yes, it's a hack, I know, but... */
else {
process_subneg();
- telnet_state = TOPLEVEL;
+ telnet_state = TELNET_TOPLEVEL;
}
break;
}
*
* Returns an error message, or NULL on success.
*
- * Also places the canonical host name into `realhost'.
*/
-static char *telnet_init (HWND hwnd, char *host, int port, char **realhost) {
- SOCKADDR_IN addr;
- struct hostent *h;
- unsigned long a;
+static char *telnet_init (Session *this_sess) {
- /*
- * Try to find host.
- */
- if ( (a = inet_addr(host)) == (unsigned long) INADDR_NONE) {
- if ( (h = gethostbyname(host)) == NULL)
- switch (WSAGetLastError()) {
- case WSAENETDOWN: return "Network is down";
- case WSAHOST_NOT_FOUND: case WSANO_DATA:
- return "Host does not exist";
- case WSATRY_AGAIN: return "Host not found";
- default: return "gethostbyname: unknown error";
- }
- memcpy (&a, h->h_addr, sizeof(a));
- *realhost = h->h_name;
- } else
- *realhost = host;
- a = ntohl(a);
-
- if (port < 0)
- port = 23; /* default telnet port */
-
- /*
- * Open socket.
- */
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s == INVALID_SOCKET)
- switch (WSAGetLastError()) {
- case WSAENETDOWN: return "Network is down";
- case WSAEAFNOSUPPORT: return "TCP/IP support not present";
- default: return "socket(): unknown error";
- }
-
-#if 0
- {
- BOOL b = TRUE;
- setsockopt (s, SOL_SOCKET, SO_OOBINLINE, (void *)&b, sizeof(b));
- }
-#endif
-
- /*
- * Bind to local address.
- */
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
- addr.sin_port = htons(0);
- if (bind (s, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR)
- switch (WSAGetLastError()) {
- case WSAENETDOWN: return "Network is down";
- default: return "bind(): unknown error";
- }
-
- /*
- * Connect to remote address.
- */
- addr.sin_addr.s_addr = htonl(a);
- addr.sin_port = htons((short)port);
- if (connect (s, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR)
- switch (WSAGetLastError()) {
- case WSAENETDOWN: return "Network is down";
- case WSAECONNREFUSED: return "Connection refused";
- case WSAENETUNREACH: return "Network is unreachable";
- case WSAEHOSTUNREACH: return "No route to host";
- default: return "connect(): unknown error";
- }
-
- if (WSAAsyncSelect (s, hwnd, WM_NETEVENT, FD_READ |
- FD_WRITE | FD_OOB | FD_CLOSE) == SOCKET_ERROR)
- switch (WSAGetLastError()) {
- case WSAENETDOWN: return "Network is down";
- default: return "WSAAsyncSelect(): unknown error";
- }
+ sess = this_sess;
+ s = net_open(sess, sess->cfg.host, sess->cfg.port);
/*
* Initialise option states.
* Process a WM_NETEVENT message. Will return 0 if the connection
* has closed, or <0 for a socket error.
*/
-static int telnet_msg (WPARAM wParam, LPARAM lParam) {
+static int telnet_msg (Session *sess, SOCKET sock, Net_Event_Type ne) {
int ret;
char buf[256];
if (s == INVALID_SOCKET) /* how the hell did we get here?! */
return -5000;
- if (WSAGETSELECTERROR(lParam) != 0)
- return -WSAGETSELECTERROR(lParam);
-
- switch (WSAGETSELECTEVENT(lParam)) {
- case FD_READ:
- ret = recv(s, buf, sizeof(buf), 0);
- if (ret < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
- return 1;
+ switch (ne) {
+ case NE_DATA:
+ ret = net_recv(s, buf, sizeof(buf), 0);
if (ret < 0) /* any _other_ error */
- return -10000-WSAGetLastError();
+ return -1;
if (ret == 0) {
s = INVALID_SOCKET;
return 0; /* can't happen, in theory */
#endif
do_telnet_read (buf, ret);
return 1;
- case FD_OOB:
+ case NE_URGENT:
do {
- ret = recv(s, buf, sizeof(buf), 0);
+ ret = net_recv(s, buf, sizeof(buf), 0);
} while (ret > 0);
- telnet_state = TOPLEVEL;
+ telnet_state = TELNET_TOPLEVEL;
do {
- ret = recv(s, buf, 1, MSG_OOB);
+ ret = net_recv(s, buf, 1, /*MSG_OOB*/ 0);
if (ret > 0)
do_telnet_read (buf, ret);
} while (ret > 0);
- if (ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
- return -30000-WSAGetLastError();
- return 1;
- case FD_WRITE:
- if (outbuf_head != outbuf_reap)
- try_write();
+ if (ret < 0)
+ return -3;
return 1;
- case FD_CLOSE:
+ case NE_CLOSING:
s = INVALID_SOCKET;
return 0;
}
/*
* Called to send data down the Telnet connection.
*/
-static void telnet_send (char *buf, int len) {
+static void telnet_send (Session *this_sess, char *buf, int len) {
char *p;
static unsigned char iac[2] = { IAC, IAC };
static unsigned char cr[2] = { CR, NUL };
/*
* Called to set the size of the window from Telnet's POV.
*/
-static void telnet_size(void) {
+static void telnet_size(Session *sess) {
unsigned char b[16];
char logbuf[50];
if (s == INVALID_SOCKET || o_naws.state != ACTIVE)
return;
b[0] = IAC; b[1] = SB; b[2] = TELOPT_NAWS;
- b[3] = cols >> 8; b[4] = cols & 0xFF;
- b[5] = rows >> 8; b[6] = rows & 0xFF;
+ b[3] = sess->cols >> 8; b[4] = sess->cols & 0xFF;
+ b[5] = sess->rows >> 8; b[6] = sess->rows & 0xFF;
b[7] = IAC; b[8] = SE;
s_write (b, 9);
sprintf(logbuf, "client:\tSB NAWS %d,%d",
/*
* Send Telnet special codes.
*/
-static void telnet_special (Telnet_Special code) {
+static void telnet_special (Session *sess, Telnet_Special code) {
unsigned char b[2];
if (s == INVALID_SOCKET)
case TS_EOR: b[1] = EOR; s_write (b, 2); break;
case TS_EOF: b[1] = xEOF; s_write (b, 2); break;
case TS_SYNCH:
- outbuf_head = outbuf_reap = 0;
+ sess->outbuf_head = sess->outbuf_reap = 0;
b[0] = DM;
- send (s, b, 1, MSG_OOB);
+ net_send (s, b, 1, SEND_URG);
break;
}
}
-/* $Id: testback.c,v 1.1.2.5 1999/03/29 19:50:24 ben Exp $ */
+/* $Id: testback.c,v 1.1.2.6 1999/04/04 18:23:35 ben Exp $ */
/*
* Copyright (c) 1999 Simon Tatham
* Copyright (c) 1999 Ben Harris
#include "putty.h"
-static char *null_init(Session *, char *, int, char **);
-static int null_msg(Session *);
+static char *null_init(Session *);
+static int null_msg(Session *, Socket *, Net_Event_Type);
static void null_send(Session *, char *, int);
static void loop_send(Session *, char *, int);
static void hexdump_send(Session *, char *, int);
null_init, null_msg, hexdump_send, null_size, null_special
};
-static char *null_init(Session *s, char *host, int port, char **realhost) {
+static char *null_init(Session *s) {
return NULL;
}
-static int null_msg(Session *s) {
+static int null_msg(Session *s, Socket *sock, Net_Event_Type ne) {
return 1;
}