diff options
author | Richard Basch <probe@mit.edu> | 1997-02-06 02:31:41 +0000 |
---|---|---|
committer | Richard Basch <probe@mit.edu> | 1997-02-06 02:31:41 +0000 |
commit | a0b9ce4bee60136363cfff7a93c4e42eab972c02 (patch) | |
tree | 400984337fe3766653ff4cc2cb6b7d3d7f87f3f4 /src/windows/wintel | |
parent | a9266b1dec31de9f33b0d032b885edd377a23ee5 (diff) | |
download | krb5-a0b9ce4bee60136363cfff7a93c4e42eab972c02.tar.gz krb5-a0b9ce4bee60136363cfff7a93c4e42eab972c02.tar.xz krb5-a0b9ce4bee60136363cfff7a93c4e42eab972c02.zip |
Windows/NT integration (V1_0_WIN32_BRANCH merge)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@9788 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/windows/wintel')
31 files changed, 8201 insertions, 5235 deletions
diff --git a/src/windows/wintel/ChangeLog b/src/windows/wintel/ChangeLog index 9e2a9a5328..521c68f580 100644 --- a/src/windows/wintel/ChangeLog +++ b/src/windows/wintel/ChangeLog @@ -1,16 +1,3 @@ -Sat Dec 21 03:34:35 1996 Theodore Y. Ts'o <tytso@mit.edu> - - * screen.c (ScreenWndProc): Remove (under #ifdef) mention of - calling Cygnus Support for support. - -Sat Nov 23 00:27:45 1996 Theodore Ts'o <tytso@rsts-11.mit.edu> - - * Makefile.in (KLIB): Change krb516.dll to krb5_16.dll. [PR#204] - -Wed Nov 20 18:32:26 1996 Theodore Y. Ts'o <tytso@mit.edu> - - * Makefile.in (KLIB): Change libkrb5.dll to be krb516.dll - Wed Jun 12 00:22:02 1996 Theodore Ts'o <tytso@rsts-11.mit.edu> * makefile: Renamed to Makefile.in, so that we can do WIN16/WIN32 diff --git a/src/windows/wintel/Makefile.in b/src/windows/wintel/Makefile.in index 5f49bcf6ea..2912ab1727 100644 --- a/src/windows/wintel/Makefile.in +++ b/src/windows/wintel/Makefile.in @@ -1,106 +1,65 @@ -# makefile: Constructs the kerborized telnet client +# Makefile for the Kerberos for Windows telnet client # Works for both k4 and k5 releases. # -NAME = telnet -OBJS = $(NAME).obj negotiat.obj auth.obj edit.obj emul.obj \ - font.obj intern.obj screen.obj +OBJS = telnet.obj negotiat.obj auth.obj edit.obj emul.obj \ + font.obj intern.obj screen.obj encrypt.obj genget.obj ##### Options DEBUG = 1 !IF ! defined(KVERSION) +KRBOPT=-DFORWARD -DAUTHENTICATION -DENCRYPTION -DDES_ENCRYPTION KVERSION = 5 !endif KRB = KRB$(KVERSION) -!if $(KVERSION) == 4 -BUILDTOP = .. -LIBDIR = $(BUILDTOP)\lib\krb -KLIB = $(LIBDIR)\kerberos.lib -WLIB = $(LIBDIR)\winsock.lib -INCLUDES = /I$(BUILDTOP)\include -XOBJS = -!endif +###WIN16##WLIB = $(BUILDTOP)\lib\winsock.lib -!if $(KVERSION) == 5 BUILDTOP =..\.. -LIBDIR = $(BUILDTOP)\lib -KLIB = $(LIBDIR)\krb5_16.lib -WLIB = $(LIBDIR)\winsock.lib INCLUDES = /I$(BUILDTOP)\include /I$(BUILDTOP)\include\krb5 \ - /I$(BUILDTOP)\lib\crypto\des -XOBJS = k5stream.obj -!endif + /I$(BUILDTOP)\lib\crypto\des +##WIN16##XOBJS = k5stream.obj +##WIN32##XOBJS = resource.obj k5stream.obj enc_des.obj -##### C Compiler -CC = cl -CFLAGS_RELEASE = /nologo /W3 /AL /GAs /G2 /Zp /O2 /DNDEBUG=1 -CFLAGS_DEBUG = /nologo /W3 /AL /GAs /G2 /Zp /O2 /Od /Zi -!if $(DEBUG) -CFLAGS = $(CFLAGS_DEBUG) $(INCLUDES) /D$(KRB)=1 +!if defined(DEBUG) +CFLAGS = $(CCOPTS2) $(INCLUDES) /D$(KRB)=1 $(KRBOPT) /Zi !else -CFLAGS = $(CFLAGS_RELEASE) $(INCLUDES) /D$(KRB)=1 +CFLAGS = $(CCOPTS2) $(INCLUDES) /D$(KRB)=1 $(KRBOPT) !endif -##### RC Compiler -RC = rc -##WIN16##RFLAGS_RELEASE = /nologo /DNDEBUG -##WIN16##RFLAGS_DEBUG = /nologo -##WIN32##RFLAGS_RELEASE = /DNDEBUG -##WIN32##RFLAGS_DEBUG = -!if $(DEBUG) -RFLAGS = $(RFLAGS_DEBUG) $(INCLUDES) -!else -RFLAGS = $(RFLAGS_RELEASE) $(INCLUDES) -!endif +#RFLAGS = /D$(KRB)=1 $(INCLUDES) $(KRBOPT) +RFLAGS = -D$(KRB)=1 $(KRBOPT) + ##### Linker -LINK = link +LINK = link LIBS = $(KLIB) $(WLIB) -SYSLIBS = libw llibcew commdlg -!if $(DEBUG) -LFLAGS = /co /nologo /nod /packc:61440 /stack:32768 /align:16 /onerror:noexe +##WIN16##SYSLIBS = libw llibcew +##WIN32##SYSLIBS = libc.lib kernel32.lib wsock32.lib user32.lib gdi32.lib \ +##WIN32## comdlg32.lib +!if defined(DEBUG) +##WIN16##LFLAGS = /co /nologo /nod /nopackcode /map:full +##WIN32##LFLAGS = /nologo /nod /debug !else -LFLAGS = /nologo /nod /packc:61440 /stack:32768 /align:16 /onerror:noexe +##WIN16##LFLAGS = /nologo /nod /nopackcode +##WIN32##LFLAGS = /nologo /nod !endif -all:: makefile $(NAME).exe - -$(NAME).exe: $*.def $*.res $(OBJS) $(XOBJS) $(LIBS) - $(LINK) $(LFLAGS) $(OBJS) $(XOBJS), $@, $*.map, \ - $(LIBS) $(SYSLIBS), $*.def - $(RC) $(RFLAGS) /k $*.res $@ - -install: - copy $(NAME).exe ..\floppy - -clean:: - if exist *.obj del *.obj - if exist *.exe del *.exe - if exist *.res del *.res - if exist *.map del *.map - if exist *.pdb del *.pdb - if exist *.err del *.err - if exist ..\floppy\$(NAME).exe del ..\floppy\$(NAME).exe +all:: makefile telnet.exe -telnet.obj: telnet.h dialog.h screen.h struct.h wt-proto.h ini.h +telnet.exe: $*.def $*.res $(OBJS) $(XOBJS) $(LIBS) +##WIN16## $(LINK) $(LFLAGS) $(OBJS) $(XOBJS), $@, $*.map, \ +##WIN16## $(LIBS) $(SYSLIBS), $*.def +##WIN16## $(RC) $(RFLAGS) /k telnet.rc $@ +##WIN32## $(LINK) $(LFLAGS) /map:$*.map /out:$@ $(OBJS) $(XOBJS) \ +##WIN32## $(LIBS) $(SYSLIBS) -negotiat.obj: telnet.h dialog.h screen.h struct.h wt-proto.h ini.h +##WIN32##telnet.res: telnet.rc +##WIN32## $(RC) $(RFLAGS) /r $*.rc +##WIN32##resource.obj: telnet.res +##WIN32## $(CVTRES) /nologo /out:resource.obj telnet.res -auth.obj: telopts.h telnet.h dialog.h screen.h struct.h wt-proto.h ini.h - -edit.obj: screen.h - -emul.obj: screen.h - -font.obj: screen.h ini.h - -intern.obj: screen.h - -screen.obj: screen.h ini.h - -telnet.res: screen.h dialog.h telnet.dlg ncsa.ico terminal.ico - -!if $(KVERSION) == 5 -k5stream.c: k5stream.h auth.h -!endif +install:: + copy telnet.exe $(DESTDIR) +clean:: + $(RM) *.exe *.res *.map diff --git a/src/windows/wintel/auth.c b/src/windows/wintel/auth.c index 4d3d380e50..bba43865fb 100644 --- a/src/windows/wintel/auth.c +++ b/src/windows/wintel/auth.c @@ -3,169 +3,197 @@ */ #ifdef KRB4 - #include <windows.h> - #include <time.h> - #include <string.h> - #include "winsock.h" - #include "kerberos.h" +#include <windows.h> +#include <time.h> +#include <string.h> +#include "winsock.h" +#include "kerberos.h" #endif #ifdef KRB5 - #include <time.h> - #include <string.h> - #include "krb5.h" - #include "com_err.h" +#include <time.h> +#include <string.h> +#include "krb5.h" +#include "com_err.h" #endif #include "telnet.h" -#include "telopts.h" +#include "telnet_arpa.h" + +#ifdef ENCRYPTION +#include "encrypt.h" +#endif /* * Constants */ - #define IS 0 - #define SEND 1 - #define REPLY 2 - #define NAME 3 - - #define AUTH_NULL 0 - #define KERBEROS_V4 1 - #define KERBEROS_V5 2 - #define SPX 3 - #define RSA 6 - #define LOKI 10 - - #define AUTH 0 - #define K4_REJECT 1 - #define K4_ACCEPT 2 - #define K4_CHALLENGE 3 - #define K4_RESPONSE 4 - - #define K5_REJECT 1 - #define K5_ACCEPT 2 - #define K5_RESPONSE 3 // They had to make it different - - #define AUTH_WHO_MASK 1 - #define AUTH_CLIENT_TO_SERVER 0 - #define AUTH_SERVER_TO_CLIENT 1 - - #define AUTH_HOW_MASK 2 - #define AUTH_HOW_ONE_WAY 0 - #define AUTH_HOW_MUTUAL 2 - - #ifndef KSUCCESS // Let K5 use K4 constants - #define KSUCCESS 0 - #define KFAILURE 255 - #endif +#ifdef KRB4 +#define KRB_AUTH 0 +#define KRB_REJECT 1 +#define KRB_ACCEPT 2 +#define KRB_CHALLENGE 3 +#define KRB_RESPONSE 4 +#endif +#ifdef KRB5 +#define KRB_AUTH 0 /* Authentication data follows */ +#define KRB_REJECT 1 /* Rejected (reason might follow) */ +#define KRB_ACCEPT 2 /* Accepted */ +#define KRB_RESPONSE 3 /* Response for mutual auth. */ + +#define KRB_FORWARD 4 /* Forwarded credentials follow */ +#define KRB_FORWARD_ACCEPT 5 /* Forwarded credentials accepted */ +#define KRB_FORWARD_REJECT 6 /* Forwarded credentials rejected */ +#endif + +#ifndef KSUCCESS /* Let K5 use K4 constants */ +#define KSUCCESS 0 +#define KFAILURE 255 +#endif + /* * Globals */ - #ifdef KRB4 - static CREDENTIALS cred; - static KTEXT_ST auth; +#ifdef KRB4 +static CREDENTIALS cred; +static KTEXT_ST auth; - #define KRB_SERVICE_NAME "rcmd" - #define KERBEROS_VERSION KERBEROS_V4 +#define KRB_SERVICE_NAME "rcmd" +#define KERBEROS_VERSION KERBEROS_V4 - static int auth_how; - static int k4_auth_send (kstream ks); - static int k4_auth_reply (kstream ks, unsigned char *data, int cnt); - #endif - #ifdef KRB5 - static krb5_data auth; - static int auth_how; - static krb5_auth_context auth_context; +static int auth_how; +static int k4_auth_send(kstream); +static int k4_auth_reply(kstream, unsigned char *, int); +#endif - #define KRB_SERVICE_NAME "host" - #define KERBEROS_VERSION KERBEROS_V5 +#ifdef KRB5 +static krb5_data auth; +static int auth_how; +static krb5_auth_context auth_context; +krb5_keyblock *session_key = NULL; +#ifdef FORWARD +void kerberos5_forward(kstream); +#endif - static int k5_auth_send (int how); - static int k5_auth_reply (int how, unsigned char *data, int cnt); - #endif +#define KRB_SERVICE_NAME "host" +#define KERBEROS_VERSION AUTHTYPE_KERBEROS_V5 + +static int k5_auth_send(kstream, int); +static int k5_auth_reply(kstream, int, unsigned char *, int); +#endif + +static int Data(kstream, int, void *, int); + +#ifdef ENCRYPTION +BOOL encrypt_flag = 1; +#endif +#ifdef FORWARD +BOOL forward_flag = 1; /* forward tickets? */ +BOOL forwardable_flag = 1; /* get forwardable tickets to forward? */ +BOOL forwarded_tickets = 0; /* were tickets forwarded? */ +#endif - BOOL encrypt_enable; +static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0, + AUTHTYPE_KERBEROS_V5, }; -/*+ +static int +Data(kstream ks, int type, void *d, int c) +{ + unsigned char *p = str_data + 4; + unsigned char *cd = (unsigned char *)d; + + if (c == -1) + c = strlen((char *)cd); + + *p++ = AUTHTYPE_KERBEROS_V5; + *p = AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL; +#ifdef ENCRYPTION + *p |= AUTH_ENCRYPT_ON; +#endif + p++; + *p++ = type; + while (c-- > 0) { + if ((*p++ = *cd++) == IAC) + *p++ = IAC; + } + *p++ = IAC; + *p++ = SE; + + return(TelnetSend(ks, (LPSTR)str_data, p - str_data, 0)); +} + +#ifdef ENCRYPTION +/* * Function: Enable or disable the encryption process. * * Parameters: * enable - TRUE to enable, FALSE to disable. */ static void -auth_encrypt_enable( - BOOL enable) +auth_encrypt_enable(BOOL enable) { - encrypt_enable = enable; - -} /* auth_encrypt_enable */ - + encrypt_flag = enable; +} +#endif -/*+ +/* * Function: Abort the authentication process * * Parameters: * ks - kstream to send abort message to. */ static void -auth_abort( - kstream ks, - char *errmsg, - long r) +auth_abort(kstream ks, char *errmsg, long r) { - char buf[9]; - - wsprintf(buf, "%c%c%c%c%c%c%c%c", IAC, SB, AUTHENTICATION, IS, AUTH_NULL, - AUTH_NULL, IAC, SE); - TelnetSend(ks, (LPSTR)buf, 8, 0); - - if (errmsg != NULL) { - strcpy(strTmp, errmsg); - - if (r != KSUCCESS) { - strcat(strTmp, "\n"); - #ifdef KRB4 - lstrcat(strTmp, krb_get_err_text((int) r)); - #endif - #ifdef KRB5 - lstrcat (strTmp, error_message(r)); - #endif - } - - MessageBox(HWND_DESKTOP, strTmp, "Kerberos authentication failed!", - MB_OK | MB_ICONEXCLAMATION); - } - -} /* auth_abort */ + char buf[9]; + + wsprintf(buf, "%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION, + TELQUAL_IS, AUTHTYPE_NULL, + AUTHTYPE_NULL, IAC, SE); + TelnetSend(ks, (LPSTR)buf, 8, 0); + + if (errmsg != NULL) { + strcpy(strTmp, errmsg); + + if (r != KSUCCESS) { + strcat(strTmp, "\n"); +#ifdef KRB4 + lstrcat(strTmp, krb_get_err_text((int)r)); +#endif +#ifdef KRB5 + lstrcat(strTmp, error_message(r)); +#endif + } + + MessageBox(HWND_DESKTOP, strTmp, "Kerberos authentication failed!", + MB_OK | MB_ICONEXCLAMATION); + } +} -/*+ +/* * Function: Copy data to buffer, doubling IAC character if present. * * Parameters: * kstream - kstream to send abort message to. */ static int -copy_for_net( - unsigned char *to, - unsigned char *from, - int c) +copy_for_net(unsigned char *to, unsigned char *from, int c) { - int n; - - n = c; + int n; - while (c-- > 0) { - if ((*to++ = *from++) == IAC) { - n++; - *to++ = IAC; - } - } + n = c; - return n; + while (c-- > 0) { + if ((*to++ = *from++) == IAC) { + n++; + *to++ = IAC; + } + } -} /* copy_for_net */ + return n; +} -/*++ +/* * Function: Parse authentication send command * * Parameters: @@ -179,70 +207,66 @@ copy_for_net( * Returns: Kerberos error code. */ static int -auth_send( - kstream ks, - unsigned char *parsedat, - int end_sub) +auth_send(kstream ks, unsigned char *parsedat, int end_sub) { - char buf[512]; - char *pname; - int plen; - int r; - int i; - - auth_how = -1; - - for (i = 2; i+1 <= end_sub; i += 2) { - if (parsedat[i] == KERBEROS_VERSION) - if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER) { - auth_how = parsedat[i+1] & AUTH_HOW_MASK; - break; - } - } - - if (auth_how == -1) { - auth_abort(ks, NULL, 0); - return KFAILURE; - } - - #ifdef KRB4 - r = k4_auth_send (ks); - #endif /* KRB4 */ - - #ifdef KRB5 - r = k5_auth_send (auth_how); - #endif /* KRB5 */ + char buf[512]; + char *pname; + int plen; + int r; + int i; + + auth_how = -1; + + for (i = 2; i+1 <= end_sub; i += 2) { + if (parsedat[i] == KERBEROS_VERSION) + if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) { + auth_how = parsedat[i+1] & AUTH_HOW_MASK; + break; + } + } + + if (auth_how == -1) { + auth_abort(ks, NULL, 0); + return KFAILURE; + } - if (! r) - return KFAILURE; +#ifdef KRB4 + r = k4_auth_send(ks); +#endif /* KRB4 */ + +#ifdef KRB5 + r = k5_auth_send(ks, auth_how); +#endif /* KRB5 */ - plen = strlen (szUserName); // Set by k#_send if needed - pname = szUserName; + if (!r) + return KFAILURE; - wsprintf(buf, "%c%c%c%c", IAC, SB, AUTHENTICATION, NAME); - memcpy (&buf[4], pname, plen); - wsprintf(&buf[plen + 4], "%c%c", IAC, SE); - TelnetSend(ks, (LPSTR)buf, lstrlen(pname)+6, 0); + plen = strlen(szUserName); /* Set by k#_send if needed */ + pname = szUserName; - wsprintf(buf, "%c%c%c%c%c%c%c", IAC, SB, AUTHENTICATION, IS, - KERBEROS_VERSION, auth_how | AUTH_CLIENT_TO_SERVER, AUTH); + wsprintf(buf, "%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME); + memcpy(&buf[4], pname, plen); + wsprintf(&buf[plen + 4], "%c%c", IAC, SE); + TelnetSend(ks, (LPSTR)buf, lstrlen(pname)+6, 0); - #if KRB4 - auth.length = copy_for_net(&buf[7], auth.dat, auth.length); - #endif /* KRB4 */ - #if KRB5 - auth.length = copy_for_net(&buf[7], auth.data, auth.length); - #endif /* KRB5 */ + wsprintf(buf, "%c%c%c%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_IS, + KERBEROS_VERSION, auth_how | AUTH_WHO_CLIENT, KRB_AUTH); - wsprintf(&buf[auth.length+7], "%c%c", IAC, SE); +#if KRB4 + auth.length = copy_for_net(&buf[7], auth.dat, auth.length); +#endif /* KRB4 */ +#if KRB5 + auth.length = copy_for_net(&buf[7], auth.data, auth.length); +#endif /* KRB5 */ - TelnetSend(ks, (LPSTR)buf, auth.length+9, 0); + wsprintf(&buf[auth.length+7], "%c%c", IAC, SE); - return KSUCCESS; + TelnetSend(ks, (LPSTR)buf, auth.length+9, 0); -} /* auth_send */ + return KSUCCESS; +} -/*+ +/* * Function: Parse authentication reply command * * Parameters: @@ -256,25 +280,22 @@ auth_send( * Returns: Kerberos error code. */ static int -auth_reply( - kstream ks, - unsigned char *parsedat, - int end_sub) +auth_reply(kstream ks, unsigned char *parsedat, int end_sub) { - int n; + int n; - #ifdef KRB4 - n = k4_auth_reply (ks, parsedat, end_sub); - #endif +#ifdef KRB4 + n = k4_auth_reply(ks, parsedat, end_sub); +#endif - #ifdef KRB5 - n = k5_auth_reply (auth_how, parsedat, end_sub); - #endif +#ifdef KRB5 + n = k5_auth_reply(ks, auth_how, parsedat, end_sub); +#endif - return n; + return n; } -/*+ +/* * Function: Parse the athorization sub-options and reply. * * Parameters: @@ -285,21 +306,17 @@ auth_reply( * end_sub - last charcter position in parsedat. */ void -auth_parse( - kstream ks, - unsigned char *parsedat, - int end_sub) +auth_parse(kstream ks, unsigned char *parsedat, int end_sub) { - if (parsedat[1] == SEND) - auth_send(ks, parsedat, end_sub); + if (parsedat[1] == TELQUAL_SEND) + auth_send(ks, parsedat, end_sub); - if (parsedat[1] == REPLY) - auth_reply(ks, parsedat, end_sub); - -} /* auth_parse */ + if (parsedat[1] == TELQUAL_REPLY) + auth_reply(ks, parsedat, end_sub); +} -/*+ +/* * Function: Initialization routine called kstream encryption system. * * Parameters: @@ -307,17 +324,17 @@ auth_parse( * * data - user data. */ -int INTERFACE -auth_init( - kstream str, - kstream_ptr data) +int +auth_init(kstream str, kstream_ptr data) { - return 0; - -} /* auth_init */ +#ifdef ENCRYPTION + encrypt_init(str, data); +#endif + return 0; +} -/*+ +/* * Function: Destroy routine called kstream encryption system. * * Parameters: @@ -325,14 +342,13 @@ auth_init( * * data - user data. */ -void INTERFACE -auth_destroy( - kstream str) +void +auth_destroy(kstream str) { -} /* auth_destroy */ +} -/*+ +/* * Function: Callback to encrypt a block of characters * * Parameters: @@ -344,22 +360,20 @@ auth_destroy( * * Returns: number of characters converted. */ -int INTERFACE -auth_encrypt( - struct kstream_data_block *out, - struct kstream_data_block *in, - kstream str) +int +auth_encrypt(struct kstream_data_block *out, + struct kstream_data_block *in, + kstream str) { - out->ptr = in->ptr; - - out->length = in->length; + out->ptr = in->ptr; - return(out->length); + out->length = in->length; -} /* auth_encrypt */ + return(out->length); +} -/*+ +/* * Function: Callback to decrypt a block of characters * * Parameters: @@ -371,81 +385,77 @@ auth_encrypt( * * Returns: number of characters converted. */ -int INTERFACE -auth_decrypt( - struct kstream_data_block *out, - struct kstream_data_block *in, - kstream str) +int +auth_decrypt(struct kstream_data_block *out, + struct kstream_data_block *in, + kstream str) { - out->ptr = in->ptr; - - out->length = in->length; + out->ptr = in->ptr; - return(out->length); + out->length = in->length; -} /* auth_decrypt */ + return(out->length); +} -/*++*/ #ifdef KRB4 /* -** -** K4_auth_send - gets authentication bits we need to send to KDC. -** -** Result is left in auth -** -** Returns: 0 on failure, 1 on success -*/ + * + * K4_auth_send - gets authentication bits we need to send to KDC. + * + * Result is left in auth + * + * Returns: 0 on failure, 1 on success + */ static int -k4_auth_send ( - kstream ks) +k4_auth_send(kstream ks) { - int r; // Return value - char instance[INST_SZ]; - char *realm; - char buf[256]; + int r; /* Return value */ + char instance[INST_SZ]; + char *realm; + char buf[256]; - memset(instance, 0, sizeof(instance)); + memset(instance, 0, sizeof(instance)); - if (realm = krb_get_phost(szHostName)) - lstrcpy(instance, realm); + if (realm = krb_get_phost(szHostName)) + lstrcpy(instance, realm); - realm = krb_realmofhost(szHostName); + realm = krb_realmofhost(szHostName); - if (!realm) { - strcpy(buf, "Can't find realm for host \""); - strcat(buf, szHostName); - strcat(buf, "\""); - auth_abort(ks, buf, 0); - return KFAILURE; - } + if (!realm) { + strcpy(buf, "Can't find realm for host \""); + strcat(buf, szHostName); + strcat(buf, "\""); + auth_abort(ks, buf, 0); + return KFAILURE; + } - r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0); + r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0); - if (r == 0) - r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred); + if (r == 0) + r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred); - if (r) { - strcpy(buf, "Can't get \""); - strcat(buf, KRB_SERVICE_NAME); - if (instance[0] != 0) { - strcat(buf, "."); - lstrcat(buf, instance); - } - strcat(buf, "@"); - lstrcat(buf, realm); - strcat(buf, "\" ticket"); - auth_abort(ks, buf, r); - - return r; + if (r) { + strcpy(buf, "Can't get \""); + strcat(buf, KRB_SERVICE_NAME); + if (instance[0] != 0) { + strcat(buf, "."); + lstrcat(buf, instance); } + strcat(buf, "@"); + lstrcat(buf, realm); + strcat(buf, "\" ticket"); + auth_abort(ks, buf, r); + + return r; + } - if (!szUserName[0]) // Copy if not there - strcpy (szUserName, cred.pname); + if (!szUserName[0]) /* Copy if not there */ + strcpy(szUserName, cred.pname); - return(1); + return(1); } -/*+ +/* * Function: K4 parse authentication reply command * * Parameters: @@ -459,232 +469,398 @@ k4_auth_send ( * Returns: Kerberos error code. */ static int -k4_auth_reply( - kstream ks, - unsigned char *parsedat, - int end_sub) +k4_auth_reply(kstream ks, unsigned char *parsedat, int end_sub) { - time_t t; - int x; - char buf[512]; - int i; - des_cblock session_key; - des_key_schedule sched; - static des_cblock challenge; - - if (end_sub < 4) - return KFAILURE; + time_t t; + int x; + char buf[512]; + int i; + des_cblock session_key; + des_key_schedule sched; + static des_cblock challenge; + + if (end_sub < 4) + return KFAILURE; - if (parsedat[2] != KERBEROS_V4) - return KFAILURE; - - if (parsedat[4] == K4_REJECT) { - buf[0] = 0; - - for (i = 5; i <= end_sub; i++) { - if (parsedat[i] == IAC) - break; - buf[i-5] = parsedat[i]; - buf[i-4] = 0; - } - - if (!buf[0]) - strcpy(buf, "Authentication rejected by remote machine!"); - MessageBox(HWND_DESKTOP, buf, NULL, MB_OK | MB_ICONEXCLAMATION); - - return KFAILURE; - } - - if (parsedat[4] == K4_ACCEPT) { - if ((parsedat[3] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY) - return KSUCCESS; - - if ((parsedat[3] & AUTH_HOW_MASK) != AUTH_HOW_MUTUAL) - return KFAILURE; - - des_key_sched(cred.session, sched); - - t = time(NULL); - memcpy(challenge, &t, 4); - memcpy(&challenge[4], &t, 4); - des_ecb_encrypt(&challenge, &session_key, sched, 1); - - /* - * Increment the challenge by 1, and encrypt it for - * later comparison. - */ - for (i = 7; i >= 0; --i) { - x = (unsigned int)challenge[i] + 1; - challenge[i] = x; /* ignore overflow */ - if (x < 256) /* if no overflow, all done */ - break; - } - - des_ecb_encrypt(&challenge, &challenge, sched, 1); - - wsprintf(buf, "%c%c%c%c%c%c%c", IAC, SB, AUTHENTICATION, IS, - KERBEROS_V4, AUTH_CLIENT_TO_SERVER|AUTH_HOW_MUTUAL, K4_CHALLENGE); - memcpy(&buf[7], session_key, 8); - wsprintf(&buf[15], "%c%c", IAC, SE); - TelnetSend(ks, (LPSTR)buf, 17, 0); - - return KSUCCESS; - } - - if (parsedat[4] == K4_RESPONSE) { - if (end_sub < 12) - return KFAILURE; - - if (memcmp(&parsedat[5], challenge, sizeof(challenge)) != 0) { - MessageBox(HWND_DESKTOP, "Remote machine is being impersonated!", - NULL, MB_OK | MB_ICONEXCLAMATION); - - return KFAILURE; - } - - return KSUCCESS; - } + if (parsedat[2] != KERBEROS_V4) + return KFAILURE; + + if (parsedat[4] == KRB_REJECT) { + buf[0] = 0; + + for (i = 5; i <= end_sub; i++) { + if (parsedat[i] == IAC) + break; + buf[i-5] = parsedat[i]; + buf[i-4] = 0; + } + + if (!buf[0]) + strcpy(buf, "Authentication rejected by remote machine!"); + MessageBox(HWND_DESKTOP, buf, NULL, MB_OK | MB_ICONEXCLAMATION); + + return KFAILURE; + } + + if (parsedat[4] == KRB_ACCEPT) { + if ((parsedat[3] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY) + return KSUCCESS; + + if ((parsedat[3] & AUTH_HOW_MASK) != AUTH_HOW_MUTUAL) + return KFAILURE; + + des_key_sched(cred.session, sched); + + t = time(NULL); + memcpy(challenge, &t, 4); + memcpy(&challenge[4], &t, 4); + des_ecb_encrypt(&challenge, &session_key, sched, 1); + + /* + * Increment the challenge by 1, and encrypt it for + * later comparison. + */ + for (i = 7; i >= 0; --i) { + x = (unsigned int)challenge[i] + 1; + challenge[i] = x; /* ignore overflow */ + if (x < 256) /* if no overflow, all done */ + break; + } + + des_ecb_encrypt(&challenge, &challenge, sched, 1); + + wsprintf(buf, "%c%c%c%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_IS, + KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, KRB_CHALLENGE); + memcpy(&buf[7], session_key, 8); + wsprintf(&buf[15], "%c%c", IAC, SE); + TelnetSend(ks, (LPSTR)buf, 17, 0); + + return KSUCCESS; + } + + if (parsedat[4] == KRB_RESPONSE) { + if (end_sub < 12) + return KFAILURE; + + if (memcmp(&parsedat[5], challenge, sizeof(challenge)) != 0) { + MessageBox(HWND_DESKTOP, "Remote machine is being impersonated!", + NULL, MB_OK | MB_ICONEXCLAMATION); + + return KFAILURE; + } + + return KSUCCESS; + } - return KFAILURE; + return KFAILURE; -} /* auth_reply */ +} #endif /* KRB4 */ -/*++*/ + #ifdef KRB5 /* -** -** K5_auth_send - gets authentication bits we need to send to KDC. -** -** Code lifted from telnet sample code in the appl directory. -** -** Result is left in auth -** -** Returns: 0 on failure, 1 on success -** -*/ + * + * K5_auth_send - gets authentication bits we need to send to KDC. + * + * Code lifted from telnet sample code in the appl directory. + * + * Result is left in auth + * + * Returns: 0 on failure, 1 on success + * + */ static int -k5_auth_send (int how) +k5_auth_send(kstream ks, int how) { - krb5_error_code r; - krb5_ccache ccache; - krb5_creds cred; - krb5_creds * new_cred; - extern krb5_flags krb5_kdc_default_options; - krb5_flags ap_opts; - int len; - - if (r = krb5_cc_default(k5_context, &ccache)) { - com_err (NULL, r, "while authorizing."); - return(0); - } - - memset((char *)&cred, 0, sizeof(cred)); - if (r = krb5_sname_to_principal(k5_context, szHostName, KRB_SERVICE_NAME, - KRB5_NT_SRV_HST, &cred.server)) { - com_err (NULL, r, "while authorizing."); - return(0); + krb5_error_code r; + krb5_ccache ccache; + krb5_creds creds; + krb5_creds * new_creds; + extern krb5_flags krb5_kdc_default_options; + krb5_flags ap_opts; + char type_check[2]; + krb5_data check_data; + int len; +#ifdef ENCRYPTION + krb5_keyblock *newkey = 0; +#endif + + if (r = krb5_cc_default(k5_context, &ccache)) { + com_err(NULL, r, "while authorizing."); + return(0); + } + + memset((char *)&creds, 0, sizeof(creds)); + if (r = krb5_sname_to_principal(k5_context, szHostName, KRB_SERVICE_NAME, + KRB5_NT_SRV_HST, &creds.server)) { + com_err(NULL, r, "while authorizing."); + return(0); + } + + if (r = krb5_cc_get_principal(k5_context, ccache, &creds.client)) { + com_err(NULL, r, "while authorizing."); + krb5_free_cred_contents(k5_context, &creds); + return(0); + } + if (szUserName[0] == '\0') { /* Get user name now */ + len = krb5_princ_component(k5_context, creds.client, 0)->length; + memcpy(szUserName, + krb5_princ_component(k5_context, creds.client, 0)->data, + len); + szUserName[len] = '\0'; + } + + if (r = krb5_get_credentials(k5_context, 0, + ccache, &creds, &new_creds)) { + com_err(NULL, r, "while authorizing."); + krb5_free_cred_contents(k5_context, &creds); + return(0); + } + + ap_opts = 0; + if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) + ap_opts = AP_OPTS_MUTUAL_REQUIRED; + +#ifdef ENCRYPTION + ap_opts |= AP_OPTS_USE_SUBKEY; +#endif + + if (auth_context) { + krb5_auth_con_free(k5_context, auth_context); + auth_context = 0; + } + if ((r = krb5_auth_con_init(k5_context, &auth_context))) { + com_err(NULL, r, "while initializing auth context"); + return(0); + } + + krb5_auth_con_setflags(k5_context, auth_context, + KRB5_AUTH_CONTEXT_RET_TIME); + + type_check[0] = AUTHTYPE_KERBEROS_V5; + type_check[1] = AUTH_WHO_CLIENT| (how & AUTH_HOW_MASK); +#ifdef ENCRYPTION + type_check[1] |= AUTH_ENCRYPT_ON; +#endif + check_data.magic = KV5M_DATA; + check_data.length = 2; + check_data.data = (char *)&type_check; + + r = krb5_mk_req_extended(k5_context, &auth_context, ap_opts, + NULL, new_creds, &auth); + +#ifdef ENCRYPTION + krb5_auth_con_getlocalsubkey(k5_context, auth_context, &newkey); + if (session_key) { + krb5_free_keyblock(k5_context, session_key); + session_key = 0; + } + + if (newkey) { + /* + * keep the key in our private storage, but don't use it + * yet---see kerberos5_reply() below + */ + if ((newkey->enctype != ENCTYPE_DES_CBC_CRC) && + (newkey-> enctype != ENCTYPE_DES_CBC_MD5)) { + if ((new_creds->keyblock.enctype == ENCTYPE_DES_CBC_CRC) || + (new_creds->keyblock.enctype == ENCTYPE_DES_CBC_MD5)) + /* use the session key in credentials instead */ + krb5_copy_keyblock(k5_context, &new_creds->keyblock, &session_key); + else + ; /* What goes here? XXX */ + } else { + krb5_copy_keyblock(k5_context, newkey, &session_key); } + krb5_free_keyblock(k5_context, newkey); + } +#endif /* ENCRYPTION */ + + krb5_free_cred_contents(k5_context, &creds); + krb5_free_creds(k5_context, new_creds); + + if (r) { + com_err(NULL, r, "while authorizing."); + return(0); + } + + return(1); +} - if (r = krb5_cc_get_principal(k5_context, ccache, &cred.client)) { - com_err (NULL, r, "while authorizing."); - krb5_free_cred_contents(k5_context, &cred); - return(0); - } - if (szUserName[0] == '\0') { /* Get user name now */ - len = krb5_princ_component(k5_context, cred.client, 0)->length; - memcpy (szUserName, - krb5_princ_component(k5_context, cred.client, 0)->data, - len); - szUserName[len] = '\0'; +/* + * + * K5_auth_reply -- checks the reply for mutual authentication. + * + * Code lifted from telnet sample code in the appl directory. + * + */ +static int +k5_auth_reply(kstream ks, int how, unsigned char *data, int cnt) +{ +#ifdef ENCRYPTION + Session_Key skey; +#endif + static int mutual_complete = 0; + + data += 4; /* Point to status byte */ + + switch (*data++) { + case KRB_REJECT: + if (cnt > 0) { + char *s; + wsprintf(strTmp, "Kerberos V5 refuses authentication because\n\t"); + s = strTmp + strlen(strTmp); + strncpy(s, data, cnt); + s[cnt] = 0; + } else + wsprintf(strTmp, "Kerberos V5 refuses authentication"); + MessageBox(HWND_DESKTOP, strTmp, "", MB_OK | MB_ICONEXCLAMATION); + + return KFAILURE; + + case KRB_ACCEPT: + if (!mutual_complete) { + if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && !mutual_complete) { + wsprintf(strTmp, + "Kerberos V5 accepted you, but didn't provide" + " mutual authentication"); + MessageBox(HWND_DESKTOP, strTmp, "", MB_OK | MB_ICONEXCLAMATION); + return KFAILURE; + } +#ifdef ENCRYPTION + if (session_key) { + skey.type = SK_DES; + skey.length = 8; + skey.data = session_key->contents; + encrypt_session_key(&skey, 0); + } +#endif } +#ifdef FORWARD + if (forward_flag) + kerberos5_forward(ks); +#endif - if (r = krb5_get_credentials(k5_context, 0, - ccache, &cred, &new_cred)) { - com_err (NULL, r, "while authorizing."); - krb5_free_cred_contents(k5_context, &cred); - return(0); - } + return KSUCCESS; + break; - ap_opts = 0; - if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) - ap_opts = AP_OPTS_MUTUAL_REQUIRED; + case KRB_RESPONSE: + if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { + /* the rest of the reply should contain a krb_ap_rep */ + krb5_ap_rep_enc_part *reply; + krb5_data inbuf; + krb5_error_code r; - r = krb5_mk_req_extended(k5_context, &auth_context, ap_opts, - NULL, new_cred, &auth); + inbuf.length = cnt; + inbuf.data = (char *)data; - krb5_free_cred_contents(k5_context, &cred); - krb5_free_creds(k5_context, new_cred); + if (r = krb5_rd_rep(k5_context, auth_context, &inbuf, &reply)) { + com_err(NULL, r, "while authorizing."); + return KFAILURE; + } + krb5_free_ap_rep_enc_part(k5_context, reply); + +#ifdef ENCRYPTION + if (encrypt_flag && session_key) { + skey.type = SK_DES; + skey.length = 8; + skey.data = session_key->contents; + encrypt_session_key(&skey, 0); + } +#endif + mutual_complete = 1; + } + return KSUCCESS; + +#ifdef FORWARD + case KRB_FORWARD_ACCEPT: + forwarded_tickets = 1; + return KSUCCESS; + + case KRB_FORWARD_REJECT: + forwarded_tickets = 0; + if (cnt > 0) { + char *s; + + wsprintf(strTmp, + "Kerberos V5 refuses forwarded credentials because\n\t"); + s = strTmp + strlen(strTmp); + strncpy(s, data, cnt); + s[cnt] = 0; + } else + wsprintf(strTmp, "Kerberos V5 refuses forwarded credentials"); + + MessageBox(HWND_DESKTOP, strTmp, "", MB_OK | MB_ICONEXCLAMATION); + return KFAILURE; +#endif /* FORWARD */ + + default: + return KFAILURE; /* Unknown reply type */ + } +} - if (r) { - com_err (NULL, r, "while authorizing."); - return(0); - } +#ifdef FORWARD +void +kerberos5_forward(kstream ks) +{ + krb5_error_code r; + krb5_ccache ccache; + krb5_principal client = 0; + krb5_principal server = 0; + krb5_data forw_creds; - return(1); -} + forw_creds.data = 0; -/*+ -** -** K5_auth_reply -- checks the reply for mutual authentication. -** -** Code lifted from telnet sample code in the appl directory. -** -*/ -static int -k5_auth_reply (int how, unsigned char *data, int cnt) { - static int mutual_complete = 0; - - data += 4; /* Point to status byte */ - - switch (*data++) { - case K5_REJECT: - if (cnt > 0) - wsprintf (strTmp, - "Kerberos V5 refuses authentication because %.*s", - cnt, data); - else - wsprintf (strTmp, "Kerberos V5 refuses authentication"); - MessageBox (HWND_DESKTOP, strTmp, "", MB_OK | MB_ICONEXCLAMATION); - - return KFAILURE; - - case K5_ACCEPT: - if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && !mutual_complete) { - wsprintf(strTmp, "Kerberos V5 accepted you, " - "but didn't provide mutual authentication"); - MessageBox (HWND_DESKTOP, strTmp, "", MB_OK | MB_ICONEXCLAMATION); - return KSUCCESS; - } - - return KSUCCESS; - break; - - case K5_RESPONSE: - if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { - /* the rest of the reply should contain a krb_ap_rep */ - krb5_ap_rep_enc_part *reply; - krb5_data inbuf; - krb5_error_code r; - - inbuf.length = cnt; - inbuf.data = (char *)data; - - if (r = krb5_rd_rep (k5_context, auth_context, &inbuf, &reply)) { - com_err (NULL, r, "while authorizing."); - return KFAILURE; - } - krb5_free_ap_rep_enc_part(k5_context, reply); - - mutual_complete = 1; - } - return KSUCCESS; - - default: - return KSUCCESS; // Unknown reply type - } + if ((r = krb5_cc_default(k5_context, &ccache))) { + com_err(NULL, r, "Kerberos V5: could not get default ccache"); + return; + } + + if ((r = krb5_cc_get_principal(k5_context, ccache, &client))) { + com_err(NULL, r, "Kerberos V5: could not get default principal"); + goto cleanup; + } + + if ((r = krb5_sname_to_principal(k5_context, szHostName, KRB_SERVICE_NAME, + KRB5_NT_SRV_HST, &server))) { + com_err(NULL, r, "Kerberos V5: could not make server principal"); + goto cleanup; + } + + if ((r = krb5_auth_con_genaddrs(k5_context, auth_context, ks->fd, + KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR))) { + com_err(NULL, r, "Kerberos V5: could not gen local full address"); + goto cleanup; + } + + if (r = krb5_fwd_tgt_creds(k5_context, auth_context, 0, client, server, + ccache, forwardable_flag, &forw_creds)) { + com_err(NULL, r, "Kerberos V5: error getting forwarded creds"); + goto cleanup; + } + + /* Send forwarded credentials */ + if (!Data(ks, KRB_FORWARD, forw_creds.data, forw_creds.length)) { + MessageBox(HWND_DESKTOP, + "Not enough room for authentication data", "", + MB_OK | MB_ICONEXCLAMATION); + } + +cleanup: + if (client) + krb5_free_principal(k5_context, client); + if (server) + krb5_free_principal(k5_context, server); +#if 0 /* XXX */ + if (forw_creds.data) + free(forw_creds.data); +#endif + krb5_cc_close(k5_context, ccache); } +#endif /* FORWARD */ + #endif /* KRB5 */ diff --git a/src/windows/wintel/auth.h b/src/windows/wintel/auth.h index ddc8b21696..e0f60ec401 100644 --- a/src/windows/wintel/auth.h +++ b/src/windows/wintel/auth.h @@ -2,24 +2,27 @@ * Implements Kerberos 4 authentication and ecryption */ -void auth_parse( - kstream ks, - unsigned char *parsedat, - int end_sub); - -int INTERFACE auth_init( - kstream str, - kstream_ptr data); - -void INTERFACE auth_destroy( - kstream str); - -int INTERFACE auth_encrypt( - struct kstream_data_block *out, - struct kstream_data_block *in, - kstream str); - -int INTERFACE auth_decrypt( - struct kstream_data_block *out, - struct kstream_data_block *in, - kstream str); +#ifndef WINTEL_AUTH_H +#define WINTEL_AUTH_H + +void auth_parse(kstream, unsigned char *, int); + +int auth_init(kstream, kstream_ptr); + +void auth_destroy(kstream); + +int auth_encrypt(struct kstream_data_block *, struct kstream_data_block *, + kstream); + +int auth_decrypt(struct kstream_data_block *, struct kstream_data_block *, + kstream); + +extern BOOL forward_flag; +extern BOOL forwardable_flag; +extern BOOL forwarded_tickets; + +#ifdef ENCRYPTION +extern BOOL encrypt_flag; +#endif + +#endif /* WINTEL_AUTH_H */ diff --git a/src/windows/wintel/dialog.h b/src/windows/wintel/dialog.h index cfec5928a1..c95ec0491b 100644 --- a/src/windows/wintel/dialog.h +++ b/src/windows/wintel/dialog.h @@ -6,6 +6,15 @@ #define TEL_MANUALCONFIGURE 203 #define TEL_OK 204 #define TEL_CANCEL 206 +#define IDC_FORWARD 207 +#define IDC_FORWARDFORWARD 208 +#define IDC_ENCRYPT 210 +#define TEL_CONNECT_USERID 211 + +#define IDM_SEND_IP 800 +#define IDM_SEND_AYT 801 +#define IDM_SEND_ABORT 802 + #define CON_SESSIONNAME 302 #define CON_WINDOWTITLE 304 #define CON_COLUMNS132 305 @@ -21,8 +30,11 @@ #define CONFIGDLG 300 #define CON_SCRLBCK 317 #define CON_NUMLINES 318 + #define PRINTQUEUE 400 + #define IDM_PRINTQUEUE 500 + #define TEL_PUSH1 601 #define TEL_PUSH2 602 #define TEL_PUSH3 603 diff --git a/src/windows/wintel/edit.c b/src/windows/wintel/edit.c index 02de7bea1d..aa230cfc9d 100644 --- a/src/windows/wintel/edit.c +++ b/src/windows/wintel/edit.c @@ -14,427 +14,431 @@ static int iLocStart; static int iLocEnd; void Edit_LbuttonDown( - HWND hWnd, - LPARAM lParam) + HWND hWnd, + LPARAM lParam) { - SCREEN *pScr; - HMENU hMenu; - int iTmp; - int iXlocStart; - int iYlocStart; - HDC hDC; - - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert(pScr != NULL); - - hDC = GetDC(hWnd); - for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) { - if (cInvertedArray[iTmp]) { - PatBlt(hDC, iTmp % pScr->width * pScr->cxChar, - (int) (iTmp / pScr->width) * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp] = 0; - } - } - bSelection = FALSE; - hMenu = GetMenu(hWnd); - EnableMenuItem(hMenu, IDM_COPY, MF_GRAYED); - ReleaseDC(hWnd, hDC); - iXlocStart = (int) LOWORD(lParam) / pScr->cxChar; - if (iXlocStart >= pScr->width) - iXlocStart = pScr->width - 1; - iYlocStart = (int) HIWORD(lParam) / pScr->cyChar; - if (iYlocStart >= pScr->height) - iYlocStart = pScr->height - 1; - iLocStart = iXlocStart + iYlocStart * pScr->width; - bMouseDown = TRUE; + SCREEN *pScr; + HMENU hMenu; + int iTmp; + int iXlocStart; + int iYlocStart; + HDC hDC; + + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert(pScr != NULL); + + hDC = GetDC(hWnd); + for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) { + if (cInvertedArray[iTmp]) { + PatBlt(hDC, iTmp % pScr->width * pScr->cxChar, + (int) (iTmp / pScr->width) * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp] = 0; + } + } + bSelection = FALSE; + hMenu = GetMenu(hWnd); + EnableMenuItem(hMenu, IDM_COPY, MF_GRAYED); + ReleaseDC(hWnd, hDC); + iXlocStart = (int) LOWORD(lParam) / pScr->cxChar; + if (iXlocStart >= pScr->width) + iXlocStart = pScr->width - 1; + iYlocStart = (int) HIWORD(lParam) / pScr->cyChar; + if (iYlocStart >= pScr->height) + iYlocStart = pScr->height - 1; + iLocStart = iXlocStart + iYlocStart * pScr->width; + bMouseDown = TRUE; } /* Edit_LbuttonDown */ void Edit_LbuttonUp( - HWND hWnd, - LPARAM lParam) + HWND hWnd, + LPARAM lParam) { - SCREEN *pScr; - int iTmp; - int iTmp2; - HMENU hMenu; - - bMouseDown = FALSE; - if (bSelection) - return; - bSelection = TRUE; - - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert(pScr != NULL); - - iTmp = (int) LOWORD(lParam) / pScr->cxChar; - if (iTmp >= pScr->width) - iTmp = pScr->width - 1; - iTmp2 = (int) HIWORD(lParam) / pScr->cyChar; - if (iTmp2 >= pScr->height) - iTmp2 = pScr->height - 1; - iLocEnd = iTmp + iTmp2 * pScr->width; - if (iLocEnd == iLocStart) { - bSelection = FALSE; - } - else { - hMenu = GetMenu(hWnd); - EnableMenuItem(hMenu, IDM_COPY, MF_ENABLED); - } + SCREEN *pScr; + int iTmp; + int iTmp2; + HMENU hMenu; + + bMouseDown = FALSE; + if (bSelection) + return; + bSelection = TRUE; + + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert(pScr != NULL); + + iTmp = (int) LOWORD(lParam) / pScr->cxChar; + if (iTmp >= pScr->width) + iTmp = pScr->width - 1; + iTmp2 = (int) HIWORD(lParam) / pScr->cyChar; + if (iTmp2 >= pScr->height) + iTmp2 = pScr->height - 1; + iLocEnd = iTmp + iTmp2 * pScr->width; + if (iLocEnd == iLocStart) { + bSelection = FALSE; + } + else { + hMenu = GetMenu(hWnd); + EnableMenuItem(hMenu, IDM_COPY, MF_ENABLED); + } } /* Edit_LbuttonUp */ void Edit_MouseMove(HWND hWnd, LPARAM lParam){ - SCREEN *pScr; - int iTmp; - int iTmp2; - int iXlocCurr; - int iYlocCurr; - int iLocCurr; - int iX; - int iX2; - int iY; - int iY2; - SCREENLINE *pScrLine; - HDC hDC; - - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert(pScr != NULL); - - hDC = GetDC(hWnd); - iXlocCurr = (int) LOWORD(lParam) / pScr->cxChar; - if (iXlocCurr >= pScr->width) - iXlocCurr = pScr->width - 1; - iYlocCurr = (int) HIWORD(lParam) / pScr->cyChar; - if (iYlocCurr >= pScr->height) - iYlocCurr = pScr->height - 1; - iLocCurr = iXlocCurr + (iYlocCurr * pScr->width); - if (iLocCurr > iLocStart) { - for (iTmp=0; iTmp < iLocStart; iTmp++) { - if (cInvertedArray[iTmp]) { - PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, - (int) (iTmp / pScr->width) * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp] = 0; - } - } - iX = iLocStart % pScr->width; - iY = (int) (iLocStart / pScr->width); - iX2 = iLocCurr % pScr->width; - iY2 = (int) (iLocCurr / pScr->width); - if (iY == iY2) { - pScrLine = GetScreenLineFromY(pScr, iY); - for (iTmp2 = iX; iTmp2 < iX2; iTmp2++) { - if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) { - PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2]; - } - } - } - else { - pScrLine = GetScreenLineFromY(pScr, iY); - - for (iTmp2 = iX; iTmp2 < pScr->width; iTmp2++) { - if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) { - PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2]; - } - } - - for (iTmp = iY + 1; iTmp < iY2; iTmp++) { - pScrLine = GetScreenLineFromY(pScr, iTmp); - for (iTmp2 = 0; iTmp2 < pScr->width; iTmp2++) { - if ((!cInvertedArray[iTmp2 + (pScr->width * iTmp)]) && pScrLine->text[iTmp2]) { - PatBlt(hDC, iTmp2 * pScr->cxChar, iTmp * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp2 + (pScr->width * iTmp)] = pScrLine->text[iTmp2]; - } - } - } - - if (iY2 != iY) { - pScrLine = GetScreenLineFromY(pScr, iY2); - for (iTmp2 = 0; iTmp2 < iX2; iTmp2++) { - if ((!cInvertedArray[iTmp2 + (pScr->width * iY2)]) && pScrLine->text[iTmp2]) { - PatBlt(hDC, iTmp2 * pScr->cxChar, iY2 * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp2 + (pScr->width * iY2)] = pScrLine->text[iTmp2]; - } - } - } - } - - for (iTmp = iLocCurr; iTmp < pScr->width * pScr->height; iTmp++) { - if (cInvertedArray[iTmp]) { - PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp] = 0; - } - } + SCREEN *pScr; + int iTmp; + int iTmp2; + int iXlocCurr; + int iYlocCurr; + int iLocCurr; + int iX; + int iX2; + int iY; + int iY2; + SCREENLINE *pScrLine; + HDC hDC; + + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert(pScr != NULL); + + hDC = GetDC(hWnd); + iXlocCurr = (int) LOWORD(lParam) / pScr->cxChar; + if (iXlocCurr >= pScr->width) + iXlocCurr = pScr->width - 1; + iYlocCurr = (int) HIWORD(lParam) / pScr->cyChar; + if (iYlocCurr >= pScr->height) + iYlocCurr = pScr->height - 1; + iLocCurr = iXlocCurr + (iYlocCurr * pScr->width); + if (iLocCurr > iLocStart) { + for (iTmp=0; iTmp < iLocStart; iTmp++) { + if (cInvertedArray[iTmp]) { + PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, + (int) (iTmp / pScr->width) * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp] = 0; + } + } + iX = iLocStart % pScr->width; + iY = (int) (iLocStart / pScr->width); + iX2 = iLocCurr % pScr->width; + iY2 = (int) (iLocCurr / pScr->width); + if (iY == iY2) { + pScrLine = GetScreenLineFromY(pScr, iY); + for (iTmp2 = iX; iTmp2 < iX2; iTmp2++) { + if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) { + PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2]; + } + } + } + else { + pScrLine = GetScreenLineFromY(pScr, iY); + + for (iTmp2 = iX; iTmp2 < pScr->width; iTmp2++) { + if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) { + PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2]; + } + } + + for (iTmp = iY + 1; iTmp < iY2; iTmp++) { + pScrLine = GetScreenLineFromY(pScr, iTmp); + for (iTmp2 = 0; iTmp2 < pScr->width; iTmp2++) { + if ((!cInvertedArray[iTmp2 + (pScr->width * iTmp)]) && pScrLine->text[iTmp2]) { + PatBlt(hDC, iTmp2 * pScr->cxChar, iTmp * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp2 + (pScr->width * iTmp)] = pScrLine->text[iTmp2]; + } } - else { /* going backwards */ - for (iTmp = 0; iTmp < iLocCurr; iTmp++) { - if (cInvertedArray[iTmp]) { - PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp] = 0; - } - } - iX = iLocCurr % pScr->width; - iY = (int) (iLocCurr / pScr->width); - iX2 = (iLocStart % pScr->width); - iY2 = (int) (iLocStart / pScr->width); - if (iY == iY2) { - pScrLine = GetScreenLineFromY(pScr, iY); - for (iTmp2= iX; iTmp2 < iX2; iTmp2++) { - if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) { - PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2]; - } - } - } - else { - pScrLine = GetScreenLineFromY(pScr, iY); - for (iTmp2 = iX; iTmp2 < pScr->width; iTmp2++) { - if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) { - PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2]; - } - } - for (iTmp = iY + 1; iTmp < iY2; iTmp++) { - pScrLine = GetScreenLineFromY(pScr, iTmp); - for (iTmp2 = 0; iTmp2 < pScr->width; iTmp2++) { - if ((!cInvertedArray[iTmp2 + (pScr->width * iTmp)]) && pScrLine->text[iTmp2]) { - PatBlt(hDC, iTmp2 * pScr->cxChar, iTmp * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp2 + (pScr->width * iTmp)] = pScrLine->text[iTmp2]; - } - } - } - if (iY2 != iY) { - pScrLine = GetScreenLineFromY(pScr, iY2); - for (iTmp2 = 0; iTmp2 < iX2; iTmp2++) { - if ((!cInvertedArray[iTmp2 + (pScr->width * iY2)]) && pScrLine->text[iTmp2]) { - PatBlt(hDC, iTmp2 * pScr->cxChar, iY2 * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp2 + (pScr->width * iY2)] = pScrLine->text[iTmp2]; - } - } - } - } - for (iTmp = iLocStart; iTmp < pScr->width * pScr->height; iTmp++) { - if (cInvertedArray[iTmp]) { - PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp] = 0; - } - } - } - ReleaseDC(hWnd, hDC); + } + + if (iY2 != iY) { + pScrLine = GetScreenLineFromY(pScr, iY2); + for (iTmp2 = 0; iTmp2 < iX2; iTmp2++) { + if ((!cInvertedArray[iTmp2 + (pScr->width * iY2)]) && pScrLine->text[iTmp2]) { + PatBlt(hDC, iTmp2 * pScr->cxChar, iY2 * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp2 + (pScr->width * iY2)] = pScrLine->text[iTmp2]; + } + } + } + } + + for (iTmp = iLocCurr; iTmp < pScr->width * pScr->height; iTmp++) { + if (cInvertedArray[iTmp]) { + PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp] = 0; + } + } + } + else { /* going backwards */ + for (iTmp = 0; iTmp < iLocCurr; iTmp++) { + if (cInvertedArray[iTmp]) { + PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp] = 0; + } + } + iX = iLocCurr % pScr->width; + iY = (int) (iLocCurr / pScr->width); + iX2 = (iLocStart % pScr->width); + iY2 = (int) (iLocStart / pScr->width); + if (iY == iY2) { + pScrLine = GetScreenLineFromY(pScr, iY); + for (iTmp2= iX; iTmp2 < iX2; iTmp2++) { + if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) { + PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2]; + } + } + } + else { + pScrLine = GetScreenLineFromY(pScr, iY); + for (iTmp2 = iX; iTmp2 < pScr->width; iTmp2++) { + if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) { + PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2]; + } + } + for (iTmp = iY + 1; iTmp < iY2; iTmp++) { + pScrLine = GetScreenLineFromY(pScr, iTmp); + for (iTmp2 = 0; iTmp2 < pScr->width; iTmp2++) { + if ((!cInvertedArray[iTmp2 + (pScr->width * iTmp)]) && pScrLine->text[iTmp2]) { + PatBlt(hDC, iTmp2 * pScr->cxChar, iTmp * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp2 + (pScr->width * iTmp)] = pScrLine->text[iTmp2]; + } + } + } + if (iY2 != iY) { + pScrLine = GetScreenLineFromY(pScr, iY2); + for (iTmp2 = 0; iTmp2 < iX2; iTmp2++) { + if ((!cInvertedArray[iTmp2 + (pScr->width * iY2)]) && pScrLine->text[iTmp2]) { + PatBlt(hDC, iTmp2 * pScr->cxChar, iY2 * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp2 + (pScr->width * iY2)] = pScrLine->text[iTmp2]; + } + } + } + } + for (iTmp = iLocStart; iTmp < pScr->width * pScr->height; iTmp++) { + if (cInvertedArray[iTmp]) { + PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp] = 0; + } + } + } + ReleaseDC(hWnd, hDC); } /* Edit_MouseMove */ void Edit_ClearSelection( - SCREEN *pScr) + SCREEN *pScr) { - int iTmp; - HDC hDC; - HMENU hMenu; - - hDC = GetDC(pScr->hWnd); - for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) { - if (cInvertedArray[iTmp]) { - PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, - (int) (iTmp / pScr->width) * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp] = 0; - } - } - bSelection = FALSE; - hMenu=GetMenu(pScr->hWnd); - EnableMenuItem(hMenu, IDM_COPY, MF_GRAYED); - ReleaseDC(pScr->hWnd, hDC); + int iTmp; + HDC hDC; + HMENU hMenu; + + hDC = GetDC(pScr->hWnd); + for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) { + if (cInvertedArray[iTmp]) { + PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, + (int) (iTmp / pScr->width) * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp] = 0; + } + } + bSelection = FALSE; + hMenu=GetMenu(pScr->hWnd); + EnableMenuItem(hMenu, IDM_COPY, MF_GRAYED); + ReleaseDC(pScr->hWnd, hDC); } /* Edit_ClearSelection */ void Edit_Copy( - HWND hWnd) + HWND hWnd) { - int iTmp,iIdx; - HGLOBAL hCutBuffer; - LPSTR lpCutBuffer; - SCREEN *pScr; - - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert(pScr != NULL); - - hCutBuffer= GlobalAlloc(GHND, (DWORD) (pScr->width * pScr->height + 1)); - lpCutBuffer= GlobalLock(hCutBuffer); - - if (iLocStart > iLocEnd) { /* swap variables */ - iTmp = iLocStart; - iLocStart = iLocEnd; - iLocEnd = iLocStart; - } - iTmp = iLocStart; - iIdx = 0; - while (iTmp < iLocEnd) { - if (!cInvertedArray[iTmp]) { - lpCutBuffer[iIdx++] = '\r'; - lpCutBuffer[iIdx++] = '\n'; - iTmp = (((int) (iTmp / pScr->width)) + 1) * pScr->width; - continue; - } - lpCutBuffer[iIdx++] = cInvertedArray[iTmp++]; - } - lpCutBuffer[iIdx] = 0; - GlobalUnlock(hCutBuffer); - OpenClipboard(hWnd); - EmptyClipboard(); - SetClipboardData(CF_TEXT, hCutBuffer); - CloseClipboard(); + int iTmp,iIdx; + HGLOBAL hCutBuffer; + LPSTR lpCutBuffer; + SCREEN *pScr; + + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert(pScr != NULL); + + hCutBuffer= GlobalAlloc(GHND, (DWORD) (pScr->width * pScr->height + 1)); + lpCutBuffer= GlobalLock(hCutBuffer); + + if (iLocStart > iLocEnd) { /* swap variables */ + iTmp = iLocStart; + iLocStart = iLocEnd; + iLocEnd = iLocStart; + } + iTmp = iLocStart; + iIdx = 0; + while (iTmp < iLocEnd) { + if (!cInvertedArray[iTmp]) { + lpCutBuffer[iIdx++] = '\r'; + lpCutBuffer[iIdx++] = '\n'; + iTmp = (((int) (iTmp / pScr->width)) + 1) * pScr->width; + continue; + } + lpCutBuffer[iIdx++] = cInvertedArray[iTmp++]; + } + lpCutBuffer[iIdx] = 0; + GlobalUnlock(hCutBuffer); + OpenClipboard(hWnd); + EmptyClipboard(); + SetClipboardData(CF_TEXT, hCutBuffer); + CloseClipboard(); } /* Edit_Copy */ void Edit_Paste( - HWND hWnd) + HWND hWnd) { - HGLOBAL hClipMemory; - static HGLOBAL hMyClipBuffer; - LPSTR lpClipMemory; - LPSTR lpMyClipBuffer; - SCREEN *pScr; - - if (hMyClipBuffer) - GlobalFree(hMyClipBuffer); - OpenClipboard(hWnd); - hClipMemory = GetClipboardData(CF_TEXT); - hMyClipBuffer = GlobalAlloc(GHND, GlobalSize(hClipMemory)); - lpMyClipBuffer = GlobalLock(hMyClipBuffer); - lpClipMemory= GlobalLock(hClipMemory); - - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert(pScr != NULL); - - lstrcpy(lpMyClipBuffer, lpClipMemory); -// OutputDebugString(lpMyClipBuffer); - PostMessage(pScr->hwndTel, WM_MYSCREENBLOCK, (WPARAM) hMyClipBuffer, (LPARAM) pScr); - CloseClipboard(); - GlobalUnlock(hClipMemory); - GlobalUnlock(hMyClipBuffer); + HGLOBAL hClipMemory; + static HGLOBAL hMyClipBuffer; + LPSTR lpClipMemory; + LPSTR lpMyClipBuffer; + SCREEN *pScr; + + if (hMyClipBuffer) + GlobalFree(hMyClipBuffer); + OpenClipboard(hWnd); + hClipMemory = GetClipboardData(CF_TEXT); + hMyClipBuffer = GlobalAlloc(GHND, GlobalSize(hClipMemory)); + lpMyClipBuffer = GlobalLock(hMyClipBuffer); + lpClipMemory= GlobalLock(hClipMemory); + + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert(pScr != NULL); + + lstrcpy(lpMyClipBuffer, lpClipMemory); +#if 0 + OutputDebugString(lpMyClipBuffer); +#endif + PostMessage(pScr->hwndTel, WM_MYSCREENBLOCK, (WPARAM) hMyClipBuffer, (LPARAM) pScr); + CloseClipboard(); + GlobalUnlock(hClipMemory); + GlobalUnlock(hMyClipBuffer); } /* Edit_Paste */ void Edit_LbuttonDblclk( - HWND hWnd, - LPARAM lParam) + HWND hWnd, + LPARAM lParam) { - HDC hDC; - SCREEN *pScr; - int iTmp; - int iTmp2; - int iXlocStart; - int iYloc; - SCREENLINE *pScrLine; - - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert(pScr != NULL); - - hDC = GetDC(hWnd); - for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) { - if (cInvertedArray[iTmp]) { - PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, - (int) (iTmp / pScr->width) * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp] = 0; - } - } - bSelection = FALSE; - iXlocStart = (int) LOWORD(lParam) / pScr->cxChar; - if (iXlocStart >= pScr->width) - iXlocStart = pScr->width - 1; - iYloc = (int) HIWORD(lParam) / pScr->cyChar; - if (iYloc >= pScr->height) - iYloc = pScr->height - 1; - iLocStart = iXlocStart + (iYloc * pScr->width); - - pScrLine = GetScreenLineFromY(pScr, iYloc); - - iTmp = iXlocStart; - while (isalnum((int) pScrLine->text[iTmp])) { - PatBlt(hDC, iTmp * pScr->cxChar, iYloc * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp + (iYloc * pScr->width)] = pScrLine->text[iTmp]; - iTmp++; - } - iTmp2 = iXlocStart - 1; - while (isalnum((int) pScrLine->text[iTmp2])) { - PatBlt(hDC, iTmp2 * pScr->cxChar, iYloc * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp2 + (iYloc * pScr->width)] = pScrLine->text[iTmp2]; - iTmp2--; - } - iLocStart = (iTmp2 + 1) + (iYloc * pScr->width); - iLocEnd = iTmp + (iYloc * pScr->width); - - bSelection = TRUE; - ReleaseDC(hWnd, hDC); + HDC hDC; + SCREEN *pScr; + int iTmp; + int iTmp2; + int iXlocStart; + int iYloc; + SCREENLINE *pScrLine; + + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert(pScr != NULL); + + hDC = GetDC(hWnd); + for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) { + if (cInvertedArray[iTmp]) { + PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, + (int) (iTmp / pScr->width) * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp] = 0; + } + } + bSelection = FALSE; + iXlocStart = (int) LOWORD(lParam) / pScr->cxChar; + if (iXlocStart >= pScr->width) + iXlocStart = pScr->width - 1; + iYloc = (int) HIWORD(lParam) / pScr->cyChar; + if (iYloc >= pScr->height) + iYloc = pScr->height - 1; + iLocStart = iXlocStart + (iYloc * pScr->width); + + pScrLine = GetScreenLineFromY(pScr, iYloc); + + iTmp = iXlocStart; + while (isalnum((int) pScrLine->text[iTmp])) { + PatBlt(hDC, iTmp * pScr->cxChar, iYloc * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp + (iYloc * pScr->width)] = pScrLine->text[iTmp]; + iTmp++; + } + iTmp2 = iXlocStart - 1; + while (isalnum((int) pScrLine->text[iTmp2])) { + PatBlt(hDC, iTmp2 * pScr->cxChar, iYloc * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp2 + (iYloc * pScr->width)] = pScrLine->text[iTmp2]; + iTmp2--; + } + iLocStart = (iTmp2 + 1) + (iYloc * pScr->width); + iLocEnd = iTmp + (iYloc * pScr->width); + + bSelection = TRUE; + ReleaseDC(hWnd, hDC); } /* Edit_LbuttonDblclk */ void Edit_TripleClick( - HWND hWnd, - LPARAM lParam) + HWND hWnd, + LPARAM lParam) { - HDC hDC; - SCREEN *pScr; - int iTmp; - int iYloc; - SCREENLINE *pScrLine; - -// OutputDebugString("Triple Click \r\n"); - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert(pScr != NULL); - - hDC = GetDC(hWnd); - for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) { - if (cInvertedArray[iTmp]) { - PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, - (int) (iTmp / pScr->width) * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp] = 0; - } - } - bSelection = FALSE; - iYloc = (int) HIWORD(lParam) / pScr->cyChar; - if (iYloc >= pScr->height) - iYloc = pScr->height - 1; - iLocStart = iYloc * pScr->width; - - pScrLine = GetScreenLineFromY(pScr, iYloc); - - for (iTmp = 0; iTmp < pScr->width; iTmp++) { - if (pScrLine->text[iTmp]) { - PatBlt(hDC, iTmp * pScr->cxChar, iYloc * pScr->cyChar, - pScr->cxChar, pScr->cyChar, DSTINVERT); - cInvertedArray[iTmp + (iYloc * pScr->width)] = pScrLine->text[iTmp]; - } - else - break; - } - iLocEnd = iTmp + (iYloc * pScr->width); - - bSelection = TRUE; - ReleaseDC(hWnd, hDC); + HDC hDC; + SCREEN *pScr; + int iTmp; + int iYloc; + SCREENLINE *pScrLine; + +#if 0 + OutputDebugString("Triple Click \r\n"); +#endif + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert(pScr != NULL); + + hDC = GetDC(hWnd); + for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) { + if (cInvertedArray[iTmp]) { + PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, + (int) (iTmp / pScr->width) * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp] = 0; + } + } + bSelection = FALSE; + iYloc = (int) HIWORD(lParam) / pScr->cyChar; + if (iYloc >= pScr->height) + iYloc = pScr->height - 1; + iLocStart = iYloc * pScr->width; + + pScrLine = GetScreenLineFromY(pScr, iYloc); + + for (iTmp = 0; iTmp < pScr->width; iTmp++) { + if (pScrLine->text[iTmp]) { + PatBlt(hDC, iTmp * pScr->cxChar, iYloc * pScr->cyChar, + pScr->cxChar, pScr->cyChar, DSTINVERT); + cInvertedArray[iTmp + (iYloc * pScr->width)] = pScrLine->text[iTmp]; + } + else + break; + } + iLocEnd = iTmp + (iYloc * pScr->width); + + bSelection = TRUE; + ReleaseDC(hWnd, hDC); } /* Edit_TripleClick */ diff --git a/src/windows/wintel/emul.c b/src/windows/wintel/emul.c index a80d37a423..18547ab807 100644 --- a/src/windows/wintel/emul.c +++ b/src/windows/wintel/emul.c @@ -4,757 +4,763 @@ #include "screen.h" -static int ScreenEmChars( - SCREEN *pScr, - char *c, - int len) +static int +ScreenEmChars(SCREEN *pScr, char *c, int len) { + /* + * Function: Send a string of characters to the screen. Placement + * continues as long as the stream of characters does not contain any + * control chracters or cause wrapping to another line. When a control + * character is encountered or wrapping occurs, display stops and a + * count of the number of characters is returned. + * + * Parameters: + * pScr - the screen to place the characters on. + * c - the string of characters to place on the screen. + * len - the number of characters contained in the string + * + * Returns: The number of characters actually placed on the screen. + */ + + int insert; + int ocount; + int attrib; + int extra; + int nchars; + char *acurrent; /* place to put attributes */ + char *current; /* place to put characters */ + char *start; + SCREENLINE *pScrLine; + + if (len <= 0) + return(0); + + if (pScr->x != pScr->width - 1) + pScr->bWrapPending = FALSE; + else { + if (pScr->bWrapPending) { + pScr->x = 0; + pScr->bWrapPending = FALSE; + ScreenIndex(pScr); + } + } + + pScrLine = GetScreenLineFromY(pScr, pScr->y); + if (pScrLine == NULL) + return(0); + + current = &pScrLine->text[pScr->x]; + acurrent = &pScrLine->attrib[pScr->x]; + start = current; + ocount = pScr->x; + extra = 0; + + attrib = pScr->attrib; + insert = pScr->IRM; + + for (nchars = 0; nchars < len && *c >= 32; nchars++) { + if (insert) + ScreenInsChar(pScr, 1); + + *current = *c; + *acurrent = (char) attrib; + c++; + if (pScr->x < pScr->width - 1) { + acurrent++; + current++; + pScr->x++; + } + else { + extra = 1; + if (pScr->DECAWM) { + pScr->bWrapPending = TRUE; + nchars++; + break; + } + } + } + + ScreenDraw(pScr, ocount, pScr->y, pScr->attrib, + pScr->x - ocount + extra, start); + + return(nchars); +} + + +void +ScreenEm(LPSTR c, int len, SCREEN *pScr) +{ + int escflg; /* vt100 escape level */ + RECT rc; + unsigned int ic; + char stat[20]; + int i; + int nchars; + + if (pScr->screen_bottom != pScr->buffer_bottom) { + ScreenUnscroll(pScr); + InvalidateRect(pScr->hWnd, NULL, TRUE); + SetScrollPos(pScr->hWnd, SB_VERT, pScr->numlines, TRUE); + } + + ScreenCursorOff(pScr); + escflg = pScr->escflg; + +#ifdef UM + if (pScr->localprint && len > 0) { /* see if printer needs anything */ + pcount = send_localprint(c, len); + len -= pcount; + c += pcount; + } +#endif + + while (len > 0) { + /* + * look at first character in the vt100 string, if it is a + * non-printable ascii code + */ + while((*c < 32) && (escflg == 0) && (len > 0)) { + switch(*c) { + + case 0x1b: /* ESC found (begin vt100 control sequence) */ + escflg++; + break; + + case -1: /* IAC from telnet session */ + escflg = 6; + break; + +#ifdef CISB + case 0x05: /* CTRL-E found (answerback) */ + bp_ENQ(); + break; +#endif + + case 0x07: /* CTRL-G found (bell) */ + ScreenBell(pScr); + break; + + case 0x08: /* CTRL-H found (backspace) */ + ScreenBackspace(pScr); + break; + + case 0x09: /* CTRL-I found (tab) */ + ScreenTab(pScr); /* Later change for versatile tabbing */ + break; + + case 0x0a: /* CTRL-J found (line feed) */ + case 0x0b: /* CTRL-K found (treat as line feed) */ + case 0x0c: /* CTRL-L found (treat as line feed) */ + ScreenIndex(pScr); + break; + + case 0x0d: /* CTRL-M found (carriage feed) */ + ScreenCarriageFeed(pScr); + break; + +#if 0 + case 0x0e: /* CTRL-N found (invoke Graphics (G1) character set) */ + if (pScr->G1) + pScr->attrib = VSgraph(pScr->attrib); + else + pScr->attrib = VSnotgraph(pScr->attrib); + pScr->charset = 1; + break; + + case 0x0f: /* CTRL-O found (invoke 'normal' (G0) character set) */ + if(pScr->G0) + pScr->attrib = VSgraph(pScr->attrib); + else + pScr->attrib = VSnotgraph(pScr->attrib); + pScr->charset = 0; + break; +#endif + +#ifdef CISB + case 0x10: /* CTRL-P found (undocumented in vt100) */ + bp_DLE(c, len); + len = 0; + break; +#endif + +#if 0 + case 0x11: /* CTRL-Q found (XON) (unused presently) */ + case 0x13: /* CTRL-S found (XOFF) (unused presently) */ + case 0x18: /* CTRL-X found (CAN) (unused presently) */ + case 0x1a: /* CTRL-Z found (SUB) (unused presently) */ + break; +#endif + } + + c++; /* advance to the next character in the string */ + len--; /* decrement the counter */ + } + + if (escflg == 0) { /* check for normal character to print */ + nchars = ScreenEmChars(pScr, c, len); + c += nchars; + len -= nchars; + } + + while ((len > 0) && (escflg == 1)) { /* ESC character was found */ + switch(*c) { + + case 0x08: /* CTRL-H found (backspace) */ + ScreenBackspace(pScr); + break; + /* - Function: Send a string of characters to the screen. Placement - continues as long as the stream of characters does not contain any - control chracters or cause wrapping to another line. When a control - character is encountered or wrapping occurs, display stops and a - count of the number of characters is returned. - - Parameters: - pScr - the screen to place the characters on. - - c - the string of characters to place on the screen. - - len - the number of characters contained in the string - - Returns: The number of characters actually placed on the screen. - */ - - int insert; - int ocount; - int attrib; - int extra; - int nchars; - char *acurrent; /* place to put attributes */ - char *current; /* place to put characters */ - char *start; - SCREENLINE *pScrLine; - - if (len <= 0) - return(0); - - if (pScr->x != pScr->width - 1) - pScr->bWrapPending = FALSE; - else { - if (pScr->bWrapPending) { - pScr->x = 0; - pScr->bWrapPending = FALSE; - ScreenIndex(pScr); - } + * mostly cursor movement options, and DEC private stuff following + */ + case '[': + ScreenApClear(pScr); + escflg = 2; + break; + + case '#': /* various screen adjustments */ + escflg = 3; + break; + + case '(': /* G0 character set options */ + escflg = 4; + break; + + case ')': /* G1 character set options */ + escflg = 5; + break; + + case '>': /* keypad numeric mode (DECKPAM) */ + pScr->DECPAM = 0; + escflg = 0; + break; + + case '=': /* keypad application mode (DECKPAM) */ + pScr->DECPAM = 1; + escflg = 0; + break; + + case '7': /* save cursor (DECSC) */ + ScreenSaveCursor(pScr); + escflg = 0; + break; + + case '8': /* restore cursor (DECRC) */ + ScreenRestoreCursor(pScr); + escflg = 0; + break; + +#if 0 + case 'c': /* reset to initial state (RIS) */ + ScreenReset(pScr); + escflg = 0; + break; +#endif + + case 'D': /* index (move down one line) (IND) */ + ScreenIndex(pScr); + escflg = 0; + break; + + case 'E': /* next line (move down one line and to first column) (NEL) */ + pScr->x = 0; + ScreenIndex(pScr); + escflg = 0; + break; + + case 'H': /* horizontal tab set (HTS) */ + pScr->tabs[pScr->x] = 'x'; + escflg = 0; + break; + +#ifdef CISB + case 'I': /* undoumented in vt100 */ + bp_ESC_I(); + break; +#endif + + case 'M': /* reverse index (move up one line) (RI) */ + ScreenRevIndex(pScr); + escflg = 0; + break; + + case 'Z': /* identify terminal (DECID) */ + escflg = 0; + break; + + default: + /* put the ESC character into the Screen */ + ScreenEmChars(pScr, "\033", 1); + /* put the next character into the Screen */ + ScreenEmChars(pScr, c, 1); + escflg = 0; + break; + + } /* end switch */ + + c++; + len--; + } + + while((escflg == 2) && (len > 0)) { /* '[' handling */ + switch(*c) { + + case 0x08: /* backspace */ + ScreenBackspace(pScr); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': /* numeric parameters */ + if (pScr->parms[pScr->parmptr] < 0) + pScr->parms[pScr->parmptr] = 0; + pScr->parms[pScr->parmptr] *= 10; + pScr->parms[pScr->parmptr] += *c - '0'; + break; + + case '?': /* vt100 mode change */ + pScr->parms[pScr->parmptr++] = -2; + break; + + case ';': /* parameter divider */ + pScr->parmptr++; + break; + + case 'A': /* cursor up (CUU) */ + pScr->bWrapPending = FALSE; + rc.left = pScr->x * pScr->cxChar; + rc.right = (pScr->x + 1) * pScr->cxChar; + rc.top = pScr->cyChar * pScr->y; + rc.bottom = pScr->cyChar * (pScr->y + 1); + InvalidateRect(pScr->hWnd, &rc, TRUE); + if (pScr->parms[0] < 1) + pScr->y--; + else + pScr->y -= pScr->parms[0]; + if(pScr->y < pScr->top) + pScr->y = pScr->top; + ScreenRange(pScr); + escflg = 0; + SendMessage(pScr->hWnd, WM_PAINT, 0, 0); + break; + + case 'B': /* cursor down (CUD) */ + pScr->bWrapPending = FALSE; + rc.left = pScr->x * pScr->cxChar; + rc.right = (pScr->x + 1) * pScr->cxChar; + rc.top = pScr->cyChar * pScr->y; + rc.bottom = pScr->cyChar * (pScr->y + 1); + InvalidateRect(pScr->hWnd, &rc, TRUE); + if (pScr->parms[0] < 1) + pScr->y++; + else + pScr->y += pScr->parms[0]; + if (pScr->y > pScr->bottom) + pScr->y = pScr->bottom; + ScreenRange(pScr); + escflg = 0; + SendMessage(pScr->hWnd, WM_PAINT, 0, 0); + break; + + case 'C': /* cursor forward (right) (CUF) */ + pScr->bWrapPending = FALSE; + rc.left = pScr->x * pScr->cxChar; + rc.right = (pScr->x + 1) * pScr->cxChar; + rc.top = pScr->cyChar * pScr->y; + rc.bottom = pScr->cyChar * (pScr->y +1); + InvalidateRect(pScr->hWnd, &rc, TRUE); + if(pScr->parms[0] < 1) + pScr->x++; + else + pScr->x += pScr->parms[0]; + ScreenRange(pScr); + if (pScr->x > pScr->width) + pScr->x = pScr->width; + escflg = 0; + SendMessage(pScr->hWnd, WM_PAINT, 0, 0); + break; + + case 'D': /* cursor backward (left) (CUB) */ + pScr->bWrapPending = FALSE; + rc.left = pScr->x * pScr->cxChar; + rc.right = (pScr->x + 1) * pScr->cxChar; + rc.top = pScr->cyChar * pScr->y; + rc.bottom = pScr->cyChar * (pScr->y + 1); + InvalidateRect(pScr->hWnd, &rc, TRUE); + if(pScr->parms[0] < 1) + pScr->x--; + else + pScr->x -= pScr->parms[0]; + ScreenRange(pScr); + escflg = 0; + SendMessage(pScr->hWnd, WM_PAINT, 0, 0); + break; + + case 'f': /* horizontal & vertical position (HVP) */ + case 'H': /* cursor position (CUP) */ + pScr->bWrapPending = FALSE; + rc.left = pScr->x * pScr->cxChar; + rc.right = (pScr->x + 1) * pScr->cxChar; + rc.top = pScr->cyChar * pScr->y; + rc.bottom = pScr->cyChar * (pScr->y + 1); + InvalidateRect(pScr->hWnd, &rc, TRUE); + pScr->x = pScr->parms[1] - 1; + pScr->y = pScr->parms[0] - 1; + ScreenRange(pScr); /* make certain the cursor position is valid */ + escflg = 0; + SendMessage(pScr->hWnd, WM_PAINT, 0, 0); + break; + + case 'J': /* erase in display (ED) */ + switch(pScr->parms[0]) { + + case -1: + case 0: /* erase from active position to end of screen */ + ScreenEraseToEndOfScreen(pScr); + break; + case 1: /* erase from start of screen to active position */ +#if 0 + ScreenEraseToPosition(pScr); +#endif + break; + + case 2: /* erase whole screen */ + ScreenEraseScreen(pScr); + break; + + default: + break; } - - pScrLine = GetScreenLineFromY(pScr, pScr->y); - if (pScrLine == NULL) - return(0); - - current = &pScrLine->text[pScr->x]; - acurrent = &pScrLine->attrib[pScr->x]; - start = current; - ocount = pScr->x; - extra = 0; - - attrib = pScr->attrib; - insert = pScr->IRM; - - for (nchars = 0; nchars < len && *c >= 32; nchars++) { - if (insert) - ScreenInsChar(pScr, 1); - - *current = *c; - *acurrent = (char) attrib; - c++; - if (pScr->x < pScr->width - 1) { - acurrent++; - current++; - pScr->x++; - } - else { - extra = 1; - if (pScr->DECAWM) { - pScr->bWrapPending = TRUE; - nchars++; - break; - } - } + + escflg = 0; + break; + + case 'K': /* erase in line (EL) */ + switch(pScr->parms[0]) { + case -1: + case 0: /* erase to end of line */ + ScreenEraseToEOL(pScr); + break; + + case 1: /* erase to beginning of line */ + ScreenEraseToBOL(pScr); + break; + + case 2: /* erase whole line */ + ScreenEraseLine(pScr, -1); + break; + + default: + break; } - - ScreenDraw(pScr, ocount, pScr->y, pScr->attrib, pScr->x - ocount + extra, start); - return(nchars); - -} /* ScreenEmChars */ - - -void ScreenEm( - LPSTR c, - int len, - SCREEN *pScr) -{ - int escflg; /* vt100 escape level */ - RECT rc; - unsigned int ic; - char stat[20]; - int i; - int nchars; - - if (pScr->screen_bottom != pScr->buffer_bottom) { - ScreenUnscroll(pScr); - InvalidateRect(pScr->hWnd, NULL, TRUE); - SetScrollPos(pScr->hWnd, SB_VERT, pScr->numlines, TRUE); + escflg = 0; + break; + + case 'L': /* insert n lines preceding current line (IL) */ + if (pScr->parms[0] < 1) + pScr->parms[0] = 1; + ScreenInsLines(pScr, pScr->parms[0], -1); + escflg = 0; + break; + + case 'M': /* delete n lines from current position downward (DL) */ + if (pScr->parms[0] < 1) + pScr->parms[0] = 1; + ScreenDelLines(pScr, pScr->parms[0], -1); + escflg = 0; + break; + + case 'P': /* delete n chars from cursor to the left (DCH) */ + if (pScr->parms[0] < 1) + pScr->parms[0] = 1; + ScreenDelChars(pScr, pScr->parms[0]); + escflg = 0; + break; + +#if 0 + case 'R': /* receive cursor position status from host */ + break; +#endif + +#if 0 + case 'c': /* device attributes (DA) */ + ScreenSendIdent(); + escflg = 0; + break; +#endif + + case 'g': /* tabulation clear (TBC) */ + if (pScr->parms[0] == 3)/* clear all tabs */ + ScreenTabClear(pScr); + else + if (pScr->parms[0] <= 0) /* clear tab stop at active position */ + pScr->tabs[pScr->x] = ' '; + escflg = 0; + break; + + case 'h': /* set mode (SM) */ + ScreenSetOption(pScr,1); + escflg = 0; + break; + + case 'i': /* toggle printer */ +#if 0 + if(pScr->parms[pScr->parmptr] == 5) + pScr->localprint = 1; + else if (pScr->parms[pScr->parmptr] == 4) + pScr->localprint = 0; +#endif + escflg = 0; + break; + + case 'l': /* reset mode (RM) */ + ScreenSetOption(pScr,0); + escflg = 0; + break; + + case 'm': /* select graphics rendition (SGR) */ + { + int temp = 0; + + while (temp <= pScr->parmptr) { + if (pScr->parms[temp] < 1) + pScr->attrib &= 128; + else + pScr->attrib |= 1 << (pScr->parms[temp] - 1); + temp++; + } } - - ScreenCursorOff(pScr); - escflg = pScr->escflg; - - #ifdef UM - if (pScr->localprint && len > 0) { /* see if printer needs anything */ - pcount = send_localprint(c, len); - len -= pcount; - c += pcount; - } - #endif - - while (len > 0) { - while((*c < 32) && (escflg == 0) && (len > 0)) { /* look at first character in the vt100 string, if it is a non-printable ascii code */ - switch(*c) { - - case 0x1b: /* ESC found (begin vt100 control sequence) */ - escflg++; - break; - - case -1: /* IAC from telnet session */ - escflg = 6; - break; - - #ifdef CISB - case 0x05: /* CTRL-E found (answerback) */ - bp_ENQ(); - break; - #endif - - case 0x07: /* CTRL-G found (bell) */ - ScreenBell(pScr); - break; - - case 0x08: /* CTRL-H found (backspace) */ - ScreenBackspace(pScr); - break; - - case 0x09: /* CTRL-I found (tab) */ - ScreenTab(pScr); /* Later change for versatile tabbing */ - break; - - case 0x0a: /* CTRL-J found (line feed) */ - case 0x0b: /* CTRL-K found (treat as line feed) */ - case 0x0c: /* CTRL-L found (treat as line feed) */ - ScreenIndex(pScr); - break; - - case 0x0d: /* CTRL-M found (carriage feed) */ - ScreenCarriageFeed(pScr); - break; - - #if 0 - case 0x0e: /* CTRL-N found (invoke Graphics (G1) character set) */ - if (pScr->G1) - pScr->attrib = VSgraph(pScr->attrib); - else - pScr->attrib = VSnotgraph(pScr->attrib); - pScr->charset = 1; - break; - - case 0x0f: /* CTRL-O found (invoke 'normal' (G0) character set) */ - if(pScr->G0) - pScr->attrib = VSgraph(pScr->attrib); - else - pScr->attrib = VSnotgraph(pScr->attrib); - pScr->charset = 0; - break; - #endif - - #ifdef CISB - case 0x10: /* CTRL-P found (undocumented in vt100) */ - bp_DLE(c, len); - len = 0; - break; - #endif - - #if 0 - case 0x11: /* CTRL-Q found (XON) (unused presently) */ - case 0x13: /* CTRL-S found (XOFF) (unused presently) */ - case 0x18: /* CTRL-X found (CAN) (unused presently) */ - case 0x1a: /* CTRL-Z found (SUB) (unused presently) */ - break; - #endif - - } /* end switch */ - - c++; /* advance to the next character in the string */ - len--; /* decrement the counter */ - - } /* end while */ - - if (escflg == 0) { /* check for normal character to print */ - nchars = ScreenEmChars(pScr, c, len); - c += nchars; - len -= nchars; - } - - while ((len > 0) && (escflg == 1)) { /* ESC character was found */ - switch(*c) { - - case 0x08: /* CTRL-H found (backspace) */ - ScreenBackspace(pScr); - break; - - case '[': /* mostly cursor movement options, and DEC private stuff following */ - ScreenApClear(pScr); - escflg = 2; - break; - - case '#': /* various screen adjustments */ - escflg = 3; - break; - - case '(': /* G0 character set options */ - escflg = 4; - break; - - case ')': /* G1 character set options */ - escflg = 5; - break; - - case '>': /* keypad numeric mode (DECKPAM) */ - pScr->DECPAM = 0; - escflg = 0; - break; - - case '=': /* keypad application mode (DECKPAM) */ - pScr->DECPAM = 1; - escflg = 0; - break; - - case '7': /* save cursor (DECSC) */ - ScreenSaveCursor(pScr); - escflg = 0; - break; - - case '8': /* restore cursor (DECRC) */ - ScreenRestoreCursor(pScr); - escflg = 0; - break; - - #if 0 - case 'c': /* reset to initial state (RIS) */ - ScreenReset(pScr); - escflg = 0; - break; - #endif - - case 'D': /* index (move down one line) (IND) */ - ScreenIndex(pScr); - escflg = 0; - break; - - case 'E': /* next line (move down one line and to first column) (NEL) */ - pScr->x = 0; - ScreenIndex(pScr); - escflg = 0; - break; - - case 'H': /* horizontal tab set (HTS) */ - pScr->tabs[pScr->x] = 'x'; - escflg = 0; - break; - - #ifdef CISB - case 'I': /* undoumented in vt100 */ - bp_ESC_I(); - break; - #endif - - case 'M': /* reverse index (move up one line) (RI) */ - ScreenRevIndex(pScr); - escflg = 0; - break; - - case 'Z': /* identify terminal (DECID) */ - escflg = 0; - break; - - default: - ScreenEmChars(pScr, "\033", 1); /* put the ESC character into the Screen */ - ScreenEmChars(pScr, c, 1); /* put the next character into the Screen */ - escflg = 0; - break; - - } /* end switch */ - - c++; - len--; - } - - while((escflg == 2) && (len > 0)) { /* '[' handling */ - switch(*c) { - - case 0x08: /* backspace */ - ScreenBackspace(pScr); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': /* numeric parameters */ - if (pScr->parms[pScr->parmptr] < 0) - pScr->parms[pScr->parmptr] = 0; - pScr->parms[pScr->parmptr] *= 10; - pScr->parms[pScr->parmptr] += *c - '0'; - break; - - case '?': /* vt100 mode change */ - pScr->parms[pScr->parmptr++] = -2; - break; - - case ';': /* parameter divider */ - pScr->parmptr++; - break; - - case 'A': /* cursor up (CUU) */ - pScr->bWrapPending = FALSE; - rc.left = pScr->x * pScr->cxChar; - rc.right = (pScr->x + 1) * pScr->cxChar; - rc.top = pScr->cyChar * pScr->y; - rc.bottom = pScr->cyChar * (pScr->y + 1); - InvalidateRect(pScr->hWnd, &rc, TRUE); - if (pScr->parms[0] < 1) - pScr->y--; - else - pScr->y -= pScr->parms[0]; - if(pScr->y < pScr->top) - pScr->y = pScr->top; - ScreenRange(pScr); - escflg = 0; - SendMessage(pScr->hWnd, WM_PAINT, NULL, NULL); - break; - - case 'B': /* cursor down (CUD) */ - pScr->bWrapPending = FALSE; - rc.left = pScr->x * pScr->cxChar; - rc.right = (pScr->x + 1) * pScr->cxChar; - rc.top = pScr->cyChar * pScr->y; - rc.bottom = pScr->cyChar * (pScr->y + 1); - InvalidateRect(pScr->hWnd, &rc, TRUE); - if (pScr->parms[0] < 1) - pScr->y++; - else - pScr->y += pScr->parms[0]; - if (pScr->y > pScr->bottom) - pScr->y = pScr->bottom; - ScreenRange(pScr); - escflg = 0; - SendMessage(pScr->hWnd, WM_PAINT, NULL, NULL); - break; - - case 'C': /* cursor forward (right) (CUF) */ - pScr->bWrapPending = FALSE; - rc.left = pScr->x * pScr->cxChar; - rc.right = (pScr->x + 1) * pScr->cxChar; - rc.top = pScr->cyChar * pScr->y; - rc.bottom = pScr->cyChar * (pScr->y +1); - InvalidateRect(pScr->hWnd, &rc, TRUE); - if(pScr->parms[0] < 1) - pScr->x++; - else - pScr->x += pScr->parms[0]; - ScreenRange(pScr); - if (pScr->x > pScr->width) - pScr->x = pScr->width; - escflg = 0; - SendMessage(pScr->hWnd, WM_PAINT, NULL, NULL); - break; - - case 'D': /* cursor backward (left) (CUB) */ - pScr->bWrapPending = FALSE; - rc.left = pScr->x * pScr->cxChar; - rc.right = (pScr->x + 1) * pScr->cxChar; - rc.top = pScr->cyChar * pScr->y; - rc.bottom = pScr->cyChar * (pScr->y + 1); - InvalidateRect(pScr->hWnd, &rc, TRUE); - if(pScr->parms[0] < 1) - pScr->x--; - else - pScr->x -= pScr->parms[0]; - ScreenRange(pScr); - escflg = 0; - SendMessage(pScr->hWnd, WM_PAINT, NULL, NULL); - break; - - case 'f': /* horizontal & vertical position (HVP) */ - case 'H': /* cursor position (CUP) */ - pScr->bWrapPending = FALSE; - rc.left = pScr->x * pScr->cxChar; - rc.right = (pScr->x + 1) * pScr->cxChar; - rc.top = pScr->cyChar * pScr->y; - rc.bottom = pScr->cyChar * (pScr->y + 1); - InvalidateRect(pScr->hWnd, &rc, TRUE); - pScr->x = pScr->parms[1] - 1; - pScr->y = pScr->parms[0] - 1; - ScreenRange(pScr); /* make certain the cursor position is valid */ - escflg = 0; - SendMessage(pScr->hWnd, WM_PAINT, NULL, NULL); - break; - - case 'J': /* erase in display (ED) */ - switch(pScr->parms[0]) { - - case -1: - case 0: /* erase from active position to end of screen */ - ScreenEraseToEndOfScreen(pScr); - break; - case 1: /* erase from start of screen to active position */ - #if 0 - ScreenEraseToPosition(pScr); - #endif - break; - - case 2: /* erase whole screen */ - ScreenEraseScreen(pScr); - break; - - default: - break; - } - - escflg = 0; - break; - - case 'K': /* erase in line (EL) */ - switch(pScr->parms[0]) { - case -1: - case 0: /* erase to end of line */ - ScreenEraseToEOL(pScr); - break; - - case 1: /* erase to beginning of line */ - ScreenEraseToBOL(pScr); - break; - - case 2: /* erase whole line */ - ScreenEraseLine(pScr, -1); - break; - - default: - break; - } - - escflg = 0; - break; - - case 'L': /* insert n lines preceding current line (IL) */ - if (pScr->parms[0] < 1) - pScr->parms[0] = 1; - ScreenInsLines(pScr, pScr->parms[0], -1); - escflg = 0; - break; - - case 'M': /* delete n lines from current position downward (DL) */ - if (pScr->parms[0] < 1) - pScr->parms[0] = 1; - ScreenDelLines(pScr, pScr->parms[0], -1); - escflg = 0; - break; - - case 'P': /* delete n chars from cursor to the left (DCH) */ - if (pScr->parms[0] < 1) - pScr->parms[0] = 1; - ScreenDelChars(pScr, pScr->parms[0]); - escflg = 0; - break; - - #if 0 - case 'R': /* receive cursor position status from host */ - break; - #endif - - #if 0 - case 'c': /* device attributes (DA) */ - ScreenSendIdent(); - escflg = 0; - break; - #endif - - case 'g': /* tabulation clear (TBC) */ - if (pScr->parms[0] == 3)/* clear all tabs */ - ScreenTabClear(pScr); - else - if (pScr->parms[0] <= 0) /* clear tab stop at active position */ - pScr->tabs[pScr->x] = ' '; - escflg = 0; - break; - - case 'h': /* set mode (SM) */ - ScreenSetOption(pScr,1); - escflg = 0; - break; - - case 'i': /* toggle printer */ - #if 0 - if(pScr->parms[pScr->parmptr] == 5) - pScr->localprint = 1; - else if (pScr->parms[pScr->parmptr] == 4) - pScr->localprint = 0; - #endif - escflg = 0; - break; - - case 'l': /* reset mode (RM) */ - ScreenSetOption(pScr,0); - escflg = 0; - break; - - case 'm': /* select graphics rendition (SGR) */ - { - int temp = 0; - - while (temp <= pScr->parmptr) { - if (pScr->parms[temp] < 1) - pScr->attrib &= 128; - else - pScr->attrib |= 1 << (pScr->parms[temp] - 1); - temp++; - } - } - escflg = 0; - break; - - case 'n': /* device status report (DSR) */ - switch (pScr->parms[0]) { - #if 0 - case 0: /* response from vt100; ready, no malfunctions */ - case 3: /* response from vt100; malfunction, retry */ - #endif - case 5: /* send status */ - case 6: /* send active position */ - wsprintf(stat, "\033[%d;%dR", pScr->y + 1, pScr->x + 1); - for (i = 0; stat[i]; i++) - SendMessage(pScr->hwndTel, WM_MYSCREENCHAR, stat[i], (LPARAM) pScr); - break; - } /* end switch */ - escflg = 0; - break; - - case 'q': /* load LEDs (unsupported) (DECLL) */ - escflg = 0; - break; - - case 'r': /* set top & bottom margins (DECSTBM) */ - if (pScr->parms[0] < 0) - pScr->top = 0; - else - pScr->top = pScr->parms[0] - 1; - if (pScr->parms[1] < 0) - pScr->bottom = pScr->height - 1; - else - pScr->bottom = pScr->parms[1] - 1; - if (pScr->top < 0) - pScr->top = 0; - if (pScr->top > pScr->height-1) - pScr->top = pScr->height-1; - if (pScr->bottom < 1) - pScr->bottom = pScr->height; - if (pScr->bottom >= pScr->height) - pScr->bottom = pScr->height - 1; - if (pScr->top >= pScr->bottom) {/* check for valid scrolling region */ - if (pScr->bottom >= 1) /* assume the bottom value has precedence, unless it is as the top of the screen */ - pScr->top = pScr->bottom - 1; - else /* totally psychotic case, bottom of screen set to the very top line, move the bottom to below the top */ - pScr->bottom = pScr->top + 1; - } - pScr->x = 0; - pScr->y = 0; - #if 0 - if (pScr->DECORG) - pScr->y = pScr->top; /* origin mode relative */ - #endif - escflg = 0; - break; - - #if 0 - case 'x': /* request/report terminal parameters (DECREQTPARM/DECREPTPARM) */ - case 'y': /* invoke confidence test (DECTST) */ - break; - #endif - - default: - escflg = 0; - break; - - } - - c++; - len--; - - #if 0 - if (pScr->localprint && (len > 0)) { /* see if printer needs anything */ - pcount = send_localprint(c, len); - len -= pcount; - c += pcount; - } - #endif - } - - while ((escflg == 3) && (len > 0)) { /* # Handling */ - switch (*c) { - case 0x08: /* backspace */ - ScreenBackspace(pScr); - break; - - #if 0 - case '3': /* top half of double line (DECDHL) */ - case '4': /* bottom half of double line (DECDHL) */ - case '5': /* single width line (DECSWL) */ - case '6': /* double width line (DECDWL) */ - break; - #endif - - case '8': /* screen alignment display (DECALN) */ - ScreenAlign(pScr); - escflg = 0; - break; - - default: - escflg = 0; - break; - - } - - c++; - len--; - } - - while ((escflg == 4) && (len > 0)) { /* ( Handling (GO character set) */ - switch (*c) { - - case 0x08: /* backspace */ - ScreenBackspace(pScr); - break; - - #if 0 - case 'A': /* united kingdom character set (unsupported) */ - case 'B': /* ASCII character set */ - case '1': /* choose standard graphics (same as ASCII) */ - pScr->G0 = 0; - if (!pScr->charset) - pScr->attrib = ScreenNotGraph(pScr->attrib); - escflg = 0; - break; - - case '0': /* choose special graphics set */ - case '2': /* alternate character set (special graphics) */ - pScr->G0 = 1; - if(!pScr->charset) - pScr->attrib = ScreenGraph(pScr->attrib); - escflg = 0; - break; - #endif - - default: - escflg = 0; - break; - } - - c++; - len--; - - } /* end while */ - - while((escflg == 5) && (len > 0)) { /* ) Handling (G1 handling) */ - switch (*c) { - - case 0x08: /* backspace */ - ScreenBackspace(pScr); - break; - - #if 0 - case 'A': /* united kingdom character set (unsupported) */ - case 'B': /* ASCII character set */ - case '1': /* choose standard graphics (same as ASCII) */ - pScr->G1 = 0; - if (pScr->charset) - pScr->attrib = ScreenNotGraph(pScr->attrib); - escflg = 0; - break; - - case '0': /* choose special graphics set */ - case '2': /* alternate character set (special graphics) */ - pScr->G1 = 1; - if(pScr->charset) - pScr->attrib = ScreenGraph(pScr->attrib); - escflg = 0; - break; - #endif - - default: - escflg = 0; - break; - } /* end switch */ - - c++; - len--; - } /* end while */ - - while ((escflg >= 6) && (escflg <= 10) && (len > 0)) { /* Handling IAC */ - ic = (unsigned char) *c; - switch (escflg) { - - case 6: /* Handling IAC xx */ - if (ic == 255) /* if IAC */ - escflg = 0; - else if (ic == 250) /* if SB */ - escflg = 7; - else - escflg = 9; - break; - - case 7: /* Handling IAC SB xx */ - if (ic == 255) /* if IAC */ - escflg = 8; - break; - - case 8: /* Handling IAC SB IAC xx */ - if (ic == 255) /* if IAC IAC */ - escflg = 7; - else if (ic == 240) /* if IAC SE */ - escflg = 0; - break; - - case 9: /* IAC xx xx */ - escflg = 0; - break; - } - c++; /* advance to the next character in the string */ - len--; /* decrement the counter */ - } - - if (escflg > 2 && escflg < 6 && len > 0) { - escflg = 0; - c++; - len--; - } + escflg = 0; + break; + + case 'n': /* device status report (DSR) */ + switch (pScr->parms[0]) { +#if 0 + case 0: /* response from vt100; ready, no malfunctions */ + case 3: /* response from vt100; malfunction, retry */ +#endif + case 5: /* send status */ + case 6: /* send active position */ + wsprintf(stat, "\033[%d;%dR", pScr->y + 1, pScr->x + 1); + for (i = 0; stat[i]; i++) + SendMessage(pScr->hwndTel, WM_MYSCREENCHAR, + stat[i], (LPARAM) pScr); + break; + } /* end switch */ + escflg = 0; + break; + + case 'q': /* load LEDs (unsupported) (DECLL) */ + escflg = 0; + break; + + case 'r': /* set top & bottom margins (DECSTBM) */ + if (pScr->parms[0] < 0) + pScr->top = 0; + else + pScr->top = pScr->parms[0] - 1; + if (pScr->parms[1] < 0) + pScr->bottom = pScr->height - 1; + else + pScr->bottom = pScr->parms[1] - 1; + if (pScr->top < 0) + pScr->top = 0; + if (pScr->top > pScr->height-1) + pScr->top = pScr->height-1; + if (pScr->bottom < 1) + pScr->bottom = pScr->height; + if (pScr->bottom >= pScr->height) + pScr->bottom = pScr->height - 1; + if (pScr->top >= pScr->bottom) {/* check for valid scrolling region */ + if (pScr->bottom >= 1) /* + * assume the bottom value has + * precedence, unless it is as the + * top of the screen + */ + pScr->top = pScr->bottom - 1; + else /* totally psychotic case, bottom of screen set to the very top line, move the bottom to below the top */ + pScr->bottom = pScr->top + 1; } - pScr->escflg = escflg; - ScreenCursorOn(pScr); - -} /* ScreenEm */ + pScr->x = 0; + pScr->y = 0; +#if 0 + if (pScr->DECORG) + pScr->y = pScr->top; /* origin mode relative */ +#endif + escflg = 0; + break; + +#if 0 + case 'x': /* request/report terminal parameters + (DECREQTPARM/DECREPTPARM) */ + case 'y': /* invoke confidence test (DECTST) */ + break; +#endif + + default: + escflg = 0; + break; + + } + + c++; + len--; + +#if 0 + if (pScr->localprint && (len > 0)) { /* see if printer needs anything */ + pcount = send_localprint(c, len); + len -= pcount; + c += pcount; + } +#endif + } + + while ((escflg == 3) && (len > 0)) { /* # Handling */ + switch (*c) { + case 0x08: /* backspace */ + ScreenBackspace(pScr); + break; + +#if 0 + case '3': /* top half of double line (DECDHL) */ + case '4': /* bottom half of double line (DECDHL) */ + case '5': /* single width line (DECSWL) */ + case '6': /* double width line (DECDWL) */ + break; +#endif + + case '8': /* screen alignment display (DECALN) */ + ScreenAlign(pScr); + escflg = 0; + break; + + default: + escflg = 0; + break; + + } + + c++; + len--; + } + + while ((escflg == 4) && (len > 0)) { /* ( Handling (GO character set) */ + switch (*c) { + + case 0x08: /* backspace */ + ScreenBackspace(pScr); + break; + +#if 0 + case 'A': /* united kingdom character set (unsupported) */ + case 'B': /* ASCII character set */ + case '1': /* choose standard graphics (same as ASCII) */ + pScr->G0 = 0; + if (!pScr->charset) + pScr->attrib = ScreenNotGraph(pScr->attrib); + escflg = 0; + break; + + case '0': /* choose special graphics set */ + case '2': /* alternate character set (special graphics) */ + pScr->G0 = 1; + if(!pScr->charset) + pScr->attrib = ScreenGraph(pScr->attrib); + escflg = 0; + break; +#endif + + default: + escflg = 0; + break; + } + + c++; + len--; + + } /* end while */ + + while((escflg == 5) && (len > 0)) { /* ) Handling (G1 handling) */ + switch (*c) { + + case 0x08: /* backspace */ + ScreenBackspace(pScr); + break; + +#if 0 + case 'A': /* united kingdom character set (unsupported) */ + case 'B': /* ASCII character set */ + case '1': /* choose standard graphics (same as ASCII) */ + pScr->G1 = 0; + if (pScr->charset) + pScr->attrib = ScreenNotGraph(pScr->attrib); + escflg = 0; + break; + + case '0': /* choose special graphics set */ + case '2': /* alternate character set (special graphics) */ + pScr->G1 = 1; + if(pScr->charset) + pScr->attrib = ScreenGraph(pScr->attrib); + escflg = 0; + break; +#endif + + default: + escflg = 0; + break; + } /* end switch */ + + c++; + len--; + } /* end while */ + + while ((escflg >= 6) && (escflg <= 10) && (len > 0)) { /* Handling IAC */ + ic = (unsigned char) *c; + switch (escflg) { + + case 6: /* Handling IAC xx */ + if (ic == 255) /* if IAC */ + escflg = 0; + else if (ic == 250) /* if SB */ + escflg = 7; + else + escflg = 9; + break; + + case 7: /* Handling IAC SB xx */ + if (ic == 255) /* if IAC */ + escflg = 8; + break; + + case 8: /* Handling IAC SB IAC xx */ + if (ic == 255) /* if IAC IAC */ + escflg = 7; + else if (ic == 240) /* if IAC SE */ + escflg = 0; + break; + + case 9: /* IAC xx xx */ + escflg = 0; + break; + } + c++; /* advance to the next character in the string */ + len--; /* decrement the counter */ + } + + if (escflg > 2 && escflg < 6 && len > 0) { + escflg = 0; + c++; + len--; + } + } + pScr->escflg = escflg; + ScreenCursorOn(pScr); +} diff --git a/src/windows/wintel/enc_des.c b/src/windows/wintel/enc_des.c new file mode 100644 index 0000000000..8357dba7c1 --- /dev/null +++ b/src/windows/wintel/enc_des.c @@ -0,0 +1,725 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* based on @(#)enc_des.c 8.1 (Berkeley) 6/4/93 */ + +#ifdef ENCRYPTION + +#include "telnet_arpa.h" +#include <stdio.h> +#include <stdlib.h> + +#include "telnet.h" + +#include "encrypt.h" + +#define CFB 0 +#define OFB 1 + +#define NO_SEND_IV 1 +#define NO_RECV_IV 2 +#define NO_KEYID 4 +#define IN_PROGRESS (NO_SEND_IV|NO_RECV_IV|NO_KEYID) +#define SUCCESS 0 +#define xFAILED -1 + + +struct fb { + Block krbdes_key; + Schedule krbdes_sched; + Block temp_feed; + unsigned char fb_feed[64]; + int need_start; + int state[2]; + int keyid[2]; + int once; + struct stinfo { + Block str_output; + Block str_feed; + Block str_iv; + Block str_ikey; + Schedule str_sched; + int str_index; + int str_flagshift; + } streams[2]; +}; + +static struct fb fb[2]; + +struct keyidlist { + char *keyid; + int keyidlen; + char *key; + int keylen; + int flags; +} keyidlist [] = { + { "\0", 1, 0, 0, 0 }, /* default key of zero */ + { 0, 0, 0, 0, 0 } +}; + +#define KEYFLAG_MASK 03 + +#define KEYFLAG_NOINIT 00 +#define KEYFLAG_INIT 01 +#define KEYFLAG_OK 02 +#define KEYFLAG_BAD 03 + +#define KEYFLAG_SHIFT 2 + +#define SHIFT_VAL(a,b) (KEYFLAG_SHIFT*((a)+((b)*2))) + +#define FB64_IV 1 +#define FB64_IV_OK 2 +#define FB64_IV_BAD 3 + +extern kstream EncryptKSGlobalHack; + +void fb64_stream_iv P((Block, struct stinfo *)); +void fb64_init P((struct fb *)); +static int fb64_start P((struct fb *, int, int)); +int fb64_is P((unsigned char *, int, struct fb *)); +int fb64_reply P((unsigned char *, int, struct fb *)); +static void fb64_session P((Session_Key *, int, struct fb *)); +void fb64_stream_key P((Block, struct stinfo *)); +int fb64_keyid P((int, unsigned char *, int *, struct fb *)); + + void +cfb64_init(server) + int server; +{ + fb64_init(&fb[CFB]); + fb[CFB].fb_feed[4] = ENCTYPE_DES_CFB64; + fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, CFB); + fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, CFB); +} + + void +ofb64_init(server) + int server; +{ + fb64_init(&fb[OFB]); + fb[OFB].fb_feed[4] = ENCTYPE_DES_OFB64; + fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, OFB); + fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, OFB); +} + + void +fb64_init(fbp) + register struct fb *fbp; +{ + memset((void *)fbp, 0, sizeof(*fbp)); + fbp->state[0] = fbp->state[1] = xFAILED; + fbp->fb_feed[0] = IAC; + fbp->fb_feed[1] = SB; + fbp->fb_feed[2] = TELOPT_ENCRYPT; + fbp->fb_feed[3] = ENCRYPT_IS; +} + +/* + * Returns: + * -1: some error. Negotiation is done, encryption not ready. + * 0: Successful, initial negotiation all done. + * 1: successful, negotiation not done yet. + * 2: Not yet. Other things (like getting the key from + * Kerberos) have to happen before we can continue. + */ + int +cfb64_start(dir, server) + int dir; + int server; +{ + return(fb64_start(&fb[CFB], dir, server)); +} + int +ofb64_start(dir, server) + int dir; + int server; +{ + return(fb64_start(&fb[OFB], dir, server)); +} + + static int +fb64_start(fbp, dir, server) + struct fb *fbp; + int dir; + int server; +{ + int x; + unsigned char *p; + register int state; + + switch (dir) { + case DIR_DECRYPT: + /* + * This is simply a request to have the other side + * start output (our input). He will negotiate an + * IV so we need not look for it. + */ + state = fbp->state[dir-1]; + if (state == xFAILED) + state = IN_PROGRESS; + break; + + case DIR_ENCRYPT: + state = fbp->state[dir-1]; + if (state == xFAILED) + state = IN_PROGRESS; + else if ((state & NO_SEND_IV) == 0) + break; + + if (!VALIDKEY(fbp->krbdes_key)) { + fbp->need_start = 1; + break; + } + state &= ~NO_SEND_IV; + state |= NO_RECV_IV; + /* + * Create a random feed and send it over. + */ + des_new_random_key(fbp->temp_feed); + des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed, + fbp->krbdes_sched, 1); + p = fbp->fb_feed + 3; + *p++ = ENCRYPT_IS; + p++; + *p++ = FB64_IV; + for (x = 0; x < sizeof(Block); ++x) { + if ((*p++ = fbp->temp_feed[x]) == IAC) + *p++ = IAC; + } + *p++ = IAC; + *p++ = SE; +#ifdef DEBUG + printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); +#endif + TelnetSend(EncryptKSGlobalHack, fbp->fb_feed, p - fbp->fb_feed, 0); + break; + default: + return(xFAILED); + } + return(fbp->state[dir-1] = state); +} + +/* + * Returns: + * -1: some error. Negotiation is done, encryption not ready. + * 0: Successful, initial negotiation all done. + * 1: successful, negotiation not done yet. + */ + int +cfb64_is(data, cnt) + unsigned char *data; + int cnt; +{ + return(fb64_is(data, cnt, &fb[CFB])); +} + int +ofb64_is(data, cnt) + unsigned char *data; + int cnt; +{ + return(fb64_is(data, cnt, &fb[OFB])); +} + + int +fb64_is(data, cnt, fbp) + unsigned char *data; + int cnt; + struct fb *fbp; +{ + unsigned char *p; + register int state = fbp->state[DIR_DECRYPT-1]; + + if (cnt-- < 1) + goto failure; + + switch (*data++) { + case FB64_IV: + if (cnt != sizeof(Block)) { +#ifdef DEBUG + if (encrypt_debug_mode) + printf("CFB64: initial vector failed on size\r\n"); +#endif + state = xFAILED; + goto failure; + } + +#ifdef DEBUG + if (encrypt_debug_mode) { + printf("CFB64: initial vector received\r\n"); + printf("Initializing Decrypt stream\r\n"); + } +#endif + fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]); + + p = fbp->fb_feed + 3; + *p++ = ENCRYPT_REPLY; + p++; + *p++ = FB64_IV_OK; + *p++ = IAC; + *p++ = SE; +#ifdef DEBUG + printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); +#endif + TelnetSend(EncryptKSGlobalHack, fbp->fb_feed, p - fbp->fb_feed, 0); + + state = fbp->state[DIR_DECRYPT-1] = IN_PROGRESS; + break; + + default: +#if 0 + if (encrypt_debug_mode) { + printf("Unknown option type: %d\r\n", *(data-1)); + printd(data, cnt); + printf("\r\n"); + } +#endif + /* FALL THROUGH */ + failure: + /* + * We failed. Send an FB64_IV_BAD option + * to the other side so it will know that + * things failed. + */ + p = fbp->fb_feed + 3; + *p++ = ENCRYPT_REPLY; + p++; + *p++ = FB64_IV_BAD; + *p++ = IAC; + *p++ = SE; +#ifdef DEBUG + printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); +#endif + TelnetSend(EncryptKSGlobalHack, fbp->fb_feed, p - fbp->fb_feed, 0); + + break; + } + return(fbp->state[DIR_DECRYPT-1] = state); +} + +/* + * Returns: + * -1: some error. Negotiation is done, encryption not ready. + * 0: Successful, initial negotiation all done. + * 1: successful, negotiation not done yet. + */ + int +cfb64_reply(data, cnt) + unsigned char *data; + int cnt; +{ + return(fb64_reply(data, cnt, &fb[CFB])); +} + int +ofb64_reply(data, cnt) + unsigned char *data; + int cnt; +{ + return(fb64_reply(data, cnt, &fb[OFB])); +} + + + int +fb64_reply(data, cnt, fbp) + unsigned char *data; + int cnt; + struct fb *fbp; +{ + register int state = fbp->state[DIR_ENCRYPT-1]; + + if (cnt-- < 1) + goto failure; + + switch (*data++) { + case FB64_IV_OK: + fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]); + if (state == xFAILED) + state = IN_PROGRESS; + state &= ~NO_RECV_IV; + encrypt_send_keyid(DIR_ENCRYPT, (unsigned char *)"\0", 1, 1); + break; + + case FB64_IV_BAD: + memset(fbp->temp_feed, 0, sizeof(Block)); + fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]); + state = xFAILED; + break; + + default: +#if 0 + if (encrypt_debug_mode) { + printf("Unknown option type: %d\r\n", data[-1]); + printd(data, cnt); + printf("\r\n"); + } +#endif + /* FALL THROUGH */ + failure: + state = xFAILED; + break; + } + return(fbp->state[DIR_ENCRYPT-1] = state); +} + + void +cfb64_session(key, server) + Session_Key *key; + int server; +{ + fb64_session(key, server, &fb[CFB]); +} + + void +ofb64_session(key, server) + Session_Key *key; + int server; +{ + fb64_session(key, server, &fb[OFB]); +} + + static void +fb64_session(key, server, fbp) + Session_Key *key; + int server; + struct fb *fbp; +{ + + if (!key || key->type != SK_DES) { +#ifdef DEBUG + if (encrypt_debug_mode) + printf("Can't set krbdes's session key (%d != %d)\r\n", + key ? key->type : -1, SK_DES); +#endif + return; + } + memcpy((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block)); + + fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_ENCRYPT-1]); + fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_DECRYPT-1]); + + if (fbp->once == 0) { + des_set_random_generator_seed(fbp->krbdes_key); + fbp->once = 1; + } + des_key_sched(fbp->krbdes_key, fbp->krbdes_sched); + /* + * Now look to see if krbdes_start() was was waiting for + * the key to show up. If so, go ahead an call it now + * that we have the key. + */ + if (fbp->need_start) { + fbp->need_start = 0; + fb64_start(fbp, DIR_ENCRYPT, server); + } +} + +/* + * We only accept a keyid of 0. If we get a keyid of + * 0, then mark the state as SUCCESS. + */ + int +cfb64_keyid(dir, kp, lenp) + int dir, *lenp; + unsigned char *kp; +{ + return(fb64_keyid(dir, kp, lenp, &fb[CFB])); +} + + int +ofb64_keyid(dir, kp, lenp) + int dir, *lenp; + unsigned char *kp; +{ + return(fb64_keyid(dir, kp, lenp, &fb[OFB])); +} + + int +fb64_keyid(dir, kp, lenp, fbp) + int dir, *lenp; + unsigned char *kp; + struct fb *fbp; +{ + register int state = fbp->state[dir-1]; + + if (*lenp != 1 || (*kp != '\0')) { + *lenp = 0; + return(state); + } + + if (state == xFAILED) + state = IN_PROGRESS; + + state &= ~NO_KEYID; + + return(fbp->state[dir-1] = state); +} + +#if 0 + void +fb64_printsub(data, cnt, buf, buflen, type) + unsigned char *data, *buf, *type; + int cnt, buflen; +{ + char lbuf[32]; + register int i; + char *cp; + + buf[buflen-1] = '\0'; /* make sure it's NULL terminated */ + buflen -= 1; + + switch(data[2]) { + case FB64_IV: + sprintf(lbuf, "%s_IV", type); + cp = lbuf; + goto common; + + case FB64_IV_OK: + sprintf(lbuf, "%s_IV_OK", type); + cp = lbuf; + goto common; + + case FB64_IV_BAD: + sprintf(lbuf, "%s_IV_BAD", type); + cp = lbuf; + goto common; + + default: + sprintf(lbuf, " %d (unknown)", data[2]); + cp = lbuf; + common: + for (; (buflen > 0) && (*buf = *cp++); buf++) + buflen--; + for (i = 3; i < cnt; i++) { + sprintf(lbuf, " %d", data[i]); + for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++) + buflen--; + } + break; + } +} + + void +cfb64_printsub(data, cnt, buf, buflen) + unsigned char *data, *buf; + int cnt, buflen; +{ + fb64_printsub(data, cnt, buf, buflen, "CFB64"); +} + + void +ofb64_printsub(data, cnt, buf, buflen) + unsigned char *data, *buf; + int cnt, buflen; +{ + fb64_printsub(data, cnt, buf, buflen, "OFB64"); +} +#endif + + void +fb64_stream_iv(seed, stp) + Block seed; + register struct stinfo *stp; +{ + + memcpy((void *)stp->str_iv, (void *)seed, sizeof(Block)); + memcpy((void *)stp->str_output, (void *)seed, sizeof(Block)); + + des_key_sched(stp->str_ikey, stp->str_sched); + + stp->str_index = sizeof(Block); +} + + void +fb64_stream_key(key, stp) + Block key; + register struct stinfo *stp; +{ + memcpy((void *)stp->str_ikey, (void *)key, sizeof(Block)); + des_key_sched(key, stp->str_sched); + + memcpy((void *)stp->str_output, (void *)stp->str_iv, sizeof(Block)); + + stp->str_index = sizeof(Block); +} + +/* + * DES 64 bit Cipher Feedback + * + * key --->+-----+ + * +->| DES |--+ + * | +-----+ | + * | v + * INPUT --(--------->(+)+---> DATA + * | | + * +-------------+ + * + * + * Given: + * iV: Initial vector, 64 bits (8 bytes) long. + * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt). + * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output. + * + * V0 = DES(iV, key) + * On = Dn ^ Vn + * V(n+1) = DES(On, key) + */ + + void +cfb64_encrypt(s, c) + register unsigned char *s; + int c; +{ + register struct stinfo *stp = &fb[CFB].streams[DIR_ENCRYPT-1]; + register int index; + + index = stp->str_index; + while (c-- > 0) { + if (index == sizeof(Block)) { + Block b; + des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1); + memcpy((void *)stp->str_feed,(void *)b,sizeof(Block)); + index = 0; + } + + /* On encryption, we store (feed ^ data) which is cypher */ + *s = stp->str_output[index] = (stp->str_feed[index] ^ *s); + s++; + index++; + } + stp->str_index = index; +} + + int +cfb64_decrypt(data) + int data; +{ + register struct stinfo *stp = &fb[CFB].streams[DIR_DECRYPT-1]; + int index; + + if (data == -1) { + /* + * Back up one byte. It is assumed that we will + * never back up more than one byte. If we do, this + * may or may not work. + */ + if (stp->str_index) + --stp->str_index; + return(0); + } + + index = stp->str_index++; + if (index == sizeof(Block)) { + Block b; + des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1); + memcpy((void *)stp->str_feed, (void *)b, sizeof(Block)); + stp->str_index = 1; /* Next time will be 1 */ + index = 0; /* But now use 0 */ + } + + /* On decryption we store (data) which is cypher. */ + stp->str_output[index] = data; + return(data ^ stp->str_feed[index]); +} + +/* + * DES 64 bit Output Feedback + * + * key --->+-----+ + * +->| DES |--+ + * | +-----+ | + * +-----------+ + * v + * INPUT -------->(+) ----> DATA + * + * Given: + * iV: Initial vector, 64 bits (8 bytes) long. + * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt). + * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output. + * + * V0 = DES(iV, key) + * V(n+1) = DES(Vn, key) + * On = Dn ^ Vn + */ + void +ofb64_encrypt(s, c) + register unsigned char *s; + int c; +{ + register struct stinfo *stp = &fb[OFB].streams[DIR_ENCRYPT-1]; + register int index; + + index = stp->str_index; + while (c-- > 0) { + if (index == sizeof(Block)) { + Block b; + des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1); + memcpy((void *)stp->str_feed,(void *)b,sizeof(Block)); + index = 0; + } + *s++ ^= stp->str_feed[index]; + index++; + } + stp->str_index = index; +} + + int +ofb64_decrypt(data) + int data; +{ + register struct stinfo *stp = &fb[OFB].streams[DIR_DECRYPT-1]; + int index; + + if (data == -1) { + /* + * Back up one byte. It is assumed that we will + * never back up more than one byte. If we do, this + * may or may not work. + */ + if (stp->str_index) + --stp->str_index; + return(0); + } + + index = stp->str_index++; + if (index == sizeof(Block)) { + Block b; + des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1); + memcpy((void *)stp->str_feed, (void *)b, sizeof(Block)); + stp->str_index = 1; /* Next time will be 1 */ + index = 0; /* But now use 0 */ + } + + return(data ^ stp->str_feed[index]); +} + +#endif /* ENCRYPTION */ diff --git a/src/windows/wintel/enc_des.h b/src/windows/wintel/enc_des.h new file mode 100644 index 0000000000..996a4f5d06 --- /dev/null +++ b/src/windows/wintel/enc_des.h @@ -0,0 +1,126 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)enc-proto.h 8.1 (Berkeley) 6/4/93 + */ + +/* + * Copyright (C) 1990 by the Massachusetts Institute of Technology + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ +#if !defined(P) +#ifdef __STDC__ +#define P(x) x +#else +#define P(x) () +#endif +#endif + +#ifdef ENCRYPTION +void encrypt_init P((char *, int)); +Encryptions *findencryption P((int)); +void encrypt_send_supprt P((void)); +void encrypt_auto P((int)); +void decrypt_auto P((int)); +void encrypt_is P((unsigned char *, int)); +void encrypt_reply P((unsigned char *, int)); +void encrypt_start_input P((int)); +void encrypt_session_key P((Session_Key *, int)); +void encrypt_end_input P((void)); +void encrypt_start_output P((int)); +void encrypt_end_output P((void)); +void encrypt_send_request_start P((void)); +void encrypt_send_request_end P((void)); +void encrypt_send_end P((void)); +void encrypt_wait P((void)); +int encrypt_is_encrypting P((void)); +void encrypt_send_support P((void)); +void encrypt_send_keyid P((int, unsigned char *, int, int)); +int net_write P((unsigned char *, int)); + +#ifdef TELENTD +void encrypt_wait P((void)); +#else +int encrypt_cmd P((int, char **)); +void encrypt_display P((void)); +#endif + +void krbdes_encrypt P((unsigned char *, int)); +int krbdes_decrypt P((int)); +int krbdes_is P((unsigned char *, int)); +int krbdes_reply P((unsigned char *, int)); +void krbdes_init P((int)); +int krbdes_start P((int, int)); +void krbdes_session P((Session_Key *, int)); +void krbdes_printsub P((unsigned char *, int, unsigned char *, int)); + +void cfb64_encrypt P((unsigned char *, int)); +int cfb64_decrypt P((int)); +void cfb64_init P((int)); +int cfb64_start P((int, int)); +int cfb64_is P((unsigned char *, int)); +int cfb64_reply P((unsigned char *, int)); +void cfb64_session P((Session_Key *, int)); +int cfb64_keyid P((int, unsigned char *, int *)); +void cfb64_printsub P((unsigned char *, int, unsigned char *, int)); + +void ofb64_encrypt P((unsigned char *, int)); +int ofb64_decrypt P((int)); +void ofb64_init P((int)); +int ofb64_start P((int, int)); +int ofb64_is P((unsigned char *, int)); +int ofb64_reply P((unsigned char *, int)); +void ofb64_session P((Session_Key *, int)); +int ofb64_keyid P((int, unsigned char *, int *)); +void ofb64_printsub P((unsigned char *, int, unsigned char *, int)); + +int des_new_random_key P((Block)); +void des_set_random_generator_seed P((Block)); +void des_key_sched P((Block, Schedule)); +void des_ecb_encrypt P((Block, Block, Schedule, int)); +int des_string_to_key P((char *, Block)); +#endif /* ENCRYPTION */ diff --git a/src/windows/wintel/encrypt.c b/src/windows/wintel/encrypt.c new file mode 100644 index 0000000000..9c72a478ff --- /dev/null +++ b/src/windows/wintel/encrypt.c @@ -0,0 +1,988 @@ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* based on @(#)encrypt.c 8.1 (Berkeley) 6/4/93 */ + +/* + * Copyright (C) 1990 by the Massachusetts Institute of Technology + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifdef ENCRYPTION + +#include <stdio.h> + +#define isprefix(a, b) (!strncmp((a), (b), strlen(b))) + +#ifdef KRB4 +#include <windows.h> +#include <time.h> +#include <string.h> +#include "winsock.h" +#include "kerberos.h" +#endif +#ifdef KRB5 +#include <time.h> +#include <string.h> +#include "krb5.h" +#include "com_err.h" +#endif + +#include "telnet.h" +#include "encrypt.h" + +#define ENCRYPT_NAMES +#include "telnet_arpa.h" + +/* + * These function pointers point to the current routines + * for encrypting and decrypting data. + */ +void (*encrypt_output) P((unsigned char *, int)); +int (*decrypt_input) P((int)); + +#ifdef DEBUG +int encrypt_debug_mode = 1; +int encrypt_verbose = 1; +#else +int encrypt_verbose = 0; +#endif + +char dbgbuf [10240]; + +static int decrypt_mode = 0; +static int encrypt_mode = 0; +static int autoencrypt = 1; +static int autodecrypt = 1; +static int havesessionkey = 0; + +kstream EncryptKSGlobalHack = NULL; + +#define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0) + +static long i_support_encrypt = + typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64); +static long i_support_decrypt = + typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64); +static long i_wont_support_encrypt = 0; +static long i_wont_support_decrypt = 0; +#define I_SUPPORT_ENCRYPT (i_support_encrypt & ~i_wont_support_encrypt) +#define I_SUPPORT_DECRYPT (i_support_decrypt & ~i_wont_support_decrypt) + +static long remote_supports_encrypt = 0; +static long remote_supports_decrypt = 0; + +static Encryptions encryptions[] = { + { "DES_CFB64", + ENCTYPE_DES_CFB64, + cfb64_encrypt, + cfb64_decrypt, + cfb64_init, + cfb64_start, + cfb64_is, + cfb64_reply, + cfb64_session, + cfb64_keyid, + NULL }, + { "DES_OFB64", + ENCTYPE_DES_OFB64, + ofb64_encrypt, + ofb64_decrypt, + ofb64_init, + ofb64_start, + ofb64_is, + ofb64_reply, + ofb64_session, + ofb64_keyid, + NULL }, + { 0, }, +}; + +static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT, + ENCRYPT_SUPPORT }; +static unsigned char str_suplen = 0; +static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPT }; +static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE }; + +void encrypt_request_end(void); +void encrypt_request_start(unsigned char *, int); +void encrypt_enc_keyid(unsigned char *, int); +void encrypt_dec_keyid(unsigned char *, int); +void encrypt_support(unsigned char *, int); +void encrypt_start(unsigned char *, int); +void encrypt_end(void); + +int encrypt_ks_stream(struct kstream_data_block *, /* output */ + struct kstream_data_block *, /* input */ + struct kstream *); + +int decrypt_ks_stream(struct kstream_data_block *, /* output */ + struct kstream_data_block *, /* input */ + struct kstream *); + +int +encrypt_ks_stream(struct kstream_data_block *i, + struct kstream_data_block *o, + struct kstream *ks) +{ + + /* + * this is really quite bogus, since it does an in-place encryption... + */ + if (encrypt_output) { + encrypt_output(i->ptr, i->length); + return 1; + } + + return 0; +} + + +int +decrypt_ks_stream(struct kstream_data_block *i, + struct kstream_data_block *o, + struct kstream *ks) +{ + unsigned int len; + /* + * this is really quite bogus, since it does an in-place decryption... + */ + if (decrypt_input) { + for (len = 0 ; len < i->length ; len++) + ((unsigned char *)i->ptr)[len] + = decrypt_input(((unsigned char *)i->ptr)[len]); + return 1; + } + + return 0; +} + +int +decrypt_ks_hack(unsigned char *buf, int cnt) +{ + int len; + /* + * this is really quite bogus, since it does an in-place decryption... + */ + for (len = 0 ; len < cnt ; len++) + buf[len] = decrypt_input(buf[len]); + +#ifdef DEBUG + hexdump("hack:", buf, cnt); +#endif + return 1; +} + +#ifdef DEBUG +int +printsub(char c, unsigned char *s, size_t len) +{ + size_t i; + char *p = dbgbuf; + + *p++ = c; + + for (i = 0 ; i < len ; i++) + p += sprintf(p, "%02x ", s[i]); + + strcat(p, "\n"); + + OutputDebugString(dbgbuf); + + return 0; +} +#endif + +/* + * parsedat[0] == the suboption we might be negoating, + */ +void +encrypt_parse(kstream ks, unsigned char *parsedat, int end_sub) +{ + char *p = dbgbuf; + +#ifdef DEBUG + printsub('<', parsedat, end_sub); +#endif + + switch(parsedat[1]) { + case ENCRYPT_START: + encrypt_start(parsedat + 2, end_sub - 2); + break; + case ENCRYPT_END: + encrypt_end(); + break; + case ENCRYPT_SUPPORT: + encrypt_support(parsedat + 2, end_sub - 2); + break; + case ENCRYPT_REQSTART: + encrypt_request_start(parsedat + 2, end_sub - 2); + break; + case ENCRYPT_REQEND: + /* + * We can always send an REQEND so that we cannot + * get stuck encrypting. We should only get this + * if we have been able to get in the correct mode + * anyhow. + */ + encrypt_request_end(); + break; + case ENCRYPT_IS: + encrypt_is(parsedat + 2, end_sub - 2); + break; + case ENCRYPT_REPLY: + encrypt_reply(parsedat + 2, end_sub - 2); + break; + case ENCRYPT_ENC_KEYID: + encrypt_enc_keyid(parsedat + 2, end_sub - 2); + break; + case ENCRYPT_DEC_KEYID: + encrypt_dec_keyid(parsedat + 2, end_sub - 2); + break; + default: + break; + } +} + +/* XXX */ +Encryptions * +findencryption(type) + int type; +{ + Encryptions *ep = encryptions; + + if (!(I_SUPPORT_ENCRYPT & remote_supports_decrypt & typemask(type))) + return(0); + while (ep->type && ep->type != type) + ++ep; + return(ep->type ? ep : 0); +} + +Encryptions * +finddecryption(int type) +{ + Encryptions *ep = encryptions; + + if (!(I_SUPPORT_DECRYPT & remote_supports_encrypt & typemask(type))) + return(0); + while (ep->type && ep->type != type) + ++ep; + return(ep->type ? ep : 0); +} + +#define MAXKEYLEN 64 + +static struct key_info { + unsigned char keyid[MAXKEYLEN]; + int keylen; + int dir; + int *modep; + Encryptions *(*getcrypt)(); +} ki[2] = { + { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption }, + { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption }, +}; + +void +encrypt_init(kstream iks, kstream_ptr data) +{ + Encryptions *ep = encryptions; + + i_support_encrypt = i_support_decrypt = 0; + remote_supports_encrypt = remote_supports_decrypt = 0; + encrypt_mode = 0; + decrypt_mode = 0; + encrypt_output = NULL; + decrypt_input = NULL; + + str_suplen = 4; + + EncryptKSGlobalHack = iks; + + while (ep->type) { +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>I will support %s\n", + ENCTYPE_NAME(ep->type)); + OutputDebugString(dbgbuf); + } +#endif + i_support_encrypt |= typemask(ep->type); + i_support_decrypt |= typemask(ep->type); + if ((i_wont_support_decrypt & typemask(ep->type)) == 0) + if ((str_send[str_suplen++] = ep->type) == IAC) + str_send[str_suplen++] = IAC; + if (ep->init) + (*ep->init)(0); + ++ep; + } + str_send[str_suplen++] = IAC; + str_send[str_suplen++] = SE; +} + +void +encrypt_send_support() +{ + if (str_suplen) { + /* + * If the user has requested that decryption start + * immediatly, then send a "REQUEST START" before + * we negotiate the type. + */ + if (autodecrypt) + encrypt_send_request_start(); + TelnetSend(EncryptKSGlobalHack, str_send, str_suplen, 0); + +#ifdef DEBUG + printsub('>', &str_send[2], str_suplen - 2); +#endif + + str_suplen = 0; + } +} + +/* + * Called when ENCRYPT SUPPORT is received. + */ +void +encrypt_support(typelist, cnt) + unsigned char *typelist; + int cnt; +{ + register int type, use_type = 0; + Encryptions *ep; + + /* + * Forget anything the other side has previously told us. + */ + remote_supports_decrypt = 0; + + while (cnt-- > 0) { + type = *typelist++; +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>Remote supports %s (%d)\n", + ENCTYPE_NAME(type), type); + OutputDebugString(dbgbuf); + } +#endif + if ((type < ENCTYPE_CNT) && + (I_SUPPORT_ENCRYPT & typemask(type))) { + remote_supports_decrypt |= typemask(type); + if (use_type == 0) + use_type = type; + } + } + if (use_type) { + ep = findencryption(use_type); + if (!ep) + return; + type = ep->start ? (*ep->start)(DIR_ENCRYPT, 0) : 0; +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>(*ep->start)() %s returned %d (%s)\n", + ENCTYPE_NAME(use_type), type, ENCRYPT_NAME(type)); + OutputDebugString(dbgbuf); + } +#endif + if (type < 0) + return; + encrypt_mode = use_type; + if (type == 0) + encrypt_start_output(use_type); + } +} + +void +encrypt_is(data, cnt) + unsigned char *data; + int cnt; +{ + Encryptions *ep; + register int type, ret; + + if (--cnt < 0) + return; + type = *data++; + if (type < ENCTYPE_CNT) + remote_supports_encrypt |= typemask(type); + if (!(ep = finddecryption(type))) { +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>encrypt_reply: " + "Can't find type %s (%d) for initial negotiation\n", + ENCTYPE_NAME_OK(type) + ? ENCTYPE_NAME(type) : "(unknown)", + type); + OutputDebugString(dbgbuf); + } +#endif + return; + } + if (!ep->is) { +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>encrypt_reply: " + "No initial negotiation needed for type %s (%d)\n", + ENCTYPE_NAME_OK(type) + ? ENCTYPE_NAME(type) : "(unknown)", + type); + OutputDebugString(dbgbuf); + } +#endif + ret = 0; + } else { + ret = (*ep->is)(data, cnt); +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, "encrypt_reply: " + "(*ep->is)(%x, %d) returned %s(%d)\n", data, cnt, + (ret < 0) ? "FAIL " : + (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); + OutputDebugString(dbgbuf); + } +#endif + } + if (ret < 0) { + autodecrypt = 0; + } else { + decrypt_mode = type; + if (ret == 0 && autodecrypt) + encrypt_send_request_start(); + } +} + +void +encrypt_reply(data, cnt) + unsigned char *data; + int cnt; +{ + Encryptions *ep; + register int ret, type; + + if (--cnt < 0) + return; + type = *data++; + if (!(ep = findencryption(type))) { +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>Can't find type %s (%d) for initial negotiation\n", + ENCTYPE_NAME_OK(type) + ? ENCTYPE_NAME(type) : "(unknown)", + type); + OutputDebugString(dbgbuf); + } +#endif + return; + } + if (!ep->reply) { +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>No initial negotiation needed for type %s (%d)\n", + ENCTYPE_NAME_OK(type) + ? ENCTYPE_NAME(type) : "(unknown)", + type); + OutputDebugString(dbgbuf); + } +#endif + ret = 0; + } else { + ret = (*ep->reply)(data, cnt); +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, "(*ep->reply)(%x, %d) returned %s(%d)\n", + data, cnt, + (ret < 0) ? "FAIL " : + (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); + OutputDebugString(dbgbuf); + } +#endif + } +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>encrypt_reply returned %d\n", ret); + OutputDebugString(dbgbuf); + } +#endif + if (ret < 0) { + autoencrypt = 0; + } else { + encrypt_mode = type; + if (ret == 0 && autoencrypt) + encrypt_start_output(type); + } +} + +/* + * Called when a ENCRYPT START command is received. + */ +void +encrypt_start(data, cnt) + unsigned char *data; + int cnt; +{ + Encryptions *ep; + + if (!decrypt_mode) { + /* + * Something is wrong. We should not get a START + * command without having already picked our + * decryption scheme. Send a REQUEST-END to + * attempt to clear the channel... + */ + printf("Warning, Cannot decrypt input stream!!!\n"); + encrypt_send_request_end(); + return; + } + + if (ep = finddecryption(decrypt_mode)) { + extern BOOL encrypt_flag; + + decrypt_input = ep->input; + EncryptKSGlobalHack->decrypt = decrypt_ks_stream; + encrypt_flag = 2; /* XXX hack */ + + if (encrypt_verbose) { + sprintf(dbgbuf, "[ Input is now decrypted with type %s ]\n", + ENCTYPE_NAME(decrypt_mode)); + OutputDebugString(dbgbuf); + } +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>Start to decrypt input with type %s\n", + ENCTYPE_NAME(decrypt_mode)); + OutputDebugString(dbgbuf); + } +#endif + } else { + printf("Warning, Cannot decrypt type %s (%d)!!!\n", + ENCTYPE_NAME_OK(decrypt_mode) + ? ENCTYPE_NAME(decrypt_mode) + : "(unknown)", + decrypt_mode); + encrypt_send_request_end(); + } +} + +void +encrypt_session_key(key, server) + Session_Key *key; + int server; +{ + Encryptions *ep = encryptions; + + havesessionkey = 1; + + while (ep->type) { + if (ep->session) + (*ep->session)(key, server); +#if defined(notdef) + if (!encrypt_output && autoencrypt && !server) + encrypt_start_output(ep->type); + if (!decrypt_input && autodecrypt && !server) + encrypt_send_request_start(); +#endif + ++ep; + } +} + +/* + * Called when ENCRYPT END is received. + */ +void +encrypt_end() +{ + decrypt_input = NULL; + EncryptKSGlobalHack->decrypt = NULL; +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>Input is back to clear text\n"); + OutputDebugString(dbgbuf); + } +#endif + if (encrypt_verbose) + printf("[ Input is now clear text ]\n"); +} + +/* + * Called when ENCRYPT REQUEST-END is received. + */ +void +encrypt_request_end() +{ + encrypt_send_end(); +} + +/* + * Called when ENCRYPT REQUEST-START is received. If we receive + * this before a type is picked, then that indicates that the + * other side wants us to start encrypting data as soon as we + * can. + */ +void +encrypt_request_start(data, cnt) + unsigned char *data; + int cnt; +{ + if (encrypt_mode == 0) { + return; + } + encrypt_start_output(encrypt_mode); +} + +static unsigned char str_keyid[(MAXKEYLEN*2)+5] = { IAC, SB, TELOPT_ENCRYPT }; + +void +encrypt_keyid(); + +void +encrypt_enc_keyid(keyid, len) + unsigned char *keyid; + int len; +{ + encrypt_keyid(&ki[1], keyid, len); +} + +void +encrypt_dec_keyid(keyid, len) + unsigned char *keyid; + int len; +{ + encrypt_keyid(&ki[0], keyid, len); +} + +void +encrypt_keyid(kp, keyid, len) + struct key_info *kp; + unsigned char *keyid; + int len; +{ + Encryptions *ep; + int dir = kp->dir; + register int ret = 0; + + if (!(ep = (*kp->getcrypt)(*kp->modep))) { + if (len == 0) + return; + kp->keylen = 0; + } else if (len == 0) { + /* + * Empty option, indicates a failure. + */ + if (kp->keylen == 0) + return; + kp->keylen = 0; + if (ep->keyid) + (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); + + } else if ((len != kp->keylen) || (memcmp(keyid, kp->keyid, len) != 0)) { + /* + * Length or contents are different + */ + kp->keylen = len; + memcpy(kp->keyid, keyid, len); + if (ep->keyid) + (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); + } else { + if (ep->keyid) + ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen); + if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt) + encrypt_start_output(*kp->modep); + return; + } + + encrypt_send_keyid(dir, kp->keyid, kp->keylen, 0); +} + +void +encrypt_send_keyid(dir, keyid, keylen, saveit) + int dir; + unsigned char *keyid; + int keylen; + int saveit; +{ + unsigned char *strp; + + str_keyid[3] = (dir == DIR_ENCRYPT) + ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID; + if (saveit) { + struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1]; + memcpy(kp->keyid, keyid, keylen); + kp->keylen = keylen; + } + + for (strp = &str_keyid[4]; keylen > 0; --keylen) { + if ((*strp++ = *keyid++) == IAC) + *strp++ = IAC; + } + *strp++ = IAC; + *strp++ = SE; + TelnetSend(EncryptKSGlobalHack, str_keyid, strp - str_keyid, 0); + +#ifdef DEBUG + printsub('>', &str_keyid[2], strp - str_keyid - 2); +#endif + +} + +void +encrypt_auto(on) + int on; +{ + if (on < 0) + autoencrypt ^= 1; + else + autoencrypt = on ? 1 : 0; +} + +void +decrypt_auto(on) + int on; +{ + if (on < 0) + autodecrypt ^= 1; + else + autodecrypt = on ? 1 : 0; +} + +void +encrypt_start_output(type) + int type; +{ + Encryptions *ep; + register unsigned char *p; + register int i; + + if (!(ep = findencryption(type))) { +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>Can't encrypt with type %s (%d)\n", + ENCTYPE_NAME_OK(type) + ? ENCTYPE_NAME(type) : "(unknown)", + type); + OutputDebugString(dbgbuf); + } +#endif + return; + } + if (ep->start) { + i = (*ep->start)(DIR_ENCRYPT, 0); +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>Encrypt start: %s (%d) %s\n", + (i < 0) ? "failed" : + "initial negotiation in progress", + i, ENCTYPE_NAME(type)); + OutputDebugString(dbgbuf); + } +#endif + if (i) + return; + } + p = str_start + 3; + *p++ = ENCRYPT_START; + for (i = 0; i < ki[0].keylen; ++i) { + if ((*p++ = ki[0].keyid[i]) == IAC) + *p++ = IAC; + } + *p++ = IAC; + *p++ = SE; + TelnetSend(EncryptKSGlobalHack, str_start, p - str_start, 0); +#ifdef DEBUG + printsub('>', &str_start[2], p - &str_start[2]); +#endif + + /* + * If we are already encrypting in some mode, then + * encrypt the ring (which includes our request) in + * the old mode, mark it all as "clear text" and then + * switch to the new mode. + */ + encrypt_output = ep->output; + EncryptKSGlobalHack->encrypt = encrypt_ks_stream; + encrypt_mode = type; +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>Started to encrypt output with type %s\n", + ENCTYPE_NAME(type)); + OutputDebugString(dbgbuf); + } +#endif + if (encrypt_verbose) { + sprintf(dbgbuf, "[ Output is now encrypted with type %s ]\n", + ENCTYPE_NAME(type)); + OutputDebugString(dbgbuf); + } +} + +void +encrypt_send_end() +{ + if (!encrypt_output) + return; + + str_end[3] = ENCRYPT_END; + TelnetSend(EncryptKSGlobalHack, str_end, sizeof(str_end), 0); +#ifdef DEBUG + printsub('>', &str_end[2], sizeof(str_end) - 2); +#endif + + /* + * Encrypt the output buffer now because it will not be done by + * netflush... + */ + encrypt_output = 0; + EncryptKSGlobalHack->encrypt = NULL; +#ifdef DEBUG + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>Output is back to clear text\n"); + OutputDebugString(dbgbuf); + } +#endif + if (encrypt_verbose) + printf("[ Output is now clear text ]\n"); +} + +void +encrypt_send_request_start() +{ + register unsigned char *p; + register int i; + + p = &str_start[3]; + *p++ = ENCRYPT_REQSTART; + for (i = 0; i < ki[1].keylen; ++i) { + if ((*p++ = ki[1].keyid[i]) == IAC) + *p++ = IAC; + } + *p++ = IAC; + *p++ = SE; + TelnetSend(EncryptKSGlobalHack, str_start, p - str_start, 0); +#ifdef DEBUG + printsub('>', &str_start[2], p - &str_start[2]); + + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>Request input to be encrypted\n"); + OutputDebugString(dbgbuf); + } +#endif +} + +void +encrypt_send_request_end() +{ + str_end[3] = ENCRYPT_REQEND; + TelnetSend(EncryptKSGlobalHack, str_end, sizeof(str_end), 0); +#ifdef DEBUG + printsub('>', &str_end[2], sizeof(str_end) - 2); + + if (encrypt_debug_mode) { + sprintf(dbgbuf, ">>>Request input to be clear text\n"); + OutputDebugString(dbgbuf); + } +#endif +} + +int encrypt_is_encrypting() +{ + if (encrypt_output && decrypt_input) + return 1; + return 0; +} + +#ifdef DEBUG +void +encrypt_debug(mode) + int mode; +{ + encrypt_debug_mode = mode; +} +#endif + +#if 0 +void +encrypt_gen_printsub(data, cnt, buf, buflen) + unsigned char *data, *buf; + int cnt, buflen; +{ + char tbuf[16], *cp; + + cnt -= 2; + data += 2; + buf[buflen-1] = '\0'; + buf[buflen-2] = '*'; + buflen -= 2;; + for (; cnt > 0; cnt--, data++) { + sprintf(tbuf, " %d", *data); + for (cp = tbuf; *cp && buflen > 0; --buflen) + *buf++ = *cp++; + if (buflen <= 0) + return; + } + *buf = '\0'; +} + +void +encrypt_printsub(data, cnt, buf, buflen) + unsigned char *data, *buf; + int cnt, buflen; +{ + Encryptions *ep; + register int type = data[1]; + + for (ep = encryptions; ep->type && ep->type != type; ep++) + ; + + if (ep->printsub) + (*ep->printsub)(data, cnt, buf, buflen); + else + encrypt_gen_printsub(data, cnt, buf, buflen); +} +#endif + +#endif /* ENCRYPTION */ diff --git a/src/windows/wintel/encrypt.h b/src/windows/wintel/encrypt.h new file mode 100644 index 0000000000..80295681ca --- /dev/null +++ b/src/windows/wintel/encrypt.h @@ -0,0 +1,182 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)encrypt.h 8.1 (Berkeley) 6/4/93 + */ + +/* + * Copyright (C) 1990 by the Massachusetts Institute of Technology + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifdef ENCRYPTION + +#ifndef __ENCRYPTION__ +#define __ENCRYPTION__ + +#define DIR_DECRYPT 1 +#define DIR_ENCRYPT 2 + +typedef unsigned char Block[8]; +typedef unsigned char *BlockT; +typedef struct { Block _; } Schedule[16]; + +#define VALIDKEY(key) ( key[0] | key[1] | key[2] | key[3] | key[4] | key[5] | key[6] | key[7]) + +#define SAMEKEY(k1, k2) (!memcmp((void *)k1, (void *)k2, sizeof(Block))) + +typedef struct { + short type; + int length; + unsigned char *data; +} Session_Key; + +#if !defined(P) +#ifdef __STDC__ +#define P(x) x +#else +#define P(x) () +#endif +#endif + +#ifdef DEBUG +int printsub(char, unsigned char *, size_t); +#endif + +void encrypt_parse(kstream, unsigned char *, int); + +typedef struct { + char *name; + int type; + void (*output) P((unsigned char *, int)); + int (*input) P((int)); + void (*init) P((int)); + int (*start) P((int, int)); + int (*is) P((unsigned char *, int)); + int (*reply) P((unsigned char *, int)); + void (*session) P((Session_Key *, int)); + int (*keyid) P((int, unsigned char *, int *)); + void (*printsub) P((unsigned char *, int, unsigned char *, int)); +} Encryptions; + +#define SK_DES 1 /* Matched Kerberos v5 ENCTYPE_DES */ + +void encrypt_init P((kstream, char *, int)); +Encryptions *findencryption P((int)); +void encrypt_send_supprt P((void)); +void encrypt_auto P((int)); +void decrypt_auto P((int)); +void encrypt_is P((unsigned char *, int)); +void encrypt_reply P((unsigned char *, int)); +void encrypt_start_input P((int)); +void encrypt_session_key P((Session_Key *, int)); +void encrypt_end_input P((void)); +void encrypt_start_output P((int)); +void encrypt_end_output P((void)); +void encrypt_send_request_start P((void)); +void encrypt_send_request_end P((void)); +void encrypt_send_end P((void)); +void encrypt_wait P((void)); +int encrypt_is_encrypting P((void)); +void encrypt_send_support P((void)); +void encrypt_send_keyid P((int, unsigned char *, int, int)); +int net_write P((unsigned char *, int)); + +int encrypt_cmd P((int, char **)); +void encrypt_display P((void)); + +void krbdes_encrypt P((unsigned char *, int)); +int krbdes_decrypt P((int)); +int krbdes_is P((unsigned char *, int)); +int krbdes_reply P((unsigned char *, int)); +void krbdes_init P((int)); +int krbdes_start P((int, int)); +void krbdes_session P((Session_Key *, int)); +void krbdes_printsub P((unsigned char *, int, unsigned char *, int)); + +void cfb64_encrypt P((unsigned char *, int)); +int cfb64_decrypt P((int)); +void cfb64_init P((int)); +int cfb64_start P((int, int)); +int cfb64_is P((unsigned char *, int)); +int cfb64_reply P((unsigned char *, int)); +void cfb64_session P((Session_Key *, int)); +int cfb64_keyid P((int, unsigned char *, int *)); +void cfb64_printsub P((unsigned char *, int, unsigned char *, int)); + +void ofb64_encrypt P((unsigned char *, int)); +int ofb64_decrypt P((int)); +void ofb64_init P((int)); +int ofb64_start P((int, int)); +int ofb64_is P((unsigned char *, int)); +int ofb64_reply P((unsigned char *, int)); +void ofb64_session P((Session_Key *, int)); +int ofb64_keyid P((int, unsigned char *, int *)); +void ofb64_printsub P((unsigned char *, int, unsigned char *, int)); + +__declspec(dllimport) int __stdcall +des_new_random_key P((Block)); +__declspec(dllimport) void __stdcall +des_set_random_generator_seed P((Block)); +__declspec(dllimport) void __stdcall +des_key_sched P((Block, Schedule)); +__declspec(dllimport) void __stdcall +des_ecb_encrypt P((Block, Block, Schedule, int)); +int des_string_to_key P((char *, Block)); + +#ifdef DEBUG +extern int encrypt_debug_mode; +#endif + +extern int (*decrypt_input) P((int)); +extern void (*encrypt_output) P((unsigned char *, int)); + +int decrypt_ks_hack(unsigned char *, int); + +#endif /* __ENCRYPTION__ */ + +#endif /* ENCRYPTION */ diff --git a/src/windows/wintel/font.c b/src/windows/wintel/font.c index ce67083250..1bab00c7ea 100644 --- a/src/windows/wintel/font.c +++ b/src/windows/wintel/font.c @@ -7,91 +7,94 @@ #include "ini.h" void ProcessFontChange( - HWND hWnd) + HWND hWnd) { - static DWORD dwFontColor; /* Color of font if one has been selected */ - CHOOSEFONT cf; - HDC hDC; - SCREEN *pScr; - TEXTMETRIC tm; - char buf[16]; - char szStyle[LF_FACESIZE]; + static DWORD dwFontColor; /* Color of font if one has been selected */ + CHOOSEFONT cf; + HDC hDC; + SCREEN *pScr; + TEXTMETRIC tm; + char buf[16]; + char szStyle[LF_FACESIZE]; - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert(pScr != NULL); + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert(pScr != NULL); - cf.lStructSize = sizeof(cf); - cf.hwndOwner = hWnd; - cf.lpLogFont = (LPLOGFONT) &(pScr->lf); - cf.lpszStyle = szStyle; - cf.Flags = CF_INITTOLOGFONTSTRUCT; // | CF_USESTYLE; - cf.Flags |= CF_SCREENFONTS; -// cf.Flags |= CF_ANSIONLY; - cf.Flags |= CF_FORCEFONTEXIST; - cf.Flags |= CF_FIXEDPITCHONLY; - cf.Flags |= CF_NOSIMULATIONS; + cf.lStructSize = sizeof(cf); + cf.hwndOwner = hWnd; + cf.lpLogFont = (LPLOGFONT) &(pScr->lf); + cf.lpszStyle = szStyle; + cf.Flags = CF_INITTOLOGFONTSTRUCT; /* | CF_USESTYLE; */ + cf.Flags |= CF_SCREENFONTS; +#if 0 + cf.Flags |= CF_ANSIONLY; +#endif + cf.Flags |= CF_FORCEFONTEXIST; + cf.Flags |= CF_FIXEDPITCHONLY; + cf.Flags |= CF_NOSIMULATIONS; - if (ChooseFont(&cf)) { - if (pScr->hSelectedFont) - DeleteObject(pScr->hSelectedFont); + if (ChooseFont(&cf)) { + if (pScr->hSelectedFont) + DeleteObject(pScr->hSelectedFont); - pScr->hSelectedFont = CreateFontIndirect(&(pScr->lf)); - pScr->lf.lfUnderline = TRUE; - pScr->hSelectedULFont = CreateFontIndirect(&(pScr->lf)); - pScr->lf.lfUnderline = FALSE; - hDC = GetDC(hWnd); - SelectObject(hDC, pScr->hSelectedFont); - GetTextMetrics(hDC, &tm); - pScr->cxChar = tm.tmAveCharWidth; - pScr->cyChar = tm.tmHeight + tm.tmExternalLeading; - ReleaseDC(hWnd, hDC); - SetWindowPos(hWnd, NULL, 0, 0, pScr->cxChar * pScr->width + - FRAME_WIDTH, pScr->cyChar * pScr->height + - FRAME_HEIGHT, SWP_NOMOVE | SWP_NOZORDER); + pScr->hSelectedFont = CreateFontIndirect(&(pScr->lf)); + pScr->lf.lfUnderline = TRUE; + pScr->hSelectedULFont = CreateFontIndirect(&(pScr->lf)); + pScr->lf.lfUnderline = FALSE; + hDC = GetDC(hWnd); + SelectObject(hDC, pScr->hSelectedFont); + GetTextMetrics(hDC, &tm); + pScr->cxChar = tm.tmAveCharWidth; + pScr->cyChar = tm.tmHeight + tm.tmExternalLeading; + ReleaseDC(hWnd, hDC); + SetWindowPos(hWnd, NULL, 0, 0, pScr->cxChar * pScr->width + + FRAME_WIDTH, pScr->cyChar * pScr->height + + FRAME_HEIGHT, SWP_NOMOVE | SWP_NOZORDER); - dwFontColor = RGB(255, 255, 255); - InvalidateRect(hWnd, NULL, TRUE); - } + dwFontColor = RGB(255, 255, 255); + InvalidateRect(hWnd, NULL, TRUE); + } - WritePrivateProfileString(INI_FONT, "FaceName", pScr->lf.lfFaceName, TELNET_INI); - wsprintf(buf, "%d", (int) pScr->lf.lfHeight); - WritePrivateProfileString(INI_FONT, "Height", buf, TELNET_INI); - wsprintf(buf, "%d", (int) pScr->lf.lfWidth); - WritePrivateProfileString(INI_FONT, "Width", buf, TELNET_INI); - wsprintf(buf, "%d", (int) pScr->lf.lfEscapement); - WritePrivateProfileString(INI_FONT, "Escapement", buf, TELNET_INI); - wsprintf(buf, "%d", (int) pScr->lf.lfCharSet); - WritePrivateProfileString(INI_FONT, "CharSet", buf, TELNET_INI); - wsprintf(buf, "%d", (int) pScr->lf.lfPitchAndFamily); - WritePrivateProfileString(INI_FONT, "PitchAndFamily", buf, TELNET_INI); + WritePrivateProfileString(INI_FONT, "FaceName", pScr->lf.lfFaceName, TELNET_INI); + wsprintf(buf, "%d", (int) pScr->lf.lfHeight); + WritePrivateProfileString(INI_FONT, "Height", buf, TELNET_INI); + wsprintf(buf, "%d", (int) pScr->lf.lfWidth); + WritePrivateProfileString(INI_FONT, "Width", buf, TELNET_INI); + wsprintf(buf, "%d", (int) pScr->lf.lfEscapement); + WritePrivateProfileString(INI_FONT, "Escapement", buf, TELNET_INI); + wsprintf(buf, "%d", (int) pScr->lf.lfCharSet); + WritePrivateProfileString(INI_FONT, "CharSet", buf, TELNET_INI); + wsprintf(buf, "%d", (int) pScr->lf.lfPitchAndFamily); + WritePrivateProfileString(INI_FONT, "PitchAndFamily", buf, TELNET_INI); - return; + return; } /* ProcessFontChange */ void NEAR InitializeStruct( - WORD wCommDlgType, - LPSTR lpStruct, - HWND hWnd) + WORD wCommDlgType, + LPSTR lpStruct, + HWND hWnd) { - LPCHOOSEFONT lpFontChunk; + LPCHOOSEFONT lpFontChunk; - if (wCommDlgType == IDC_FONT) { - lpFontChunk = (LPCHOOSEFONT) lpStruct; + if (wCommDlgType == IDC_FONT) { + lpFontChunk = (LPCHOOSEFONT) lpStruct; - lpFontChunk->lStructSize = sizeof(CHOOSEFONT); - lpFontChunk->hwndOwner = hWnd; - lpFontChunk->Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY | CF_INITTOLOGFONTSTRUCT | CF_APPLY; - lpFontChunk->rgbColors = RGB(0, 0, 255); - lpFontChunk->lCustData = 0L; - lpFontChunk->lpfnHook = NULL; - lpFontChunk->lpTemplateName = NULL; - lpFontChunk->hInstance = NULL; - lpFontChunk->lpszStyle = NULL; - lpFontChunk->nFontType = SCREEN_FONTTYPE; - lpFontChunk->nSizeMin = 0; - lpFontChunk->nSizeMax = 0; - } + lpFontChunk->lStructSize = sizeof(CHOOSEFONT); + lpFontChunk->hwndOwner = hWnd; + lpFontChunk->Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY + | CF_INITTOLOGFONTSTRUCT | CF_APPLY; + lpFontChunk->rgbColors = RGB(0, 0, 255); + lpFontChunk->lCustData = 0L; + lpFontChunk->lpfnHook = NULL; + lpFontChunk->lpTemplateName = NULL; + lpFontChunk->hInstance = NULL; + lpFontChunk->lpszStyle = NULL; + lpFontChunk->nFontType = SCREEN_FONTTYPE; + lpFontChunk->nSizeMin = 0; + lpFontChunk->nSizeMax = 0; + } } /* InitialiseStruct */ diff --git a/src/windows/wintel/genget.c b/src/windows/wintel/genget.c new file mode 100644 index 0000000000..4e760d72e1 --- /dev/null +++ b/src/windows/wintel/genget.c @@ -0,0 +1,101 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* based on @(#)genget.c 8.1 (Berkeley) 6/4/93 */ + +#include <ctype.h> + +#define LOWER(x) (isupper(x) ? tolower(x) : (x)) +/* + * The prefix function returns 0 if *s1 is not a prefix + * of *s2. If *s1 exactly matches *s2, the negative of + * the length is returned. If *s1 is a prefix of *s2, + * the length of *s1 is returned. + */ + int +isprefix(s1, s2) + register char *s1, *s2; +{ + char *os1; + register char c1, c2; + + if (*s1 == '\0') + return(-1); + os1 = s1; + c1 = *s1; + c2 = *s2; + while (LOWER(c1) == LOWER(c2)) { + if (c1 == '\0') + break; + c1 = *++s1; + c2 = *++s2; + } + return(*s1 ? 0 : (*s2 ? (s1 - os1) : (os1 - s1))); +} + +static char *ambiguous; /* special return value for command routines */ + + char ** +genget(name, table, stlen) + char *name; /* name to match */ + char **table; /* name entry in table */ + int stlen; +{ + register char **c, **found; + register int n; + + if (name == 0) + return 0; + + found = 0; + for (c = table; *c != 0; c = (char **)((char *)c + stlen)) { + if ((n = isprefix(name, *c)) == 0) + continue; + if (n < 0) /* exact match */ + return(c); + if (found) + return(&ambiguous); + found = c; + } + return(found); +} + +/* + * Function call version of Ambiguous() + */ + int +Ambiguous(s) + char *s; +{ + return((char **)s == &ambiguous); +} diff --git a/src/windows/wintel/ini.h b/src/windows/wintel/ini.h index d391c8a860..f26c162e37 100644 --- a/src/windows/wintel/ini.h +++ b/src/windows/wintel/ini.h @@ -1,16 +1,16 @@ /* Defines INI file vocabulary */ #define TELNET_INI "kerberos.ini" - #define INI_TELNET "Telnet" - #define INI_FONT "Font" - #define INI_WIDTH "Width" - #define INI_HEIGHT "Height" - #define INI_POSITION "Position" - #define INI_BACKSPACE "Backspace" - #define INI_BACKSPACE_BS "BS" - #define INI_BACKSPACE_DEL "DEL" +#define INI_TELNET "Telnet" +#define INI_FONT "Font" +#define INI_WIDTH "Width" +#define INI_HEIGHT "Height" +#define INI_POSITION "Position" +#define INI_BACKSPACE "Backspace" +#define INI_BACKSPACE_BS "BS" +#define INI_BACKSPACE_DEL "DEL" - #define INI_HOSTS "Telnet Hosts" - #define INI_HOST "Host" - #define INI_HOST_BS "BS" - #define INI_HOST_DEL "DEL" +#define INI_HOSTS "Telnet Hosts" +#define INI_HOST "Host" +#define INI_HOST_BS "BS" +#define INI_HOST_DEL "DEL" diff --git a/src/windows/wintel/intern.c b/src/windows/wintel/intern.c index 426de2f829..176cbedcd0 100644 --- a/src/windows/wintel/intern.c +++ b/src/windows/wintel/intern.c @@ -7,859 +7,808 @@ #define ScreenClearAttrib 0 -SCREENLINE *GetScreenLineFromY( - SCREEN *pScr, - int y) +SCREENLINE * +GetScreenLineFromY(SCREEN *pScr, int y) { - SCREENLINE *pScrLine; - int idx; + SCREENLINE *pScrLine; + int idx; - pScrLine = pScr->screen_top; - for (idx = 0; idx < pScr->height; idx++) { - if (idx == y) - return(pScrLine); - if (pScrLine == NULL) - return(NULL); - pScrLine = pScrLine->next; - } + pScrLine = pScr->screen_top; + for (idx = 0; idx < pScr->height; idx++) { + if (idx == y) + return(pScrLine); + if (pScrLine == NULL) + return(NULL); + pScrLine = pScrLine->next; + } - return(NULL); + return(NULL); +} -} /* GetScreenLineFromY */ - -SCREENLINE *ScreenClearLine( - SCREEN *pScr, - SCREENLINE *pScrLine) +SCREENLINE * +ScreenClearLine(SCREEN *pScr, SCREENLINE *pScrLine) { - memset(pScrLine->attrib, ScreenClearAttrib, pScr->width); - memset(pScrLine->text, ' ', pScr->width); - return(pScrLine); - -} /* ScreenClearLine */ + memset(pScrLine->attrib, ScreenClearAttrib, pScr->width); + memset(pScrLine->text, ' ', pScr->width); + return(pScrLine); +} -void ScreenUnscroll( - SCREEN *pScr) +void +ScreenUnscroll(SCREEN *pScr) { - int idx; - SCREENLINE *pScrLine; - - if (pScr->screen_bottom == pScr->buffer_bottom) - return; + int idx; + SCREENLINE *pScrLine; - pScr->screen_bottom = pScr->buffer_bottom; - pScrLine = pScr->screen_bottom; - for (idx = 1; idx < pScr->height; idx++) { - if (pScrLine == NULL) - return; - pScrLine = pScrLine->prev; - } - pScr->screen_top = pScrLine; + if (pScr->screen_bottom == pScr->buffer_bottom) + return; -} /* ScreenUnscroll */ + pScr->screen_bottom = pScr->buffer_bottom; + pScrLine = pScr->screen_bottom; + for (idx = 1; idx < pScr->height; idx++) { + if (pScrLine == NULL) + return; + pScrLine = pScrLine->prev; + } + pScr->screen_top = pScrLine; +} -void ScreenCursorOn( - SCREEN *pScr) +void +ScreenCursorOn(SCREEN *pScr) { - int y; - int nlines; + int y; + int nlines; - if (pScr->screen_bottom != pScr->buffer_bottom) - nlines = pScr->numlines - GetScrollPos(pScr->hWnd, SB_VERT); - else - nlines = 0; + if (pScr->screen_bottom != pScr->buffer_bottom) + nlines = pScr->numlines - GetScrollPos(pScr->hWnd, SB_VERT); + else + nlines = 0; - y = pScr->y + nlines; - SetCaretPos(pScr->x * pScr->cxChar, (y+1) * pScr->cyChar); - ShowCaret(pScr->hWnd); + y = pScr->y + nlines; + SetCaretPos(pScr->x * pScr->cxChar, (y+1) * pScr->cyChar); + ShowCaret(pScr->hWnd); +} -} /* ScreenCursorOn */ - -void ScreenCursorOff( - SCREEN *pScr) +void +ScreenCursorOff(SCREEN *pScr) { - HideCaret(pScr->hWnd); - -} /* ScreenCursorOff */ + HideCaret(pScr->hWnd); +} -void ScreenELO( - SCREEN *pScr, - int s) +void +ScreenELO(SCREEN *pScr, int s) { - SCREENLINE *pScrLine; - RECT rc; + SCREENLINE *pScrLine; + RECT rc; - if (s < 0) - s = pScr->y; + if (s < 0) + s = pScr->y; - pScrLine = GetScreenLineFromY(pScr,s); - memset(pScrLine->attrib, ScreenClearAttrib, pScr->width); - memset(pScrLine->text, ' ', pScr->width); - rc.left = 0; - rc.right = pScr->width * pScr->cxChar; - rc.top = pScr->cyChar * s; - rc.bottom = pScr->cyChar * (s+1); - InvalidateRect(pScr->hWnd, &rc, TRUE); - -} /* ScreenELO */ - -void ScreenEraseScreen( - SCREEN *pScr) -{ - int i; - int x1 = 0; - int y1 = 0; - int x2 = pScr->width; - int y2 = pScr->height; - int n = -1; + pScrLine = GetScreenLineFromY(pScr,s); + memset(pScrLine->attrib, ScreenClearAttrib, pScr->width); + memset(pScrLine->text, ' ', pScr->width); + rc.left = 0; + rc.right = pScr->width * pScr->cxChar; + rc.top = pScr->cyChar * s; + rc.bottom = pScr->cyChar * (s+1); + InvalidateRect(pScr->hWnd, &rc, TRUE); +} + +void +ScreenEraseScreen(SCREEN *pScr) +{ + int i; + int x1 = 0; + int y1 = 0; + int x2 = pScr->width; + int y2 = pScr->height; + int n = -1; - for(i = 0; i < pScr->height; i++) - ScreenELO(pScr,i); + for(i = 0; i < pScr->height; i++) + ScreenELO(pScr,i); - InvalidateRect(pScr->hWnd, NULL, TRUE); - UpdateWindow(pScr->hWnd); + InvalidateRect(pScr->hWnd, NULL, TRUE); + UpdateWindow(pScr->hWnd); +} -} /* ScreenEraseScreen */ - -void ScreenTabClear( - SCREEN *pScr) +void +ScreenTabClear(SCREEN *pScr) { - int x = 0; - - while(x <= pScr->width) { - pScr->tabs[x] = ' '; - x++; - } + int x = 0; -} /* ScreenTabClear */ + while(x <= pScr->width) { + pScr->tabs[x] = ' '; + x++; + } +} -void ScreenTabInit( - SCREEN *pScr) +void +ScreenTabInit(SCREEN *pScr) { - int x = 0; - - ScreenTabClear(pScr); + int x = 0; - while(x <= pScr->width) { - pScr->tabs[x] = 'x'; - x += 8; - } - pScr->tabs[pScr->width] = 'x'; + ScreenTabClear(pScr); -} /* ScreenTabInit */ + while(x <= pScr->width) { + pScr->tabs[x] = 'x'; + x += 8; + } + pScr->tabs[pScr->width] = 'x'; +} -void ScreenReset( - SCREEN *pScr) +void +ScreenReset(SCREEN *pScr) { - pScr->top = 0; - pScr->bottom = pScr->height-1; - pScr->parmptr = 0; - pScr->escflg = 0; - pScr->DECAWM = 1; - pScr->bWrapPending = FALSE; - pScr->DECCKM = 0; - pScr->DECPAM = 0; -/* pScr->DECORG = 0; */ -/* pScr->Pattrib = -1; */ - pScr->IRM = 0; - pScr->attrib = 0; - pScr->x = 0; - pScr->y = 0; -// pScr->charset = 0; - ScreenEraseScreen(pScr); - ScreenTabInit(pScr); -// set_vtwrap(pScrn, pScr->DECAWM); /* QAK - 7/27/90: added because resetting the virtual screen's wrapping flag doesn't reset telnet window's wrapping */ - -} /* ScreenReset */ + pScr->top = 0; + pScr->bottom = pScr->height-1; + pScr->parmptr = 0; + pScr->escflg = 0; + pScr->DECAWM = 1; + pScr->bWrapPending = FALSE; + pScr->DECCKM = 0; + pScr->DECPAM = 0; + /* pScr->DECORG = 0; */ + /* pScr->Pattrib = -1; */ + pScr->IRM = 0; + pScr->attrib = 0; + pScr->x = 0; + pScr->y = 0; + /* pScr->charset = 0; */ + ScreenEraseScreen(pScr); + ScreenTabInit(pScr); +#if 0 + /* + * QAK - 7/27/90: added because resetting the virtual screen's + * wrapping flag doesn't reset telnet window's wrapping + */ + set_vtwrap(pScrn, pScr->DECAWM); +#endif +} -void ScreenListMove( - SCREENLINE *TD, - SCREENLINE *BD, - SCREENLINE *TI, - SCREENLINE *BI) +void +ScreenListMove(SCREENLINE *TD, SCREENLINE *BD, SCREENLINE *TI, SCREENLINE *BI) { - if (TD->prev != NULL) - TD->prev->next = BD->next; /* Maintain circularity */ + if (TD->prev != NULL) + TD->prev->next = BD->next; /* Maintain circularity */ - if (BD->next != NULL) - BD->next->prev = TD->prev; + if (BD->next != NULL) + BD->next->prev = TD->prev; - TD->prev = TI; /* Place the node in its new home */ - BD->next = BI; + TD->prev = TI; /* Place the node in its new home */ + BD->next = BI; - if (TI != NULL) - TI->next = TD; /* Ditto prev->prev */ + if (TI != NULL) + TI->next = TD; /* Ditto prev->prev */ - if (BI != NULL) - BI->prev = BD; + if (BI != NULL) + BI->prev = BD; +} -} /* ScreenListMove */ - -void ScreenDelLines( - SCREEN *pScr, - int n, - int s) +void +ScreenDelLines(SCREEN *pScr, int n, int s) { - SCREENLINE *BI; - SCREENLINE *TI; - SCREENLINE *TD; - SCREENLINE *BD; - SCREENLINE *pLine; - int idx; - RECT rc; - HDC hDC; + SCREENLINE *BI; + SCREENLINE *TI; + SCREENLINE *TD; + SCREENLINE *BD; + SCREENLINE *pLine; + int idx; + RECT rc; + HDC hDC; - pScr->bWrapPending = FALSE; - - if (s < 0) - s = pScr->y; - - if (s + n - 1 > pScr->bottom) - n = pScr->bottom - s + 1; - - TD = GetScreenLineFromY(pScr, s); - BD = GetScreenLineFromY(pScr, s + n - 1); - TI = GetScreenLineFromY(pScr, pScr->bottom); - BI = TI->next; - - /* - Adjust the top of the screen and buffer if they will move. - */ - if (TD == pScr->screen_top) { - if (pScr->screen_top == pScr->buffer_top) - pScr->buffer_top = BD->next; - pScr->screen_top = BD->next; - } - - /* - Adjust the bottom of the screen and buffer if they will move. - */ - if (TI == pScr->screen_bottom) { - if (pScr->screen_bottom == pScr->buffer_bottom) - pScr->buffer_bottom = BD; - pScr->screen_bottom = BD; - } - - if (TI != BD) - ScreenListMove(TD, BD, TI, BI); - - /* - Clear the lines moved from the deleted area to the - bottom of the scrolling area. - */ - pLine = TI; - - for (idx = 0; idx < n; idx++) { - pLine = pLine->next; - ScreenClearLine(pScr, pLine); - } - -// CheckScreen(pScr); - - /* - Scroll the affected area on the screen. - */ - rc.left = 0; - rc.right = pScr->width * pScr->cxChar; - rc.top = s * pScr->cyChar; - rc.bottom = (pScr->bottom + 1) * pScr->cyChar; - - hDC = GetDC(pScr->hWnd); - - ScrollDC(hDC, 0, -pScr->cyChar * n, &rc, &rc, NULL, NULL); - - PatBlt(hDC, 0, (pScr->bottom - n + 1) * pScr->cyChar, - pScr->width * pScr->cxChar, n * pScr->cyChar, WHITENESS); - - ReleaseDC(pScr->hWnd, hDC); - -} /* ScreenDelLines */ - - -void ScreenInsertLine( - SCREEN *pScr, - int s) + pScr->bWrapPending = FALSE; + + if (s < 0) + s = pScr->y; + + if (s + n - 1 > pScr->bottom) + n = pScr->bottom - s + 1; + + TD = GetScreenLineFromY(pScr, s); + BD = GetScreenLineFromY(pScr, s + n - 1); + TI = GetScreenLineFromY(pScr, pScr->bottom); + BI = TI->next; + + /* + * Adjust the top of the screen and buffer if they will move. + */ + if (TD == pScr->screen_top) { + if (pScr->screen_top == pScr->buffer_top) + pScr->buffer_top = BD->next; + pScr->screen_top = BD->next; + } + + /* + * Adjust the bottom of the screen and buffer if they will move. + */ + if (TI == pScr->screen_bottom) { + if (pScr->screen_bottom == pScr->buffer_bottom) + pScr->buffer_bottom = BD; + pScr->screen_bottom = BD; + } + + if (TI != BD) + ScreenListMove(TD, BD, TI, BI); + + /* + * Clear the lines moved from the deleted area to the + * bottom of the scrolling area. + */ + pLine = TI; + + for (idx = 0; idx < n; idx++) { + pLine = pLine->next; + ScreenClearLine(pScr, pLine); + } + + /* CheckScreen(pScr); */ + + /* + * Scroll the affected area on the screen. + */ + rc.left = 0; + rc.right = pScr->width * pScr->cxChar; + rc.top = s * pScr->cyChar; + rc.bottom = (pScr->bottom + 1) * pScr->cyChar; + + hDC = GetDC(pScr->hWnd); + + ScrollDC(hDC, 0, -pScr->cyChar * n, &rc, &rc, NULL, NULL); + + PatBlt(hDC, 0, (pScr->bottom - n + 1) * pScr->cyChar, + pScr->width * pScr->cxChar, n * pScr->cyChar, WHITENESS); + + ReleaseDC(pScr->hWnd, hDC); +} + + +void +ScreenInsertLine(SCREEN *pScr, int s) { - ScreenInsLines(pScr, 1, s); - -} /* ScreenInsertLine */ + ScreenInsLines(pScr, 1, s); +} -void ScreenInsLines( - SCREEN *pScr, - int n, - int s) +void +ScreenInsLines(SCREEN *pScr, int n, int s) { - SCREENLINE *TI; - SCREENLINE *BI; - SCREENLINE *TD; - SCREENLINE *BD; - SCREENLINE *pLine; - int idx; - RECT rc; - HDC hDC; + SCREENLINE *TI; + SCREENLINE *BI; + SCREENLINE *TD; + SCREENLINE *BD; + SCREENLINE *pLine; + int idx; + RECT rc; + HDC hDC; - pScr->bWrapPending = FALSE; - - if (s < 0) - s = pScr->y; - - if (s + n - 1 > pScr->bottom) - n = pScr->bottom - s + 1; - - /* - Determine the top and bottom of the insert area. Also determine - the top and bottom of the area to be deleted and moved to the - insert area. - */ - BI = GetScreenLineFromY(pScr, s); - TI = BI->prev; - TD = GetScreenLineFromY(pScr, pScr->bottom - n + 1); - BD = GetScreenLineFromY(pScr, pScr->bottom); - - /* - Adjust the top of the screen and buffer if they will move. - */ - if (BI == pScr->screen_top) { - if (pScr->screen_top == pScr->buffer_top) - pScr->buffer_top = TD; - pScr->screen_top = TD; - } - - /* - Adjust the bottom of the screen and buffer if they will move. - */ - if (BD == pScr->screen_bottom) { - if (pScr->screen_bottom == pScr->buffer_bottom) - pScr->buffer_bottom = TD->prev; - pScr->screen_bottom = TD->prev; - } - - /* - Move lines from the bottom of the scrolling region to the insert area. - */ - if (TD != BI) - ScreenListMove(TD,BD,TI,BI); - - /* - Clear the inserted lines - */ - pLine = GetScreenLineFromY(pScr, s); - - for (idx = 0; idx < n; idx++) { - ScreenClearLine(pScr, pLine); - pLine = pLine->next; - } - -// CheckScreen(pScr); - - /* - Scroll the affected area on the screen. - */ - rc.left = 0; - rc.right = pScr->width * pScr->cxChar; - rc.top = s * pScr->cyChar; - rc.bottom = (pScr->bottom + 1) * pScr->cyChar; - - hDC = GetDC(pScr->hWnd); - - ScrollDC(hDC, 0, pScr->cyChar * n, &rc, &rc, NULL, NULL); - - PatBlt(hDC, 0, s * pScr->cyChar, - pScr->width * pScr->cxChar, n * pScr->cyChar, WHITENESS); - - ReleaseDC(pScr->hWnd, hDC); - -} /* ScreenInsLines */ - - -void ScreenIndex( - SCREEN * pScr) + pScr->bWrapPending = FALSE; + + if (s < 0) + s = pScr->y; + + if (s + n - 1 > pScr->bottom) + n = pScr->bottom - s + 1; + + /* + * Determine the top and bottom of the insert area. Also determine + * the top and bottom of the area to be deleted and moved to the + * insert area. + */ + BI = GetScreenLineFromY(pScr, s); + TI = BI->prev; + TD = GetScreenLineFromY(pScr, pScr->bottom - n + 1); + BD = GetScreenLineFromY(pScr, pScr->bottom); + + /* + * Adjust the top of the screen and buffer if they will move. + */ + if (BI == pScr->screen_top) { + if (pScr->screen_top == pScr->buffer_top) + pScr->buffer_top = TD; + pScr->screen_top = TD; + } + + /* + * Adjust the bottom of the screen and buffer if they will move. + */ + if (BD == pScr->screen_bottom) { + if (pScr->screen_bottom == pScr->buffer_bottom) + pScr->buffer_bottom = TD->prev; + pScr->screen_bottom = TD->prev; + } + + /* + * Move lines from the bottom of the scrolling region to the insert area. + */ + if (TD != BI) + ScreenListMove(TD,BD,TI,BI); + + /* + * Clear the inserted lines + */ + pLine = GetScreenLineFromY(pScr, s); + + for (idx = 0; idx < n; idx++) { + ScreenClearLine(pScr, pLine); + pLine = pLine->next; + } + + /* CheckScreen(pScr); */ + + /* + * Scroll the affected area on the screen. + */ + rc.left = 0; + rc.right = pScr->width * pScr->cxChar; + rc.top = s * pScr->cyChar; + rc.bottom = (pScr->bottom + 1) * pScr->cyChar; + + hDC = GetDC(pScr->hWnd); + + ScrollDC(hDC, 0, pScr->cyChar * n, &rc, &rc, NULL, NULL); + + PatBlt(hDC, 0, s * pScr->cyChar, + pScr->width * pScr->cxChar, n * pScr->cyChar, WHITENESS); + + ReleaseDC(pScr->hWnd, hDC); +} + + +void +ScreenIndex(SCREEN * pScr) { - if (pScr->y >= pScr->bottom) - ScreenScroll(pScr); - else - pScr->y++; - - pScr->bWrapPending = FALSE; + if (pScr->y >= pScr->bottom) + ScreenScroll(pScr); + else + pScr->y++; -} /* ScreenIndex */ + pScr->bWrapPending = FALSE; +} -void ScreenWrapNow( - SCREEN *pScr, - int *xp, - int *yp) +void +ScreenWrapNow(SCREEN *pScr, int *xp, int *yp) { - if (pScr->bWrapPending && pScr->x >= pScr->width - 1) { - pScr->x = 0; - ScreenIndex(pScr); - } - - pScr->bWrapPending = FALSE; + if (pScr->bWrapPending && pScr->x >= pScr->width - 1) { + pScr->x = 0; + ScreenIndex(pScr); + } - *xp = pScr->x; - *yp = pScr->y; + pScr->bWrapPending = FALSE; -} /* ScreenWrapNow */ + *xp = pScr->x; + *yp = pScr->y; +} -void ScreenEraseToEOL( - SCREEN *pScr) +void +ScreenEraseToEOL(SCREEN *pScr) { - int x1 = pScr->x; - int y1 = pScr->y; - int x2 = pScr->width; - int y2 = pScr->y; - int n = -1; - SCREENLINE *pScrLine; - RECT rc; + int x1 = pScr->x; + int y1 = pScr->y; + int x2 = pScr->width; + int y2 = pScr->y; + int n = -1; + SCREENLINE *pScrLine; + RECT rc; - ScreenWrapNow(pScr, &x1, &y1); - - y2 = y1; -// wsprintf(strTmp,"[EraseEOL:%d]",y2); -// OutputDebugString(strTmp); - pScrLine = GetScreenLineFromY(pScr,y2); - memset(&pScrLine->attrib[x1], ScreenClearAttrib, pScr->width-x1+1); - memset(&pScrLine->text[x1], ' ', pScr->width - x1 + 1); - rc.left = x1 * pScr->cxChar; - rc.right = pScr->width * pScr->cxChar; - rc.top = pScr->cyChar * y1; - rc.bottom = pScr->cyChar * (y1 + 1); - InvalidateRect(pScr->hWnd, &rc, TRUE); - UpdateWindow(pScr->hWnd); - -} /* ScreenEraseToEOL */ - - -void ScreenDelChars( - SCREEN *pScr, - int n) -{ - int x = pScr->x; - int y = pScr->y; - int width; - SCREENLINE *pScrLine; - RECT rc; + ScreenWrapNow(pScr, &x1, &y1); + + y2 = y1; +#if 0 + wsprintf(strTmp,"[EraseEOL:%d]",y2); + OutputDebugString(strTmp); +#endif + pScrLine = GetScreenLineFromY(pScr,y2); + memset(&pScrLine->attrib[x1], ScreenClearAttrib, pScr->width-x1+1); + memset(&pScrLine->text[x1], ' ', pScr->width - x1 + 1); + rc.left = x1 * pScr->cxChar; + rc.right = pScr->width * pScr->cxChar; + rc.top = pScr->cyChar * y1; + rc.bottom = pScr->cyChar * (y1 + 1); + InvalidateRect(pScr->hWnd, &rc, TRUE); + UpdateWindow(pScr->hWnd); +} + + +void +ScreenDelChars(SCREEN *pScr, int n) +{ + int x = pScr->x; + int y = pScr->y; + int width; + SCREENLINE *pScrLine; + RECT rc; - pScr->bWrapPending = FALSE; + pScr->bWrapPending = FALSE; - pScrLine = GetScreenLineFromY(pScr, y); + pScrLine = GetScreenLineFromY(pScr, y); - width = pScr->width - x - n; + width = pScr->width - x - n; - if (width > 0) { - memmove(&pScrLine->attrib[x], &pScrLine->attrib[x + n], width); - memmove(&pScrLine->text[x], &pScrLine->text[x + n], width); - } + if (width > 0) { + memmove(&pScrLine->attrib[x], &pScrLine->attrib[x + n], width); + memmove(&pScrLine->text[x], &pScrLine->text[x + n], width); + } - memset(&pScrLine->attrib[pScr->width - n], ScreenClearAttrib, n); - memset(&pScrLine->text[pScr->width - n], ' ', n); + memset(&pScrLine->attrib[pScr->width - n], ScreenClearAttrib, n); + memset(&pScrLine->text[pScr->width - n], ' ', n); - rc.left = x * pScr->cxChar; - rc.right = pScr->width * pScr->cxChar; - rc.top = pScr->cyChar * y; - rc.bottom = pScr->cyChar * (y + 1); + rc.left = x * pScr->cxChar; + rc.right = pScr->width * pScr->cxChar; + rc.top = pScr->cyChar * y; + rc.bottom = pScr->cyChar * (y + 1); - InvalidateRect(pScr->hWnd, &rc, TRUE); + InvalidateRect(pScr->hWnd, &rc, TRUE); - UpdateWindow(pScr->hWnd); + UpdateWindow(pScr->hWnd); +} -} /* ScreenDelChars */ - -void ScreenRevIndex( - SCREEN *pScr) +void +ScreenRevIndex(SCREEN *pScr) { - SCREENLINE *pScrLine; - SCREENLINE *pTopLine; + SCREENLINE *pScrLine; + SCREENLINE *pTopLine; - pScr->bWrapPending = FALSE; - pScrLine = GetScreenLineFromY(pScr, pScr->y); - pTopLine = GetScreenLineFromY(pScr, pScr->top); - - if(pScrLine == pTopLine) - ScreenInsertLine(pScr, pScr->y); - else - pScr->y--; + pScr->bWrapPending = FALSE; + pScrLine = GetScreenLineFromY(pScr, pScr->y); + pTopLine = GetScreenLineFromY(pScr, pScr->top); -} /* ScreenRevIndex */ + if(pScrLine == pTopLine) + ScreenInsertLine(pScr, pScr->y); + else + pScr->y--; +} -void ScreenEraseToBOL( - SCREEN *pScr) +void +ScreenEraseToBOL(SCREEN *pScr) { - int x1 = 0; - int y1 = pScr->y; - int x2 = pScr->x; - int y2 = pScr->y; - int n = -1; - SCREENLINE *pScrLine; + int x1 = 0; + int y1 = pScr->y; + int x2 = pScr->x; + int y2 = pScr->y; + int n = -1; + SCREENLINE *pScrLine; - pScrLine = GetScreenLineFromY(pScr, pScr->y); + pScrLine = GetScreenLineFromY(pScr, pScr->y); - ScreenWrapNow(pScr, &x2, &y1); - y2 = y1; - memset(pScrLine->attrib, ScreenClearAttrib, x2); - memset(pScrLine->text, ' ', x2); + ScreenWrapNow(pScr, &x2, &y1); + y2 = y1; + memset(pScrLine->attrib, ScreenClearAttrib, x2); + memset(pScrLine->text, ' ', x2); +} -} /* ScreenEraseToBOL */ - -void ScreenEraseLine( - SCREEN *pScr, - int s) +void +ScreenEraseLine(SCREEN *pScr, int s) { - int x1 = 0; - int y1 = s; - int x2 = pScr->width; - int y2 = s; - int n = -1; - SCREENLINE *pScrLine; - RECT rc; + int x1 = 0; + int y1 = s; + int x2 = pScr->width; + int y2 = s; + int n = -1; + SCREENLINE *pScrLine; + RECT rc; - if (s < 0) { - ScreenWrapNow(pScr, &x1, &y1); - s = y2 = y1; - x1 = 0; - } - - pScrLine = GetScreenLineFromY(pScr,y1); - memset(pScrLine->attrib, ScreenClearAttrib, pScr->width); - memset(pScrLine->text, ' ', pScr->width); - rc.left = 0; - rc.right = pScr->width * pScr->cxChar; - rc.top = pScr->cyChar * y1; - rc.bottom = pScr->cyChar * (y1+1); - InvalidateRect(pScr->hWnd, &rc, TRUE); - SendMessage(pScr->hWnd, WM_PAINT, NULL, NULL); - -} /* ScreenEraseLine */ - - -void ScreenEraseToEndOfScreen( - SCREEN *pScr) + if (s < 0) { + ScreenWrapNow(pScr, &x1, &y1); + s = y2 = y1; + x1 = 0; + } + + pScrLine = GetScreenLineFromY(pScr,y1); + memset(pScrLine->attrib, ScreenClearAttrib, pScr->width); + memset(pScrLine->text, ' ', pScr->width); + rc.left = 0; + rc.right = pScr->width * pScr->cxChar; + rc.top = pScr->cyChar * y1; + rc.bottom = pScr->cyChar * (y1+1); + InvalidateRect(pScr->hWnd, &rc, TRUE); + SendMessage(pScr->hWnd, WM_PAINT, 0, 0); +} + + +void +ScreenEraseToEndOfScreen(SCREEN *pScr) { - int i; - int x1 = 0; - int y1 = pScr->y+1; - int x2 = pScr->width; - int y2 = pScr->height; - int n = -1; - - ScreenWrapNow(pScr, &x1, &y1); - y1++; - x1 = 0; - i = y1; - ScreenEraseToEOL(pScr); - while (i < pScr->height) { - ScreenELO(pScr, i); - ScreenEraseLine(pScr, i); - i++; - } - -} /* ScreenEraseToEndOfScreen */ - - -void ScreenRange( - SCREEN *pScr) + int i; + int x1 = 0; + int y1 = pScr->y+1; + int x2 = pScr->width; + int y2 = pScr->height; + int n = -1; + + ScreenWrapNow(pScr, &x1, &y1); + y1++; + x1 = 0; + i = y1; + ScreenEraseToEOL(pScr); + while (i < pScr->height) { + ScreenELO(pScr, i); + ScreenEraseLine(pScr, i); + i++; + } +} + + +void +ScreenRange(SCREEN *pScr) { - if (pScr->x < 0) - pScr->x = 0; + if (pScr->x < 0) + pScr->x = 0; - if (pScr->x >= pScr->width) - pScr->x = pScr->width - 1; + if (pScr->x >= pScr->width) + pScr->x = pScr->width - 1; - if (pScr->y < 0) - pScr->y = 0; + if (pScr->y < 0) + pScr->y = 0; - if (pScr->y >= pScr->height) - pScr->y = pScr->height - 1; + if (pScr->y >= pScr->height) + pScr->y = pScr->height - 1; +} -} /* ScreenRange */ - -void ScreenAlign( - SCREEN *pScr) /* vt100 alignment, fill screen with 'E's */ +void +ScreenAlign(SCREEN *pScr) /* vt100 alignment, fill screen with 'E's */ { - char *tt; - int i; - int j; - SCREENLINE *pScrLine; + char *tt; + int i; + int j; + SCREENLINE *pScrLine; - pScrLine = GetScreenLineFromY(pScr, pScr->top); - ScreenEraseScreen(pScr); - - for(j = 0; j < pScr->height; j++) { - tt = &pScrLine->text[0]; - for(i = 0; i <= pScr->width; i++) - *tt++ = 'E'; - pScrLine = pScrLine->next; - } + pScrLine = GetScreenLineFromY(pScr, pScr->top); + ScreenEraseScreen(pScr); -} /* ScreenAlign */ + for(j = 0; j < pScr->height; j++) { + tt = &pScrLine->text[0]; + for(i = 0; i <= pScr->width; i++) + *tt++ = 'E'; + pScrLine = pScrLine->next; + } +} -void ScreenApClear( - SCREEN *pScr) +void +ScreenApClear(SCREEN *pScr) { - /* - reset all the ANSI parameters back to the default state - */ - for(pScr->parmptr=5; pScr->parmptr>=0; pScr->parmptr--) - pScr->parms[pScr->parmptr] = -1; + /* + * reset all the ANSI parameters back to the default state + */ + for(pScr->parmptr=5; pScr->parmptr>=0; pScr->parmptr--) + pScr->parms[pScr->parmptr] = -1; - pScr->parmptr = 0; + pScr->parmptr = 0; +} -} /* ScreenApClear */ - -void ScreenSetOption( - SCREEN *pScr, - int toggle) +void +ScreenSetOption(SCREEN *pScr, int toggle) { - if (pScr->parms[0] == -2 && pScr->parms[1] == 1) - pScr->DECCKM = toggle; - - #if 0 - switch(pScr->parms[0]) { + if (pScr->parms[0] == -2 && pScr->parms[1] == 1) + pScr->DECCKM = toggle; - case -2: // Set on the '?' char - switch(pScr->parms[1]) { +#if 0 + switch(pScr->parms[0]) { - case 1: /* set/reset cursor key mode */ - pScr->DECCKM = toggle; - break; + case -2: /* Set on the '?' char */ + switch(pScr->parms[1]) { - #ifdef NOT_SUPPORTED - case 2: /* set/reset ANSI/vt52 mode */ - break; - #endif + case 1: /* set/reset cursor key mode */ + pScr->DECCKM = toggle; + break; - case 3: /* set/reset column mode */ - pScr->x = pScr->y = 0; /* Clear the screen, mama! */ - ScreenEraseScreen(pScr); - #if 0 /* removed for variable screen size */ - if (toggle) /* 132 column mode */ - pScr->width = pScr->allwidth; - else - pScr->width = 79; - #endif - break; +#ifdef NOT_SUPPORTED + case 2: /* set/reset ANSI/vt52 mode */ + break; +#endif - #ifdef NOT_SUPPORTED - case 4: /* set/reset scrolling mode */ - case 5: /* set/reset screen mode */ - case 6: /* set/rest origin mode */ - pScr->DECORG = toggle; - break; - #endif + case 3: /* set/reset column mode */ + pScr->x = pScr->y = 0; /* Clear the screen, mama! */ + ScreenEraseScreen(pScr); +#if 0 /* removed for variable screen size */ + if (toggle) /* 132 column mode */ + pScr->width = pScr->allwidth; + else + pScr->width = 79; +#endif + break; - case 7: /* set/reset wrap mode */ - pScr->DECAWM = toggle; -// set_vtwrap(pScrn, fpScr->DECAWM); /* QAK - 7/27/90: added because resetting the virtual screen's wrapping flag doesn't reset telnet window's wrapping */ - break; +#ifdef NOT_SUPPORTED + case 4: /* set/reset scrolling mode */ + case 5: /* set/reset screen mode */ + case 6: /* set/rest origin mode */ + pScr->DECORG = toggle; + break; +#endif - #ifdef NOT_SUPPORTED - case 8: /* set/reset autorepeat mode */ - case 9: /* set/reset interlace mode */ - break; - #endif + case 7: /* set/reset wrap mode */ + pScr->DECAWM = toggle; +#if 0 + /* + * QAK - 7/27/90: added because resetting the virtual screen's + * wrapping flag doesn't reset telnet window's wrapping + */ + set_vtwrap(pScrn, fpScr->DECAWM); +#endif + break; - default: - break; - } /* end switch */ - break; +#ifdef NOT_SUPPORTED + case 8: /* set/reset autorepeat mode */ + case 9: /* set/reset interlace mode */ + break; +#endif - case 4: - pScr->IRM=toggle; - break; + default: + break; + } /* end switch */ + break; - default: - break; + case 4: + pScr->IRM=toggle; + break; - } /* end switch */ + default: + break; - #endif -} /* ScreenSetOption */ + } /* end switch */ +#endif +} #ifdef NOT_SUPPORTED - void ScreenTab( - SCREEN *pScr) - { - if (pScr->x> = pScr->width) - pScr->x = pScr->width; - pScr->x++; - while (pScr->tabs[fpScr->x] != 'x' && pScr->x < pScr->width) - pScr->x++; - } /* ScreenTab */ +void +ScreenTab(SCREEN *pScr) +{ + if (pScr->x> = pScr->width) + pScr->x = pScr->width; + pScr->x++; + while (pScr->tabs[fpScr->x] != 'x' && pScr->x < pScr->width) + pScr->x++; +} #endif -int ScreenInsChar( - SCREEN *pScr, - int x) +int +ScreenInsChar(SCREEN *pScr, int x) { - int i; - SCREENLINE *pScrLine; - RECT rc; + int i; + SCREENLINE *pScrLine; + RECT rc; - pScrLine = GetScreenLineFromY(pScr, pScr->y); - if (pScrLine == NULL) - return(-1); - - for(i = pScr->width - x; i >= pScr->x; i--) { - pScrLine->text[x+i] = pScrLine->text[i]; - pScrLine->attrib[x+i] = pScrLine->attrib[i]; - } - - memset(&pScrLine->attrib[pScr->x], ScreenClearAttrib, x); - memset(&pScrLine->text[pScr->x], ' ', x); - rc.left = pScr->cxChar * x; - rc.right = pScr->cxChar * (x + pScr->x); - rc.top = pScr->cyChar * (pScr->y - 1); - rc.bottom = pScr->cyChar * pScr->y; - InvalidateRect(pScr->hWnd, &rc, TRUE); - SendMessage(pScr->hWnd, WM_PAINT, NULL, NULL); - -} /* ScreenInsChar */ - - -void ScreenSaveCursor( - SCREEN *pScr) + pScrLine = GetScreenLineFromY(pScr, pScr->y); + if (pScrLine == NULL) + return(-1); + + for(i = pScr->width - x; i >= pScr->x; i--) { + pScrLine->text[x+i] = pScrLine->text[i]; + pScrLine->attrib[x+i] = pScrLine->attrib[i]; + } + + memset(&pScrLine->attrib[pScr->x], ScreenClearAttrib, x); + memset(&pScrLine->text[pScr->x], ' ', x); + rc.left = pScr->cxChar * x; + rc.right = pScr->cxChar * (x + pScr->x); + rc.top = pScr->cyChar * (pScr->y - 1); + rc.bottom = pScr->cyChar * pScr->y; + InvalidateRect(pScr->hWnd, &rc, TRUE); + SendMessage(pScr->hWnd, WM_PAINT, 0, 0); +} + + +void +ScreenSaveCursor(SCREEN *pScr) { - pScr->Px = pScr->x; - pScr->Py = pScr->y; - pScr->Pattrib = pScr->attrib; - -} /* ScreenSaveCursor */ + pScr->Px = pScr->x; + pScr->Py = pScr->y; + pScr->Pattrib = pScr->attrib; +} -void ScreenRestoreCursor( - SCREEN *pScr) +void +ScreenRestoreCursor(SCREEN *pScr) { - pScr->x = pScr->Px; - pScr->y = pScr->Py; - ScreenRange(pScr); - -} /* ScreenRestoreCursor */ + pScr->x = pScr->Px; + pScr->y = pScr->Py; + ScreenRange(pScr); +} -void ScreenDraw( - SCREEN *pScr, - int x, - int y, - int a, - int len, - char *c) +void +ScreenDraw(SCREEN *pScr, int x, int y, int a, int len, char *c) { - int idx; - SCREENLINE *pScrLine; - RECT rc; + int idx; + SCREENLINE *pScrLine; + RECT rc; - pScrLine = GetScreenLineFromY(pScr, y); - assert(pScrLine != NULL); + pScrLine = GetScreenLineFromY(pScr, y); + assert(pScrLine != NULL); - for(idx = x; idx < x + len; idx++) { - pScrLine->text[idx] = c[idx - x]; - pScrLine->attrib[idx - x] = a; - } + for(idx = x; idx < x + len; idx++) { + pScrLine->text[idx] = c[idx - x]; + pScrLine->attrib[idx - x] = a; + } - rc.left = pScr->cxChar * x; - rc.right = pScr->cxChar * (x + len); - rc.top = pScr->cyChar * pScr->y; - rc.bottom = pScr->cyChar * (pScr->y + 1); - InvalidateRect(pScr->hWnd, &rc, TRUE); - SendMessage(pScr->hWnd, WM_PAINT, NULL, NULL); - -} /* ScreenDraw */ + rc.left = pScr->cxChar * x; + rc.right = pScr->cxChar * (x + len); + rc.top = pScr->cyChar * pScr->y; + rc.bottom = pScr->cyChar * (pScr->y + 1); + InvalidateRect(pScr->hWnd, &rc, TRUE); + SendMessage(pScr->hWnd, WM_PAINT, 0, 0); +} #if ! defined(NDEBUG) - BOOL CheckScreen( - SCREEN *pScr) - { - SCREENLINE *pLinePrev; - SCREENLINE *pLine; - int nscreen = 0; - int nbuffer = 0; - int topline = 0; - char buf[512]; - BOOL bBottom; - BOOL bOK; - - pLine = pScr->buffer_top; - - if (pLine == NULL) { - OutputDebugString("CheckScreen: buffer_top invalid"); - MessageBox(NULL, "buffer_top invalid", "CheckScreen", MB_OK); - return(FALSE); - } - - bBottom = FALSE; - while (TRUE) { - pLinePrev = pLine; - if (nscreen > 0 || pLine == pScr->screen_top) - if (!bBottom) - nscreen++; - nbuffer++; - if (pLine == pScr->screen_top) - topline = nbuffer - 1; - if (pLine == pScr->screen_bottom) - bBottom = TRUE; - pLine = pLine->next; - if (pLine == NULL) - break; - if (pLine->prev != pLinePrev) { - wsprintf(buf, - "Previous ptr of line %d does not match next ptr of line %d", - nbuffer, nbuffer - 1); - OutputDebugString(buf); - MessageBox(NULL, buf, "CheckScreen", MB_OK); - } - } - - if (pLinePrev == pScr->buffer_bottom && nscreen == pScr->height) - bOK = TRUE; - else { - OutputDebugString("CheckScreen: Invalid number of lines on screen"); - bOK = FALSE; - } - - wsprintf(buf, \ - "screen.width = %d\n" - "screen.height = %d\n" - "screen.maxlines = %d\n" - "screen.numlines = %d\n" - "screen.x = %d\n" - "screen.y = %d\n" - "screen.top = %d\n" - "screen.bottom = %d\n" - "Actual top line = %d\n" - "Actual buffer lines = %d\n" - "Actual screen lines = %d\n" - "Bottom of buffer is %s", - pScr->width, pScr->height, pScr->maxlines, pScr->numlines, - pScr->x, pScr->y, pScr->top, pScr->bottom, - topline, nbuffer, nscreen, - (pLinePrev == pScr->buffer_bottom) ? "valid" : "invalid"); - - MessageBox(NULL, buf, "CheckScreen", MB_OK); - - return(bOK); - - } /* CheckScreen */ +BOOL +CheckScreen(SCREEN *pScr) +{ + SCREENLINE *pLinePrev; + SCREENLINE *pLine; + int nscreen = 0; + int nbuffer = 0; + int topline = 0; + char buf[512]; + BOOL bBottom; + BOOL bOK; + + pLine = pScr->buffer_top; + + if (pLine == NULL) { + OutputDebugString("CheckScreen: buffer_top invalid"); + MessageBox(NULL, "buffer_top invalid", "CheckScreen", MB_OK); + return(FALSE); + } + + bBottom = FALSE; + while (TRUE) { + pLinePrev = pLine; + if (nscreen > 0 || pLine == pScr->screen_top) + if (!bBottom) + nscreen++; + nbuffer++; + if (pLine == pScr->screen_top) + topline = nbuffer - 1; + if (pLine == pScr->screen_bottom) + bBottom = TRUE; + pLine = pLine->next; + if (pLine == NULL) + break; + if (pLine->prev != pLinePrev) { + wsprintf(buf, + "Previous ptr of line %d does not match next ptr of line %d", + nbuffer, nbuffer - 1); + OutputDebugString(buf); + MessageBox(NULL, buf, "CheckScreen", MB_OK); + } + } + + if (pLinePrev == pScr->buffer_bottom && nscreen == pScr->height) + bOK = TRUE; + else { + OutputDebugString("CheckScreen: Invalid number of lines on screen"); + bOK = FALSE; + } + + wsprintf(buf, "screen.width = %d\nscreen.height = %d\nscreen.maxlines = %d\nscreen.numlines = %d\nscreen.x = %d\nscreen.y = %d\nscreen.top = %d\nscreen.bottom = %d\nActual top line = %d\nActual buffer lines = %d\nActual screen lines = %d\nBottom of buffer is %s", + pScr->width, pScr->height, pScr->maxlines, pScr->numlines, + pScr->x, pScr->y, pScr->top, pScr->bottom, + topline, nbuffer, nscreen, + (pLinePrev == pScr->buffer_bottom) ? "valid" : "invalid"); + + MessageBox(NULL, buf, "CheckScreen", MB_OK); + + return(bOK); +} #endif diff --git a/src/windows/wintel/k5stream.c b/src/windows/wintel/k5stream.c index 3745ed5a1a..4c36cd0b0d 100644 --- a/src/windows/wintel/k5stream.c +++ b/src/windows/wintel/k5stream.c @@ -1,10 +1,10 @@ -/*+************************************************************************* -** -** K5stream -** -** Emulates the kstream package in Kerberos 4 -** -***************************************************************************/ +/* + * + * K5stream + * + * Emulates the kstream package in Kerberos 4 + * + */ #include <stdio.h> #include <io.h> @@ -14,50 +14,106 @@ #include "auth.h" int -kstream_destroy (kstream ks) { - if (ks != NULL) { - auth_destroy (ks); /* Destroy authorizing */ - - closesocket (ks->fd); /* Close the socket??? */ - free (ks); - } - return 0; +kstream_destroy(kstream ks) +{ + if (ks != NULL) { + auth_destroy(ks); /* Destroy authorizing */ + + closesocket(ks->fd); /* Close the socket??? */ + free(ks); + } + return 0; } void -kstream_set_buffer_mode (kstream ks, int mode) { +kstream_set_buffer_mode(kstream ks, int mode) +{ } kstream -kstream_create_from_fd (int fd, - const struct kstream_crypt_ctl_block __far *ctl, - kstream_ptr data) +kstream_create_from_fd(int fd, + const struct kstream_crypt_ctl_block FAR *ctl, + kstream_ptr data) { - kstream ks; - int n; + kstream ks; + int n; + BOOL on = 1; + + ks = malloc(sizeof(struct kstream_int)); + if (ks == NULL) + return NULL; + + ks->fd = fd; - ks = malloc (sizeof(kstream *)); - if (ks == NULL) - return NULL; + setsockopt(ks->fd, SOL_SOCKET, SO_OOBINLINE, (const char *)&on, sizeof(on)); - ks->fd = fd; + n = auth_init(ks, data); /* Initialize authorizing */ + if (n) { + free(ks); + return NULL; + } - n = auth_init (ks, data); /* Initialize authorizing */ - if (n) { - free (ks); - return NULL; - } + ks->encrypt = NULL; + ks->decrypt = NULL; - return ks; + return ks; } int -kstream_write (kstream ks, void __far *p_data, size_t p_len) { - int n; +kstream_write(kstream ks, void FAR *p_data, size_t p_len) +{ + int n; + struct kstream_data_block i; + +#ifdef DEBUG + hexdump("plaintext:", p_data, p_len); +#endif + + if (ks->encrypt) { + i.ptr = p_data; + i.length = p_len; + ks->encrypt(&i, NULL, NULL); +#ifdef DEBUG + hexdump("cyphertext:", p_data, p_len); +#endif + } - n = send (ks->fd, p_data, p_len, 0); /* Write the data */ + n = send(ks->fd, p_data, p_len, 0); /* Write the data */ - return n; /* higher layer does retries */ + return n; /* higher layer does retries */ +} + + +int +kstream_read(kstream ks, void FAR *p_data, size_t p_len) +{ + int n; + struct kstream_data_block i; + + n = recv(ks->fd, p_data, p_len, 0); /* read the data */ + + if (n < 0) + return n; + +#ifdef DEBUG + hexdump("input data:", p_data, n); +#endif + + if (ks->decrypt) { + extern int encrypt_flag; + + if (encrypt_flag == 2) + encrypt_flag = 1; + + i.ptr = p_data; + i.length = n; + ks->decrypt(&i, NULL, NULL); +#ifdef DEBUG + hexdump("decrypted data:", p_data, n); +#endif + } + + return n; /* higher layer does retries */ } diff --git a/src/windows/wintel/k5stream.h b/src/windows/wintel/k5stream.h index 0a9ce08082..b9b9ebd33c 100644 --- a/src/windows/wintel/k5stream.h +++ b/src/windows/wintel/k5stream.h @@ -15,38 +15,43 @@ #ifndef K5STREAM_H #define K5STREAM_H -typedef struct { /* Object we pass around */ - int fd; /* Open socket descriptor */ +typedef struct kstream_int { /* Object we pass around */ + int fd; /* Open socket descriptor */ + int (*encrypt)(struct kstream_data_block *, /* output */ + struct kstream_data_block *, /* input */ + struct kstream *kstream); + int (*decrypt)(struct kstream_data_block *, /* output */ + struct kstream_data_block *, /* input */ + struct kstream *kstream); } *kstream; typedef void *kstream_ptr; /* Data send on the kstream */ struct kstream_data_block { - kstream_ptr ptr; - size_t length; + kstream_ptr ptr; + size_t length; }; struct kstream_crypt_ctl_block { - int (INTERFACE *encrypt) ( - struct kstream_data_block *, /* output -- written */ - struct kstream_data_block *, /* input */ - kstream str); - int (INTERFACE *decrypt) ( - struct kstream_data_block *, /* output -- written */ - struct kstream_data_block *, /* input */ - kstream str); - int (INTERFACE *init) (kstream str, kstream_ptr data); - void (INTERFACE *destroy) (kstream str); + int (*encrypt)(struct kstream_data_block *, /* output */ + struct kstream_data_block *, /* input */ + kstream); + int (*decrypt)(struct kstream_data_block *, /* output */ + struct kstream_data_block *, /* input */ + kstream); + int (*init)(kstream, kstream_ptr); + void (*destroy)(kstream); }; /* Prototypes */ -int kstream_destroy (kstream); -void kstream_set_buffer_mode (kstream, int); -kstream kstream_create_from_fd (int fd, - const struct kstream_crypt_ctl_block __far *ctl, - kstream_ptr data); -int kstream_write (kstream, void __far *, size_t); +int kstream_destroy(kstream); +void kstream_set_buffer_mode(kstream, int); +kstream kstream_create_from_fd(int fd, + const struct kstream_crypt_ctl_block FAR *, + kstream_ptr); +int kstream_write(kstream, void FAR *, size_t); +int kstream_read(kstream, void FAR *, size_t); #endif /* K5STREAM_H */ diff --git a/src/windows/wintel/ktelnet.doc b/src/windows/wintel/ktelnet.doc Binary files differnew file mode 100644 index 0000000000..64e4f45269 --- /dev/null +++ b/src/windows/wintel/ktelnet.doc diff --git a/src/windows/wintel/ktelnet.hlp b/src/windows/wintel/ktelnet.hlp Binary files differnew file mode 100644 index 0000000000..e44cebfe57 --- /dev/null +++ b/src/windows/wintel/ktelnet.hlp diff --git a/src/windows/wintel/ktelnet.hpj b/src/windows/wintel/ktelnet.hpj new file mode 100644 index 0000000000..d69185cd81 --- /dev/null +++ b/src/windows/wintel/ktelnet.hpj @@ -0,0 +1,92 @@ +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +; Help Project File for KTELNET +; +; This file is maintained by RoboHELP. Do not modify this file directly. +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +[OPTIONS] +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +; The Options section contains the following information: +; +; The optional BMROOT= entry sets the directories in which the Help Compiler +; will look for graphics. +; +; The CONTENTS= tells WinHelp which topic contains the contents. +; +; The TITLE= is displayed in the Title Bar of WINHELP.EXE +; +; The BUILD= setting allows you to create different Help systems from +; the same source file. +; +; The COMPRESS= option tells the Help Compiler how much to compress +; the Help file. +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;BMROOT=C:\WINDOWS\DESKTOP\KERBEROS 5\WIN95 GUI\CNS HELP +TITLE=Kerb*Net Telnet for Windows +BUILD=WINDOWS +NOTES=1 + + +OLDKEYPHRASE=NO +OPTCDROM=0 +REPORT=YES +COMPRESS=12 +ERRORLOG=C:\windows\desktop\kerberos 5\win95 gui\cns help\KTELNET.ERR +[BUILDTAGS] +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +; The Build Tags section specifies to the Help Compiler the names +; of all the valid build tags used in this Help project. +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +WINDOWS + + +[CONFIG] +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +; The Config section defines macros which will run at startup. +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + + + +[FILES] +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +; The Files section specifies the RTF files for a project. +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +KTELNET.RTF +[ALIAS] +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +; The Alias section sets up aliases for Topic IDs in your Help system. +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +[MAP] +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +; The Map section specifies the project HH files. +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +[BITMAPS] +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +; The Bitmaps section specifies the referenced bitmaps used in +; your help system. +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +[WINDOWS] +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +; The Windows section contains all of the information about the windows +; in a Help project. +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;Gloss = "Glossary",(100,100,350,350),0,(255,255,255),(255,255,255) +main=,,29188,, +(w95sec)=,,20740,(r14745599),(r14745599),f2 + + +[BAGGAGE] +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +; The Baggage section specifies any additional files. +;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + diff --git a/src/windows/wintel/negotiat.c b/src/windows/wintel/negotiat.c index 58bf97d90f..685092df59 100644 --- a/src/windows/wintel/negotiat.c +++ b/src/windows/wintel/negotiat.c @@ -1,24 +1,34 @@ /* -* negotiat.c -* -* Telnet option negotiation functions -* + * negotiat.c + * + * Telnet option negotiation functions + * /* -* Includes -*/ + * Includes + */ /* #define USETEK */ /* #define USERAS */ -#if 0 /* define this to print the raw network data to debuging monitor */ -#define NEGOTIATEDEBUG +#ifdef DEBUG /* define this to print the raw network data to debuging monitor */ +#define NEGOTIATEDEBUG +#endif + +#if 0 +#define PRINT_EVERYTHING /* talk a lot */ #endif #include <time.h> #include "telnet.h" -#include "telopts.h" +#include "telnet_arpa.h" #include "auth.h" +#include "encrypt.h" + +#define STNORM 0 +#define NEGOTIATE 1 +#define ESCFOUND 5 +#define IACFOUND 6 unsigned char parsedat[256]; @@ -27,766 +37,829 @@ static void parse_subnegotiat(kstream ks,int end_sub); /* Local variables */ static char *telstates[]={ - "EOF", - "Suspend Process", - "Abort Process", - "Unknown (239)", - "Subnegotiation End", - "NOP", - "Data Mark", - "Break", - "Interrupt Process", - "Abort Output", - "Are You There", - "Erase Character", - "Erase Line", - "Go Ahead", - "Subnegotiate", - "Will", - "Won't", - "Do", - "Don't" + "EOF", + "Suspend Process", + "Abort Process", + "Unknown (239)", + "Subnegotiation End", + "NOP", + "Data Mark", + "Break", + "Interrupt Process", + "Abort Output", + "Are You There", + "Erase Character", + "Erase Line", + "Go Ahead", + "Subnegotiate", + "Will", + "Won't", + "Do", + "Don't" }; static char *teloptions[256]={ /* ascii strings for Telnet options */ - "Binary", /* 0 */ - "Echo", - "Reconnection", - "Supress Go Ahead", - "Message Size Negotiation", - "Status", /* 5 */ - "Timing Mark", - "Remote Controlled Trans and Echo", - "Output Line Width", - "Output Page Size", - "Output Carriage-Return Disposition", /* 10 */ - "Output Horizontal Tab Stops", - "Output Horizontal Tab Disposition", - "Output Formfeed Disposition", - "Output Vertical Tabstops", - "Output Vertical Tab Disposition", /* 15 */ - "Output Linefeed Disposition", - "Extended ASCII", - "Logout", - "Byte Macro", - "Data Entry Terminal", /* 20 */ - "SUPDUP", - "SUPDUP Output", - "Send Location", - "Terminal Type", - "End of Record", /* 25 */ - "TACACS User Identification", - "Output Marking", - "Terminal Location Number", - "3270 Regime", - "X.3 PAD", /* 30 */ - "Negotiate About Window Size", - "Terminal Speed", - "Toggle Flow Control", - "Linemode", - "X Display Location", /* 35 */ - "Environment", - "Authentication", - "Data Encryption", - "39", - "40","41","42","43","44","45","46","47","48","49", - "50","51","52","53","54","55","56","57","58","59", - "60","61","62","63","64","65","66","67","68","69", - "70","71","72","73","74","75","76","77","78","79", - "80","81","82","83","84","85","86","87","88","89", - "90","91","92","93","94","95","96","97","98","99", - "100","101","102","103","104","105","106","107","108","109", - "110","111","112","113","114","115","116","117","118","119", - "120","121","122","123","124","125","126","127","128","129", - "130","131","132","133","134","135","136","137","138","139", - "140","141","142","143","144","145","146","147","148","149", - "150","151","152","153","154","155","156","157","158","159", - "160","161","162","163","164","165","166","167","168","169", - "170","171","172","173","174","175","176","177","178","179", - "180","181","182","183","184","185","186","187","188","189", - "190","191","192","193","194","195","196","197","198","199", - "200","201","202","203","204","205","206","207","208","209", - "210","211","212","213","214","215","216","217","218","219", - "220","221","222","223","224","225","226","227","228","229", - "230","231","232","233","234","235","236","237","238","239", - "240","241","242","243","244","245","246","247","248","249", - "250","251","252","253","254", - "Extended Options List" /* 255 */ + "Binary", /* 0 */ + "Echo", + "Reconnection", + "Supress Go Ahead", + "Message Size Negotiation", + "Status", /* 5 */ + "Timing Mark", + "Remote Controlled Trans and Echo", + "Output Line Width", + "Output Page Size", + "Output Carriage-Return Disposition", /* 10 */ + "Output Horizontal Tab Stops", + "Output Horizontal Tab Disposition", + "Output Formfeed Disposition", + "Output Vertical Tabstops", + "Output Vertical Tab Disposition", /* 15 */ + "Output Linefeed Disposition", + "Extended ASCII", + "Logout", + "Byte Macro", + "Data Entry Terminal", /* 20 */ + "SUPDUP", + "SUPDUP Output", + "Send Location", + "Terminal Type", + "End of Record", /* 25 */ + "TACACS User Identification", + "Output Marking", + "Terminal Location Number", + "3270 Regime", + "X.3 PAD", /* 30 */ + "Negotiate About Window Size", + "Terminal Speed", + "Toggle Flow Control", + "Linemode", + "X Display Location", /* 35 */ + "Environment", + "Authentication", + "Data Encryption", + "39", + "40","41","42","43","44","45","46","47","48","49", + "50","51","52","53","54","55","56","57","58","59", + "60","61","62","63","64","65","66","67","68","69", + "70","71","72","73","74","75","76","77","78","79", + "80","81","82","83","84","85","86","87","88","89", + "90","91","92","93","94","95","96","97","98","99", + "100","101","102","103","104","105","106","107","108","109", + "110","111","112","113","114","115","116","117","118","119", + "120","121","122","123","124","125","126","127","128","129", + "130","131","132","133","134","135","136","137","138","139", + "140","141","142","143","144","145","146","147","148","149", + "150","151","152","153","154","155","156","157","158","159", + "160","161","162","163","164","165","166","167","168","169", + "170","171","172","173","174","175","176","177","178","179", + "180","181","182","183","184","185","186","187","188","189", + "190","191","192","193","194","195","196","197","198","199", + "200","201","202","203","204","205","206","207","208","209", + "210","211","212","213","214","215","216","217","218","219", + "220","221","222","223","224","225","226","227","228","229", + "230","231","232","233","234","235","236","237","238","239", + "240","241","242","243","244","245","246","247","248","249", + "250","251","252","253","254", + "Extended Options List" /* 255 */ }; static char *LMoptions[]={ /* ascii strings for Linemode sub-options */ - "None", "MODE", "FORWARDMASK", "SLC" + "None", "MODE", "FORWARDMASK", "SLC" }; static char *ModeOptions[]={ /* ascii strings for Linemode edit options */ - "None", "EDIT", "TRAPSIG", "ACK", "SOFT TAB", "LIT ECHO" + "None", "EDIT", "TRAPSIG", "ACK", "SOFT TAB", "LIT ECHO" }; static char *SLCoptions[]={ /* ascii strings for Linemode SLC characters */ - "None", "SYNCH", "BREAK", "IP", "ABORT OUTPUT", - "AYT", "EOR", "ABORT", "EOF", "SUSP", - "EC", "EL", "EW", "RP", "LNEXT", - "XON", "XOFF", "FORW1", "FORW2", "MCL", - "MCR", "MCWL", "MCWR", "MCBOL", "MCEOL", - "INSRT", "OVER", "ECR", "EWR", "EBOL", - "EEOL" + "None", "SYNCH", "BREAK", "IP", "ABORT OUTPUT", + "AYT", "EOR", "ABORT", "EOF", "SUSP", + "EC", "EL", "EW", "RP", "LNEXT", + "XON", "XOFF", "FORW1", "FORW2", "MCL", + "MCR", "MCWL", "MCWR", "MCBOL", "MCEOL", + "INSRT", "OVER", "ECR", "EWR", "EBOL", + "EEOL" }; static char *SLCflags[]={ /* ascii strings for Linemode SLC flags */ - "SLC_NOSUPPORT", "SLC_CANTCHANGE", "SLC_VALUE", "SLC_DEFAULT" + "SLC_NOSUPPORT", "SLC_CANTCHANGE", "SLC_VALUE", "SLC_DEFAULT" }; - /* Linemode default character for each function */ -static unsigned char LMdefaults[NUMLMODEOPTIONS+1]={ - (unsigned char)-1, /* zero isn't used */ - (unsigned char)-1, /* we don't support SYNCH */ - 3, /* ^C is default for BRK */ - 3, /* ^C is default for IP */ - 15, /* ^O is default for AO */ - 25, /* ^Y is default for AYT */ /* 5 */ - (unsigned char)-1, /* we don't support EOR */ - 3, /* ^C is default for ABORT */ - 4, /* ^D is default for EOF */ - 26, /* ^Z is default for SUSP */ - 8, /* ^H is default for EC */ /* 10 */ - 21, /* ^U is default for EL */ - 23, /* ^W is default for EW */ - 18, /* ^R is default for RP */ - 22, /* ^V is default for LNEXT */ - 17, /* ^Q is default for XON */ /* 15 */ - 19, /* ^S is default for XOFF */ - 22, /* ^V is default for FORW1 */ - 5, /* ^E is default for FORW2 */ - (unsigned char)-1, /* we don't support MCL */ - (unsigned char)-1, /* we don't support MCR */ /* 20 */ - (unsigned char)-1, /* we don't support MCWL */ - (unsigned char)-1, /* we don't support MCWR */ - (unsigned char)-1, /* we don't support MCBOL */ - (unsigned char)-1, /* we don't support MCEOL */ - (unsigned char)-1, /* we don't support INSRT */ /* 25 */ - (unsigned char)-1, /* we don't support OVER */ - (unsigned char)-1, /* we don't support ECR */ - (unsigned char)-1, /* we don't support EWR */ - (unsigned char)-1, /* we don't support EBOL */ - (unsigned char)-1 /* we don't support EEOL */ /* 30 */ +/* Linemode default character for each function */ +static unsigned char LMdefaults[NTELOPTS + 1]={ + (unsigned char)-1, /* zero isn't used */ + (unsigned char)-1, /* we don't support SYNCH */ + 3, /* ^C is default for BRK */ + 3, /* ^C is default for IP */ + 15, /* ^O is default for AO */ + 25, /* ^Y is default for AYT */ /* 5 */ + (unsigned char)-1, /* we don't support EOR */ + 3, /* ^C is default for ABORT */ + 4, /* ^D is default for EOF */ + 26, /* ^Z is default for SUSP */ + 8, /* ^H is default for EC */ /* 10 */ + 21, /* ^U is default for EL */ + 23, /* ^W is default for EW */ + 18, /* ^R is default for RP */ + 22, /* ^V is default for LNEXT */ + 17, /* ^Q is default for XON */ /* 15 */ + 19, /* ^S is default for XOFF */ + 22, /* ^V is default for FORW1 */ + 5, /* ^E is default for FORW2 */ + (unsigned char)-1, /* we don't support MCL */ + (unsigned char)-1, /* we don't support MCR */ /* 20 */ + (unsigned char)-1, /* we don't support MCWL */ + (unsigned char)-1, /* we don't support MCWR */ + (unsigned char)-1, /* we don't support MCBOL */ + (unsigned char)-1, /* we don't support MCEOL */ + (unsigned char)-1, /* we don't support INSRT */ /* 25 */ + (unsigned char)-1, /* we don't support OVER */ + (unsigned char)-1, /* we don't support ECR */ + (unsigned char)-1, /* we don't support EWR */ + (unsigned char)-1, /* we don't support EBOL */ + (unsigned char)-1 /* we don't support EEOL */ /* 30 */ }; -/*+******************************************************************** -* Function : start_negotiation() -* Purpose : Send the initial negotiations on the network and print -* the negotitations to the console screen. -* Parameters : -* dat - the port number to write to -* cvs - the console's virtual screen -* Returns : none -* Calls : tprintf(), netprintf() -* Called by : dosessions() -**********************************************************************/ +/* + * Function : start_negotiation() + * Purpose : Send the initial negotiations on the network and print + * the negotitations to the console screen. + * Parameters : + * dat - the port number to write to + * cvs - the console's virtual screen + * Returns : none + * Calls : tprintf(), netprintf() + * Called by : dosessions() + */ void start_negotiation(kstream ks) { - char buf[128]; + char buf[128]; - /* Send the initial tlnet negotiations */ - wsprintf(buf,"%c%c%c",IAC,DOTEL,SGA); - TelnetSend(ks,buf,lstrlen(buf),0); - wsprintf(buf,"%c%c%c",IAC,DOTEL,ECHO); - TelnetSend(ks,buf,lstrlen(buf),0); - wsprintf(buf,"%c%c%c",IAC,WILLTEL,NAWS); - TelnetSend(ks,buf,lstrlen(buf),0); + /* Send the initial telnet negotiations */ +#ifdef ENCRYPTION /* XXX */ + if (encrypt_flag) + wsprintf(buf,"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", + IAC, WILL, TELOPT_AUTHENTICATION, + IAC, WILL, TELOPT_ENCRYPT, + IAC, DO, TELOPT_SGA, + IAC, DO, TELOPT_ECHO, + IAC, WILL, TELOPT_NAWS + ); + else +#endif + wsprintf(buf,"%c%c%c%c%c%c%c%c%c%c%c%c", + IAC, WILL, TELOPT_AUTHENTICATION, + IAC, DO, TELOPT_SGA, + IAC, DO, TELOPT_ECHO, + IAC, WILL, TELOPT_NAWS + ); + TelnetSend(ks,buf,lstrlen(buf),0); #ifdef NOT - /* check whether we are going to be output mapping */ - if(tw->mapoutput) { - netprintf(tw->pnum,"%c%c%c",IAC,DOTEL,BINARY); + /* check whether we are going to be output mapping */ + if(tw->mapoutput) { + netprintf(tw->pnum,"%c%c%c",IAC,DO,TELOPT_BINARY); /* set the flag indicating we wanted server to start transmitting binary */ - tw->uwantbinary=1; - netprintf(tw->pnum,"%c%c%c",IAC,WILLTEL,BINARY); + tw->uwantbinary=1; + netprintf(tw->pnum,"%c%c%c",IAC,WILL,TELOPT_BINARY); /* set the flag indicating we want to start transmitting binary */ - tw->iwantbinary=1; - } /* end if */ + tw->iwantbinary=1; + } /* end if */ #endif - /* Print to the console what we just did */ + /* Print to the console what we just did */ #ifdef NEGOTIATEDEBUG - wsprintf(strTmp,"SEND: %ls %ls\r\n",telstates[DOTEL-LOW_TEL_OPT], - teloptions[ECHO]); - OutputDebugString(strTmp); - wsprintf(strTmp,"SEND: %ls %ls\r\n",telstates[DOTEL-LOW_TEL_OPT], - teloptions[SGA]); - OutputDebugString(strTmp); - wsprintf(strTmp,"SEND: %ls %ls\r\n",telstates[WILLTEL-LOW_TEL_OPT], - teloptions[NAWS]); - OutputDebugString(strTmp); + wsprintf(strTmp,"SEND: %s %s\r\n",telstates[DO - TELCMD_FIRST], + teloptions[TELOPT_ECHO]); + OutputDebugString(strTmp); + wsprintf(strTmp,"SEND: %s %s\r\n",telstates[DO - TELCMD_FIRST], + teloptions[TELOPT_SGA]); + OutputDebugString(strTmp); + wsprintf(strTmp,"SEND: %s %s\r\n",telstates[WILL - TELCMD_FIRST], + teloptions[TELOPT_NAWS]); + OutputDebugString(strTmp); #ifdef NOT - tprintf(cvs,"SEND: %ls %ls\r\n",telstates[DOTEL-LOW_TEL_OPT], - teloptions[BINARY]); - tprintf(cvs,"SEND: %ls %ls\r\n",telstates[WILLTEL-LOW_TEL_OPT], - teloptions[BINARY]); + tprintf(cvs,"SEND: %s %s\r\n",telstates[DO - TELCMD_FIRST], + teloptions[BINARY]); + tprintf(cvs,"SEND: %s %s\r\n",telstates[WILL - TELCMD_FIRST], + teloptions[BINARY]); #endif #endif } /* end start_negotiation() */ -/*+******************************************************************* -* parse -* Do the telnet negotiation parsing. -* -* look at the string which has just come in from outside and -* check for special sequences that we are interested in. -* -* Tries to pass through routine strings immediately, waiting for special -* characters ESC and IAC to change modes. -*/ +/* + * parse + * Do the telnet negotiation parsing. + * + * look at the string which has just come in from outside and + * check for special sequences that we are interested in. + * + * Tries to pass through routine strings immediately, waiting for special + * characters ESC and IAC to change modes. + */ void -parse (CONNECTION *con,unsigned char *st,int cnt) { - static int sub_pos; /* the position we are in the subnegotiation parsing */ - static int end_sub; /* index of last byte in parsedat in a subnegotiation */ - unsigned char *mark, *orig; - char buf[256]; - kstream ks; +parse(CONNECTION *con,unsigned char *st,int cnt) +{ + static int sub_pos; /* the position we are in the subnegotiation parsing */ + static int end_sub; /* index of last byte in parsedat in a subnegotiation */ + unsigned char *mark, *orig; + char buf[256]; + kstream ks; - ks=con->ks; + ks = con->ks; -#ifdef PRINT_EVERYTHING - OutputDebugString("\r\n"); - for(i=0; i<cnt; i++) { - int j; - - for(j=0; (j < 16) && ((i + j) < cnt); j++) { - wsprintf(strTmp,"%2.2X ", *(unsigned char *) (st + i + j)); - OutputDebugString(strTmp); - } - i+=j-1; - OutputDebugString("\r\n"); - } /* end for */ - OutputDebugString("\r\n"); -#endif //PRINT_EVERYTHING +#ifdef PRINT_EVERYTHING + hexdump("Options to process:", st, cnt); +#endif /* PRINT_EVERYTHING */ - orig=st; /* remember beginning point */ - mark=st+cnt; /* set to end of input string */ + orig = st; /* remember beginning point */ + mark = st + cnt; /* set to end of input string */ #ifdef HUH - netpush(tw->pnum); + netpush(tw->pnum); #endif -/* -* traverse string, looking for any special characters which indicate that -* we need to change modes. -*/ - while(st<mark) { - while(con->telstate!=STNORM && st<mark) { - switch(con->telstate) { - case IACFOUND: /* telnet option negotiation */ - if(*st==IAC) { /* real data=255 */ - st++; /* real 255 will get sent */ - con->telstate=STNORM; - break; - } /* end if */ - - if(*st>239) { - con->telstate=*st++; /* by what the option is */ - break; - } /* end if */ + /* + * traverse string, looking for any special characters which indicate that + * we need to change modes. + */ + while(st < mark) { + + while(con->telstate != STNORM && st < mark) { + switch(con->telstate) { + case IACFOUND: /* telnet option negotiation */ + if(*st == IAC) { /* real data=255 */ + st++; /* real 255 will get sent */ + con->telstate = STNORM; + break; + } /* end if */ + + if(*st > 239) { + con->telstate = *st++; /* by what the option is */ + break; + } /* end if */ #ifdef NEGOTIATEDEBUG - wsprintf(buf,"\r\n strange telnet option"); - OutputDebugString(buf); + wsprintf(buf, "\r\n strange telnet option"); + OutputDebugString(buf); #endif - orig=++st; - con->telstate=STNORM; - break; - - case EL: /* received a telnet erase line command */ - case EC: /* received a telnet erase character command */ - case AYT: /* received a telnet Are-You-There command */ - case AO: /* received a telnet Abort Output command */ - case IP: /* received a telnet Interrupt Process command */ - case BREAK: /* received a telnet Break command */ - case DM: /* received a telnet Data Mark command */ - case NOP: /* received a telnet No Operation command */ - case SE: /* received a telnet Subnegotiation End command */ - case ABORT: /* received a telnet Abort Process command */ - case SUSP: /* received a telnet Suspend Process command */ - case TEL_EOF:/* received a telnet EOF command */ + orig=++st; + con->telstate=STNORM; + break; + + case EL: /* received a telnet erase line command */ + case EC: /* received a telnet erase character command */ + case AYT: /* received a telnet Are-You-There command */ + case AO: /* received a telnet Abort Output command */ + case IP: /* received a telnet Interrupt Process command */ + case BREAK: /* received a telnet Break command */ + case DM: /* received a telnet Data Mark command */ + case NOP: /* received a telnet No Operation command */ + case SE: /* received a telnet Subnegotiation End command */ + case ABORT: /* received a telnet Abort Process command */ + case SUSP: /* received a telnet Suspend Process command */ + case xEOF: /* received a telnet EOF command */ #ifdef NEGOTIATEDEBUG - wsprintf(buf,"RECV: %ls\r\n", - telstates[con->telstate-LOW_TEL_OPT]); - OutputDebugString(buf); + wsprintf(buf,"RECV: %s\r\n", + telstates[con->telstate-TELCMD_FIRST]); + OutputDebugString(buf); #endif - con->telstate=STNORM; - orig=++st; - break; + con->telstate=STNORM; + orig=++st; + break; - case GOAHEAD: /* telnet go ahead option*/ + case GA: /* telnet go ahead option*/ #ifdef NEGOTIATEDEBUG - wsprintf(buf,"RECV: %ls\r\n", - telstates[con->telstate-LOW_TEL_OPT]); - OutputDebugString(buf); + wsprintf(buf,"RECV: %s\r\n", + telstates[con->telstate-TELCMD_FIRST]); + OutputDebugString(buf); #endif - con->telstate=STNORM; - orig=++st; - break; + con->telstate=STNORM; + orig=++st; + break; - case DOTEL: /* received a telnet DO negotiation */ + case DO: /* received a telnet DO negotiation */ #ifdef NEGOTIATEDEBUG - wsprintf(buf,"RECV: %ls %ls\r\n", - telstates[con->telstate-LOW_TEL_OPT],teloptions[*st]); - OutputDebugString(buf); + wsprintf(buf,"RECV: %s %s\r\n", + telstates[con->telstate-TELCMD_FIRST],teloptions[*st]); + OutputDebugString(buf); #endif - switch(*st) { + switch(*st) { #ifdef NOT - case BINARY: /* DO: binary transmission */ - if(!tw->ibinary) { /* binary */ - if(!tw->iwantbinary) { - netprintf(tw->pnum,"%c%c%c", - IAC,WILLTEL,BINARY); - if(tw->condebug>0) - tprintf(cv,"SEND: %ls %ls\r\n", - telstates[WILLTEL-LOW_TEL_OPT], - teloptions[BINARY]); - } /* end if */ - else - tw->iwantbinary=0; /* turn off this now */ - tw->ibinary=1; - } /* end if */ - else { - if(tw->condebug>0) - tprintf(cv,"NO REPLY NEEDED: %ls %ls\r\n", - telstates[WILLTEL-LOW_TEL_OPT], - teloptions[BINARY]); - } /* end else */ - break; -#endif - - case SGA: /* DO: Suppress go-ahead */ - if(!con->igoahead) { /* suppress go-ahead */ - wsprintf(buf,"%c%c%c",IAC,WILLTEL,SGA); - TelnetSend(ks,buf,lstrlen(buf),0); + case TELOPT_BINARY: /* DO: binary transmission */ + if(!tw->ibinary) { /* binary */ + if(!tw->iwantbinary) { + netprintf(tw->pnum,"%c%c%c", + IAC,WILL,BINARY); + if(tw->condebug>0) + tprintf(cv,"SEND: %s %s\r\n", + telstates[WILL - TELCMD_FIRST], + teloptions[BINARY]); + } /* end if */ + else + tw->iwantbinary=0; /* turn off this now */ + tw->ibinary=1; + } /* end if */ + else { + if(tw->condebug>0) + tprintf(cv,"NO REPLY NEEDED: %s %s\r\n", + telstates[WILL - TELCMD_FIRST], + teloptions[BINARY]); + } /* end else */ + break; +#endif + + case TELOPT_SGA: /* DO: Suppress go-ahead */ + if(!con->igoahead) { /* suppress go-ahead */ + wsprintf(buf,"%c%c%c",IAC,WILL,TELOPT_SGA); + TelnetSend(ks,buf,lstrlen(buf),0); #ifdef NEGOTIATEDEBUG - wsprintf(strTmp,"SEND: %ls %ls\r\n", - telstates[WILLTEL-LOW_TEL_OPT], - teloptions[SGA]); - OutputDebugString(strTmp); - OutputDebugString("igoahead"); -#endif - con->igoahead=1; - } /* end if */ - else { + wsprintf(strTmp,"SEND: %s %s\r\n", + telstates[WILL - TELCMD_FIRST], + teloptions[TELOPT_SGA]); + OutputDebugString(strTmp); + OutputDebugString("igoahead"); +#endif + con->igoahead=1; + } /* end if */ + else { #ifdef NEGOTIATEDEBUG - wsprintf(strTmp, - "NO REPLY NEEDED: %ls %ls\r\n", - telstates[WILLTEL-LOW_TEL_OPT], - teloptions[SGA]); - OutputDebugString(strTmp); -#endif - } /* end else */ - break; - - case TERMTYPE: /* DO: terminal type negotiation */ - if(!con->termsent) { - con->termsent=TRUE; - wsprintf(buf,"%c%c%c",IAC,WILLTEL,TERMTYPE); - TelnetSend(ks,buf,lstrlen(buf),0); + wsprintf(strTmp, + "NO REPLY NEEDED: %s %s\r\n", + telstates[WILL - TELCMD_FIRST], + teloptions[TELOPT_SGA]); + OutputDebugString(strTmp); +#endif + } /* end else */ + break; + + case TELOPT_TTYPE: /* DO: terminal type negotiation */ + if(!con->termsent) { + con->termsent=TRUE; + wsprintf(buf,"%c%c%c",IAC,WILL,TELOPT_TTYPE); + TelnetSend(ks,buf,lstrlen(buf),0); #ifdef NEGOTIATEDEBUG - wsprintf(strTmp,"SEND: %ls %ls\r\n", - telstates[WILLTEL-LOW_TEL_OPT], - teloptions[TERMTYPE]); - OutputDebugString(strTmp); + wsprintf(strTmp,"SEND: %s %s\r\n", + telstates[WILL - TELCMD_FIRST], + teloptions[TELOPT_TTYPE]); + OutputDebugString(strTmp); #endif - } /* end if */ - else { + } /* end if */ + else { #ifdef NEGOTIATEDEBUG - wsprintf(strTmp,"NO REPLY NEEDED: %ls %ls\r\n", - telstates[WILLTEL-LOW_TEL_OPT], - teloptions[TERMTYPE]); - OutputDebugString(strTmp); + wsprintf(strTmp,"NO REPLY NEEDED: %s %s\r\n", + telstates[WILL - TELCMD_FIRST], + teloptions[TELOPT_TTYPE]); + OutputDebugString(strTmp); #endif - } /* end else */ - break; + } /* end else */ + break; #ifdef LATER - case LINEMODE: /* DO: linemode negotiation */ - tw->lmflag=1; /* set the linemode flag */ - netprintf(tw->pnum,"%c%c%c",IAC,WILLTEL,LINEMODE); - /* - ** Tell the other side to send us - ** it's default character set - */ - netprintf(tw->pnum,"%c%c%c%c", - IAC,SB,LINEMODE,SLC,0,SLC_DEFAULT,0,IAC,SE); - if(tw->condebug>0) { - tprintf(cv,"SEND: %ls %ls\r\n", - telstates[WILLTEL-LOW_TEL_OPT], - teloptions[LINEMODE]); - tprintf(cv, - "SEND: SB LINEMODE SLC 0 SLC_DEFAULT 0 IAC SE\r\n"); - } /* end if */ - break; -#endif - case NAWS: /* DO: Negotiate About Window Size */ - con->bResizeable=TRUE; - send_naws(con); - break; - - case AUTHENTICATION: /* DO: Authentication requested */ - wsprintf(buf,"%c%c%c",IAC,WILLTEL,AUTHENTICATION); - TelnetSend(ks,buf,lstrlen(buf),0); + case TELOPT_LINEMODE: /* DO: linemode negotiation */ + tw->lmflag=1; /* set the linemode flag */ + netprintf(tw->pnum,"%c%c%c",IAC,WILL,TELOPT_LINEMODE); + /* + * Tell the other side to send us + * its default character set + */ + netprintf(tw->pnum,"%c%c%c%c", + IAC,SB,TELOPT_LINEMODE,SLC,0,SLC_DEFAULT,0,IAC,SE); + if(tw->condebug>0) { + tprintf(cv,"SEND: %s %s\r\n", + telstates[WILL - TELCMD_FIRST], + teloptions[TELOPT_LINEMODE]); + tprintf(cv, + "SEND: SB LINEMODE SLC 0 SLC_DEFAULT 0 IAC SE\r\n"); + } /* end if */ + break; +#endif + case TELOPT_NAWS: /* DO: Negotiate About Window Size */ + con->bResizeable=TRUE; + send_naws(con); + break; + + case TELOPT_AUTHENTICATION: /* DO: Authentication requested */ + wsprintf(buf, "%c%c%c", IAC, WILL, TELOPT_AUTHENTICATION); + TelnetSend(ks, buf, lstrlen(buf), 0); +#ifdef NEGOTIATEDEBUG + wsprintf(strTmp,"SEND: %s %s\r\n", + telstates[WILL - TELCMD_FIRST], + teloptions[TELOPT_AUTHENTICATION]); + OutputDebugString(strTmp); +#endif + break; + +#ifdef ENCRYPTION + case TELOPT_ENCRYPT: /* DO: Remote is willing to receive encrypted */ + wsprintf(buf, "%c%c%c", IAC, + (encrypt_flag ? WILL : WONT), TELOPT_ENCRYPT); + TelnetSend(ks, buf, lstrlen(buf), 0); #ifdef NEGOTIATEDEBUG - wsprintf(strTmp,"SEND: %ls %ls\r\n", - telstates[WILLTEL-LOW_TEL_OPT], - teloptions[AUTHENTICATION]); - OutputDebugString(strTmp); + wsprintf(strTmp,"SEND: %s %s\r\n", + telstates[(encrypt_flag ? WILL : WONT) + - TELCMD_FIRST], + teloptions[TELOPT_ENCRYPT]); + OutputDebugString(strTmp); #endif - break; + break; +#endif /* ENCRYPTION */ - default: /* DO: */ - wsprintf(buf,"%c%c%c",IAC,WONTTEL,*st); - TelnetSend(ks,buf,lstrlen(buf),0); + default: /* DO: */ + wsprintf(buf, "%c%c%c", IAC, WONT, *st); + TelnetSend(ks, buf, lstrlen(buf), 0); #ifdef NEGOTIATEDEBUG - wsprintf(strTmp,"SEND: %ls %ls\r\n", - telstates[WONTTEL-LOW_TEL_OPT],teloptions[*st]); - OutputDebugString(strTmp); + wsprintf(strTmp,"SEND: %s %s\r\n", + telstates[WONT - TELCMD_FIRST], teloptions[*st]); + OutputDebugString(strTmp); #endif - break; + break; - } /* end switch */ - con->telstate=STNORM; - orig=++st; - break; + } /* end switch */ + con->telstate = STNORM; + orig = ++st; + break; - case DONTTEL: /* Received a telnet DONT option */ - if (*st==NAWS) - con->bResizeable=FALSE; + case DONT: /* Received a telnet DONT option */ + switch (*st) { + case TELOPT_NAWS: + con->bResizeable=FALSE; #ifdef NEGOTIATEDEBUG - wsprintf(strTmp,"RECV: %ls %ls\r\n", - telstates[con->telstate-LOW_TEL_OPT],teloptions[*st]); - OutputDebugString(strTmp); + wsprintf(strTmp,"RECV: %s %s\r\n", + telstates[con->telstate-TELCMD_FIRST],teloptions[*st]); + OutputDebugString(strTmp); #endif + break; #ifdef NOT - if((*st)==BINARY) { /* DONT: check for binary neg. */ - if(tw->ibinary) { /* binary */ - if(!tw->iwantbinary) { - netprintf(tw->pnum,"%c%c%c",IAC,WONTTEL,BINARY); - if(tw->condebug>0) - tprintf(cv,"SEND: %ls %ls\r\n", - telstates[WONTTEL-LOW_TEL_OPT], - teloptions[BINARY]); - } /* end if */ - else - tw->iwantbinary=0; /* turn off this now */ - tw->ibinary=0; - tw->mapoutput=0; /* turn output mapping off */ - } /* end if */ + case BINARY: /* DONT: check for binary neg. */ + if(tw->ibinary) { /* binary */ + if(!tw->iwantbinary) { + netprintf(tw->pnum,"%c%c%c",IAC,WONT,BINARY); + if(tw->condebug>0) + tprintf(cv,"SEND: %s %s\r\n", + telstates[WONT-TELCMD_FIRST], + teloptions[BINARY]); + } /* end if */ + else + tw->iwantbinary=0; /* turn off this now */ + tw->ibinary=0; + tw->mapoutput=0; /* turn output mapping off */ + } /* end if */ #ifdef NEGOTIATEDEBUG - wsprintf(strTmp,"NO REPLY NEEDED: %ls %ls\r\n", - telstates[WONTTEL-LOW_TEL_OPT], - teloptions[BINARY]); - OutputDebugString(strTmp); + wsprintf(strTmp,"NO REPLY NEEDED: %s %s\r\n", + telstates[WONT-TELCMD_FIRST], + teloptions[BINARY]); + OutputDebugString(strTmp); #endif - } + break; #endif - con->telstate=STNORM; - orig=++st; - break; - - case WILLTEL: /* received a telnet WILL option */ +#ifdef ENCRYPTION + case ENCRYPTION: + break; +#endif + } + + /* all these just fall through to here... */ + + con->telstate=STNORM; + orig=++st; + break; + + case WILL: /* received a telnet WILL option */ #ifdef NEGOTIATEDEBUG - wsprintf(strTmp,"RECV: %ls %ls\r\n", - telstates[con->telstate-LOW_TEL_OPT], - teloptions[*st]); - OutputDebugString(strTmp); + wsprintf(strTmp,"RECV: %s %s\r\n", + telstates[con->telstate-TELCMD_FIRST], + teloptions[*st]); + OutputDebugString(strTmp); #endif - switch(*st) { + switch(*st) { #ifdef NOT - case BINARY: /* WILL: binary */ - if(!tw->ubinary) { /* binary */ - if(!tw->uwantbinary) { - netprintf(tw->pnum,"%c%c%c", - IAC,DOTEL,BINARY); - if(tw->condebug>0) - tprintf(cv,"SEND: %ls %ls\r\n", - telstates[DOTEL-LOW_TEL_OPT], - teloptions[BINARY]); - } /* end if */ - else - tw->uwantbinary=0; /* turn off this now */ - tw->ubinary=1; - } /* end if */ - else { - if(tw->condebug>0) - tprintf(cv,"NO REPLY NEEDED: %ls %ls\r\n", - telstates[DOTEL-LOW_TEL_OPT], - teloptions[BINARY]); - } /* end else */ - break; -#endif - - case SGA: /* WILL: suppress go-ahead */ - if(!con->ugoahead) { - con->ugoahead=1; - wsprintf(buf,"%c%c%c",IAC,DOTEL,SGA); /* ack */ - TelnetSend(ks,buf,lstrlen(buf),0); + case TELOPT_BINARY: /* WILL: binary */ + if(!tw->ubinary) { /* binary */ + if(!tw->uwantbinary) { + netprintf(tw->pnum,"%c%c%c", + IAC,DO,TELOPT_BINARY); + if(tw->condebug>0) + tprintf(cv,"SEND: %s %s\r\n", + telstates[DO - TELCMD_FIRST], + teloptions[TELOPT_BINARY]); + } /* end if */ + else + tw->uwantbinary=0; /* turn off this now */ + tw->ubinary=1; + } /* end if */ + else { + if(tw->condebug>0) + tprintf(cv,"NO REPLY NEEDED: %s %s\r\n", + telstates[DO - TELCMD_FIRST], + teloptions[TELOPT_BINARY]); + } /* end else */ + break; +#endif + + case TELOPT_SGA: /* WILL: suppress go-ahead */ + if(!con->ugoahead) { + con->ugoahead=1; + wsprintf(buf,"%c%c%c",IAC,DO,TELOPT_SGA); /* ack */ + TelnetSend(ks,buf,lstrlen(buf),0); #ifdef NEGOTIATEDEBUG - wsprintf(strTmp,"SEND: %ls %ls\r\n", - telstates[DOTEL-LOW_TEL_OPT], - teloptions[SGA]); - OutputDebugString(strTmp); -#endif - } /* end if */ - break; - - case ECHO: /* WILL: echo */ - if(!con->echo) { - con->echo=1; - wsprintf(buf,"%c%c%c",IAC,DOTEL,ECHO); /* ack */ - TelnetSend(ks,buf,lstrlen(buf),0); + wsprintf(strTmp,"SEND: %s %s\r\n", + telstates[DO - TELCMD_FIRST], + teloptions[TELOPT_SGA]); + OutputDebugString(strTmp); +#endif + } /* end if */ + break; + + case TELOPT_ECHO: /* WILL: echo */ + if(!con->echo) { + con->echo = 1; + wsprintf(buf, "%c%c%c", IAC, DO, TELOPT_ECHO); /* ack */ + TelnetSend(ks, buf, lstrlen(buf), 0); #ifdef NEGOTIATEDEBUG - - wsprintf(strTmp,"SEND: %ls %ls\r\n", - telstates[DOTEL-LOW_TEL_OPT], - teloptions[ECHO]); - OutputDebugString(strTmp); + wsprintf(strTmp,"SEND: %s %s\r\n", + telstates[DO - TELCMD_FIRST], + teloptions[TELOPT_ECHO]); + OutputDebugString(strTmp); #endif - } /* end if */ - break; - - case TIMING: /* WILL: Timing mark */ - con->timing=0; - break; + } /* end if */ + break; + + case TELOPT_TM: /* WILL: Timing mark */ + con->timing=0; + break; +#ifdef ENCRYPTION + case TELOPT_ENCRYPT: /* WILL: decrypt our input */ + wsprintf(buf, "%c%c%c", IAC, + (encrypt_flag ? DO : DONT), TELOPT_ENCRYPT); + TelnetSend(ks, buf, lstrlen(buf), 0); + if (encrypt_flag) + encrypt_send_support(); - default: - wsprintf(buf,"%c%c%c",IAC,DONTTEL,*st); - TelnetSend(ks,buf,lstrlen(buf),0); #ifdef NEGOTIATEDEBUG - wsprintf(strTmp,"SEND: %ls %ls\r\n", - telstates[DONTTEL-LOW_TEL_OPT],teloptions[*st]); - OutputDebugString(strTmp); + wsprintf(strTmp,"SEND: %s %s\r\n", + telstates[(encrypt_flag ? DO : DONT) - TELCMD_FIRST], + teloptions[TELOPT_ENCRYPT]); + OutputDebugString(strTmp); +#endif + break; +#endif + + default: + wsprintf(buf,"%c%c%c",IAC,DONT,*st); + TelnetSend(ks,buf,lstrlen(buf),0); +#ifdef NEGOTIATEDEBUG + wsprintf(strTmp,"SEND: %s %s\r\n", + telstates[DONT-TELCMD_FIRST],teloptions[*st]); + OutputDebugString(strTmp); #endif - break; - } /* end switch */ - con->telstate=STNORM; - orig=++st; - break; + break; + } /* end switch */ + con->telstate=STNORM; + orig=++st; + break; - case WONTTEL: /* Received a telnet WONT option */ + case WONT: /* Received a telnet WONT option */ #ifdef NEGOTIATEDEBUG - wsprintf(strTmp,"RECV: %ls %ls\r\n", - telstates[con->telstate-LOW_TEL_OPT],teloptions[*st]); - OutputDebugString((LPSTR)strTmp); + wsprintf(strTmp,"RECV: %s %s\r\n", + telstates[con->telstate-TELCMD_FIRST],teloptions[*st]); + OutputDebugString((LPSTR)strTmp); #endif - con->telstate=STNORM; - switch(*st++) { /* which option? */ + con->telstate=STNORM; + switch(*st++) { /* which option? */ #ifdef NOT - case BINARY: /* WONT: binary */ - if(tw->ubinary) { /* binary */ - if(!tw->uwantbinary) { - netprintf(tw->pnum,"%c%c%c", - IAC,DONTTEL,BINARY); - if(tw->condebug>0) - tprintf(cv,"SEND: %ls %ls\r\n", - telstates[DONTTEL-LOW_TEL_OPT], - teloptions[BINARY]); - } /* end if */ - else - tw->uwantbinary=0; /* turn off this now */ - tw->ubinary=0; - tw->mapoutput=0; /* turn output mapping off */ - } /* end if */ - else { - if(tw->condebug>0) - tprintf(cv,"NO REPLY NEEDED: %ls %ls\r\n", - telstates[DONTTEL-LOW_TEL_OPT], - teloptions[BINARY]); - } /* end else */ - break; - -#endif - case ECHO: /* WONT: echo */ - if(con->echo) { - con->echo=0; - wsprintf(buf,"%c%c%c",IAC,DONTTEL,ECHO); - TelnetSend(ks,buf,lstrlen(buf),0); + case BINARY: /* WONT: binary */ + if(tw->ubinary) { /* binary */ + if(!tw->uwantbinary) { + netprintf(tw->pnum,"%c%c%c", + IAC,DONT,BINARY); + if(tw->condebug>0) + tprintf(cv,"SEND: %s %s\r\n", + telstates[DONT-TELCMD_FIRST], + teloptions[BINARY]); + } /* end if */ + else + tw->uwantbinary=0; /* turn off this now */ + tw->ubinary=0; + tw->mapoutput=0; /* turn output mapping off */ + } /* end if */ + else { + if(tw->condebug>0) + tprintf(cv,"NO REPLY NEEDED: %s %s\r\n", + telstates[DONT-TELCMD_FIRST], + teloptions[BINARY]); + } /* end else */ + break; + +#endif + case TELOPT_ECHO: /* WONT: echo */ + if(con->echo) { + con->echo=0; + wsprintf(buf,"%c%c%c",IAC,DONT,TELOPT_ECHO); + TelnetSend(ks,buf,lstrlen(buf),0); #ifdef NEGOTIATEDEBUG - wsprintf(strTmp,"SEND: %ls %ls\r\n", - telstates[DONTTEL-LOW_TEL_OPT], - teloptions[ECHO]); - OutputDebugString(strTmp); - OutputDebugString("Other side won't echo!"); -#endif - } /* end if */ - break; - - case TIMING: /* WONT: Telnet timing mark option */ - con->timing=0; - break; - - default: - break; - } /* end switch */ - orig=st; - break; - - case SB: /* telnet sub-options negotiation */ -// OutputDebugString("[SB]"); - con->telstate=NEGOTIATE; - orig=st; - end_sub=0; - sub_pos=con->substate=0; /* Defined for each */ + wsprintf(strTmp,"SEND: %s %s\r\n", + telstates[DONT-TELCMD_FIRST], + teloptions[TELOPT_ECHO]); + OutputDebugString(strTmp); + OutputDebugString("Other side won't echo!"); +#endif + } /* end if */ + break; + + case TELOPT_TM: /* WONT: Telnet timing mark option */ + con->timing=0; + break; + +#ifdef ENCRYPTION + case TELOPT_ENCRYPT: /* WONT: don't encrypt our input */ + break; +#endif + + default: + break; + } /* end switch */ + orig=st; + break; + + case SB: /* telnet sub-options negotiation */ + con->telstate=NEGOTIATE; + orig=st; + end_sub=0; + sub_pos=con->substate=0; /* Defined for each */ #ifdef OLD_WAY - break; + break; #endif - case NEGOTIATE: -// OutputDebugString("[NEG:"); -// OutputDebugString(st); + case NEGOTIATE: /* until we change sub-negotiation states, accumulate bytes */ - if(con->substate==0) { - if(*st==IAC) { /* check if we found an IAC byte */ - if(*(st+1)==IAC) { /* skip over double IAC's */ - st++; - parsedat[sub_pos++]=*st++; - } /* end if */ - else { - end_sub=sub_pos; - con->substate=*st++; - } /* end else */ - } /* end if */ - else /* otherwise, just stash the byte */ - parsedat[sub_pos++]=*st++; - } /* end if */ - else { - con->substate=*st++; - /* check if we've really ended the sub-negotiations */ - if(con->substate==SE) - parse_subnegotiat(ks,end_sub); - orig=st; - con->telstate=STNORM; - } /* end else */ - break; - - default: - con->telstate=STNORM; - break; - } /* end switch */ - } /* end while */ - -/* -* quick scan of the remaining string, skip chars while they are -* uninteresting -*/ - if(con->telstate==STNORM && st<mark) { -/* -* skip along as fast as possible until an interesting character is found -*/ - while(st<mark && *st!=27 && *st!=IAC) { -// if(!tw->ubinary) -// *st&=127; /* mask off high bit */ - st++; - } /* end while */ -// if(!tw->timing) -// parsewrite(tw,orig,st-orig); - orig=st; /* forget what we have sent already */ - if(st<mark) - switch(*st) { - case IAC: /* telnet IAC */ - con->telstate=IACFOUND; - st++; - break; - - default: -#ifdef NEGOTIATEDEBUG -// wsprintf(buf," strange char>128\r\n"); -// OutputDebugString(buf); + if(con->substate==0) { + if(*st==IAC) { /* check if we found an IAC byte */ + if(*(st+1)==IAC) { /* skip over double IAC's */ + st++; + parsedat[sub_pos++]=*st++; + } /* end if */ + else { + end_sub=sub_pos; + con->substate=*st++; + } /* end else */ + } /* end if */ + else /* otherwise, just stash the byte */ + parsedat[sub_pos++]=*st++; + } /* end if */ + else { + con->substate=*st++; + /* check if we've really ended the sub-negotiations */ + if(con->substate==SE) + parse_subnegotiat(ks,end_sub); + + orig=st; + /* + * XXX hack to decrypt the rest of the buffer + */ + if (encrypt_flag == 2) { + decrypt_ks_hack(orig, mark - orig); + encrypt_flag = 1; + } + + con->telstate=STNORM; + } /* end else */ + break; + + default: + con->telstate=STNORM; + break; + } /* end switch */ + } /* end while */ + + /* + * quick scan of the remaining string, skip chars while they are + * uninteresting + */ + if(con->telstate==STNORM && st<mark) { + /* + * skip along as fast as possible until an interesting character is found + */ + while(st<mark && *st!=27 && *st!=IAC) { +#if 0 + if(!tw->ubinary) + *st&=127; /* mask off high bit */ #endif - st++; - break; - } /* end switch */ - } /* end if */ + st++; } /* end while */ +#if 0 + if(!tw->timing) + parsewrite(tw,orig,st-orig); +#endif + orig=st; /* forget what we have sent already */ + if(st<mark) + switch(*st) { + case IAC: /* telnet IAC */ + con->telstate=IACFOUND; + st++; + break; + + default: +#ifdef NEGOTIATEDEBUG + wsprintf(buf," strange char>128 0x%x\r\n", *st); + OutputDebugString(buf); +#endif + st++; + break; + } /* end switch */ + } /* end if */ + } /* end while */ } /* end parse() */ - -/*+******************************************************************** -* Function : parse_subnegotiat() -* Purpose : Parse the telnet sub-negotiations read into the parsedat -* array. -* Parameters : -* end_sub - index of the character in the 'parsedat' array which -* is the last byte in a sub-negotiation -* Returns : none -* Calls : -* Called by : parse() -**********************************************************************/ +/* + * Function : parse_subnegotiat() + * Purpose : Parse the telnet sub-negotiations read into the parsedat + * array. + * Parameters : + * end_sub - index of the character in the 'parsedat' array which + * is the last byte in a sub-negotiation + * Returns : none + * Calls : + * Called by : parse() + */ static void -parse_subnegotiat(kstream ks,int end_sub) { - char buf[128]; - -// OutputDebugString("INTO SUBNEGOTIATE"); - switch(parsedat[0]) { - case TERMTYPE: -// OutputDebugString(":INTO TERMTYPE"); - if(parsedat[1]==1) { -/* QAK!!! */ wsprintf(buf,"%c%c%c%cvt100%c%c",IAC,SB,TERMTYPE,0,IAC,SE); - TelnetSend(ks,(LPSTR)buf,11,0); +parse_subnegotiat(kstream ks, int end_sub) +{ + char buf[128]; + + switch(parsedat[0]) { + case TELOPT_TTYPE: + if(parsedat[1]==1) { + /* QAK!!! */ wsprintf(buf,"%c%c%c%cvt100%c%c",IAC,SB,TELOPT_TTYPE, + 0,IAC,SE); + TelnetSend(ks,(LPSTR)buf,11,0); #ifdef NEGOTIATEDEBUG - wsprintf(strTmp,"SB TERMINAL-TYPE SEND\r\n" - "SEND: SB TERMINAL-TYPE IS vt100 \r\n len=%d \r\n", - lstrlen((LPSTR)buf)); -// OutputDebugString(strTmp); + wsprintf(strTmp,"SB TERMINAL-TYPE SEND\r\n" + "SEND: SB TERMINAL-TYPE IS vt100 \r\n len=%d \r\n", + lstrlen((LPSTR)buf)); + OutputDebugString(strTmp); #endif - } - break; - - case AUTHENTICATION: - auth_parse(ks, parsedat, end_sub); - break; - default: - break; - } /* end switch */ + } + break; + + case TELOPT_AUTHENTICATION: + auth_parse(ks, parsedat, end_sub); + break; +#ifdef ENCRYPTION + case TELOPT_ENCRYPT: + if (encrypt_flag) + encrypt_parse(ks, parsedat, end_sub); + break; +#endif + default: + break; + } /* end switch */ } /* parse_subnegotiat */ -/*+******************************************************************** -* Function : send_naws -* Purpose : Send a window size sub-negotiation. -* Parameters : -* ks - the kstream to send to. -* Returns : none -**********************************************************************/ +/* + * Function : send_naws + * Purpose : Send a window size sub-negotiation. + * Parameters : + * ks - the kstream to send to. + * Returns : none + */ void send_naws(CONNECTION *con) { - unsigned char buf[40]; - int len; + unsigned char buf[40]; + int len; - wsprintf(buf, "%c%c%c", IAC, SB, NAWS); - len = 3; + wsprintf(buf, "%c%c%c", IAC, SB, TELOPT_NAWS); + len = 3; - buf[len++] = HIBYTE(con->width); - if (buf[len-1] == IAC) buf[len++] = IAC; + buf[len++] = HIBYTE(con->width); + if (buf[len-1] == IAC) buf[len++] = IAC; - buf[len++] = LOBYTE(con->width); - if (buf[len-1] == IAC) buf[len++] = IAC; + buf[len++] = LOBYTE(con->width); + if (buf[len-1] == IAC) buf[len++] = IAC; - buf[len++] = HIBYTE(con->height); - if (buf[len-1] == IAC) buf[len++] = IAC; + buf[len++] = HIBYTE(con->height); + if (buf[len-1] == IAC) buf[len++] = IAC; - buf[len++] = LOBYTE(con->height); - if (buf[len-1] == IAC) buf[len++] = IAC; + buf[len++] = LOBYTE(con->height); + if (buf[len-1] == IAC) buf[len++] = IAC; - buf[len++] = IAC; - buf[len++] = SE; + buf[len++] = IAC; + buf[len++] = SE; - TelnetSend(con->ks, buf, len, 0); + TelnetSend(con->ks, buf, len, 0); - #ifdef NEGOTIATEDEBUG - wsprintf(buf, "SEND: SB NAWS %d %d %d %d IAC SE\r\n", - HIBYTE(con->width), LOBYTE(con->width), - HIBYTE(con->height), LOBYTE(con->height)); - OutputDebugString(buf); - #endif +#ifdef NEGOTIATEDEBUG + wsprintf(buf, "SEND: SB NAWS %d %d %d %d IAC SE\r\n", + HIBYTE(con->width), LOBYTE(con->width), + HIBYTE(con->height), LOBYTE(con->height)); + OutputDebugString(buf); +#endif } /* send_naws */ diff --git a/src/windows/wintel/resource.h b/src/windows/wintel/resource.h new file mode 100644 index 0000000000..0d39d5ca09 --- /dev/null +++ b/src/windows/wintel/resource.h @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by telnet.rc +// +#define IDD_DIALOG1 101 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40005 +#define _APS_NEXT_CONTROL_VALUE 1002 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/windows/wintel/screen.c b/src/windows/wintel/screen.c index 505f235991..888103cdbf 100644 --- a/src/windows/wintel/screen.c +++ b/src/windows/wintel/screen.c @@ -7,6 +7,10 @@ #include <assert.h> #include "telnet.h" #include "ini.h" +#include "auth.h" + +extern char *encrypt_output; /* XXX hack... I wonder if this will work. These are */ +extern char *decrypt_input; /* XXX really functions... */ extern char *cInvertedArray; extern int bMouseDown; @@ -16,1126 +20,1127 @@ static SCREEN *ScreenList; static HINSTANCE hInst; static char szScreenClass[] = "ScreenWClass"; static char szScreenMenu[] = "ScreenMenu"; -static char cursor_key[8][4] = { // Send for cursor keys - "\x1B[D", "\x1B[A", "\x1B[C", "\x1B[B", // Normal mode - "\x1BOD", "\x1BOA", "\x1BOC", "\x1BOB", // Numpad on mode +static char cursor_key[8][4] = { /* Send for cursor keys */ + "\x1B[D", "\x1B[A", "\x1B[C", "\x1B[B", /* Normal mode */ + "\x1BOD", "\x1BOA", "\x1BOC", "\x1BOB", /* Numpad on mode */ }; -void ScreenInit( - HINSTANCE hInstance) +void +ScreenInit(HINSTANCE hInstance) { - BOOL b; - WNDCLASS wc; + BOOL b; + WNDCLASS wc; - hInst = hInstance; - - ScreenList = NULL; + hInst = hInstance; - wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; /* Class style(s) */ - wc.lpfnWndProc = ScreenWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = sizeof(long); - wc.hInstance = hInstance; - wc.hIcon = LoadIcon(hInstance, "TERMINAL"); - wc.hCursor = LoadCursor(NULL, IDC_IBEAM); - wc.hbrBackground = GetStockObject(WHITE_BRUSH); - wc.lpszMenuName = szScreenMenu; - wc.lpszClassName = szScreenClass; + ScreenList = NULL; - b = RegisterClass(&wc); - assert(b); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; /* Class style(s) */ + wc.lpfnWndProc = ScreenWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = sizeof(long); + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(hInstance, "TERMINAL"); + wc.hCursor = LoadCursor(NULL, IDC_IBEAM); + wc.hbrBackground = GetStockObject(WHITE_BRUSH); + wc.lpszMenuName = szScreenMenu; + wc.lpszClassName = szScreenClass; -} /* ScreenInit */ + b = RegisterClass(&wc); + assert(b); +} -void SetScreenInstance( - HINSTANCE hInstance) +void +SetScreenInstance(HINSTANCE hInstance) { - hInst = hInstance; - -} /* SetScreenInstance */ - + hInst = hInstance; +} -int GetNewScreen(void) +int +GetNewScreen(void) { - SCREEN *pScr; - static int id = 0; - - pScr = (SCREEN *) calloc(sizeof(SCREEN), 1); - if (pScr == NULL) - return(-1); - - if (ScreenList == NULL) { - pScr->next = NULL; - pScr->prev = NULL; - } - else { - if (ScreenList->next == NULL) { - ScreenList->next = ScreenList; - ScreenList->prev = ScreenList; - } - pScr->next = ScreenList; - pScr->prev = ScreenList->prev; - ScreenList->prev->next = pScr; - ScreenList->prev = pScr; - } - - ScreenList = pScr; - return(id++); - -} /* GetNewScreen */ - - -SCREENLINE *ScreenNewLine(void) + SCREEN *pScr; + static int id = 0; + + pScr = (SCREEN *) calloc(sizeof(SCREEN), 1); + if (pScr == NULL) + return(-1); + + if (ScreenList == NULL) { + pScr->next = NULL; + pScr->prev = NULL; + } + else { + if (ScreenList->next == NULL) { + ScreenList->next = ScreenList; + ScreenList->prev = ScreenList; + } + pScr->next = ScreenList; + pScr->prev = ScreenList->prev; + ScreenList->prev->next = pScr; + ScreenList->prev = pScr; + } + + ScreenList = pScr; + return(id++); +} + +SCREENLINE * +ScreenNewLine(void) { - SCREENLINE *pScrLine; - - pScrLine = calloc(sizeof(SCREENLINE) + 2*MAX_LINE_WIDTH, 1); - if (pScrLine == NULL) - return (NULL); - pScrLine->text = &pScrLine->buffer[0]; - pScrLine->attrib = &pScrLine->buffer[MAX_LINE_WIDTH]; - return(pScrLine); - -} /* ScreenNewLine */ - - -static void MakeWindowTitle( - char *host, - int width, - int height, - char *title, - int nchars) + SCREENLINE *pScrLine; + + pScrLine = calloc(sizeof(SCREENLINE) + 2*MAX_LINE_WIDTH, 1); + if (pScrLine == NULL) + return (NULL); + pScrLine->text = &pScrLine->buffer[0]; + pScrLine->attrib = &pScrLine->buffer[MAX_LINE_WIDTH]; + return(pScrLine); +} + +static void +MakeWindowTitle(char *host, int width, int height, char *title, int nchars) { - char buf[128]; - int hlen; - - hlen = strlen(host); + char buf[128]; + int hlen; - title[0] = 0; + hlen = strlen(host); - if (hlen + 1 > nchars) - return; + title[0] = 0; - strcpy(title, host); + if (hlen + 1 > nchars) + return; - wsprintf(buf, " (%dh x %dw)", height, width); + strcpy(title, host); - if ((int) strlen(buf) + hlen + 1 > nchars) - return; + wsprintf(buf, " (%dh x %dw)", height, width); - strcat(title, buf); + if ((int) strlen(buf) + hlen + 1 > nchars) + return; -} /* MakeWindowTitle */ + strcat(title, buf); +} -SCREEN *InitNewScreen( - CONFIG *Config) +SCREEN * +InitNewScreen(CONFIG *Config) { - TEXTMETRIC tm; - HMENU hMenu = NULL; - SCREEN *scr = NULL; - SCREENLINE *pScrLine; - SCREENLINE *pScrLineLast; - int id; - int idx = 0; - char title[128]; - HDC hDC; - HFONT hFont; - - id = GetNewScreen(); - if (id == -1) - return(0); - - scr = ScreenList; - assert(scr != NULL); - - hMenu = LoadMenu(hInst, szScreenMenu); - assert(hMenu != NULL); - - scr->title = Config->title; - MakeWindowTitle(Config->title, Config->width, Config->height, title, sizeof(title)); - - scr->hwndTel = Config->hwndTel; /* save HWND of calling window */ - - if (Config->backspace) { - CheckMenuItem(hMenu, IDM_BACKSPACE, MF_CHECKED); - CheckMenuItem(hMenu, IDM_DELETE, MF_UNCHECKED); - } - else { - CheckMenuItem(hMenu, IDM_BACKSPACE, MF_UNCHECKED); - CheckMenuItem(hMenu, IDM_DELETE, MF_CHECKED); - } - - hDC = GetDC(NULL); - assert(hDC != NULL); - - scr->lf.lfPitchAndFamily = FIXED_PITCH; - GetPrivateProfileString(INI_FONT, "FaceName", "Courier", scr->lf. - lfFaceName, LF_FACESIZE, TELNET_INI); - scr->lf.lfHeight = (int) GetPrivateProfileInt(INI_FONT, "Height", 0, TELNET_INI); - scr->lf.lfWidth = (int) GetPrivateProfileInt(INI_FONT, "Width", 0, TELNET_INI); - scr->lf.lfPitchAndFamily = (BYTE) GetPrivateProfileInt(INI_FONT, "PitchAndFamily", 0, TELNET_INI); - scr->lf.lfCharSet = (BYTE) GetPrivateProfileInt(INI_FONT, "CharSet", 0, TELNET_INI); - scr->lf.lfEscapement = (BYTE) GetPrivateProfileInt(INI_FONT, "Escapement", 0, TELNET_INI); - scr->lf.lfQuality = PROOF_QUALITY; - scr->hSelectedFont = CreateFontIndirect((LPLOGFONT) &(scr->lf)); - hFont = SelectObject(hDC, scr->hSelectedFont); - GetTextMetrics(hDC, (LPTEXTMETRIC) &tm); - SelectObject(hDC, hFont); - scr->cxChar = tm.tmAveCharWidth; - scr->cyChar = tm.tmHeight + tm.tmExternalLeading; - - ReleaseDC(NULL, hDC); - - scr->width = Config->width; - scr->height = Config->height; - scr->ID = id; - scr->x = 0; - scr->y = 0; - scr->Oldx = 0; - scr->Oldy = 0; - scr->attrib = 0; - scr->DECAWM = 1; - scr->bWrapPending = FALSE; - scr->top = 0; - scr->bottom = scr->height-1; - scr->parmptr = 0; - scr->escflg = 0; - scr->bAlert = FALSE; - scr->numlines = 0; - scr->maxlines = 150; - - cInvertedArray = calloc(scr->width * scr->height, 1); - - pScrLineLast = ScreenNewLine(); - if (pScrLineLast == NULL) - return(NULL); - scr->screen_top = scr->buffer_top = pScrLineLast; - - for (idx = 0; idx < scr->height - 1; idx++) { - pScrLine = ScreenNewLine(); - if (pScrLine == NULL) - return(NULL); - pScrLine->prev = pScrLineLast; - pScrLineLast->next = pScrLine; - pScrLineLast = pScrLine; - } - - scr->screen_bottom = scr->buffer_bottom = pScrLine; - - scr->hWnd = CreateWindow(szScreenClass, title, WS_OVERLAPPEDWINDOW | WS_VSCROLL, - CW_USEDEFAULT, CW_USEDEFAULT, - scr->cxChar * scr->width + FRAME_WIDTH, - scr->cyChar * scr->height + FRAME_HEIGHT, - NULL, hMenu, hInst, scr); - assert(scr->hWnd != NULL); - - ShowWindow(scr->hWnd, SW_SHOW); - - CreateCaret(scr->hWnd, NULL, scr->cxChar, 2); - SetCaretPos(scr->x*scr->cxChar, (scr->y+1) * scr->cyChar); - ShowCaret(scr->hWnd); - - return(ScreenList); - -} /* InitNewScreen */ + TEXTMETRIC tm; + HMENU hMenu = NULL; + SCREEN *scr = NULL; + SCREENLINE *pScrLine; + SCREENLINE *pScrLineLast; + int id; + int idx = 0; + char title[128]; + HDC hDC; + HFONT hFont; + + id = GetNewScreen(); + if (id == -1) + return(0); + + scr = ScreenList; + assert(scr != NULL); + + hMenu = LoadMenu(hInst, szScreenMenu); + assert(hMenu != NULL); + + scr->title = Config->title; + MakeWindowTitle(Config->title, Config->width, Config->height, + title, sizeof(title)); + + scr->hwndTel = Config->hwndTel; /* save HWND of calling window */ + + if (Config->backspace) { + CheckMenuItem(hMenu, IDM_BACKSPACE, MF_CHECKED); + CheckMenuItem(hMenu, IDM_DELETE, MF_UNCHECKED); + } else { + CheckMenuItem(hMenu, IDM_BACKSPACE, MF_UNCHECKED); + CheckMenuItem(hMenu, IDM_DELETE, MF_CHECKED); + } + + hDC = GetDC(NULL); + assert(hDC != NULL); + + scr->lf.lfPitchAndFamily = FIXED_PITCH; + GetPrivateProfileString(INI_FONT, "FaceName", "Courier", scr->lf. + lfFaceName, LF_FACESIZE, TELNET_INI); + scr->lf.lfHeight = (int) GetPrivateProfileInt(INI_FONT, "Height", 0, TELNET_INI); + scr->lf.lfWidth = (int) GetPrivateProfileInt(INI_FONT, "Width", 0, TELNET_INI); + scr->lf.lfPitchAndFamily = (BYTE) GetPrivateProfileInt(INI_FONT, "PitchAndFamily", 0, TELNET_INI); + scr->lf.lfCharSet = (BYTE) GetPrivateProfileInt(INI_FONT, "CharSet", 0, TELNET_INI); + scr->lf.lfEscapement = (BYTE) GetPrivateProfileInt(INI_FONT, "Escapement", 0, TELNET_INI); + scr->lf.lfQuality = PROOF_QUALITY; + scr->hSelectedFont = CreateFontIndirect((LPLOGFONT) &(scr->lf)); + hFont = SelectObject(hDC, scr->hSelectedFont); + GetTextMetrics(hDC, (LPTEXTMETRIC) &tm); + SelectObject(hDC, hFont); + scr->cxChar = tm.tmAveCharWidth; + scr->cyChar = tm.tmHeight + tm.tmExternalLeading; + + ReleaseDC(NULL, hDC); + + scr->width = Config->width; + scr->height = Config->height; + scr->ID = id; + scr->x = 0; + scr->y = 0; + scr->Oldx = 0; + scr->Oldy = 0; + scr->attrib = 0; + scr->DECAWM = 1; + scr->bWrapPending = FALSE; + scr->top = 0; + scr->bottom = scr->height-1; + scr->parmptr = 0; + scr->escflg = 0; + scr->bAlert = FALSE; + scr->numlines = 0; + scr->maxlines = 150; + + cInvertedArray = calloc(scr->width * scr->height, 1); + + pScrLineLast = ScreenNewLine(); + if (pScrLineLast == NULL) + return(NULL); + scr->screen_top = scr->buffer_top = pScrLineLast; + + for (idx = 0; idx < scr->height - 1; idx++) { + pScrLine = ScreenNewLine(); + if (pScrLine == NULL) + return(NULL); + pScrLine->prev = pScrLineLast; + pScrLineLast->next = pScrLine; + pScrLineLast = pScrLine; + } + + scr->screen_bottom = scr->buffer_bottom = pScrLine; + + scr->hWnd = CreateWindow(szScreenClass, title, WS_OVERLAPPEDWINDOW | WS_VSCROLL, + CW_USEDEFAULT, CW_USEDEFAULT, + scr->cxChar * scr->width + FRAME_WIDTH, + scr->cyChar * scr->height + FRAME_HEIGHT, + NULL, hMenu, hInst, scr); + assert(scr->hWnd != NULL); + + ShowWindow(scr->hWnd, SW_SHOW); + + CreateCaret(scr->hWnd, NULL, scr->cxChar, 2); + SetCaretPos(scr->x*scr->cxChar, (scr->y+1) * scr->cyChar); + ShowCaret(scr->hWnd); + + return(ScreenList); +} void DeleteTopLine( - SCREEN *pScr) + SCREEN *pScr) { - assert(pScr->buffer_top != NULL); + assert(pScr->buffer_top != NULL); - pScr->buffer_top = pScr->buffer_top->next; - assert(pScr->buffer_top != NULL); + pScr->buffer_top = pScr->buffer_top->next; + assert(pScr->buffer_top != NULL); - pScr->buffer_top->prev = NULL; + pScr->buffer_top->prev = NULL; - pScr->numlines--; + pScr->numlines--; } /* DeleteTopLine */ static void SetScreenScrollBar( - SCREEN *pScr) + SCREEN *pScr) { - if (pScr->numlines <= 0) { - SetScrollRange(pScr->hWnd, SB_VERT, 0, 100, FALSE); - SetScrollPos(pScr->hWnd, SB_VERT, 0, TRUE); - EnableScrollBar(pScr->hWnd, SB_VERT, ESB_DISABLE_BOTH); - } - else { - SetScrollRange(pScr->hWnd, SB_VERT, 0, pScr->numlines, FALSE); - SetScrollPos(pScr->hWnd, SB_VERT, pScr->numlines, TRUE); - EnableScrollBar(pScr->hWnd, SB_VERT, ESB_ENABLE_BOTH); - } + if (pScr->numlines <= 0) { + SetScrollRange(pScr->hWnd, SB_VERT, 0, 100, FALSE); + SetScrollPos(pScr->hWnd, SB_VERT, 0, TRUE); + EnableScrollBar(pScr->hWnd, SB_VERT, ESB_DISABLE_BOTH); + } + else { + SetScrollRange(pScr->hWnd, SB_VERT, 0, pScr->numlines, FALSE); + SetScrollPos(pScr->hWnd, SB_VERT, pScr->numlines, TRUE); + EnableScrollBar(pScr->hWnd, SB_VERT, ESB_ENABLE_BOTH); + } } /* SetScreenScrollBar */ int ScreenScroll( - SCREEN *pScr) + SCREEN *pScr) { - SCREENLINE *pScrLine; - SCREENLINE *pPrev; - SCREENLINE *pNext; - SCREENLINE *pScrollTop; - SCREENLINE *pScrollBottom; - BOOL bFullScreen = TRUE; - HDC hDC; - RECT rc; + SCREENLINE *pScrLine; + SCREENLINE *pPrev; + SCREENLINE *pNext; + SCREENLINE *pScrollTop; + SCREENLINE *pScrollBottom; + BOOL bFullScreen = TRUE; + HDC hDC; + RECT rc; + + Edit_ClearSelection(pScr); + + pScrollTop = GetScreenLineFromY(pScr, pScr->top); + + pScrollBottom = GetScreenLineFromY(pScr, pScr->bottom); + + if (pScrollTop != pScr->screen_top) { + bFullScreen = FALSE; + rc.left = 0; + rc.right = pScr->cxChar * pScr->width; + rc.top = pScr->cyChar * (pScr->top); + rc.bottom = pScr->cyChar * (pScr->bottom+1); + + pNext = pScrollTop->next; + pPrev = pScrollTop->prev; + + pPrev->next = pNext; + pNext->prev = pPrev; + + pScrLine = pScrollTop; + ScreenClearLine(pScr, pScrLine); + } + else { + pScr->numlines++; + pScrLine = ScreenNewLine(); + if (pScrLine == NULL) + return(0); + pScr->screen_top = pScrollTop->next; + } + + if (pScrLine == NULL) + return(0); + + pNext = pScrollBottom->next; + pScrollBottom->next = pScrLine; + pScrLine->next = pNext; + pScrLine->prev = pScrollBottom; + if (pNext != NULL) + pNext->prev = pScrLine; + + if (pScrollBottom != pScr->screen_bottom) { + bFullScreen = FALSE; + rc.left = 0; + rc.right = pScr->cxChar * pScr->width; + rc.top = pScr->cyChar * pScr->top; + rc.bottom = pScr->cyChar * (pScr->bottom+1); + } + else { + if (pScr->screen_bottom == pScr->buffer_bottom) + pScr->buffer_bottom = pScrLine; + pScr->screen_bottom = pScrLine; + } + +#if 0 + CheckScreen(fpScr); +#endif - Edit_ClearSelection(pScr); + pScr->y++; - pScrollTop = GetScreenLineFromY(pScr, pScr->top); + if (pScr->y > pScr->bottom) + pScr->y = pScr->bottom; - pScrollBottom = GetScreenLineFromY(pScr, pScr->bottom); + hDC = GetDC(pScr->hWnd); + assert(hDC != NULL); - if (pScrollTop != pScr->screen_top) { - bFullScreen = FALSE; - rc.left = 0; - rc.right = pScr->cxChar * pScr->width; - rc.top = pScr->cyChar * (pScr->top); - rc.bottom = pScr->cyChar * (pScr->bottom+1); + if (bFullScreen) + ScrollDC(hDC, 0, -pScr->cyChar, NULL, NULL, NULL, NULL); + else + ScrollDC(hDC, 0, -pScr->cyChar, &rc, &rc, NULL, NULL); - pNext = pScrollTop->next; - pPrev = pScrollTop->prev; + PatBlt(hDC, 0, pScr->bottom * pScr->cyChar, + pScr->width * pScr->cxChar, pScr->cyChar, WHITENESS); - pPrev->next = pNext; - pNext->prev = pPrev; + ReleaseDC(pScr->hWnd, hDC); - pScrLine = pScrollTop; - ScreenClearLine(pScr, pScrLine); - } - else { - pScr->numlines++; - pScrLine = ScreenNewLine(); - if (pScrLine == NULL) - return(0); - pScr->screen_top = pScrollTop->next; - } - - if (pScrLine == NULL) - return(0); - - pNext = pScrollBottom->next; - pScrollBottom->next = pScrLine; - pScrLine->next = pNext; - pScrLine->prev = pScrollBottom; - if (pNext != NULL) - pNext->prev = pScrLine; - - if (pScrollBottom != pScr->screen_bottom) { - bFullScreen = FALSE; - rc.left = 0; - rc.right = pScr->cxChar * pScr->width; - rc.top = pScr->cyChar * pScr->top; - rc.bottom = pScr->cyChar * (pScr->bottom+1); - } - else { - if (pScr->screen_bottom == pScr->buffer_bottom) - pScr->buffer_bottom = pScrLine; - pScr->screen_bottom = pScrLine; - } + if (pScr->numlines == pScr->maxlines) + DeleteTopLine(pScr); + else + SetScreenScrollBar(pScr); -// CheckScreen(fpScr); + return(1); - pScr->y++; +} /* ScreenScroll */ - if (pScr->y > pScr->bottom) - pScr->y = pScr->bottom; - hDC = GetDC(pScr->hWnd); - assert(hDC != NULL); +int DrawTextScreen( + RECT rcInvalid, + SCREEN *pScr, + HDC hDC) +{ + SCREENLINE *pScrLineTmp; + SCREENLINE *pScrLine; + int x = 0; + int y = 0; + int left = 0; + int right = 0; + int i; + int len; + char attrib; +#define YPOS (y*pScr->cyChar) - if (bFullScreen) - ScrollDC(hDC, 0, -pScr->cyChar, NULL, NULL, NULL, NULL); - else - ScrollDC(hDC, 0, -pScr->cyChar, &rc, &rc, NULL, NULL); + pScrLine = pScr->screen_top; - PatBlt(hDC, 0, pScr->bottom * pScr->cyChar, - pScr->width * pScr->cxChar, pScr->cyChar, WHITENESS); - - ReleaseDC(pScr->hWnd, hDC); + for (y = 0; y < pScr->height; y++) { + if (!pScrLine) + continue; - if (pScr->numlines == pScr->maxlines) - DeleteTopLine(pScr); - else - SetScreenScrollBar(pScr); + if (YPOS >= rcInvalid.top - pScr->cyChar && + YPOS <= rcInvalid.bottom + pScr->cyChar) { - return(1); + if (y < 0) + y = 0; -} /* ScreenScroll */ + if (y >= pScr->height) + y = pScr->height - 1; + left = (rcInvalid.left / pScr->cxChar) - 1; -int DrawTextScreen( - RECT rcInvalid, - SCREEN *pScr, - HDC hDC) -{ - SCREENLINE *pScrLineTmp; - SCREENLINE *pScrLine; - int x = 0; - int y = 0; - int left = 0; - int right = 0; - int i; - int len; - char attrib; - #define YPOS (y*pScr->cyChar) - - pScrLine = pScr->screen_top; - - for (y = 0; y < pScr->height; y++) { - if (!pScrLine) - continue; - - if (YPOS >= rcInvalid.top - pScr->cyChar && - YPOS <= rcInvalid.bottom + pScr->cyChar) { - - if (y < 0) - y = 0; - - if (y >= pScr->height) - y = pScr->height - 1; - - left = (rcInvalid.left / pScr->cxChar) - 1; - - right = (rcInvalid.right / pScr->cxChar) + 1; - - if (left < 0) - left = 0; - - if (right > pScr->width - 1) - right = pScr->width - 1; - - x = left; - - while (x <= right) { - if (!pScrLine->text[x]) { - x++; - continue; - } - - if (SCR_isrev(pScrLine->attrib[x])) { - SelectObject(hDC, pScr->hSelectedFont); - SetTextColor(hDC, RGB(255, 255, 255)); - SetBkColor(hDC, RGB(0, 0, 0)); - } - else if (SCR_isblnk(pScrLine->attrib[x])) { - SelectObject(hDC, pScr->hSelectedFont); - SetTextColor(hDC, RGB(255, 0, 0)); - SetBkColor(hDC, RGB(255, 255, 255)); - } - else if (SCR_isundl(pScrLine->attrib[x])) { - SetTextColor(hDC, RGB(255, 0, 0)); - SetBkColor(hDC, RGB(255, 255, 255)); - SelectObject(hDC, pScr->hSelectedULFont); - } - else { - SelectObject(hDC,pScr->hSelectedFont); - SetTextColor(hDC, RGB(0, 0, 0)); - SetBkColor(hDC, RGB(255, 255, 255)); - } - - len = 1; - attrib = pScrLine->attrib[x]; - for (i = x + 1; i <= right; i++) { - if (pScrLine->attrib[i] != attrib || !pScrLine->text[i]) - break; - len++; - } - - TextOut(hDC, x*pScr->cxChar, y*pScr->cyChar, &pScrLine->text[x], len); - x += len; - } - } - pScrLineTmp = pScrLine->next; - pScrLine = pScrLineTmp; + right = (rcInvalid.right / pScr->cxChar) + 1; + + if (left < 0) + left = 0; + + if (right > pScr->width - 1) + right = pScr->width - 1; + + x = left; + + while (x <= right) { + if (!pScrLine->text[x]) { + x++; + continue; + } + + if (SCR_isrev(pScrLine->attrib[x])) { + SelectObject(hDC, pScr->hSelectedFont); + SetTextColor(hDC, RGB(255, 255, 255)); + SetBkColor(hDC, RGB(0, 0, 0)); + } + else if (SCR_isblnk(pScrLine->attrib[x])) { + SelectObject(hDC, pScr->hSelectedFont); + SetTextColor(hDC, RGB(255, 0, 0)); + SetBkColor(hDC, RGB(255, 255, 255)); + } + else if (SCR_isundl(pScrLine->attrib[x])) { + SetTextColor(hDC, RGB(255, 0, 0)); + SetBkColor(hDC, RGB(255, 255, 255)); + SelectObject(hDC, pScr->hSelectedULFont); + } + else { + SelectObject(hDC,pScr->hSelectedFont); + SetTextColor(hDC, RGB(0, 0, 0)); + SetBkColor(hDC, RGB(255, 255, 255)); + } + + len = 1; + attrib = pScrLine->attrib[x]; + for (i = x + 1; i <= right; i++) { + if (pScrLine->attrib[i] != attrib || !pScrLine->text[i]) + break; + len++; } - return(0); + TextOut(hDC, x*pScr->cxChar, y*pScr->cyChar, &pScrLine->text[x], len); + x += len; + } + } + pScrLineTmp = pScrLine->next; + pScrLine = pScrLineTmp; + } + + return(0); } /* DrawTextScreen */ static BOOL SetInternalScreenSize( - SCREEN *pScr, - int width, - int height) + SCREEN *pScr, + int width, + int height) { - RECT rc; - char *p; - int idx; - int n; - int newlines; - SCREENLINE *pNewLine; - SCREENLINE *pTopLine; - SCREENLINE *pBottomLine; - #if 0 - int col; - int row; - int dydestbottom; - #endif - - GetClientRect(pScr->hWnd, &rc); - - width = (rc.right - rc.left) / pScr->cxChar; - height = (rc.bottom - rc.top) / pScr->cyChar; - - if (pScr->height == height && pScr->width == width) - return(FALSE); - - pScr->Oldx = 0; - pScr->Oldy = 0; - pScr->attrib = 0; - - /* - Reallocate the inverted array of bytes and copy the values - from the old screen to the new screen. - */ - p = calloc(width * height, 1); - - ScreenCursorOff(pScr); - - #if 0 /* Copy inversion array to desitination */ - for (col = 0; col < width; col++) { - for (row = 0; row < height; row++) { - dydestbottom = height - 1 - row; - if (col < pScr->width && dydestbottom < pScr->height - 1) - p[row * width + col] = - cInvertedArray[(pScr->height - 1 - dydestbottom) * pScr->width + col]; - } - } - #endif - - free(cInvertedArray); - cInvertedArray = p; - - /* - Append any new lines which need to be added to accomodate the new - screen size. - */ - pBottomLine = pScr->buffer_bottom; - newlines = height - (pScr->height + pScr->numlines); - - if (newlines > 0) { - pScr->y += pScr->numlines; - pScr->numlines = 0; - - for (idx = 0; idx < newlines; idx++) { - pNewLine = ScreenNewLine(); - if (pNewLine == NULL) - return(FALSE); - pNewLine->prev = pBottomLine; - if (pBottomLine == NULL) - return(FALSE); - pBottomLine->next = pNewLine; - pBottomLine = pNewLine; - } - } + RECT rc; + char *p; + int idx; + int n; + int newlines; + SCREENLINE *pNewLine; + SCREENLINE *pTopLine; + SCREENLINE *pBottomLine; +#if 0 + int col; + int row; + int dydestbottom; +#endif - /* - If we already have plenty of lines, then we need to get rid of the - scrollback lines, if too many exist. The cursor should end up - the same distance from the bottom of the screen as is started out - in this instance. - */ - if (newlines < 0) { - pScr->y = (height - 1) - (pScr->bottom - pScr->y); - if (pScr->y < 0) - pScr->y = 0; - pScr->numlines = -newlines; - n = pScr->numlines - pScr->maxlines; - for (idx = 0; idx < n; idx++) - DeleteTopLine(pScr); - } - - /* - Calculate the position of the buffer relative to the screen. - */ - pScr->screen_bottom = pBottomLine; - pScr->buffer_bottom = pBottomLine; + GetClientRect(pScr->hWnd, &rc); - pTopLine = pBottomLine; + width = (rc.right - rc.left) / pScr->cxChar; + height = (rc.bottom - rc.top) / pScr->cyChar; - for (idx = 1; idx < height; idx++) { - pTopLine = pTopLine->prev; - } + if (pScr->height == height && pScr->width == width) + return(FALSE); - pScr->screen_top = pTopLine; - pScr->width = width; - pScr->height = height; - pScr->top = 0; - pScr->bottom = height - 1; + pScr->Oldx = 0; + pScr->Oldy = 0; + pScr->attrib = 0; - if (pScr->x >= width) - pScr->x = width - 1; + /* + Reallocate the inverted array of bytes and copy the values + from the old screen to the new screen. + */ + p = calloc(width * height, 1); - if (pScr->y >= height) - pScr->y = height - 1; + ScreenCursorOff(pScr); + +#if 0 /* Copy inversion array to desitination */ + for (col = 0; col < width; col++) { + for (row = 0; row < height; row++) { + dydestbottom = height - 1 - row; + if (col < pScr->width && dydestbottom < pScr->height - 1) + p[row * width + col] = + cInvertedArray[(pScr->height - 1 - dydestbottom) * pScr->width + col]; + } + } +#endif - SetScreenScrollBar(pScr); - ScreenCursorOn(pScr); - return(TRUE); + free(cInvertedArray); + cInvertedArray = p; + + /* + Append any new lines which need to be added to accomodate the new + screen size. + */ + pBottomLine = pScr->buffer_bottom; + newlines = height - (pScr->height + pScr->numlines); + + if (newlines > 0) { + pScr->y += pScr->numlines; + pScr->numlines = 0; + + for (idx = 0; idx < newlines; idx++) { + pNewLine = ScreenNewLine(); + if (pNewLine == NULL) + return(FALSE); + pNewLine->prev = pBottomLine; + if (pBottomLine == NULL) + return(FALSE); + pBottomLine->next = pNewLine; + pBottomLine = pNewLine; + } + } + + /* + If we already have plenty of lines, then we need to get rid of the + scrollback lines, if too many exist. The cursor should end up + the same distance from the bottom of the screen as is started out + in this instance. + */ + if (newlines < 0) { + pScr->y = (height - 1) - (pScr->bottom - pScr->y); + if (pScr->y < 0) + pScr->y = 0; + pScr->numlines = -newlines; + n = pScr->numlines - pScr->maxlines; + for (idx = 0; idx < n; idx++) + DeleteTopLine(pScr); + } + + /* + Calculate the position of the buffer relative to the screen. + */ + pScr->screen_bottom = pBottomLine; + pScr->buffer_bottom = pBottomLine; + + pTopLine = pBottomLine; + + for (idx = 1; idx < height; idx++) { + pTopLine = pTopLine->prev; + } + + pScr->screen_top = pTopLine; + pScr->width = width; + pScr->height = height; + pScr->top = 0; + pScr->bottom = height - 1; + + if (pScr->x >= width) + pScr->x = width - 1; + + if (pScr->y >= height) + pScr->y = height - 1; + + SetScreenScrollBar(pScr); + ScreenCursorOn(pScr); + return(TRUE); } /* SetInternalScreenSize */ static int ScreenAdjustUp( - SCREEN *pScr, - int n) + SCREEN *pScr, + int n) { - int idx; - SCREENLINE *pLine1; - SCREENLINE *pLine2; - - for (idx = 0; idx < n; idx++) { - if (pScr->screen_top == pScr->buffer_top) - return(-idx); - pLine1 = pScr->screen_top->prev; - if (pLine1 == NULL) - return(-idx); - pLine2 = pScr->screen_bottom->prev; - if (pLine2 == NULL) - return(-idx); - pScr->screen_top = pLine1; - pScr->screen_bottom = pLine2; - } - - return(idx); + int idx; + SCREENLINE *pLine1; + SCREENLINE *pLine2; + + for (idx = 0; idx < n; idx++) { + if (pScr->screen_top == pScr->buffer_top) + return(-idx); + pLine1 = pScr->screen_top->prev; + if (pLine1 == NULL) + return(-idx); + pLine2 = pScr->screen_bottom->prev; + if (pLine2 == NULL) + return(-idx); + pScr->screen_top = pLine1; + pScr->screen_bottom = pLine2; + } + + return(idx); } /* ScreenAdjustUp */ static int ScreenAdjustDown( - SCREEN *pScr, - int n) + SCREEN *pScr, + int n) { - int idx; - SCREENLINE *pLine1; - SCREENLINE *pLine2; - - for (idx = 0; idx < n; idx++) { - if (pScr->screen_bottom == pScr->buffer_bottom) - return(-idx); - pLine1 = pScr->screen_top->next; - if (pLine1 == NULL) - return(-idx); - pLine2 = pScr->screen_bottom->next; - if (pLine2 == NULL) - return(-idx); - pScr->screen_top = pLine1; - pScr->screen_bottom = pLine2; - } - - return(idx); + int idx; + SCREENLINE *pLine1; + SCREENLINE *pLine2; + + for (idx = 0; idx < n; idx++) { + if (pScr->screen_bottom == pScr->buffer_bottom) + return(-idx); + pLine1 = pScr->screen_top->next; + if (pLine1 == NULL) + return(-idx); + pLine2 = pScr->screen_bottom->next; + if (pLine2 == NULL) + return(-idx); + pScr->screen_top = pLine1; + pScr->screen_bottom = pLine2; + } + + return(idx); } /* ScreenAdjustDown */ long FAR PASCAL ScreenWndProc( - HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam) + HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam) { - MINMAXINFO *lpmmi; - SCREEN *pScr; - HMENU hMenu; - PAINTSTRUCT ps; - int x = 0; - int y = 0; - int ScrollPos; - int tmpScroll = 0; - int idx; - HDC hDC; - RECT rc; - char title[128]; - static int bDoubleClick = FALSE; - - switch (message) { - - case WM_COMMAND: - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert (pScr != NULL); - - switch (wParam) { - - case IDM_BACKSPACE: - hMenu = GetMenu(hWnd); - CheckMenuItem(hMenu, IDM_BACKSPACE, MF_CHECKED); - CheckMenuItem(hMenu, IDM_DELETE, MF_UNCHECKED); - SendMessage(pScr->hwndTel, WM_MYSCREENCHANGEBKSP, VK_BACK, (LPARAM) pScr); - break; - - case IDM_DELETE: - hMenu = GetMenu(hWnd); - CheckMenuItem(hMenu, IDM_BACKSPACE, MF_UNCHECKED); - CheckMenuItem(hMenu, IDM_DELETE, MF_CHECKED); - SendMessage(pScr->hwndTel, WM_MYSCREENCHANGEBKSP, 0x7f, (LPARAM) pScr); - break; - - case IDM_FONT: - ScreenCursorOff(pScr); - ProcessFontChange(hWnd); - ScreenCursorOn(pScr); - break; - - case IDM_COPY: - Edit_Copy(hWnd); - hMenu=GetMenu(hWnd); - Edit_ClearSelection(pScr); - break; - - case IDM_PASTE: - Edit_Paste(hWnd); - break; - - case IDM_ABOUT: + MINMAXINFO *lpmmi; + SCREEN *pScr; + HMENU hMenu; + PAINTSTRUCT ps; + int x = 0; + int y = 0; + int ScrollPos; + int tmpScroll = 0; + int idx; + HDC hDC; + RECT rc; + char title[128]; + static int bDoubleClick = FALSE; + + switch (message) { + + case WM_COMMAND: + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert (pScr != NULL); + + switch (wParam) { + + case IDM_EXIT: + if (MessageBox(hWnd, "Terminate this connection?", "Telnet", MB_OKCANCEL) == IDOK) { + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert (pScr != NULL); + SendMessage(pScr->hwndTel, WM_MYSCREENCLOSE, 0, (LPARAM) pScr); + } + break; + + case IDM_BACKSPACE: + hMenu = GetMenu(hWnd); + CheckMenuItem(hMenu, IDM_BACKSPACE, MF_CHECKED); + CheckMenuItem(hMenu, IDM_DELETE, MF_UNCHECKED); + SendMessage(pScr->hwndTel, WM_MYSCREENCHANGEBKSP, VK_BACK, (LPARAM) pScr); + break; + + case IDM_DELETE: + hMenu = GetMenu(hWnd); + CheckMenuItem(hMenu, IDM_BACKSPACE, MF_UNCHECKED); + CheckMenuItem(hMenu, IDM_DELETE, MF_CHECKED); + SendMessage(pScr->hwndTel, WM_MYSCREENCHANGEBKSP, 0x7f, (LPARAM) pScr); + break; + + case IDM_FONT: + ScreenCursorOff(pScr); + ProcessFontChange(hWnd); + ScreenCursorOn(pScr); + break; + + case IDM_COPY: + Edit_Copy(hWnd); + hMenu=GetMenu(hWnd); + Edit_ClearSelection(pScr); + break; + + case IDM_PASTE: + Edit_Paste(hWnd); + break; + + case IDM_HELP_INDEX: + WinHelp(hWnd, HELP_FILE, HELP_INDEX, 0); + break; + + case IDM_ABOUT: #ifdef CYGNUS #ifdef KRB4 - strcpy(strTmp, " Kerberos 4 for Windows\n"); + strcpy(strTmp, " Kerberos 4 for Windows\n"); #endif #ifdef KRB5 - strcpy(strTmp, " Kerberos 5 for Windows\n"); + strcpy(strTmp, " KerbNet for Windows\n"); #endif - strcat(strTmp, "\n Version 1.00\n\n"); - strcat(strTmp, " For support, contact:\n"); - strcat(strTmp, "Cygnus Support"); - strcat(strTmp, " - (415) 903-1400"); -#else - strcpy(strTmp, " Kerberos 5 Telnet for Windows\n"); - strcat(strTmp, "\n Version 1.00\n\n"); + strcat(strTmp, "\n Version 1.00\n\n"); + strcat(strTmp, " For support, contact:\n"); + strcat(strTmp, " Cygnus Support - (415) 903-1400\n"); +#else /* CYGNUS */ + strcpy(strTmp, " Kerberos 5 Telnet for Windows\n"); + strcat(strTmp, " ALPHA SNAPSHOT 1\n\n"); +#endif /* CYGNUS */ + if (encrypt_flag) { + strcat(strTmp, "\n[Encryption of output requested. State: "); + strcat(strTmp, (encrypt_output ? "encrypting]" : "INACTIVE]")); + strcat(strTmp, "\n[Decryption of input requested. State: "); + strcat(strTmp, (decrypt_input ? "decrypting]\n" : "INACTIVE]\n")); + } + MessageBox(NULL, strTmp, "Kerberos", MB_OK); + break; + +#if defined(DEBUG) + case IDM_DEBUG: + CheckScreen(pScr); + break; #endif - MessageBox(NULL, strTmp, "Kerberos", MB_OK); - break; - - #if ! defined(NDEBUG) - case IDM_DEBUG: - CheckScreen(pScr); - break; - #endif - } - - break; - - case WM_NCCREATE: - pScr = (SCREEN *) ((LPCREATESTRUCT) lParam)->lpCreateParams; - pScr->hWnd = hWnd; - SetWindowLong(hWnd, SCREEN_HANDLE, (LONG) pScr); - SetScrollRange(hWnd, SB_VERT, 0, 100, FALSE); - SetScrollPos(hWnd, SB_VERT, 0, TRUE); - EnableScrollBar(hWnd, SB_VERT, ESB_DISABLE_BOTH); - return(TRUE); - - case WM_VSCROLL: - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert (pScr != NULL); - - ScreenCursorOff(pScr); - - switch(wParam) { - - case SB_LINEDOWN: - if (ScreenAdjustDown(pScr, 1) <= 0) - break; - hDC = GetDC(hWnd); - assert(hDC != NULL); - rc.left = 0; - rc.right = pScr->cxChar * pScr->width; - rc.top = 0; - rc.bottom = pScr->cyChar * (pScr->bottom + 1); - ScrollDC(hDC, 0, -pScr->cyChar, &rc, &rc, NULL, NULL); - ReleaseDC(hWnd, hDC); - rc.top = pScr->cyChar * pScr->bottom; - InvalidateRect(hWnd, &rc, TRUE); - ScrollPos = GetScrollPos(hWnd, SB_VERT); - SetScrollPos(hWnd, SB_VERT, ScrollPos + 1, TRUE); - UpdateWindow(hWnd); - break; - - case SB_LINEUP: - if (ScreenAdjustUp(pScr, 1) <= 0) - break; - hDC = GetDC(hWnd); - assert(hDC != NULL); - rc.left = 0; - rc.right = pScr->cxChar * pScr->width; - rc.top = 0; - rc.bottom = pScr->cyChar * (pScr->bottom + 1); - ScrollDC(hDC, 0, pScr->cyChar, &rc, &rc, NULL, NULL); - ReleaseDC(hWnd, hDC); - rc.bottom = pScr->cyChar; - InvalidateRect(hWnd, &rc, TRUE); - ScrollPos = GetScrollPos(pScr->hWnd, SB_VERT); - SetScrollPos(hWnd,SB_VERT, ScrollPos - 1, TRUE); - UpdateWindow(hWnd); - break; - - case SB_PAGEDOWN: - idx = abs(ScreenAdjustDown(pScr, pScr->height)); - hDC = GetDC(hWnd); - assert(hDC != NULL); - rc.left = 0; - rc.right = pScr->cxChar * pScr->width; - rc.top = 0; - rc.bottom = pScr->cyChar * (pScr->bottom+1); - ScrollDC(hDC, 0, -idx * pScr->cyChar, &rc, &rc, NULL, NULL); - ReleaseDC(hWnd, hDC); - rc.top = pScr->cyChar * (pScr->bottom - idx + 1); - InvalidateRect(hWnd, &rc, TRUE); - ScrollPos=GetScrollPos(hWnd, SB_VERT); - SetScrollPos(hWnd, SB_VERT, ScrollPos + idx, TRUE); - break; - - case SB_PAGEUP: - idx = abs(ScreenAdjustUp(pScr, pScr->height)); - hDC = GetDC(hWnd); - assert(hDC != NULL); - rc.left = 0; - rc.right = pScr->cxChar * pScr->width; - rc.top = 0; - rc.bottom = pScr->cyChar * (pScr->bottom + 1); - ScrollDC(hDC, 0, idx * pScr->cyChar, &rc, &rc, NULL, NULL); - ReleaseDC(hWnd, hDC); - rc.bottom = idx * pScr->cyChar; - InvalidateRect(hWnd, &rc, TRUE); - ScrollPos=GetScrollPos(hWnd, SB_VERT); - SetScrollPos(hWnd, SB_VERT, ScrollPos - idx, TRUE); - break; - - case SB_THUMBPOSITION: - case SB_THUMBTRACK: - ScrollPos = GetScrollPos(hWnd, SB_VERT); - tmpScroll = ScrollPos - LOWORD(lParam); - if (tmpScroll == 0) - break; - if (tmpScroll > 0) - ScreenAdjustUp(pScr, tmpScroll); - else - ScreenAdjustDown(pScr, -tmpScroll); - if (abs(tmpScroll) < pScr->height) { - hDC = GetDC(hWnd); - assert(hDC != NULL); - rc.left = 0; - rc.right = pScr->cxChar * pScr->width; - rc.top = 0; - rc.bottom = pScr->cyChar * (pScr->bottom + 1); - ScrollDC(hDC, 0, tmpScroll * pScr->cyChar, &rc, &rc, NULL, NULL); - ReleaseDC(hWnd, hDC); - if (tmpScroll > 0) { - rc.bottom = tmpScroll * pScr->cyChar; - InvalidateRect(hWnd, &rc, TRUE); - } - else { - rc.top = (pScr->bottom + tmpScroll + 1) * pScr->cyChar; - InvalidateRect(hWnd, &rc, TRUE); - } - } - else - InvalidateRect(hWnd, NULL, TRUE); - - SetScrollPos(hWnd, SB_VERT, LOWORD(lParam), TRUE); - UpdateWindow(hWnd); - break; - } - - ScreenCursorOn(pScr); - break; - - case WM_KEYDOWN: - if (wParam == VK_INSERT) { - if (GetKeyState(VK_SHIFT) < 0) - PostMessage(hWnd, WM_COMMAND, IDM_PASTE, NULL); - else if (GetKeyState(VK_CONTROL) < 0) - PostMessage(hWnd, WM_COMMAND, IDM_COPY, NULL); - break; - } - /* - ** Check for cursor keys. With control pressed, we treat as - ** keyboard equivalents to scrolling. Otherwise, we send - ** a WM_MYCURSORKEY message with the appropriate string - ** to be sent. Sending the actual string allows the upper - ** level to be ignorant of keyboard modes, etc. - */ - if (wParam < VK_PRIOR || wParam > VK_DOWN) // Is it a cursor key? - break; - - if (GetKeyState (VK_CONTROL) >= 0) { // No control key - if (wParam >= VK_LEFT && wParam <= VK_DOWN) { - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert (pScr != NULL); - wParam = wParam - VK_LEFT + (pScr->DECCKM ? 4 : 0); - SendMessage (pScr->hwndTel, WM_MYCURSORKEY, - strlen(cursor_key[wParam]), - (LPARAM) (char FAR *) cursor_key[wParam]); - } - } else { // Control is down - switch (wParam) { - case VK_PRIOR: /* Page up */ - SendMessage(hWnd, WM_VSCROLL, SB_PAGEUP, NULL); - break; - case VK_NEXT: /* Page down */ - SendMessage(hWnd, WM_VSCROLL, SB_PAGEDOWN, NULL); - break; - case VK_UP: /* Line up */ - SendMessage(hWnd, WM_VSCROLL, SB_LINEUP, NULL); - break; - case VK_DOWN: /* Line down */ - SendMessage(hWnd, WM_VSCROLL, SB_LINEDOWN, NULL); - break; - } - } - UpdateWindow(hWnd); - break; - - case WM_CHAR: - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert (pScr != NULL); - SendMessage(pScr->hwndTel, WM_MYSCREENCHAR, wParam, (LPARAM) pScr); - break; - - case WM_SYSCHAR: - if (wParam == 'c' || wParam == 'e') - return (DefWindowProc(hWnd, message, wParam, lParam)); - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert (pScr != NULL); - SendMessage(pScr->hwndTel, WM_MYSYSCHAR, wParam, (LPARAM) pScr); - break; - - case WM_INITMENU: - if (IsClipboardFormatAvailable(CF_TEXT)) - EnableMenuItem((HMENU) wParam, IDM_PASTE, MF_ENABLED); - else - EnableMenuItem((HMENU) wParam, IDM_PASTE, MF_GRAYED); - if (bSelection) - EnableMenuItem((HMENU) wParam, IDM_COPY, MF_ENABLED); - else - EnableMenuItem((HMENU) wParam, IDM_COPY, MF_GRAYED); - break; - - case WM_GETMINMAXINFO: - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - if (pScr == NULL) // Used on creation when window word not set - pScr = ScreenList; - lpmmi = (MINMAXINFO *) lParam; - if (FRAME_WIDTH + MAX_LINE_WIDTH * pScr->cxChar < lpmmi->ptMaxSize.x) - lpmmi->ptMaxSize.x = FRAME_WIDTH + MAX_LINE_WIDTH * pScr->cxChar; - lpmmi->ptMaxTrackSize.x = lpmmi->ptMaxSize.x; - lpmmi->ptMinTrackSize.x = FRAME_WIDTH + 20 * pScr->cxChar; - lpmmi->ptMinTrackSize.y = FRAME_HEIGHT + 4 * pScr->cyChar; - break; - - case WM_LBUTTONDOWN: - if (bDoubleClick) - Edit_TripleClick(hWnd, lParam); - else - Edit_LbuttonDown(hWnd, lParam); - break; - - case WM_LBUTTONUP: - Edit_LbuttonUp(hWnd, lParam); - break; - - case WM_LBUTTONDBLCLK: - bDoubleClick = TRUE; - SetTimer(hWnd, TIMER_TRIPLECLICK, GetDoubleClickTime(), NULL); - Edit_LbuttonDblclk(hWnd, lParam); - break; - - case WM_TIMER: - if (wParam == TIMER_TRIPLECLICK) - bDoubleClick = FALSE; - break; - - case WM_RBUTTONUP: - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert (pScr != NULL); - Edit_Copy(hWnd); - Edit_ClearSelection(pScr); - Edit_Paste(hWnd); - break; - - case WM_MOUSEMOVE: - if (bMouseDown) - Edit_MouseMove(hWnd, lParam); - break; - - case WM_RBUTTONDOWN: - #if 0 - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert (pScr != NULL); - wsprintf(strTmp,"fp->x=%d fp->y=%d text=%s \r\n", - pScr->screen_top->x, pScr->screen_top->y, pScr->screen_top->text); - OutputDebugString(strTmp); - #endif - break; - - case WM_PAINT: - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert (pScr != NULL); - BeginPaint (hWnd, &ps); - SelectObject(ps.hdc, pScr->hSelectedFont); - if (pScr->screen_bottom != NULL) - DrawTextScreen(ps.rcPaint, pScr, ps.hdc); - else - OutputDebugString("screen_bottom is NULL.\r\n"); - EndPaint(hWnd, &ps); - break; - - case WM_CLOSE: - if (MessageBox(hWnd, "Terminate this connection?", "Telnet", MB_OKCANCEL) == IDOK) { - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert (pScr != NULL); - SendMessage(pScr->hwndTel, WM_MYSCREENCLOSE, NULL, (LPARAM) pScr); - return (DefWindowProc(hWnd, message, wParam, lParam)); - } - break; - - case WM_DESTROY: - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - if (pScr != NULL) - DeleteObject(pScr->hSelectedFont); - return (DefWindowProc(hWnd, message, wParam, lParam)); - - case WM_ACTIVATE: - if (wParam != WA_INACTIVE) { - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert (pScr != NULL); - if (pScr->bAlert) { - char strTitle[128]; - int idx; - - GetWindowText(hWnd, strTitle, sizeof(strTitle)); - if (strTitle[0] == ALERT) { - idx = lstrlen(strTitle); - strTitle[idx - 2] = 0; - SetWindowText(hWnd, &strTitle[2]); - pScr->bAlert = FALSE; - } - } - } - return (DefWindowProc(hWnd, message, wParam, lParam)); - - case WM_SIZE: - if (wParam == SIZE_MINIMIZED) - break; - - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert (pScr != NULL); - - if (SetInternalScreenSize(pScr, LOWORD(lParam), HIWORD(lParam))) { - SendMessage(pScr->hwndTel, WM_MYSCREENSIZE, 0, - MAKELONG(pScr->width, pScr->height)); - } - MakeWindowTitle(pScr->title, pScr->width, pScr->height, title, sizeof(title)); - SetWindowText(hWnd, title); - break; - - case WM_SETFOCUS: - pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); - assert (pScr != NULL); - CreateCaret(hWnd, NULL, pScr->cxChar, 2); - ScreenCursorOn(pScr); - break; - - case WM_KILLFOCUS: - DestroyCaret(); - break; - - default: - return(DefWindowProc(hWnd, message, wParam, lParam)); + } + + break; + + case WM_NCCREATE: + pScr = (SCREEN *) ((LPCREATESTRUCT) lParam)->lpCreateParams; + pScr->hWnd = hWnd; + SetWindowLong(hWnd, SCREEN_HANDLE, (LONG) pScr); + SetScrollRange(hWnd, SB_VERT, 0, 100, FALSE); + SetScrollPos(hWnd, SB_VERT, 0, TRUE); + EnableScrollBar(hWnd, SB_VERT, ESB_DISABLE_BOTH); + return(TRUE); + + case WM_VSCROLL: + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert (pScr != NULL); + + ScreenCursorOff(pScr); + + switch(wParam) { + + case SB_LINEDOWN: + if (ScreenAdjustDown(pScr, 1) <= 0) + break; + hDC = GetDC(hWnd); + assert(hDC != NULL); + rc.left = 0; + rc.right = pScr->cxChar * pScr->width; + rc.top = 0; + rc.bottom = pScr->cyChar * (pScr->bottom + 1); + ScrollDC(hDC, 0, -pScr->cyChar, &rc, &rc, NULL, NULL); + ReleaseDC(hWnd, hDC); + rc.top = pScr->cyChar * pScr->bottom; + InvalidateRect(hWnd, &rc, TRUE); + ScrollPos = GetScrollPos(hWnd, SB_VERT); + SetScrollPos(hWnd, SB_VERT, ScrollPos + 1, TRUE); + UpdateWindow(hWnd); + break; + + case SB_LINEUP: + if (ScreenAdjustUp(pScr, 1) <= 0) + break; + hDC = GetDC(hWnd); + assert(hDC != NULL); + rc.left = 0; + rc.right = pScr->cxChar * pScr->width; + rc.top = 0; + rc.bottom = pScr->cyChar * (pScr->bottom + 1); + ScrollDC(hDC, 0, pScr->cyChar, &rc, &rc, NULL, NULL); + ReleaseDC(hWnd, hDC); + rc.bottom = pScr->cyChar; + InvalidateRect(hWnd, &rc, TRUE); + ScrollPos = GetScrollPos(pScr->hWnd, SB_VERT); + SetScrollPos(hWnd,SB_VERT, ScrollPos - 1, TRUE); + UpdateWindow(hWnd); + break; + + case SB_PAGEDOWN: + idx = abs(ScreenAdjustDown(pScr, pScr->height)); + hDC = GetDC(hWnd); + assert(hDC != NULL); + rc.left = 0; + rc.right = pScr->cxChar * pScr->width; + rc.top = 0; + rc.bottom = pScr->cyChar * (pScr->bottom+1); + ScrollDC(hDC, 0, -idx * pScr->cyChar, &rc, &rc, NULL, NULL); + ReleaseDC(hWnd, hDC); + rc.top = pScr->cyChar * (pScr->bottom - idx + 1); + InvalidateRect(hWnd, &rc, TRUE); + ScrollPos=GetScrollPos(hWnd, SB_VERT); + SetScrollPos(hWnd, SB_VERT, ScrollPos + idx, TRUE); + break; + + case SB_PAGEUP: + idx = abs(ScreenAdjustUp(pScr, pScr->height)); + hDC = GetDC(hWnd); + assert(hDC != NULL); + rc.left = 0; + rc.right = pScr->cxChar * pScr->width; + rc.top = 0; + rc.bottom = pScr->cyChar * (pScr->bottom + 1); + ScrollDC(hDC, 0, idx * pScr->cyChar, &rc, &rc, NULL, NULL); + ReleaseDC(hWnd, hDC); + rc.bottom = idx * pScr->cyChar; + InvalidateRect(hWnd, &rc, TRUE); + ScrollPos=GetScrollPos(hWnd, SB_VERT); + SetScrollPos(hWnd, SB_VERT, ScrollPos - idx, TRUE); + break; + + case SB_THUMBPOSITION: + case SB_THUMBTRACK: + ScrollPos = GetScrollPos(hWnd, SB_VERT); + tmpScroll = ScrollPos - LOWORD(lParam); + if (tmpScroll == 0) + break; + if (tmpScroll > 0) + ScreenAdjustUp(pScr, tmpScroll); + else + ScreenAdjustDown(pScr, -tmpScroll); + if (abs(tmpScroll) < pScr->height) { + hDC = GetDC(hWnd); + assert(hDC != NULL); + rc.left = 0; + rc.right = pScr->cxChar * pScr->width; + rc.top = 0; + rc.bottom = pScr->cyChar * (pScr->bottom + 1); + ScrollDC(hDC, 0, tmpScroll * pScr->cyChar, &rc, &rc, NULL, NULL); + ReleaseDC(hWnd, hDC); + if (tmpScroll > 0) { + rc.bottom = tmpScroll * pScr->cyChar; + InvalidateRect(hWnd, &rc, TRUE); } + else { + rc.top = (pScr->bottom + tmpScroll + 1) * pScr->cyChar; + InvalidateRect(hWnd, &rc, TRUE); + } + } + else + InvalidateRect(hWnd, NULL, TRUE); + + SetScrollPos(hWnd, SB_VERT, LOWORD(lParam), TRUE); + UpdateWindow(hWnd); + break; + } + + ScreenCursorOn(pScr); + break; + + case WM_KEYDOWN: + if (wParam == VK_INSERT) { + if (GetKeyState(VK_SHIFT) < 0) + PostMessage(hWnd, WM_COMMAND, IDM_PASTE, 0); + else if (GetKeyState(VK_CONTROL) < 0) + PostMessage(hWnd, WM_COMMAND, IDM_COPY, 0); + break; + } + /* + ** Check for cursor keys. With control pressed, we treat as + ** keyboard equivalents to scrolling. Otherwise, we send + ** a WM_MYCURSORKEY message with the appropriate string + ** to be sent. Sending the actual string allows the upper + ** level to be ignorant of keyboard modes, etc. + */ + if (wParam < VK_PRIOR || wParam > VK_DOWN) /* Is it a cursor key? */ + break; + + if (GetKeyState (VK_CONTROL) >= 0) { /* No control key */ + if (wParam >= VK_LEFT && wParam <= VK_DOWN) { + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert (pScr != NULL); + wParam = wParam - VK_LEFT + (pScr->DECCKM ? 4 : 0); + SendMessage (pScr->hwndTel, WM_MYCURSORKEY, + strlen(cursor_key[wParam]), + (LPARAM) (char FAR *) cursor_key[wParam]); + } + } else { /* Control is down */ + switch (wParam) { + case VK_PRIOR: /* Page up */ + SendMessage(hWnd, WM_VSCROLL, SB_PAGEUP, 0); + break; + case VK_NEXT: /* Page down */ + SendMessage(hWnd, WM_VSCROLL, SB_PAGEDOWN, 0); + break; + case VK_UP: /* Line up */ + SendMessage(hWnd, WM_VSCROLL, SB_LINEUP, 0); + break; + case VK_DOWN: /* Line down */ + SendMessage(hWnd, WM_VSCROLL, SB_LINEDOWN, 0); + break; + } + } + UpdateWindow(hWnd); + break; + + case WM_CHAR: + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert (pScr != NULL); + SendMessage(pScr->hwndTel, WM_MYSCREENCHAR, wParam, (LPARAM) pScr); + break; + + case WM_INITMENU: + if (IsClipboardFormatAvailable(CF_TEXT)) + EnableMenuItem((HMENU) wParam, IDM_PASTE, MF_ENABLED); + else + EnableMenuItem((HMENU) wParam, IDM_PASTE, MF_GRAYED); + if (bSelection) + EnableMenuItem((HMENU) wParam, IDM_COPY, MF_ENABLED); + else + EnableMenuItem((HMENU) wParam, IDM_COPY, MF_GRAYED); + break; + + case WM_GETMINMAXINFO: + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + if (pScr == NULL) /* Used on creation when window word not set */ + pScr = ScreenList; + lpmmi = (MINMAXINFO *) lParam; + if (FRAME_WIDTH + MAX_LINE_WIDTH * pScr->cxChar < lpmmi->ptMaxSize.x) + lpmmi->ptMaxSize.x = FRAME_WIDTH + MAX_LINE_WIDTH * pScr->cxChar; + lpmmi->ptMaxTrackSize.x = lpmmi->ptMaxSize.x; + lpmmi->ptMinTrackSize.x = FRAME_WIDTH + 20 * pScr->cxChar; + lpmmi->ptMinTrackSize.y = FRAME_HEIGHT + 4 * pScr->cyChar; + break; + + case WM_LBUTTONDOWN: + if (bDoubleClick) + Edit_TripleClick(hWnd, lParam); + else + Edit_LbuttonDown(hWnd, lParam); + break; + + case WM_LBUTTONUP: + Edit_LbuttonUp(hWnd, lParam); + break; + + case WM_LBUTTONDBLCLK: + bDoubleClick = TRUE; + SetTimer(hWnd, TIMER_TRIPLECLICK, GetDoubleClickTime(), NULL); + Edit_LbuttonDblclk(hWnd, lParam); + break; + + case WM_TIMER: + if (wParam == TIMER_TRIPLECLICK) + bDoubleClick = FALSE; + break; + + case WM_RBUTTONUP: + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert (pScr != NULL); + Edit_Copy(hWnd); + Edit_ClearSelection(pScr); + Edit_Paste(hWnd); + break; + + case WM_MOUSEMOVE: + if (bMouseDown) + Edit_MouseMove(hWnd, lParam); + break; + + case WM_RBUTTONDOWN: +#if 0 + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert (pScr != NULL); + wsprintf(strTmp,"fp->x=%d fp->y=%d text=%s \r\n", + pScr->screen_top->x, pScr->screen_top->y, pScr->screen_top->text); + OutputDebugString(strTmp); +#endif + break; + + case WM_PAINT: + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert (pScr != NULL); + BeginPaint (hWnd, &ps); + SelectObject(ps.hdc, pScr->hSelectedFont); + if (pScr->screen_bottom != NULL) + DrawTextScreen(ps.rcPaint, pScr, ps.hdc); + else + OutputDebugString("screen_bottom is NULL.\r\n"); + EndPaint(hWnd, &ps); + break; + + case WM_CLOSE: + if (MessageBox(hWnd, "Terminate this connection?", "Telnet", MB_OKCANCEL) == IDOK) { + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert (pScr != NULL); + SendMessage(pScr->hwndTel, WM_MYSCREENCLOSE, 0, (LPARAM) pScr); + return (DefWindowProc(hWnd, message, wParam, lParam)); + } + break; + + case WM_DESTROY: + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + if (pScr != NULL) + DeleteObject(pScr->hSelectedFont); + return (DefWindowProc(hWnd, message, wParam, lParam)); + + case WM_ACTIVATE: + if (wParam != WA_INACTIVE) { + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert (pScr != NULL); + if (pScr->bAlert) { + char strTitle[128]; + int idx; - return(NULL); + GetWindowText(hWnd, strTitle, sizeof(strTitle)); + if (strTitle[0] == ALERT) { + idx = lstrlen(strTitle); + strTitle[idx - 2] = 0; + SetWindowText(hWnd, &strTitle[2]); + pScr->bAlert = FALSE; + } + } + } + return (DefWindowProc(hWnd, message, wParam, lParam)); + + case WM_SIZE: + if (wParam == SIZE_MINIMIZED) + break; + + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert (pScr != NULL); + + if (SetInternalScreenSize(pScr, LOWORD(lParam), HIWORD(lParam))) { + SendMessage(pScr->hwndTel, WM_MYSCREENSIZE, 0, + MAKELONG(pScr->width, pScr->height)); + } + MakeWindowTitle(pScr->title, pScr->width, pScr->height, + title, sizeof(title)); + SetWindowText(hWnd, title); + break; + + case WM_SETFOCUS: + pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); + assert (pScr != NULL); + CreateCaret(hWnd, NULL, pScr->cxChar, 2); + ScreenCursorOn(pScr); + break; + + case WM_KILLFOCUS: + DestroyCaret(); + break; + + default: + return(DefWindowProc(hWnd, message, wParam, lParam)); + } + + return(0); } /* ScreenWndProc */ void ScreenBell( - SCREEN *pScr) + SCREEN *pScr) { - char strTitle[128]; - int idx; - - MessageBeep(MB_ICONEXCLAMATION); - if (pScr->hWnd != GetActiveWindow()) { - FlashWindow(pScr->hWnd, TRUE); - if (!pScr->bAlert) { - strTitle[0] = ALERT; - strTitle[1] = SPACE; - GetWindowText(pScr->hWnd, &strTitle[2], sizeof(strTitle) - 2); - idx = lstrlen(strTitle); - strTitle[idx] = SPACE; - strTitle[idx+1] = ALERT; - strTitle[idx+2] = 0; - SetWindowText(pScr->hWnd, strTitle); - } - FlashWindow(pScr->hWnd, FALSE); - pScr->bAlert = TRUE; - } + char strTitle[128]; + int idx; + + MessageBeep(MB_ICONEXCLAMATION); + if (pScr->hWnd != GetActiveWindow()) { + FlashWindow(pScr->hWnd, TRUE); + if (!pScr->bAlert) { + strTitle[0] = ALERT; + strTitle[1] = SPACE; + GetWindowText(pScr->hWnd, &strTitle[2], sizeof(strTitle) - 2); + idx = lstrlen(strTitle); + strTitle[idx] = SPACE; + strTitle[idx+1] = ALERT; + strTitle[idx+2] = 0; + SetWindowText(pScr->hWnd, strTitle); + } + FlashWindow(pScr->hWnd, FALSE); + pScr->bAlert = TRUE; + } } /* ScreenBell */ void ScreenBackspace(SCREEN *pScr) { - RECT rc; - - pScr->bWrapPending = FALSE; - rc.left = pScr->x * pScr->cxChar; - rc.right = (pScr->x + 1) * pScr->cxChar; - rc.top = pScr->cyChar * pScr->y; - rc.bottom = pScr->cyChar * (pScr->y + 1); - InvalidateRect(pScr->hWnd, &rc, TRUE); - pScr->x--; - if (pScr->x < 0) - pScr->x = 0; - UpdateWindow(pScr->hWnd); + RECT rc; + + pScr->bWrapPending = FALSE; + rc.left = pScr->x * pScr->cxChar; + rc.right = (pScr->x + 1) * pScr->cxChar; + rc.top = pScr->cyChar * pScr->y; + rc.bottom = pScr->cyChar * (pScr->y + 1); + InvalidateRect(pScr->hWnd, &rc, TRUE); + pScr->x--; + if (pScr->x < 0) + pScr->x = 0; + UpdateWindow(pScr->hWnd); } /* ScreenBackspace */ void ScreenTab( - SCREEN *pScr) + SCREEN *pScr) { - int num_spaces; - int idx; - SCREENLINE *pScrLine; - int iTest = 0; - HDC hDC; - - num_spaces = TAB_SPACES - (pScr->x % TAB_SPACES); - if (pScr->x + num_spaces >= pScr->width) - num_spaces = pScr->width - pScr->x; - pScrLine = GetScreenLineFromY(pScr, pScr->y); - if (pScrLine == NULL) - return; - for (idx = 0; idx < num_spaces; idx++, pScr->x++) { - if (!pScrLine->text[pScr->x]) - iTest=1; - if (iTest) - pScrLine->text[pScr->x] = SPACE; - } - hDC = GetDC(pScr->hWnd); - assert(hDC != NULL); - SelectObject(hDC, pScr->hSelectedFont); - TextOut(hDC, (pScr->x - num_spaces) * pScr->cxChar, pScr->y * pScr->cyChar, - pScrLine->text + pScr->x - num_spaces, num_spaces); - ReleaseDC(pScr->hWnd, hDC); - if (pScr->x >= pScr->width) - pScr->x = pScr->width - 1; - pScr->bWrapPending = FALSE; + int num_spaces; + int idx; + SCREENLINE *pScrLine; + int iTest = 0; + HDC hDC; + + num_spaces = TAB_SPACES - (pScr->x % TAB_SPACES); + if (pScr->x + num_spaces >= pScr->width) + num_spaces = pScr->width - pScr->x; + pScrLine = GetScreenLineFromY(pScr, pScr->y); + if (pScrLine == NULL) + return; + for (idx = 0; idx < num_spaces; idx++, pScr->x++) { + if (!pScrLine->text[pScr->x]) + iTest=1; + if (iTest) + pScrLine->text[pScr->x] = SPACE; + } + hDC = GetDC(pScr->hWnd); + assert(hDC != NULL); + SelectObject(hDC, pScr->hSelectedFont); + TextOut(hDC, (pScr->x - num_spaces) * pScr->cxChar, pScr->y * pScr->cyChar, + pScrLine->text + pScr->x - num_spaces, num_spaces); + ReleaseDC(pScr->hWnd, hDC); + if (pScr->x >= pScr->width) + pScr->x = pScr->width - 1; + pScr->bWrapPending = FALSE; } /* ScreenTab */ void ScreenCarriageFeed( - SCREEN *pScr) + SCREEN *pScr) { - pScr->bWrapPending = FALSE; - pScr->x = 0; + pScr->bWrapPending = FALSE; + pScr->x = 0; } /* ScreenCarriageFeed */ diff --git a/src/windows/wintel/screen.h b/src/windows/wintel/screen.h index 60618f7b6f..bc4267b334 100644 --- a/src/windows/wintel/screen.h +++ b/src/windows/wintel/screen.h @@ -40,7 +40,7 @@ extern long FAR PASCAL ScreenWndProc(HWND,UINT,WPARAM,LPARAM); #define TAB_SPACES 8 #define SPACE 32 #define ALERT 0x21 -#define MAX_LINE_WIDTH 256 /* not restricted to 1 byte */ +#define MAX_LINE_WIDTH 512 /* not restricted to 1 byte */ typedef struct SCREENLINE { struct SCREENLINE *next; @@ -63,32 +63,32 @@ typedef struct SCREEN { int type; int width; int height; - int maxlines; // Maximum number of scrollback lines - int numlines; // Current number of scrollback lines - int savelines; // Save lines off top? - int ESscroll; // Scroll screen when ES received - int attrib; // current attribute - int x; // current cursor position - int y; // current cursor position - int Oldx; // internally used to redraw cursor + int maxlines; /* Maximum number of scrollback lines */ + int numlines; /* Current number of scrollback lines */ + int savelines; /* Save lines off top? */ + int ESscroll; /* Scroll screen when ES received */ + int attrib; /* current attribute */ + int x; /* current cursor position */ + int y; /* current cursor position */ + int Oldx; /* internally used to redraw cursor */ int Oldy; - int Px; // saved cursor pos and attribute + int Px; /* saved cursor pos and attribute */ int Py; int Pattrib; - int VSIDC; // Insert/Delete character mode 0=draw line - int DECAWM; // AutoWrap mode 0=off - BOOL bWrapPending; // AutoWrap mode is on - wrap on next character - int DECCKM; // Cursor key mode - int DECPAM; // keyPad Application mode - int IRM; // Insert/Replace mode - int escflg; // Current Escape level - int top; // Vertical bounds of screen + int VSIDC; /* Insert/Delete character mode 0=draw line */ + int DECAWM; /* AutoWrap mode 0=off */ + BOOL bWrapPending; /* AutoWrap mode is on - wrap on next character */ + int DECCKM; /* Cursor key mode */ + int DECPAM; /* keyPad Application mode */ + int IRM; /* Insert/Replace mode */ + int escflg; /* Current Escape level */ + int top; /* Vertical bounds of screen */ int bottom; int parmptr; - int cxChar; // Width of the current font - int cyChar; // Height of the current font + int cxChar; /* Width of the current font */ + int cyChar; /* Height of the current font */ BOOL bAlert; - int parms[6]; // Ansi Params + int parms[6]; /* Ansi Params */ LOGFONT lf; HFONT hSelectedFont; HFONT hSelectedULFont; @@ -104,12 +104,12 @@ typedef struct CONFIG { int type; int height; int width; - int maxlines; // Maximum number of scrollback lines + int maxlines; /* Maximum number of scrollback lines */ int backspace; - int ESscroll; // Scroll screen when ES received - int VSIDC; // Insert/Delete character mode 0=draw line - int DECAWM; // AutoWrap mode 0=off - int IRM; // Insert/Replace mode + int ESscroll; /* Scroll screen when ES received */ + int VSIDC; /* Insert/Delete character mode 0=draw line */ + int DECAWM; /* AutoWrap mode 0=off */ + int IRM; /* Insert/Replace mode */ } CONFIG; #define TELNET_SCREEN 0 @@ -119,6 +119,10 @@ typedef struct CONFIG { #define IDM_BACKSPACE 101 #define IDM_DELETE 102 #define IDM_ABOUT 103 +#define IDM_HELP_INDEX 104 +#define IDM_EXIT 105 + +#define HELP_FILE "ktelnet.hlp" #define IDM_COPY 200 #define IDM_PASTE 201 diff --git a/src/windows/wintel/struct.h b/src/windows/wintel/struct.h index cbea7850b8..bc1cc49121 100644 --- a/src/windows/wintel/struct.h +++ b/src/windows/wintel/struct.h @@ -9,12 +9,12 @@ #define HCONNECTION HGLOBAL typedef struct CONNECTION { - SCREEN *pScreen; // handle to screen associated with connection + SCREEN *pScreen; /* handle to screen associated with connection */ kstream ks; SOCKET socket; - int pnum; // port number associated with connection - int telstate; // telnet state for this connection - int substate; // telnet subnegotiation state + int pnum; /* port number associated with connection */ + int telstate; /* telnet state for this connection */ + int substate; /* telnet subnegotiation state */ int termsent; int echo; int ugoahead; @@ -22,7 +22,7 @@ typedef struct CONNECTION { int timing; int backspace; int ctrl_backspace; - int termstate; // terminal type for this connection + int termstate; /* terminal type for this connection */ int width; int height; BOOL bResizeable; diff --git a/src/windows/wintel/telnet.c b/src/windows/wintel/telnet.c index 1b9ef1098c..0845b74c61 100644 --- a/src/windows/wintel/telnet.c +++ b/src/windows/wintel/telnet.c @@ -1,24 +1,24 @@ /**************************************************************************** - - PROGRAM: telnet.c - - PURPOSE: Windows networking kernel - Telnet - - FUNCTIONS: - - WinMain() - calls initialization function, processes message loop - InitApplication() - initializes window data and registers window - InitInstance() - saves instance handle and creates main window - MainWndProc() - processes messages - About() - processes messages for "About" dialog box - - COMMENTS: - - Windows can have several copies of your application running at the - same time. The variable hInst keeps track of which instance this - application is so that processing will be to the correct window. - -****************************************************************************/ + + Program: telnet.c + + PURPOSE: Windows networking kernel - Telnet + + FUNCTIONS: + + WinMain() - calls initialization function, processes message loop + InitApplication() - initializes window data and registers window + InitInstance() - saves instance handle and creates main window + MainWndProc() - processes messages + About() - processes messages for "About" dialog box + + COMMENTS: + + Windows can have several copies of your application running at the + same time. The variable hInst keeps track of which instance this + application is so that processing will be to the correct window. + + ****************************************************************************/ #include <windows.h> #include <stdlib.h> @@ -35,852 +35,874 @@ static char hostdata[MAXGETHOSTSTRUCT]; static SCREEN *pScr; static int debug = 1; -char strTmp[1024]; // Scratch buffer +char strTmp[1024]; /* Scratch buffer */ BOOL bAutoConnection = FALSE; -int port_no = 23; -char szUserName[64]; // Used in auth.c +short port_no = 23; +char szUserName[64]; /* Used in auth.c */ char szHostName[64]; #ifdef KRB4 - #define WINDOW_CLASS "K4_telnetWClass" +#define WINDOW_CLASS "K4_telnetWClass" #endif #ifdef KRB5 - krb5_context k5_context; - #define WINDOW_CLASS "K5_telnetWClass" +krb5_context k5_context; +#define WINDOW_CLASS "K5_telnetWClass" #endif -/*+************************************************************************** - - FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int) - - PURPOSE: calls initialization function, processes message loop - - COMMENTS: - - Windows recognizes this function by name as the initial entry point - for the program. This function calls the application initialization - routine, if no other instance of the program is running, and always - calls the instance initialization routine. It then executes a message - retrieval and dispatch loop that is the top-level control structure - for the remainder of execution. The loop is terminated when a WM_QUIT - message is received, at which time this function exits the application - instance by returning the value passed by PostQuitMessage(). - - If this function must abort before entering the message loop, it - returns the conventional value NULL. - -****************************************************************************/ +/* + * + * FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int) + * + * PURPOSE: calls initialization function, processes message loop + * + * COMMENTS: + * + * Windows recognizes this function by name as the initial entry point + * for the program. This function calls the application initialization + * routine, if no other instance of the program is running, and always + * calls the instance initialization routine. It then executes a message + * retrieval and dispatch loop that is the top-level control structure + * for the remainder of execution. The loop is terminated when a WM_QUIT + * message is received, at which time this function exits the application + * instance by returning the value passed by PostQuitMessage(). + * + * If this function must abort before entering the message loop, it + * returns the conventional value NULL. + */ -int PASCAL WinMain( - HANDLE hInstance, // current instance - HANDLE hPrevInstance, // previous instance - LPSTR lpCmdLine, // command line - int nCmdShow) // show-window type (open/icon) +int PASCAL +WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { - MSG msg; - - if (!hPrevInstance) - if (!InitApplication(hInstance)) - return(FALSE); - - /* - Perform initializations that apply to a specific instance - */ - bAutoConnection = parse_cmdline(lpCmdLine); - - if (!InitInstance(hInstance, nCmdShow)) - return(FALSE); - - /* - Acquire and dispatch messages until a WM_QUIT message is received. - */ - while (GetMessage(&msg, NULL, NULL, NULL)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - return (msg.wParam); // Returns the value from PostQuitMessage - -} /* WinMain */ - - -/*+************************************************************************** - - FUNCTION: InitApplication(HANDLE) - - PURPOSE: Initializes window data and registers window class - - COMMENTS: - - This function is called at initialization time only if no other - instances of the application are running. This function performs - initialization tasks that can be done once for any number of running - instances. - - In this case, we initialize a window class by filling out a data - structure of type WNDCLASS and calling the Windows RegisterClass() - function. Since all instances of this application use the same window - class, we only need to do this when the first instance is initialized. - - -****************************************************************************/ + MSG msg; + + if (!hPrevInstance) + if (!InitApplication(hInstance)) + return(FALSE); + + /* + * Perform initializations that apply to a specific instance + */ + bAutoConnection = parse_cmdline(lpCmdLine); + + if (!InitInstance(hInstance, nCmdShow)) + return(FALSE); + + SetDebugErrorLevel(SLE_WARNING); + + /* + * Acquire and dispatch messages until a WM_QUIT message is received. + */ + while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + + /* Process all non-network messages */ + while (PeekMessage(&msg, NULL, 0, WM_NETWORKEVENT-1, PM_REMOVE) || + PeekMessage(&msg, NULL, WM_NETWORKEVENT+1, (UINT)-1, PM_REMOVE)) + { + if (msg.message == WM_QUIT) // Special case: WM_QUIT -- return + return msg.wParam; // the value from PostQuitMessage + + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + return (msg.wParam); /* Returns the value from PostQuitMessage */ +} + +/* + * FUNCTION: InitApplication(HANDLE) + * + * PURPOSE: Initializes window data and registers window class + * + * COMMENTS: + * + * This function is called at initialization time only if no other + * instances of the application are running. This function performs + * initialization tasks that can be done once for any number of running + * instances. + * + * In this case, we initialize a window class by filling out a data + * structure of type WNDCLASS and calling the Windows RegisterClass() + * function. Since all instances of this application use the same window + * class, we only need to do this when the first instance is initialized. + */ -BOOL InitApplication( - HANDLE hInstance) +BOOL +InitApplication(HANDLE hInstance) { - WNDCLASS wc; - - ScreenInit(hInstance); - - /* - Fill in window class structure with parameters that describe the - main window. - */ - wc.style = CS_HREDRAW | CS_VREDRAW; // Class style(s). - wc.lpfnWndProc = MainWndProc; // Function to retrieve messages for - // windows of this class. - wc.cbClsExtra = 0; // No per-class extra data. - wc.cbWndExtra = 0; // No per-window extra data. - wc.hInstance = hInstance; // Application that owns the class. - wc.hIcon = NULL; // LoadIcon(hInstance, "NCSA"); - wc.hCursor = NULL; // Cursor(NULL, IDC_ARROW); - wc.hbrBackground = NULL; // GetStockObject(WHITE_BRUSH); - wc.lpszMenuName = NULL; // Name of menu resource in .RC file. - wc.lpszClassName = WINDOW_CLASS; // Name used in call to CreateWindow. - - return(RegisterClass(&wc)); - -} /* InitApplication */ - - -/*+************************************************************************** - - FUNCTION: InitInstance(HANDLE, int) - - PURPOSE: Saves instance handle and creates main window - - COMMENTS: - - This function is called at initialization time for every instance of - this application. This function performs initialization tasks that - cannot be shared by multiple instances. - - In this case, we save the instance handle in a static variable and - create and display the main program window. - -****************************************************************************/ - -BOOL InitInstance( - HANDLE hInstance, - int nCmdShow) + WNDCLASS wc; + + ScreenInit(hInstance); + + /* + * Fill in window class structure with parameters that describe the + * main window. + */ + wc.style = CS_HREDRAW | CS_VREDRAW; /* Class style(s). */ + wc.lpfnWndProc = MainWndProc; /* Function to retrieve messages for + * windows of this class. + */ + wc.cbClsExtra = 0; /* No per-class extra data. */ + wc.cbWndExtra = 0; /* No per-window extra data. */ + wc.hInstance = hInstance; /* Application that owns the class. */ + wc.hIcon = NULL; /* LoadIcon(hInstance, "NCSA"); */ + wc.hCursor = NULL; /* Cursor(NULL, IDC_ARROW); */ + wc.hbrBackground = NULL; /* GetStockObject(WHITE_BRUSH); */ + wc.lpszMenuName = NULL; /* Name of menu resource in .RC file. */ + wc.lpszClassName = WINDOW_CLASS; /* Name used in call to CreateWindow. */ + + return(RegisterClass(&wc)); +} + + +/* + * FUNCTION: InitInstance(HANDLE, int) + * + * PURPOSE: Saves instance handle and creates main window + * + * COMMENTS: + * + * This function is called at initialization time for every instance of + * this application. This function performs initialization tasks that + * cannot be shared by multiple instances. + * + * In this case, we save the instance handle in a static variable and + * create and display the main program window. + */ +BOOL +InitInstance(HANDLE hInstance, int nCmdShow) { - int xScreen = 0; - int yScreen = 0; - WSADATA wsaData; - - SetScreenInstance(hInstance); - - /* - Save the instance handle in static variable, which will be used in - many subsequence calls from this application to Windows. - */ - hInst = hInstance; - - /* - Create a main window for this application instance. - */ - hWnd = CreateWindow( - WINDOW_CLASS, // See RegisterClass() call. - "TCPWin", // Text for window title bar. - WS_SYSMENU, // Window style. - xScreen / 3, // Default horizontal position. - yScreen / 3, // Default vertical position. - xScreen / 3, // Default width. - yScreen / 3, // Default height. - NULL, // Overlapped windows have no parent. - NULL, // Use the window class menu. - hInstance, // This instance owns this window. - NULL); // Pointer not needed. - - if (!hWnd) - return (FALSE); + int xScreen = 0; + int yScreen = 0; + WSADATA wsaData; + + SetScreenInstance(hInstance); + + /* + * Save the instance handle in static variable, which will be used in + * many subsequence calls from this application to Windows. + */ + hInst = hInstance; + + /* + * Create a main window for this application instance. + */ + hWnd = CreateWindow( + WINDOW_CLASS, /* See RegisterClass() call. */ + "TCPWin", /* Text for window title bar. */ + WS_SYSMENU, /* Window style. */ + xScreen / 3, /* Default horizontal position. */ + yScreen / 3, /* Default vertical position. */ + xScreen / 3, /* Default width. */ + yScreen / 3, /* Default height. */ + NULL, /* Overlapped windows have no parent */ + NULL, /* Use the window class menu. */ + hInstance, /* This instance owns this window. */ + NULL); /* Pointer not needed. */ + + if (!hWnd) + return (FALSE); - if (WSAStartup(0x0101, &wsaData) != 0) { /* Initialize the network */ - MessageBox(NULL, "Couldn't initialize Winsock!", NULL, - MB_OK | MB_ICONEXCLAMATION); - return(FALSE); - } - - if (!OpenTelnetConnection()) { - WSACleanup(); - return(FALSE); - } - - #ifdef KRB5 - krb5_init_context(&k5_context); - krb5_init_ets(k5_context); - #endif + if (WSAStartup(0x0101, &wsaData) != 0) { /* Initialize the network */ + MessageBox(NULL, "Couldn't initialize Winsock!", NULL, + MB_OK | MB_ICONEXCLAMATION); + return(FALSE); + } - return (TRUE); + if (!OpenTelnetConnection()) { + WSACleanup(); + return(FALSE); + } -} /* InitInstance */ - - -/*+*************************************************************************** - - FUNCTION: MainWndProc(HWND, UINT, WPARAM, LPARAM) - - PURPOSE: Processes messages - - MESSAGES: +#ifdef KRB5 + krb5_init_context(&k5_context); + krb5_init_ets(k5_context); +#endif - WM_COMMAND - application menu (About dialog box) - WM_DESTROY - destroy window + return (TRUE); +} -****************************************************************************/ +char buf[2048]; -long FAR PASCAL MainWndProc( - HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam) +/* + * FUNCTION: MainWndProc(HWND, UINT, WPARAM, LPARAM) + * + * PURPOSE: Processes messages + * + * MESSAGES: + * + * WM_COMMAND - application menu (About dialog box) + * WM_DESTROY - destroy window + */ +long FAR PASCAL +MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - HGLOBAL hBuffer; - LPSTR lpBuffer; - char c; - int iEvent, namelen, cnt, ret; - char buf[1024]; - struct sockaddr_in name; - struct sockaddr_in remote_addr; - struct hostent *remote_host; - char *tmpCommaLoc; + HGLOBAL hBuffer; + LPSTR lpBuffer; + int iEvent, cnt, ret; + char *tmpCommaLoc; + struct sockaddr_in remote_addr; + struct hostent *remote_host; - switch (message) { - - case WM_MYSCREENCHANGEBKSP: - if (!con) - break; - con->backspace = wParam; - if (con->backspace == VK_BACK) { - con->ctrl_backspace = 0x7f; - WritePrivateProfileString(INI_TELNET, INI_BACKSPACE, + switch (message) { + case WM_MYSCREENCHANGEBKSP: + if (!con) + break; + con->backspace = wParam; + if (con->backspace == VK_BACK) { + con->ctrl_backspace = 0x7f; + WritePrivateProfileString(INI_TELNET, INI_BACKSPACE, INI_BACKSPACE_BS, TELNET_INI); - } - else { - con->ctrl_backspace = VK_BACK; - WritePrivateProfileString(INI_TELNET, INI_BACKSPACE, + } + else { + con->ctrl_backspace = VK_BACK; + WritePrivateProfileString(INI_TELNET, INI_BACKSPACE, INI_BACKSPACE_DEL, TELNET_INI); - } - GetPrivateProfileString(INI_HOSTS, INI_HOST "0", "", buf, 128, TELNET_INI); - tmpCommaLoc = strchr(buf, ','); - if (tmpCommaLoc == NULL) { - strcat (buf, ","); - tmpCommaLoc = strchr(buf, ','); - } - if (tmpCommaLoc) { - tmpCommaLoc++; - if (con->backspace == VK_BACK) - strcpy(tmpCommaLoc, INI_HOST_BS); - else - strcpy(tmpCommaLoc, INI_HOST_DEL); - } - WritePrivateProfileString(INI_HOSTS, INI_HOST "0", buf, TELNET_INI); - break; - - case WM_MYSCREENCHAR: - if (!con) - break; - if (wParam == VK_BACK) - wParam = con->backspace; - else if (wParam == 0x7f) - wParam = con->ctrl_backspace; - else if (wParam == VK_SPACE && GetKeyState(VK_CONTROL) < 0) - wParam = 0; - TelnetSend(con->ks, (char *) &wParam, 1, NULL); - break; - - case WM_MYCURSORKEY: - /* Acts as a send through: buffer is lParam and length in wParam */ - if (!con) - break; - TelnetSend (con->ks, (char *) lParam, wParam, NULL); - break; - - case WM_MYSYSCHAR: - if (!con) - break; - c = (char) wParam; - - switch (c) { - - case 'f': - getsockname(con->socket, (struct sockaddr *) &name, (int *) &namelen); - wsprintf(buf, "ftp %d.%d.%d.%d\n", - name.sin_addr.S_un.S_un_b.s_b1, - name.sin_addr.S_un.S_un_b.s_b2, - name.sin_addr.S_un.S_un_b.s_b3, - name.sin_addr.S_un.S_un_b.s_b4); - TelnetSend(con->ks, buf, lstrlen(buf), NULL); - break; - - case 'x': - PostMessage(con->pScreen->hWnd, WM_CLOSE, NULL, NULL); - break; - } - - break; - - case WM_MYSCREENBLOCK: - if (!con) - break; - hBuffer = (HGLOBAL) wParam; - lpBuffer = GlobalLock(hBuffer); - TelnetSend(con->ks, lpBuffer, lstrlen(lpBuffer), NULL); - GlobalUnlock(hBuffer); - break; - - case WM_MYSCREENCLOSE: - if (!con) - break; - kstream_destroy(con->ks); - DestroyWindow(hWnd); - break; - - case WM_QUERYOPEN: - return(0); - break; - - case WM_DESTROY: /* message: window being destroyed */ - kstream_destroy(con->ks); - free(con); - WSACleanup(); - PostQuitMessage(0); - break; - - case WM_NETWORKEVENT: - iEvent = WSAGETSELECTEVENT(lParam); - - switch (iEvent) { - - case FD_READ: - cnt = recv(con->socket, buf, 1024, NULL); - /* - The following line has been removed until kstream supports - non-blocking IO or larger size reads (jrivlin@fusion.com). - */ - /* cnt = kstream_read(con->ks, buf, 1024); */ - buf[cnt] = 0; - parse((CONNECTION *) con, (unsigned char *) buf, cnt); - ScreenEm(buf, cnt, con->pScreen); - break; - - case FD_CLOSE: - kstream_destroy(con->ks); - free(con); - WSACleanup(); - PostQuitMessage(0); - break; - - case FD_CONNECT: - ret = WSAGETSELECTERROR(lParam); - if (ret) { - wsprintf(buf, "Error %d on Connect", ret); - MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); - kstream_destroy(con->ks); - free(con); - WSACleanup(); - PostQuitMessage(0); - break; - } - start_negotiation(con->ks); - break; - } - - break; - - case WM_HOSTNAMEFOUND: - ret = WSAGETASYNCERROR(lParam); - if (ret) { - wsprintf(buf, "Error %d on GetHostbyName", ret); - MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); - kstream_destroy(con->ks); - free(con); - WSACleanup(); - PostQuitMessage(0); - break; - } - - remote_host = (struct hostent *) hostdata; - remote_addr.sin_family = AF_INET; - remote_addr.sin_addr.S_un.S_un_b.s_b1 = remote_host->h_addr[0]; - remote_addr.sin_addr.S_un.S_un_b.s_b2 = remote_host->h_addr[1]; - remote_addr.sin_addr.S_un.S_un_b.s_b3 = remote_host->h_addr[2]; - remote_addr.sin_addr.S_un.S_un_b.s_b4 = remote_host->h_addr[3]; - remote_addr.sin_port = htons(port_no); - - connect(con->socket, (struct sockaddr *) &remote_addr, - sizeof(struct sockaddr)); - break; - - case WM_MYSCREENSIZE: - con->width = LOWORD(lParam); // width in characters - con->height = HIWORD(lParam); // height in characters - if (con->bResizeable && con->ks) - send_naws(con); - wsprintf(buf, "%d", con->height); - WritePrivateProfileString(INI_TELNET, INI_HEIGHT, buf, TELNET_INI); - wsprintf(buf, "%d", con->width); - WritePrivateProfileString(INI_TELNET, INI_WIDTH, buf, TELNET_INI); - break; + } + GetPrivateProfileString(INI_HOSTS, INI_HOST "0", "", buf, 128, TELNET_INI); + tmpCommaLoc = strchr(buf, ','); + if (tmpCommaLoc == NULL) { + strcat (buf, ","); + tmpCommaLoc = strchr(buf, ','); + } + if (tmpCommaLoc) { + tmpCommaLoc++; + if (con->backspace == VK_BACK) + strcpy(tmpCommaLoc, INI_HOST_BS); + else + strcpy(tmpCommaLoc, INI_HOST_DEL); + } + WritePrivateProfileString(INI_HOSTS, INI_HOST "0", buf, TELNET_INI); + break; + + case WM_MYSCREENCHAR: + { + unsigned char c; + + if (!con) + break; + if (wParam == VK_BACK) + c = con->backspace; + else if (wParam == 0x7f) + c = con->ctrl_backspace; + else if (wParam == VK_SPACE && GetKeyState(VK_CONTROL) < 0) + c = 0; + else + c = wParam; + TelnetSend(con->ks, &c, 1, 0); + } + break; + + case WM_MYCURSORKEY: + /* Acts as a send through: buffer is lParam and length in wParam */ + if (!con) + break; + memcpy(buf, (char *)lParam, wParam); + TelnetSend (con->ks, buf, wParam, 0); + break; + + case WM_MYSCREENBLOCK: + if (!con) + break; + hBuffer = (HGLOBAL) wParam; + lpBuffer = GlobalLock(hBuffer); + TelnetSend(con->ks, lpBuffer, lstrlen(lpBuffer), 0); + GlobalUnlock(hBuffer); + break; + + case WM_MYSCREENCLOSE: +#if 0 + if (con) + { + kstream_destroy(con->ks); + con->ks = NULL; + } +#endif + DestroyWindow(hWnd); + break; + + case WM_QUERYOPEN: + return(0); + break; + + case WM_DESTROY: /* message: window being destroyed */ + if (con) + { + kstream_destroy(con->ks); + free(con); + WSACleanup(); + } + PostQuitMessage(0); + break; + + case WM_NETWORKEVENT: + iEvent = WSAGETSELECTEVENT(lParam); + + switch (iEvent) { + + case FD_READ: + if (con == NULL) + break; + cnt = kstream_read(con->ks, buf, 1500); + buf[cnt] = 0; + parse((CONNECTION *)con, (unsigned char *)buf, cnt); + ScreenEm(buf, cnt, con->pScreen); + break; + + case FD_CLOSE: + kstream_destroy(con->ks); + free(con); + con = NULL; + WSACleanup(); + PostQuitMessage(0); + break; + + case FD_CONNECT: + ret = WSAGETSELECTERROR(lParam); + if (ret) { + wsprintf(buf, "Error %d on Connect", ret); + MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); + kstream_destroy(con->ks); + free(con); + WSACleanup(); + PostQuitMessage(0); + break; + } + start_negotiation(con->ks); + break; + } + + break; + + case WM_HOSTNAMEFOUND: + ret = WSAGETASYNCERROR(lParam); + if (ret) { + wsprintf(buf, "Error %d on GetHostbyName", ret); + MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); + kstream_destroy(con->ks); + free(con); + WSACleanup(); + PostQuitMessage(0); + break; + } + + remote_host = (struct hostent *)hostdata; + remote_addr.sin_family = AF_INET; + memcpy(&(remote_addr.sin_addr), &(remote_host->h_addr[0]), 4); + remote_addr.sin_port = htons(port_no); + + connect(con->socket, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)); + break; + + case WM_MYSCREENSIZE: + con->width = LOWORD(lParam); /* width in characters */ + con->height = HIWORD(lParam); /* height in characters */ + if (con->bResizeable && con->ks) + send_naws(con); + wsprintf(buf, "%d", con->height); + WritePrivateProfileString(INI_TELNET, INI_HEIGHT, buf, TELNET_INI); + wsprintf(buf, "%d", con->width); + WritePrivateProfileString(INI_TELNET, INI_WIDTH, buf, TELNET_INI); + break; - default: // Passes it on if unproccessed - return(DefWindowProc(hWnd, message, wParam, lParam)); - } - return (NULL); + default: /* Passes it on if unproccessed */ + return(DefWindowProc(hWnd, message, wParam, lParam)); + } + return (0); +} -} /* MainWndProc */ - -/*+*************************************************************************** - - FUNCTION: SaveHostName(hostname, port) - - PURPOSE: Saves the currently selected host name and port number - in the KERBEROS.INI file and returns the preferred backspace - setting if one exists for that host. - - RETURNS: VK_BACK or 0x7f depending on the desired backspace setting. - -****************************************************************************/ - -int SaveHostName( - char *host, - int port) +/* + * + * FUNCTION: SaveHostName(hostname, port) + * + * PURPOSE: Saves the currently selected host name and port number + * in the KERBEROS.INI file and returns the preferred backspace + * setting if one exists for that host. + * + * RETURNS: VK_BACK or 0x7f depending on the desired backspace setting. + */ +int +SaveHostName(char *host, int port) { - char buf[128]; // Scratch buffer - char fullhost[128]; // Host & port combination - char hostName[10][128]; // Entries from INI files - char *comma; // For parsing del/bs info - int len; // Length of fullhost - int n; // Number of items written - int i; // Index - int bs; // What we return - - if (port == 23) // Default telnet port - strcpy(fullhost, host); // ...then don't add it on - else - wsprintf(fullhost, "%s %d", host, port); - len = strlen(fullhost); - - comma = NULL; - for (i = 0; i < 10; i++) { - wsprintf(buf, INI_HOST "%d", i); // INI item to fetch - GetPrivateProfileString(INI_HOSTS, buf, "", hostName[i], - 128, TELNET_INI); - - if (!hostName[i][0]) - break; - - if (strncmp (hostName[i], fullhost, len)) // A match?? - continue; // Nope, keep going - comma = strchr (hostName[i], ','); - } - - if (comma) { - ++comma; // Past the comma - while (*comma == ' ') // Past leading white space - ++comma; - bs = VK_BACK; // Default for unknown entry - if (_stricmp(comma, INI_HOST_DEL) == 0) - bs = 0x7f; - } - else { // No matching entry - GetPrivateProfileString(INI_TELNET, INI_BACKSPACE, INI_BACKSPACE_BS, - buf, sizeof(buf), TELNET_INI); - bs = VK_BACK; // Default value - if (_stricmp(buf, INI_BACKSPACE_DEL) == 0) - bs = 0x7f; - } - - /* - ** Build up default host name - */ - strcpy(buf, fullhost); - strcat(buf, ", "); - strcat(buf, (bs == VK_BACK) ? INI_BACKSPACE_BS : INI_BACKSPACE_DEL); - WritePrivateProfileString(INI_HOSTS, INI_HOST "0", buf, TELNET_INI); - - n = 0; - for (i = 0; i < 10; i++) { - if (!hostName[i][0]) // End of the list? - break; - if (strncmp(hostName[i], fullhost, len) != 0) { - wsprintf(buf, INI_HOST "%d", ++n); - WritePrivateProfileString(INI_HOSTS, buf, hostName[i], TELNET_INI); - } - } - return(bs); - -} /* SaveHostName */ - - -int OpenTelnetConnection(void) + char buf[128]; /* Scratch buffer */ + char fullhost[128]; /* Host & port combination */ + char hostName[10][128]; /* Entries from INI files */ + char *comma; /* For parsing del/bs info */ + int len; /* Length of fullhost */ + int n; /* Number of items written */ + int i; /* Index */ + int bs; /* What we return */ + + if (port == 23) /* Default telnet port */ + strcpy(fullhost, host); /* ...then don't add it on */ + else + wsprintf(fullhost, "%s %d", host, port); + len = strlen(fullhost); + + comma = NULL; + for (i = 0; i < 10; i++) { + wsprintf(buf, INI_HOST "%d", i); /* INI item to fetch */ + GetPrivateProfileString(INI_HOSTS, buf, "", hostName[i], + 128, TELNET_INI); + + if (!hostName[i][0]) + break; + + if (strncmp (hostName[i], fullhost, len)) /* A match?? */ + continue; /* Nope, keep going */ + comma = strchr (hostName[i], ','); + } + + if (comma) { + ++comma; /* Past the comma */ + while (*comma == ' ') /* Past leading white space */ + ++comma; + bs = VK_BACK; /* Default for unknown entry */ + if (_stricmp(comma, INI_HOST_DEL) == 0) + bs = 0x7f; + } + else { /* No matching entry */ + GetPrivateProfileString(INI_TELNET, INI_BACKSPACE, INI_BACKSPACE_BS, + buf, sizeof(buf), TELNET_INI); + bs = VK_BACK; /* Default value */ + if (_stricmp(buf, INI_BACKSPACE_DEL) == 0) + bs = 0x7f; + } + + /* + * Build up default host name + */ + strcpy(buf, fullhost); + strcat(buf, ", "); + strcat(buf, (bs == VK_BACK) ? INI_BACKSPACE_BS : INI_BACKSPACE_DEL); + WritePrivateProfileString(INI_HOSTS, INI_HOST "0", buf, TELNET_INI); + + n = 0; + for (i = 0; i < 10; i++) { + if (!hostName[i][0]) /* End of the list? */ + break; + if (strncmp(hostName[i], fullhost, len) != 0) { + wsprintf(buf, INI_HOST "%d", ++n); + WritePrivateProfileString(INI_HOSTS, buf, hostName[i], TELNET_INI); + } + } + return(bs); +} + + +int +OpenTelnetConnection(void) { - int nReturn, ret; - struct sockaddr_in sockaddr; - char *p; - static struct kstream_crypt_ctl_block ctl; - char buf[128]; + int nReturn, ret; + struct sockaddr_in sockaddr; + char *p; + static struct kstream_crypt_ctl_block ctl; + char buf[128]; - tmpConfig = calloc(sizeof(CONFIG), 1); + tmpConfig = calloc(sizeof(CONFIG), 1); - if (bAutoConnection) { - tmpConfig->title = calloc(lstrlen(szHostName), 1); - lstrcpy(tmpConfig->title, (char *) szHostName); - } else { - nReturn = DoDialog("OPENTELNETDLG", OpenTelnetDlg); - if (nReturn == FALSE) - return(FALSE); - } + if (bAutoConnection) { + tmpConfig->title = calloc(lstrlen(szHostName), 1); + lstrcpy(tmpConfig->title, (char *) szHostName); + } else { + nReturn = DoDialog("OPENTELNETDLG", OpenTelnetDlg); + if (nReturn == FALSE) + return(FALSE); + } - con = (CONNECTION *) GetNewConnection(); - if (con == NULL) - return(0); - - tmpConfig->width = - GetPrivateProfileInt(INI_TELNET, INI_WIDTH, DEF_WIDTH, TELNET_INI); - - tmpConfig->height = - GetPrivateProfileInt(INI_TELNET, INI_HEIGHT, DEF_HEIGHT, TELNET_INI); - con->width = tmpConfig->width; - con->height = tmpConfig->height; - - con->backspace = SaveHostName(tmpConfig->title, port_no); - - if (con->backspace == VK_BACK) { - tmpConfig->backspace = TRUE; - con->ctrl_backspace = 0x7f; - } else { - tmpConfig->backspace = FALSE; - con->ctrl_backspace = 0x08; - } - - tmpConfig->hwndTel = hWnd; - con->pScreen = InitNewScreen(tmpConfig); - if (!con->pScreen) { - assert(FALSE); - free(con->pScreen); - free(con); - free(tmpConfig); - return(-1); - } - - ret = (SOCKET) socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + con = (CONNECTION *) GetNewConnection(); + if (con == NULL) + return(0); + + tmpConfig->width = + GetPrivateProfileInt(INI_TELNET, INI_WIDTH, DEF_WIDTH, TELNET_INI); + + tmpConfig->height = + GetPrivateProfileInt(INI_TELNET, INI_HEIGHT, DEF_HEIGHT, TELNET_INI); + con->width = tmpConfig->width; + con->height = tmpConfig->height; + + con->backspace = SaveHostName(tmpConfig->title, port_no); + + if (con->backspace == VK_BACK) { + tmpConfig->backspace = TRUE; + con->ctrl_backspace = 0x7f; + } else { + tmpConfig->backspace = FALSE; + con->ctrl_backspace = 0x08; + } + + tmpConfig->hwndTel = hWnd; + con->pScreen = InitNewScreen(tmpConfig); + if (!con->pScreen) { + assert(FALSE); + free(con->pScreen); + free(con); + free(tmpConfig); + return(-1); + } + + ret = (SOCKET) socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (ret == SOCKET_ERROR) { - wsprintf(buf, "Socket error on socket = %d!", WSAGetLastError()); - MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); - if (con->pScreen != NULL) - DestroyWindow(con->pScreen->hWnd); - free(con); - free(tmpConfig); - return(-1); - } + if (ret == SOCKET_ERROR) { + wsprintf(buf, "Socket error on socket = %d!", WSAGetLastError()); + MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); + if (con->pScreen != NULL) + DestroyWindow(con->pScreen->hWnd); + free(con); + free(tmpConfig); + return(-1); + } - con->socket = ret; + con->socket = ret; - sockaddr.sin_family = AF_INET; - sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); - sockaddr.sin_port = htons(0); + sockaddr.sin_family = AF_INET; + sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); + sockaddr.sin_port = htons(0); - ret = bind(con->socket, (struct sockaddr *) &sockaddr, - (int) sizeof(struct sockaddr_in)); + ret = bind(con->socket, (struct sockaddr *) &sockaddr, + (int) sizeof(struct sockaddr_in)); - if (ret == SOCKET_ERROR) { - wsprintf(buf, "Socket error on bind!"); - MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); - if (con->pScreen != NULL) - DestroyWindow(con->pScreen->hWnd); - free(con); - free(tmpConfig); - return(-1); - } - - WSAAsyncSelect(con->socket, hWnd, WM_NETWORKEVENT, - FD_READ | FD_CLOSE | FD_CONNECT); + if (ret == SOCKET_ERROR) { + wsprintf(buf, "Socket error on bind!"); + MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); + if (con->pScreen != NULL) + DestroyWindow(con->pScreen->hWnd); + free(con); + free(tmpConfig); + return(-1); + } - lstrcpy(szHostName, tmpConfig->title); - p = strchr(szHostName, '@'); - if (p != NULL) { - *p = 0; - strcpy (szUserName, szHostName); - strcpy(szHostName, ++p); - } + WSAAsyncSelect(con->socket, hWnd, WM_NETWORKEVENT, + FD_READ | FD_CLOSE | FD_CONNECT); - WSAAsyncGetHostByName(hWnd, WM_HOSTNAMEFOUND, szHostName, hostdata, - MAXGETHOSTSTRUCT); - free(tmpConfig); + lstrcpy(szHostName, tmpConfig->title); + p = strchr(szHostName, '@'); + if (p != NULL) { + *p = 0; + strcpy (szUserName, szHostName); + strcpy(szHostName, ++p); + } - ctl.encrypt = auth_encrypt; - ctl.decrypt = auth_decrypt; - ctl.init = auth_init; - ctl.destroy = auth_destroy; + WSAAsyncGetHostByName(hWnd, WM_HOSTNAMEFOUND, szHostName, hostdata, + MAXGETHOSTSTRUCT); - con->ks = kstream_create_from_fd(con->socket, &ctl, NULL); + ctl.encrypt = auth_encrypt; + ctl.decrypt = auth_decrypt; + ctl.init = auth_init; + ctl.destroy = auth_destroy; - kstream_set_buffer_mode(con->ks, 0); + con->ks = kstream_create_from_fd(con->socket, &ctl, NULL); - if (con->ks == NULL) - return(-1); + if (con->ks == NULL) + return(-1); - return(1); + kstream_set_buffer_mode(con->ks, 0); -} /* OpenTelnetConnection */ + return(1); +} -CONNECTION *GetNewConnection(void) +CONNECTION * +GetNewConnection(void) { - CONNECTION *pCon; + CONNECTION *pCon; - pCon = calloc(sizeof(CONNECTION), 1); - if (pCon == NULL) - return NULL; - pCon->backspace = TRUE; - pCon->bResizeable = TRUE; - return(pCon); + pCon = calloc(sizeof(CONNECTION), 1); + if (pCon == NULL) + return NULL; + pCon->backspace = TRUE; + pCon->bResizeable = TRUE; + return(pCon); +} -} /* GetNewConnection */ - -int NEAR DoDialog( - char *szDialog, - FARPROC lpfnDlgProc) +int NEAR +DoDialog(char *szDialog, FARPROC lpfnDlgProc) { - int nReturn; + int nReturn; - lpfnDlgProc = MakeProcInstance(lpfnDlgProc, hInst); - if (lpfnDlgProc == NULL) - MessageBox(hWnd, "Couldn't make procedure instance", NULL, MB_OK); + lpfnDlgProc = MakeProcInstance(lpfnDlgProc, hInst); + if (lpfnDlgProc == NULL) + MessageBox(hWnd, "Couldn't make procedure instance", NULL, MB_OK); - nReturn = DialogBox(hInst, szDialog, hWnd, lpfnDlgProc); - FreeProcInstance(lpfnDlgProc); - return (nReturn); - -} /* DoDialog */ - + nReturn = DialogBox(hInst, szDialog, hWnd, lpfnDlgProc); + FreeProcInstance(lpfnDlgProc); + return (nReturn); +} -/*+*************************************************************************** - FUNCTION: OpenTelnetDlg(HWND, unsigned, WORD, LONG) - - PURPOSE: Processes messages for "Open New Telnet Connection" dialog box +/* + * FUNCTION: OpenTelnetDlg(HWND, unsigned, WORD, LONG) + * + * PURPOSE: Processes messages for "Open New Telnet Connection" dialog box + * + * MESSAGES: + * + * WM_INITDIALOG - initialize dialog box + * WM_COMMAND - Input received + */ +BOOL FAR PASCAL +OpenTelnetDlg(HWND hDlg, WORD message, WORD wParam, LONG lParam) +{ + char szConnectName[256]; + HDC hDC; + int xExt, yExt; + DWORD Ext; + HWND hEdit; + int n; + int iHostNum = 0; + char tmpName[128]; + char tmpBuf[80]; + char *tmpCommaLoc; + + switch (message) { + case WM_INITDIALOG: + hDC = GetDC(hDlg); + Ext = GetDialogBaseUnits(); + xExt = (190 *LOWORD(Ext)) /4 ; + yExt = (72 * HIWORD(Ext)) /8 ; + GetPrivateProfileString(INI_HOSTS, INI_HOST "0", "", tmpName, + 128, TELNET_INI); + if (tmpName[0]) { + tmpCommaLoc = strchr(tmpName, ','); + if (tmpCommaLoc) + *tmpCommaLoc = '\0'; + SetDlgItemText(hDlg, TEL_CONNECT_NAME, tmpName); + } + hEdit = GetWindow(GetDlgItem(hDlg, TEL_CONNECT_NAME), GW_CHILD); + while (TRUE) { + wsprintf(tmpBuf, INI_HOST "%d", iHostNum++); + GetPrivateProfileString(INI_HOSTS, tmpBuf, "", tmpName, + 128, TELNET_INI); + tmpCommaLoc = strchr(tmpName, ','); + if (tmpCommaLoc) + *tmpCommaLoc = '\0'; + if (tmpName[0]) + SendDlgItemMessage(hDlg, TEL_CONNECT_NAME, CB_ADDSTRING, 0, + (LPARAM) ((LPSTR) tmpName)); + else + break; + } +#ifdef FORWARD + EnableWindow(GetDlgItem(hDlg, IDC_FORWARD), 1); + SendDlgItemMessage(hDlg, IDC_FORWARD, BM_SETCHECK, forward_flag, 0); + if (forward_flag) + EnableWindow(GetDlgItem(hDlg, IDC_FORWARDFORWARD), 1); + else + EnableWindow(GetDlgItem(hDlg, IDC_FORWARDFORWARD), 0); + SendDlgItemMessage(hDlg, IDC_FORWARDFORWARD, BM_SETCHECK, + forwardable_flag, 0); +#endif - MESSAGES: +#ifdef ENCRYPTION + EnableWindow(GetDlgItem(hDlg, IDC_ENCRYPT), 1); + SendDlgItemMessage(hDlg, IDC_ENCRYPT, + BM_SETCHECK, encrypt_flag, 0); +#endif - WM_INITDIALOG - initialize dialog box - WM_COMMAND - Input received + EnableWindow(GetDlgItem(hDlg, TEL_CONNECT_USERID), 1); + + SetWindowPos(hDlg, NULL, + (GetSystemMetrics(SM_CXSCREEN)/2)-(xExt/2), + (GetSystemMetrics(SM_CYSCREEN)/2)-(yExt/2), + 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + ReleaseDC(hDlg, hDC); + SendMessage(hEdit, WM_USER + 1, 0, 0); + SendMessage(hDlg, WM_SETFOCUS, 0, 0); + return (TRUE); + + case WM_COMMAND: + switch (wParam) { + case TEL_CANCEL: + case IDCANCEL: /* From the menu */ + EndDialog(hDlg, FALSE); + break; + +#ifdef FORWARD + case IDC_FORWARD: + forward_flag = (BOOL)SendDlgItemMessage(hDlg, IDC_FORWARD, + BM_GETCHECK, 0, 0); + if (forward_flag) + EnableWindow(GetDlgItem(hDlg, IDC_FORWARDFORWARD), 1); + else + EnableWindow(GetDlgItem(hDlg, IDC_FORWARDFORWARD), 0); + break; + + case IDC_FORWARDFORWARD: + forwardable_flag = (BOOL)SendDlgItemMessage(hDlg, IDC_FORWARDFORWARD, + BM_GETCHECK, 0, 0); + break; +#endif -****************************************************************************/ +#if ENCRYPTION + case IDC_ENCRYPT: + encrypt_flag = (BOOL)SendDlgItemMessage(hDlg, IDC_ENCRYPT, + BM_GETCHECK, 0, 0); + break; +#endif + case TEL_CONNECT_USERID: + GetDlgItemText(hDlg, TEL_CONNECT_USERID, szUserName, sizeof(szUserName)); + break; -BOOL FAR PASCAL OpenTelnetDlg( - HWND hDlg, - WORD message, - WORD wParam, - LONG lParam) -{ - char szConnectName[256]; - HDC hDC; - int xExt, yExt; - DWORD Ext; - HWND hEdit; - int n; - int iHostNum = 0; - char tmpName[128]; - char tmpBuf[80]; - char *tmpCommaLoc; - - switch (message) { - - case WM_INITDIALOG: - hDC = GetDC(hDlg); - Ext = GetDialogBaseUnits(); - xExt = (190 *LOWORD(Ext)) /4 ; - yExt = (72 * HIWORD(Ext)) /8 ; - GetPrivateProfileString(INI_HOSTS, INI_HOST "0", "", tmpName, - 128, TELNET_INI); - if (tmpName[0]) { - tmpCommaLoc = strchr(tmpName, ','); - if (tmpCommaLoc) - *tmpCommaLoc = '\0'; - SetDlgItemText(hDlg, TEL_CONNECT_NAME, tmpName); - } - hEdit = GetWindow(GetDlgItem(hDlg, TEL_CONNECT_NAME), GW_CHILD); - while (TRUE) { - wsprintf(tmpBuf, INI_HOST "%d", iHostNum++); - GetPrivateProfileString(INI_HOSTS, tmpBuf, "", tmpName, - 128, TELNET_INI); - tmpCommaLoc = strchr(tmpName, ','); - if (tmpCommaLoc) - *tmpCommaLoc = '\0'; - if (tmpName[0]) - SendDlgItemMessage(hDlg, TEL_CONNECT_NAME, CB_ADDSTRING, 0, - (LPARAM) ((LPSTR) tmpName)); - else - break; - } - SetWindowPos(hDlg, NULL, - (GetSystemMetrics(SM_CXSCREEN)/2)-(xExt/2), - (GetSystemMetrics(SM_CYSCREEN)/2)-(yExt/2), - 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); - ReleaseDC(hDlg, hDC); - SendMessage(hEdit, WM_USER+1, NULL, NULL); - SendMessage(hDlg, WM_SETFOCUS, NULL, NULL); - return (TRUE); - - case WM_COMMAND: - switch (wParam) { - case TEL_CANCEL: - case IDCANCEL: // From the menu - EndDialog(hDlg, FALSE); - break; - - case TEL_OK: - GetDlgItemText(hDlg, TEL_CONNECT_NAME, szConnectName, 256); + case TEL_OK: + GetDlgItemText(hDlg, TEL_CONNECT_NAME, szConnectName, 256); - n = parse_cmdline (szConnectName); - if (! n) { - MessageBox(hDlg, "You must enter a session name!", - NULL, MB_OK); - break; - } - tmpConfig->title = calloc(lstrlen(szHostName) + 1, 1); - lstrcpy(tmpConfig->title, szConnectName); - EndDialog(hDlg, TRUE); - break; - } - return (FALSE); - } - return(FALSE); - -} /* OpenTelnetDlg */ - - -/*+*************************************************************************** - - FUNCTION: TelnetSend(kstream ks, char *buf, int len, int flags) - - PURPOSE: This is a replacement for the WinSock send() function, to - send a buffer of characters to an output socket. It differs - by retrying endlessly if sending the bytes would cause - the send() to block. <gnu@cygnus.com> observed EWOULDBLOCK - errors when running using TCP Software's PC/TCP 3.0 stack, - even when writing as little as 109 bytes into a socket - that had no more than 9 bytes queued for output. Note also that - a kstream is used during output rather than a socket to facilitate - encryption. - - Eventually, for cleanliness and responsiveness, this - routine should not loop; instead, if the send doesn't - send all the bytes, it should put them into a buffer - and return. Message handling code would send out the - buffer whenever it gets an FD_WRITE message. - -****************************************************************************/ - -int TelnetSend( - kstream ks, - char *buf, - int len, - int flags) + n = parse_cmdline (szConnectName); + if (! n) { + MessageBox(hDlg, "You must enter a session name!", + NULL, MB_OK); + break; + } + tmpConfig->title = calloc(lstrlen(szHostName) + 1, 1); + lstrcpy(tmpConfig->title, szConnectName); + EndDialog(hDlg, TRUE); + break; + } + return (FALSE); + } + return(FALSE); +} + + +/* + * + * FUNCTION: TelnetSend(kstream ks, char *buf, int len, int flags) + * + * PURPOSE: This is a replacement for the WinSock send() function, to + * send a buffer of characters to an output socket. It differs + * by retrying endlessly if sending the bytes would cause + * the send() to block. <gnu@cygnus.com> observed EWOULDBLOCK + * errors when running using TCP Software's PC/TCP 3.0 stack, + * even when writing as little as 109 bytes into a socket + * that had no more than 9 bytes queued for output. Note also + * that a kstream is used during output rather than a socket + * to facilitate encryption. + * + * Eventually, for cleanliness and responsiveness, this + * routine should not loop; instead, if the send doesn't + * send all the bytes, it should put them into a buffer + * and return. Message handling code would send out the + * buffer whenever it gets an FD_WRITE message. + */ +int +TelnetSend(kstream ks, char *buf, int len, int flags) { - int writelen; - int origlen = len; - - while (TRUE) { - writelen = kstream_write(ks, buf, len); + int writelen; + int origlen = len; + + while (TRUE) { + writelen = kstream_write(ks, buf, len); + + if (writelen == len) /* Success, first or Nth time */ + return (origlen); + + if (writelen == SOCKET_ERROR) { + if (WSAGetLastError() != WSAEWOULDBLOCK) + return (SOCKET_ERROR); /* Some error */ + /* For WOULDBLOCK, immediately repeat the send. */ + } + else { + /* Partial write; update the pointers and retry. */ + len -= writelen; + buf += writelen; + } + } +} + + +/* + * Function: Trim leading and trailing white space from a string. + * + * Parameters: + * s - the string to trim. + */ +void +trim(char *s) +{ + int l; + int i; - if (writelen == len) /* Success, first or Nth time */ - return (origlen); + for (i = 0; s[i]; i++) + if (s[i] != ' ' && s[i] != '\t') + break; - if (writelen == SOCKET_ERROR) { - if (WSAGetLastError() != WSAEWOULDBLOCK) - return (SOCKET_ERROR); /* Some error */ - /* For WOULDBLOCK, immediately repeat the send. */ - } - else { - /* Partial write; update the pointers and retry. */ - len -= writelen; - buf += writelen; - } - } + l = strlen(&s[i]); + memmove(s, &s[i], l + 1); -} /* TelnetSend */ + for (l--; l >= 0; l--) { + if (s[l] != ' ' && s[l] != '\t') + break; + } + s[l + 1] = 0; +} -/*+ - * Function: Trim leading and trailing white space from a string. +/* + * + * Parse_cmdline + * + * Reads hostname and port number off the command line. * - * Parameters: - * s - the string to trim. + * Formats: telnet + * telnet <host> + * telnet <host> <port no> + * telnet -p <port no> + * + * Returns: TRUE if we have a hostname */ -void trim( - char *s) +BOOL +parse_cmdline(char *cmdline) { - int l; - int i; - - for (i = 0; s[i]; i++) - if (s[i] != ' ' && s[i] != '\t') - break; - - l = strlen(&s[i]); - memmove(s, &s[i], l + 1); - - for (l--; l >= 0; l--) { - if (s[l] != ' ' && s[l] != '\t') - break; - } - s[l + 1] = 0; - -} /* trim */ - - -/*+ -** -** Parse_cmdline -** -** Reads hostname and port number off the command line. -** -** Formats: telnet -** telnet <host> -** telnet <host> <port no> -** telnet -p <port no> -** -** Returns: TRUE if we have a hostname -*/ -BOOL parse_cmdline( - char *cmdline) -{ - char *ptr; + char *ptr; - *szHostName = '\0'; // Nothing yet - if (*cmdline == '\0') // Empty command line? - return(FALSE); + *szHostName = '\0'; /* Nothing yet */ + if (*cmdline == '\0') /* Empty command line? */ + return(FALSE); - trim (cmdline); // Remove excess spaces - ptr = strchr (cmdline, ' '); // Find 2nd token + trim (cmdline); /* Remove excess spaces */ + ptr = strchr (cmdline, ' '); /* Find 2nd token */ - if (ptr != NULL) { // Port number given - *ptr++ = '\0'; // Separate into 2 words - port_no = atoi (ptr); - } + if (ptr != NULL) { /* Port number given */ + *ptr++ = '\0'; /* Separate into 2 words */ + port_no = atoi (ptr); + } - if (*cmdline != '-' && *cmdline != '/') { // Host name given - lstrcpy (szHostName, cmdline); - return(TRUE); - } + if (*cmdline != '-' && *cmdline != '/') { /* Host name given */ + lstrcpy (szHostName, cmdline); + return(TRUE); + } - return(FALSE); + return(FALSE); +} -} /* parse_cmdline */ +#ifdef DEBUG +void +hexdump(char *msg, unsigned char *st, int cnt) +{ + int i; + char strTmp[128]; + + OutputDebugString("\r\n"); + if (msg != NULL) { + OutputDebugString(msg); + OutputDebugString("\r\n"); + } + for(i = 0 ; i < cnt ; i++) { + int j; + + for(j = 0 ; (j < 16) && ((i + j) < cnt) ; j++) { + wsprintf(strTmp,"%02x ", st[i + j]); + if (j == 8) + OutputDebugString("| "); + OutputDebugString(strTmp); + } + i += j - 1; + OutputDebugString("\r\n"); + } /* end for */ +} +#endif diff --git a/src/windows/wintel/telnet.dlg b/src/windows/wintel/telnet.dlg deleted file mode 100644 index 8b73ee8426..0000000000 --- a/src/windows/wintel/telnet.dlg +++ /dev/null @@ -1,77 +0,0 @@ -DLGINCLUDE RCDATA DISCARDABLE -BEGIN - "DIALOG.H\0" -END - -OPENTELNETDLG DIALOG 63, 65, 175, 51 -STYLE DS_ABSALIGN | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Open New Telnet Connection" -FONT 8, "MS Sans Serif" -BEGIN - CONTROL "To Host:", -1, "STATIC", NOT WS_GROUP, 3, 10, 33, 10 - CONTROL "", TEL_CONNECT_NAME, "COMBOBOX", CBS_DROPDOWN | WS_VSCROLL | WS_GROUP | WS_TABSTOP, 42, 9, 128, 60 - CONTROL "OK", TEL_OK, "BUTTON", WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON, 27, 30, 51, 14 - CONTROL "Cancel", TEL_CANCEL, "BUTTON", WS_TABSTOP, 97, 30, 51, 14 -END - -ABOUTBOX DIALOG 69, 33, 175, 148 -STYLE DS_ABSALIGN | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "About TCPwin" -BEGIN - ICON "NCSA", -1, 15, 12, 16, 16 - CTEXT "Microsoft Windows", -1, 48, 11, 93, 8 - CTEXT "NCSA TCP/IP Networking Kernel", -1, 38, 21, 120, 8 - CTEXT "Version 1.0b2", -1, 20, 31, 144, 8 - CONTROL "OK", IDOK, "BUTTON", WS_GROUP, 72, 126, 39, 14 - CTEXT "Written By:", 606, 20, 50, 144, 8 - CTEXT "Jon Mittelhauser (jonm@ncsa.uiuc.edu)", 607, 20, 61, 144, 8 - CTEXT "Chris Wilson (cwilson@ncsa.uiuc.edu)", 608, 20, 71, 144, 8 - CTEXT "Special Thanks to:", 609, 21, 97, 143, 8 - CTEXT "Joe Lepore for DPMI interface code", 610, 20, 107, 144, 8 - CTEXT "Keberized by: Cygnus Support", 611, 20, 82, 144, 8 -END - -CONFIG_DLG DIALOG 6, 18, 160, 130 -STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Configure Session" -FONT 8, "MS Sans Serif" -BEGIN - LTEXT "Session Name:", 301, 1, 5, 54, 8 - LTEXT "Default Session", CON_SESSIONNAME, 55, 5, 105, 8 - LTEXT "Window Title:", 303, 1, 17, 49, 8 - EDITTEXT CON_WINDOWTITLE, 53, 15, 102, 12, ES_AUTOHSCROLL - CONTROL "132", CON_COLUMNS132, "Button", BS_AUTORADIOBUTTON | - WS_GROUP, 53, 33, 39, 10 - CONTROL "80", CON_COLUMNS80, "Button", BS_AUTORADIOBUTTON, 110, - 33, 39, 10 - CONTROL "Backspace", CON_BACKSPACE, "Button", BS_AUTORADIOBUTTON | - WS_GROUP, 53, 46, 49, 10 - CONTROL "Delete", CON_DELETE, "Button", BS_AUTORADIOBUTTON, 110, - 46, 39, 10 - CONTROL "CRLF", CON_CRLF, "Button", BS_AUTORADIOBUTTON | - WS_GROUP, 53, 59, 39, 10 - CONTROL "CR-NUL", CON_CRNUL, "Button", BS_AUTORADIOBUTTON, 110, - 59, 39, 10 - CONTROL "Buffers", CON_BUFFERS, "Button", BS_AUTORADIOBUTTON | - WS_GROUP, 53, 72, 39, 10 - CONTROL "Sends", CON_SENDS, "Button", BS_AUTORADIOBUTTON, 110, - 72, 39, 10 - LTEXT "Columns", 313, 1, 33, 49, 8 - LTEXT "Backspace is", 314, 1, 46, 51, 8 - LTEXT "Return Sends", 315, 1, 59, 49, 8 - LTEXT "Echo Mode", 316, 1, 72, 49, 8 - CONTROL "Scrollback", CON_SCRLBCK, "Button", BS_AUTOCHECKBOX | - WS_TABSTOP, 1, 86, 50, 10 - EDITTEXT CON_NUMLINES, 53, 85, 28, 12, ES_AUTOHSCROLL - LTEXT "lines", 319, 85, 86, 33, 8 - DEFPUSHBUTTON "OK", CON_OK, 20, 108, 50, 14, WS_GROUP - PUSHBUTTON "Use Defaults", CON_USEDEFAULTS, 90, 108, 50, 14 -END - -IDM_PRINTQUEUE DIALOG 69, 25, 160, 80 -STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | - WS_VSCROLL | WS_HSCROLL | WS_SYSMENU -CAPTION "Print Queue" -FONT 8, "MS Sans Serif" -BEGIN -END diff --git a/src/windows/wintel/telnet.h b/src/windows/wintel/telnet.h index 3a69dd1f2b..cd1904a140 100644 --- a/src/windows/wintel/telnet.h +++ b/src/windows/wintel/telnet.h @@ -5,8 +5,8 @@ #include <stdarg.h> #ifdef KRB5 - #include "krb5.h" - #include "k5stream.h" +#include "krb5.h" +#include "k5stream.h" #endif #include "dialog.h" @@ -22,21 +22,20 @@ extern char szUserName[64]; extern char szHostName[64]; #ifdef KRB5 - extern krb5_context k5_context; +extern krb5_context k5_context; #endif -extern void parse( - CONNECTION *con, - unsigned char *st, - int cnt); +extern void parse(CONNECTION *, unsigned char *, int); -extern void send_naws( - CONNECTION *con); +extern void send_naws(CONNECTION *); extern char strTmp[1024]; #define DEF_WIDTH 80 #define DEF_HEIGHT 24 -#endif /* TELNET_H_INC */ +#ifdef DEBUG +void hexdump(char *, unsigned char *, int); +#endif +#endif /* TELNET_H_INC */ diff --git a/src/windows/wintel/telnet.rc b/src/windows/wintel/telnet.rc index ba00382286..bdd18d973c 100644 --- a/src/windows/wintel/telnet.rc +++ b/src/windows/wintel/telnet.rc @@ -1,27 +1,244 @@ -#include <windows.h> +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS #include "dialog.h" -#include "telnet.dlg" #include "screen.h" -NCSA ICON ncsa.ico -TERMINAL ICON terminal.ico - -ScreenMenu MENU -BEGIN - POPUP "&Configure" - BEGIN - MENUITEM "&Backspace", IDM_BACKSPACE, CHECKED - MENUITEM "&Delete", IDM_DELETE - MENUITEM SEPARATOR - MENUITEM "&Font...", IDM_FONT - MENUITEM "&About...", IDM_ABOUT - END - POPUP "&Edit" - BEGIN - MENUITEM "&Copy Cltr+Ins",IDM_COPY - MENUITEM "&Paste Shift+Ins", IDM_PASTE - #if ! defined(NDEBUG) - MENUITEM "&Debug", IDM_DEBUG - #endif - END +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +OPENTELNETDLG DIALOG DISCARDABLE 63, 65, 175, 129 +#ifdef _WIN32 +STYLE DS_ABSALIGN | DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | + WS_SYSMENU +#else +STYLE DS_ABSALIGN | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +#endif +CAPTION "Open New Telnet Connection" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "To Host:",IDC_STATIC,3,10,33,10,NOT WS_GROUP + COMBOBOX TEL_CONNECT_NAME,37,9,128,76,CBS_DROPDOWN | WS_VSCROLL | + WS_GROUP | WS_TABSTOP + CONTROL "Forward credentials",IDC_FORWARD,"Button", + BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,37,28,77,10 + CONTROL "Forward remote credentials",IDC_FORWARDFORWARD,"Button", + BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,37,44,101,10 + CONTROL "Enable encryption",IDC_ENCRYPT,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,37,60,73,10 + CONTROL "Connect as userid",IDC_STATIC,"Static", + SS_LEFTNOWORDWRAP,15,84,58,8 + EDITTEXT TEL_CONNECT_USERID,77,82,80,13,ES_AUTOHSCROLL | + WS_DISABLED + DEFPUSHBUTTON "OK",TEL_OK,20,106,51,14,WS_GROUP + PUSHBUTTON "Cancel",TEL_CANCEL,106,106,51,14 +END + +ABOUTBOX DIALOG DISCARDABLE 69, 33, 175, 148 +STYLE DS_ABSALIGN | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About TCPwin" +BEGIN + ICON "NCSA",-1,15,12,16,16 + CTEXT "Microsoft Windows",-1,48,11,93,8 + CTEXT "NCSA TCP/IP Networking Kernel",-1,38,21,120,8 + CTEXT "Version 1.0b2",-1,20,31,144,8 + PUSHBUTTON "OK",IDOK,72,126,39,14,WS_GROUP | NOT WS_TABSTOP + CTEXT "Written By:",606,20,50,144,8 + CTEXT "Jon Mittelhauser (jonm@ncsa.uiuc.edu)",607,20,61,144,8 + CTEXT "Chris Wilson (cwilson@ncsa.uiuc.edu)",608,20,71,144,8 + CTEXT "Special Thanks to:",609,21,97,143,8 + CTEXT "Joe Lepore for DPMI interface code",610,20,107,144,8 + CTEXT "Keberized by: Cygnus Support",611,20,82,144,8 +END + +CONFIG_DLG DIALOG DISCARDABLE 6, 18, 160, 130 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Configure Session" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "Session Name:",301,1,5,54,8 + LTEXT "Default Session",CON_SESSIONNAME,55,5,105,8 + LTEXT "Window Title:",303,1,17,49,8 + EDITTEXT CON_WINDOWTITLE,53,15,102,12,ES_AUTOHSCROLL + CONTROL "132",CON_COLUMNS132,"Button",BS_AUTORADIOBUTTON | + WS_GROUP,53,33,39,10 + CONTROL "80",CON_COLUMNS80,"Button",BS_AUTORADIOBUTTON,110,33,39, + 10 + CONTROL "Backspace",CON_BACKSPACE,"Button",BS_AUTORADIOBUTTON | + WS_GROUP,53,46,49,10 + CONTROL "Delete",CON_DELETE,"Button",BS_AUTORADIOBUTTON,110,46, + 39,10 + CONTROL "CRLF",CON_CRLF,"Button",BS_AUTORADIOBUTTON | WS_GROUP, + 53,59,39,10 + CONTROL "CR-NUL",CON_CRNUL,"Button",BS_AUTORADIOBUTTON,110,59,39, + 10 + CONTROL "Buffers",CON_BUFFERS,"Button",BS_AUTORADIOBUTTON | + WS_GROUP,53,72,39,10 + CONTROL "Sends",CON_SENDS,"Button",BS_AUTORADIOBUTTON,110,72,39, + 10 + LTEXT "Columns",313,1,33,49,8 + LTEXT "Backspace is",314,1,46,51,8 + LTEXT "Return Sends",315,1,59,49,8 + LTEXT "Echo Mode",316,1,72,49,8 + CONTROL "Scrollback",CON_SCRLBCK,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,1,86,50,10 + EDITTEXT CON_NUMLINES,53,85,28,12,ES_AUTOHSCROLL + LTEXT "lines",319,85,86,33,8 + DEFPUSHBUTTON "OK",CON_OK,20,108,50,14,WS_GROUP + PUSHBUTTON "Use Defaults",CON_USEDEFAULTS,90,108,50,14 +END + +IDM_PRINTQUEUE DIALOG DISCARDABLE 69, 25, 160, 80 +STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_VSCROLL | WS_HSCROLL | WS_SYSMENU +CAPTION "Print Queue" +FONT 8, "MS Sans Serif" +BEGIN +END + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 183, 92 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,126,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,126,24,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +NCSA ICON DISCARDABLE "ncsa.ico" +TERMINAL ICON DISCARDABLE "terminal.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +SCREENMENU MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "E&xit Alt+F4", IDM_EXIT + END + POPUP "&Edit" + BEGIN + MENUITEM "&Copy Cltr+Ins", IDM_COPY + MENUITEM "&Paste Shift+Ins", IDM_PASTE + END + POPUP "&Options" + BEGIN + MENUITEM "&Backspace", IDM_BACKSPACE + MENUITEM "&Delete", IDM_DELETE, CHECKED + MENUITEM SEPARATOR + MENUITEM "&Font...", IDM_FONT + END +#if 0 + POPUP "&Send", GRAYED + BEGIN + MENUITEM "&Interrupt Process", IDM_SEND_IP + MENUITEM "&Are You There?", IDM_SEND_AYT + MENUITEM "A&bort Process", IDM_SEND_ABORT + END +#endif + POPUP "&Help" + BEGIN + MENUITEM "&Index...", IDM_HELP_INDEX + MENUITEM SEPARATOR + MENUITEM "&About...", IDM_ABOUT + END END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""dialog.h""\r\n" + "#include ""screen.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_DIALOG1, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 176 + TOPMARGIN, 7 + BOTTOMMARGIN, 85 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/windows/wintel/telnet_arpa.h b/src/windows/wintel/telnet_arpa.h new file mode 100644 index 0000000000..f6d0eb566a --- /dev/null +++ b/src/windows/wintel/telnet_arpa.h @@ -0,0 +1,327 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)telnet.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _TELNET_H_ +#define _TELNET_H_ + +/* + * Definitions for the TELNET protocol. + */ +#define IAC 255 /* interpret as command: */ +#define DONT 254 /* you are not to use option */ +#define DO 253 /* please, you use option */ +#define WONT 252 /* I won't use option */ +#define WILL 251 /* I will use option */ +#define SB 250 /* interpret as subnegotiation */ +#define GA 249 /* you may reverse the line */ +#define EL 248 /* erase the current line */ +#define EC 247 /* erase the current character */ +#define AYT 246 /* are you there */ +#define AO 245 /* abort output--but let prog finish */ +#define IP 244 /* interrupt process--permanently */ +#define BREAK 243 /* break */ +#define DM 242 /* data mark--for connect. cleaning */ +#define NOP 241 /* nop */ +#define SE 240 /* end sub negotiation */ +#define EOR 239 /* end of record (transparent mode) */ +#define ABORT 238 /* Abort process */ +#define SUSP 237 /* Suspend process */ +#define xEOF 236 /* End of file: EOF is already used... */ + +#define SYNCH 242 /* for telfunc calls */ + +#ifdef TELCMDS +char *telcmds[] = { + "EOF", "SUSP", "ABORT", "EOR", + "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC", + "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0, +}; +#else +extern char *telcmds[]; +#endif + +#define TELCMD_FIRST xEOF +#define TELCMD_LAST IAC +#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \ + (unsigned int)(x) >= TELCMD_FIRST) +#define TELCMD(x) telcmds[(x)-TELCMD_FIRST] + +/* telnet options */ +#define TELOPT_BINARY 0 /* 8-bit data path */ +#define TELOPT_ECHO 1 /* echo */ +#define TELOPT_RCP 2 /* prepare to reconnect */ +#define TELOPT_SGA 3 /* suppress go ahead */ +#define TELOPT_NAMS 4 /* approximate message size */ +#define TELOPT_STATUS 5 /* give status */ +#define TELOPT_TM 6 /* timing mark */ +#define TELOPT_RCTE 7 /* remote controlled transmission and echo */ +#define TELOPT_NAOL 8 /* negotiate about output line width */ +#define TELOPT_NAOP 9 /* negotiate about output page size */ +#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */ +#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */ +#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */ +#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */ +#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */ +#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */ +#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */ +#define TELOPT_XASCII 17 /* extended ascic character set */ +#define TELOPT_LOGOUT 18 /* force logout */ +#define TELOPT_BM 19 /* byte macro */ +#define TELOPT_DET 20 /* data entry terminal */ +#define TELOPT_SUPDUP 21 /* supdup protocol */ +#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */ +#define TELOPT_SNDLOC 23 /* send location */ +#define TELOPT_TTYPE 24 /* terminal type */ +#define TELOPT_EOR 25 /* end or record */ +#define TELOPT_TUID 26 /* TACACS user identification */ +#define TELOPT_OUTMRK 27 /* output marking */ +#define TELOPT_TTYLOC 28 /* terminal location number */ +#define TELOPT_3270REGIME 29 /* 3270 regime */ +#define TELOPT_X3PAD 30 /* X.3 PAD */ +#define TELOPT_NAWS 31 /* window size */ +#define TELOPT_TSPEED 32 /* terminal speed */ +#define TELOPT_LFLOW 33 /* remote flow control */ +#define TELOPT_LINEMODE 34 /* Linemode option */ +#define TELOPT_XDISPLOC 35 /* X Display Location */ +#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */ +#define TELOPT_AUTHENTICATION 37/* Authenticate */ +#define TELOPT_ENCRYPT 38 /* Encryption option */ +#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */ +#define TELOPT_EXOPL 255 /* extended-options-list */ + + +#define NTELOPTS (1+TELOPT_NEW_ENVIRON) +#ifdef TELOPTS +char *telopts[NTELOPTS+1] = { + "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME", + "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP", + "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS", + "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO", + "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT", + "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD", + "TACACS UID", "OUTPUT MARKING", "TTYLOC", + "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW", + "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION", + "ENCRYPT", "NEW-ENVIRON", + 0, +}; +#define TELOPT_FIRST TELOPT_BINARY +#define TELOPT_LAST TELOPT_NEW_ENVIRON +#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST) +#define TELOPT(x) telopts[(x)-TELOPT_FIRST] +#endif + +/* sub-option qualifiers */ +#define TELQUAL_IS 0 /* option is... */ +#define TELQUAL_SEND 1 /* send option */ +#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */ +#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */ +#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */ + +#define LFLOW_OFF 0 /* Disable remote flow control */ +#define LFLOW_ON 1 /* Enable remote flow control */ +#define LFLOW_RESTART_ANY 2 /* Restart output on any char */ +#define LFLOW_RESTART_XON 3 /* Restart output only on XON */ + +/* + * LINEMODE suboptions + */ + +#define LM_MODE 1 +#define LM_FORWARDMASK 2 +#define LM_SLC 3 + +#define MODE_EDIT 0x01 +#define MODE_TRAPSIG 0x02 +#define MODE_ACK 0x04 +#define MODE_SOFT_TAB 0x08 +#define MODE_LIT_ECHO 0x10 + +#define MODE_MASK 0x1f + +/* Not part of protocol, but needed to simplify things... */ +#define MODE_FLOW 0x0100 +#define MODE_ECHO 0x0200 +#define MODE_INBIN 0x0400 +#define MODE_OUTBIN 0x0800 +#define MODE_FORCE 0x1000 + +#define SLC_SYNCH 1 +#define SLC_BRK 2 +#define SLC_IP 3 +#define SLC_AO 4 +#define SLC_AYT 5 +#define SLC_EOR 6 +#define SLC_ABORT 7 +#define SLC_EOF 8 +#define SLC_SUSP 9 +#define SLC_EC 10 +#define SLC_EL 11 +#define SLC_EW 12 +#define SLC_RP 13 +#define SLC_LNEXT 14 +#define SLC_XON 15 +#define SLC_XOFF 16 +#define SLC_FORW1 17 +#define SLC_FORW2 18 + +#define NSLC 18 + +/* + * For backwards compatability, we define SLC_NAMES to be the + * list of names if SLC_NAMES is not defined. + */ +#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \ + "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \ + "LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0, +#ifdef SLC_NAMES +char *slc_names[] = { + SLC_NAMELIST +}; +#else +extern char *slc_names[]; +#define SLC_NAMES SLC_NAMELIST +#endif + +#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC) +#define SLC_NAME(x) slc_names[x] + +#define SLC_NOSUPPORT 0 +#define SLC_CANTCHANGE 1 +#define SLC_VARIABLE 2 +#define SLC_DEFAULT 3 +#define SLC_LEVELBITS 0x03 + +#define SLC_FUNC 0 +#define SLC_FLAGS 1 +#define SLC_VALUE 2 + +#define SLC_ACK 0x80 +#define SLC_FLUSHIN 0x40 +#define SLC_FLUSHOUT 0x20 + +#define OLD_ENV_VAR 1 +#define OLD_ENV_VALUE 0 +#define NEW_ENV_VAR 0 +#define NEW_ENV_VALUE 1 +#define ENV_ESC 2 +#define ENV_USERVAR 3 + +/* + * AUTHENTICATION suboptions + */ + +/* + * Who is authenticating who ... + */ +#define AUTH_WHO_CLIENT 0 /* Client authenticating server */ +#define AUTH_WHO_SERVER 1 /* Server authenticating client */ +#define AUTH_WHO_MASK 1 + +/* + * amount of authentication done + */ +#define AUTH_HOW_ONE_WAY 0 +#define AUTH_HOW_MUTUAL 2 +#define AUTH_HOW_MASK 2 + +/* + * should we be encrypting? (not yet formally standardized) + */ +#define AUTH_ENCRYPT_OFF 0 +#define AUTH_ENCRYPT_ON 4 +#define AUTH_ENCRYPT_MASK 4 + +#define AUTHTYPE_NULL 0 +#define AUTHTYPE_KERBEROS_V4 1 +#define AUTHTYPE_KERBEROS_V5 2 +#define AUTHTYPE_SPX 3 +#define AUTHTYPE_MINK 4 +#define AUTHTYPE_CNT 5 + +#define AUTHTYPE_TEST 99 + +#ifdef AUTH_NAMES +char *authtype_names[] = { + "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0, +}; +#else +extern char *authtype_names[]; +#endif + +#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT) +#define AUTHTYPE_NAME(x) authtype_names[x] + +/* + * ENCRYPTion suboptions + */ +#define ENCRYPT_IS 0 /* I pick encryption type ... */ +#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */ +#define ENCRYPT_REPLY 2 /* Initial setup response */ +#define ENCRYPT_START 3 /* Am starting to send encrypted */ +#define ENCRYPT_END 4 /* Am ending encrypted */ +#define ENCRYPT_REQSTART 5 /* Request you start encrypting */ +#define ENCRYPT_REQEND 6 /* Request you send encrypting */ +#define ENCRYPT_ENC_KEYID 7 +#define ENCRYPT_DEC_KEYID 8 +#define ENCRYPT_CNT 9 + +#define ENCTYPE_ANY 0 +#define ENCTYPE_DES_CFB64 1 +#define ENCTYPE_DES_OFB64 2 +#define ENCTYPE_CNT 3 + +#ifdef ENCRYPT_NAMES +char *encrypt_names[] = { + "IS", "SUPPORT", "REPLY", "START", "END", + "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID", + 0, +}; +char *enctype_names[] = { + "ANY", "DES_CFB64", "DES_OFB64", 0, +}; +#else +extern char *encrypt_names[]; +extern char *enctype_names[]; +#endif + + +#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT) +#define ENCRYPT_NAME(x) encrypt_names[x] + +#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT) +#define ENCTYPE_NAME(x) enctype_names[x] + +#endif /* !_TELNET_H_ */ diff --git a/src/windows/wintel/telopts.h b/src/windows/wintel/telopts.h index e928a84285..54d67cde3d 100644 --- a/src/windows/wintel/telopts.h +++ b/src/windows/wintel/telopts.h @@ -1,22 +1,22 @@ /* -* telopts.h -* Used for telnet options -**************************************************************************** -* * -* * -* NCSA Telnet * -* by Tim Krauskopf, VT100 by Gaige Paulsen, Tek by Aaron Contorer * -* Additions by Kurt Mahan, Heeren Pathak, & Quincey Koziol * -* * -* National Center for Supercomputing Applications * -* 152 Computing Applications Building * -* 605 E. Springfield Ave. * -* Champaign, IL 61820 * -* * -**************************************************************************** -* Quincey Koziol -* Defines for telnet options and related things -*/ + * telopts.h + * Used for telnet options + **************************************************************************** + * * + * * + * NCSA Telnet * + * by Tim Krauskopf, VT100 by Gaige Paulsen, Tek by Aaron Contorer * + * Additions by Kurt Mahan, Heeren Pathak, & Quincey Koziol * + * * + * National Center for Supercomputing Applications * + * 152 Computing Applications Building * + * 605 E. Springfield Ave. * + * Champaign, IL 61820 * + * * + **************************************************************************** + * Quincey Koziol + * Defines for telnet options and related things + */ #ifndef TELOPTS_H #define TELOPTS_H @@ -37,18 +37,18 @@ #define SE 240 #define NOP 241 #define DM 242 -#define BREAK 243 +#define BREAK 243 #define IP 244 #define AO 245 #define AYT 246 #define EC 247 #define EL 248 -#define GOAHEAD 249 +#define GOAHEAD 249 #define SB 250 -#define WILLTEL 251 -#define WONTTEL 252 -#define DOTEL 253 -#define DONTTEL 254 +#define WILLTEL 251 +#define WONTTEL 252 +#define DOTEL 253 +#define DONTTEL 254 #define IAC 255 /* Assigned Telnet Options */ @@ -87,68 +87,74 @@ #define TERMSPEED 32 #define TFLOWCNTRL 33 #define LINEMODE 34 - #define MODE 1 - #define MODE_EDIT 1 - #define MODE_TRAPSIG 2 - #define MODE_ACK 4 - #define MODE_SOFT_TAB 8 - #define MODE_LIT_ECHO 16 - - #define FORWARDMASK 2 - - #define SLC 3 - #define SLC_DEFAULT 3 - #define SLC_VALUE 2 - #define SLC_CANTCHANGE 1 - #define SLC_NOSUPPORT 0 - #define SLC_LEVELBITS 3 - - #define SLC_ACK 128 - #define SLC_FLUSHIN 64 - #define SLC_FLUSHOUT 32 - - #define SLC_SYNCH 1 - #define SLC_BRK 2 - #define SLC_IP 3 - #define SLC_AO 4 - #define SLC_AYT 5 - #define SLC_EOR 6 - #define SLC_ABORT 7 - #define SLC_EOF 8 - #define SLC_SUSP 9 - #define SLC_EC 10 - #define SLC_EL 11 - #define SLC_EW 12 - #define SLC_RP 13 - #define SLC_LNEXT 14 - #define SLC_XON 15 - #define SLC_XOFF 16 - #define SLC_FORW1 17 - #define SLC_FORW2 18 - #define SLC_MCL 19 - #define SLC_MCR 20 - #define SLC_MCWL 21 - #define SLC_MCWR 22 - #define SLC_MCBOL 23 - #define SLC_MCEOL 24 - #define SLC_INSRT 25 - #define SLC_OVER 26 - #define SLC_ECR 27 - #define SLC_EWR 28 - #define SLC_EBOL 29 - #define SLC_EEOL 30 - -#define XDISPLOC 35 -#define ENVIRONMENT 36 + +#define MODE 1 +#define MODE_EDIT 1 +#define MODE_TRAPSIG 2 +#define MODE_ACK 4 +#define MODE_SOFT_TAB 8 +#define MODE_LIT_ECHO 16 + +#define FORWARDMASK 2 + +#define SLC 3 +#define SLC_DEFAULT 3 +#define SLC_VALUE 2 +#define SLC_CANTCHANGE 1 +#define SLC_NOSUPPORT 0 +#define SLC_LEVELBITS 3 + +#define SLC_ACK 128 +#define SLC_FLUSHIN 64 +#define SLC_FLUSHOUT 32 + +#define SLC_SYNCH 1 +#define SLC_BRK 2 +#define SLC_IP 3 +#define SLC_AO 4 +#define SLC_AYT 5 +#define SLC_EOR 6 +#define SLC_ABORT 7 +#define SLC_EOF 8 +#define SLC_SUSP 9 +#define SLC_EC 10 +#define SLC_EL 11 +#define SLC_EW 12 +#define SLC_RP 13 +#define SLC_LNEXT 14 +#define SLC_XON 15 +#define SLC_XOFF 16 +#define SLC_FORW1 17 +#define SLC_FORW2 18 +#define SLC_MCL 19 +#define SLC_MCR 20 +#define SLC_MCWL 21 +#define SLC_MCWR 22 +#define SLC_MCBOL 23 +#define SLC_MCEOL 24 +#define SLC_INSRT 25 +#define SLC_OVER 26 +#define SLC_ECR 27 +#define SLC_EWR 28 +#define SLC_EBOL 29 +#define SLC_EEOL 30 + +#define XDISPLOC 35 +#define ENVIRONMENT 36 #define AUTHENTICATION 37 -#define DATA_ENCRYPTION 38 -#define XOPTIONS 255 +#define TELOPT_AUTHENTICATION AUTHENTICATION +#define DATA_ENCRYPTION 38 +#define XOPTIONS 255 #define LINEMODE_MODES_SUPPORTED 0x1B -/* set this flag for linemode special functions which are supported by Telnet, even though they are not currently active */ -/* This is to allow the other side to negotiate to a "No Support" state for an option */ -/* and then change later to supporting it, so we know it's ok to change our "No Support" */ -/* state to something else ("Can't Change", "Value", whatever) */ +/* + * set this flag for linemode special functions which are supported by + * Telnet, even though they are not currently active. This is to allow + * the other side to negotiate to a "No Support" state for an option + * and then change later to supporting it, so we know it's ok to change + * our "No Support" state to something else ("Can't Change", "Value", + * whatever) + */ #define SLC_SUPPORTED 0x10 #define ESCFOUND 5 @@ -156,4 +162,3 @@ #define NEGOTIATE 1 #endif /* telopts.h */ - |