mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-02-03 21:52:24 +00:00
Experimental Rlogin support, thanks to Delian Delchev. Local flow
control is unsupported, and server-to-client comms may fail for want of working TCP Urgent. [originally from svn r875]
This commit is contained in:
parent
72cdcc611a
commit
ca90be26a8
3
Makefile
3
Makefile
@ -65,7 +65,7 @@ RES=res
|
|||||||
GOBJS1 = window.$(OBJ) windlg.$(OBJ) winctrls.$(OBJ) terminal.$(OBJ)
|
GOBJS1 = window.$(OBJ) windlg.$(OBJ) winctrls.$(OBJ) terminal.$(OBJ)
|
||||||
GOBJS2 = xlat.$(OBJ) sizetip.$(OBJ)
|
GOBJS2 = xlat.$(OBJ) sizetip.$(OBJ)
|
||||||
##-- objects putty puttytel plink
|
##-- objects putty puttytel plink
|
||||||
LOBJS1 = telnet.$(OBJ) raw.$(OBJ) ldisc.$(OBJ) winnet.$(OBJ)
|
LOBJS1 = telnet.$(OBJ) raw.$(OBJ) rlogin.$(OBJ) ldisc.$(OBJ) winnet.$(OBJ)
|
||||||
##-- objects putty plink
|
##-- objects putty plink
|
||||||
POBJS = be_all.$(OBJ)
|
POBJS = be_all.$(OBJ)
|
||||||
##-- objects puttytel
|
##-- objects puttytel
|
||||||
@ -224,6 +224,7 @@ terminal.$(OBJ): terminal.c putty.h puttymem.h network.h
|
|||||||
sizetip.$(OBJ): sizetip.c putty.h puttymem.h network.h winstuff.h
|
sizetip.$(OBJ): sizetip.c putty.h puttymem.h network.h winstuff.h
|
||||||
telnet.$(OBJ): telnet.c putty.h puttymem.h network.h
|
telnet.$(OBJ): telnet.c putty.h puttymem.h network.h
|
||||||
raw.$(OBJ): raw.c putty.h puttymem.h network.h
|
raw.$(OBJ): raw.c putty.h puttymem.h network.h
|
||||||
|
rlogin.$(OBJ): rlogin.c putty.h puttymem.h network.h
|
||||||
xlat.$(OBJ): xlat.c putty.h puttymem.h network.h
|
xlat.$(OBJ): xlat.c putty.h puttymem.h network.h
|
||||||
ldisc.$(OBJ): ldisc.c putty.h puttymem.h network.h
|
ldisc.$(OBJ): ldisc.c putty.h puttymem.h network.h
|
||||||
misc.$(OBJ): misc.c putty.h puttymem.h network.h
|
misc.$(OBJ): misc.c putty.h puttymem.h network.h
|
||||||
|
1
be_all.c
1
be_all.c
@ -10,6 +10,7 @@
|
|||||||
struct backend_list backends[] = {
|
struct backend_list backends[] = {
|
||||||
{PROT_SSH, "ssh", &ssh_backend},
|
{PROT_SSH, "ssh", &ssh_backend},
|
||||||
{PROT_TELNET, "telnet", &telnet_backend},
|
{PROT_TELNET, "telnet", &telnet_backend},
|
||||||
|
{PROT_RLOGIN, "rlogin", &rlogin_backend},
|
||||||
{PROT_RAW, "raw", &raw_backend},
|
{PROT_RAW, "raw", &raw_backend},
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
struct backend_list backends[] = {
|
struct backend_list backends[] = {
|
||||||
{PROT_SSH, "ssh", NULL},
|
{PROT_SSH, "ssh", NULL},
|
||||||
{PROT_TELNET, "telnet", NULL},
|
{PROT_TELNET, "telnet", NULL},
|
||||||
|
{PROT_RLOGIN, "rlogin", NULL},
|
||||||
{PROT_RAW, "raw", NULL},
|
{PROT_RAW, "raw", NULL},
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
struct backend_list backends[] = {
|
struct backend_list backends[] = {
|
||||||
{PROT_TELNET, "telnet", &telnet_backend},
|
{PROT_TELNET, "telnet", &telnet_backend},
|
||||||
|
{PROT_RLOGIN, "rlogin", &rlogin_backend},
|
||||||
{PROT_RAW, "raw", &raw_backend},
|
{PROT_RAW, "raw", &raw_backend},
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
|
@ -26,7 +26,7 @@ void sk_init(void); /* called once at program startup */
|
|||||||
SockAddr sk_namelookup(char *host, char **canonicalname);
|
SockAddr sk_namelookup(char *host, char **canonicalname);
|
||||||
void sk_addr_free(SockAddr addr);
|
void sk_addr_free(SockAddr addr);
|
||||||
|
|
||||||
Socket sk_new(SockAddr addr, int port, sk_receiver_t receiver);
|
Socket sk_new(SockAddr addr, int port, int privport, sk_receiver_t receiver);
|
||||||
void sk_close(Socket s);
|
void sk_close(Socket s);
|
||||||
void sk_write(Socket s, char *buf, int len);
|
void sk_write(Socket s, char *buf, int len);
|
||||||
void sk_write_oob(Socket s, char *buf, int len);
|
void sk_write_oob(Socket s, char *buf, int len);
|
||||||
|
9
putty.h
9
putty.h
@ -137,7 +137,7 @@ typedef struct {
|
|||||||
/* Basic options */
|
/* Basic options */
|
||||||
char host[512];
|
char host[512];
|
||||||
int port;
|
int port;
|
||||||
enum { PROT_RAW, PROT_TELNET, PROT_SSH } protocol;
|
enum { PROT_RAW, PROT_TELNET, PROT_RLOGIN, PROT_SSH } protocol;
|
||||||
int close_on_exit;
|
int close_on_exit;
|
||||||
int warn_on_close;
|
int warn_on_close;
|
||||||
int ping_interval; /* in seconds */
|
int ping_interval; /* in seconds */
|
||||||
@ -156,6 +156,7 @@ typedef struct {
|
|||||||
char termspeed[32];
|
char termspeed[32];
|
||||||
char environmt[1024]; /* VAR\tvalue\0VAR\tvalue\0\0 */
|
char environmt[1024]; /* VAR\tvalue\0VAR\tvalue\0\0 */
|
||||||
char username[32];
|
char username[32];
|
||||||
|
char localusername[32];
|
||||||
int rfc_environ;
|
int rfc_environ;
|
||||||
/* Keyboard options */
|
/* Keyboard options */
|
||||||
int bksp_is_delete;
|
int bksp_is_delete;
|
||||||
@ -333,6 +334,12 @@ void term_copyall(void);
|
|||||||
|
|
||||||
extern Backend raw_backend;
|
extern Backend raw_backend;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exports from rlogin.c.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern Backend rlogin_backend;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exports from telnet.c.
|
* Exports from telnet.c.
|
||||||
*/
|
*/
|
||||||
|
2
raw.c
2
raw.c
@ -59,7 +59,7 @@ static char *raw_init (char *host, int port, char **realhost) {
|
|||||||
/*
|
/*
|
||||||
* Open socket.
|
* Open socket.
|
||||||
*/
|
*/
|
||||||
s = sk_new(addr, port, raw_receive);
|
s = sk_new(addr, port, 0, raw_receive);
|
||||||
if ( (err = sk_socket_error(s)) )
|
if ( (err = sk_socket_error(s)) )
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
149
rlogin.c
Normal file
149
rlogin.c
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "putty.h"
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static Socket s = NULL;
|
||||||
|
|
||||||
|
static void rlogin_size(void);
|
||||||
|
|
||||||
|
static int sb_opt, sb_len;
|
||||||
|
static char *sb_buf = NULL;
|
||||||
|
static int sb_size = 0;
|
||||||
|
#define SB_DELTA 1024
|
||||||
|
|
||||||
|
static void c_write (char *buf, int len) {
|
||||||
|
from_backend(0, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rlogin_receive (Socket s, int urgent, char *data, int len) {
|
||||||
|
if (!len) {
|
||||||
|
/* Connection has closed. */
|
||||||
|
sk_close(s);
|
||||||
|
s = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (urgent == 2) {
|
||||||
|
char c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
c = *data++; len--;
|
||||||
|
if (c == 0x80)
|
||||||
|
rlogin_size();
|
||||||
|
/*
|
||||||
|
* We should flush everything (aka Telnet SYNCH) if we see
|
||||||
|
* 0x02, and we should turn off and on _local_ flow control
|
||||||
|
* on 0x10 and 0x20 respectively. I'm not convinced it's
|
||||||
|
* worth it...
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
c_write(data, len);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called to set up the rlogin connection.
|
||||||
|
*
|
||||||
|
* Returns an error message, or NULL on success.
|
||||||
|
*
|
||||||
|
* Also places the canonical host name into `realhost'.
|
||||||
|
*/
|
||||||
|
static char *rlogin_init (char *host, int port, char **realhost) {
|
||||||
|
SockAddr addr;
|
||||||
|
char *err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to find host.
|
||||||
|
*/
|
||||||
|
addr = sk_namelookup(host, realhost);
|
||||||
|
if ( (err = sk_addr_error(addr)) )
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (port < 0)
|
||||||
|
port = 513; /* default rlogin port */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open socket.
|
||||||
|
*/
|
||||||
|
s = sk_new(addr, port, 1, rlogin_receive);
|
||||||
|
if ( (err = sk_socket_error(s)) )
|
||||||
|
return err;
|
||||||
|
|
||||||
|
sk_addr_free(addr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send local username, remote username, terminal/speed
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
char z = 0;
|
||||||
|
char *p;
|
||||||
|
sk_write(s, &z, 1);
|
||||||
|
sk_write(s, cfg.localusername, strlen(cfg.localusername));
|
||||||
|
sk_write(s, &z, 1);
|
||||||
|
sk_write(s, cfg.username, strlen(cfg.username));
|
||||||
|
sk_write(s, &z, 1);
|
||||||
|
sk_write(s, cfg.termtype, strlen(cfg.termtype));
|
||||||
|
sk_write(s, "/", 1);
|
||||||
|
for(p = cfg.termspeed; isdigit(*p); p++);
|
||||||
|
sk_write(s, cfg.termspeed, p - cfg.termspeed);
|
||||||
|
sk_write(s, &z, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
begin_session();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called to send data down the rlogin connection.
|
||||||
|
*/
|
||||||
|
static void rlogin_send (char *buf, int len) {
|
||||||
|
|
||||||
|
if (s == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sk_write(s, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called to set the size of the window
|
||||||
|
*/
|
||||||
|
static void rlogin_size(void) {
|
||||||
|
char b[12] = { 0xFF, 0xFF, 0x73, 0x73, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
b[6] = cols >> 8; b[7] = cols & 0xFF;
|
||||||
|
b[4] = rows >> 8; b[5] = rows & 0xFF;
|
||||||
|
sk_write(s, b, 12);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send rlogin special codes.
|
||||||
|
*/
|
||||||
|
static void rlogin_special (Telnet_Special code) {
|
||||||
|
/* Do nothing! */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Socket rlogin_socket(void) { return s; }
|
||||||
|
|
||||||
|
static int rlogin_sendok(void) { return 1; }
|
||||||
|
|
||||||
|
Backend rlogin_backend = {
|
||||||
|
rlogin_init,
|
||||||
|
rlogin_send,
|
||||||
|
rlogin_size,
|
||||||
|
rlogin_special,
|
||||||
|
rlogin_socket,
|
||||||
|
rlogin_sendok,
|
||||||
|
1
|
||||||
|
};
|
@ -68,6 +68,7 @@ void save_settings (char *section, int do_host, Config *cfg) {
|
|||||||
write_setting_s (sesskey, "Environment", buf);
|
write_setting_s (sesskey, "Environment", buf);
|
||||||
}
|
}
|
||||||
write_setting_s (sesskey, "UserName", cfg->username);
|
write_setting_s (sesskey, "UserName", cfg->username);
|
||||||
|
write_setting_s (sesskey, "LocalUserName", cfg->localusername);
|
||||||
write_setting_i (sesskey, "NoPTY", cfg->nopty);
|
write_setting_i (sesskey, "NoPTY", cfg->nopty);
|
||||||
write_setting_i (sesskey, "Compression", cfg->compression);
|
write_setting_i (sesskey, "Compression", cfg->compression);
|
||||||
write_setting_i (sesskey, "AgentFwd", cfg->agentfwd);
|
write_setting_i (sesskey, "AgentFwd", cfg->agentfwd);
|
||||||
@ -199,6 +200,7 @@ void load_settings (char *section, int do_host, Config *cfg) {
|
|||||||
*q = '\0';
|
*q = '\0';
|
||||||
}
|
}
|
||||||
gpps (sesskey, "UserName", "", cfg->username, sizeof(cfg->username));
|
gpps (sesskey, "UserName", "", cfg->username, sizeof(cfg->username));
|
||||||
|
gpps (sesskey, "LocalUserName", "", cfg->localusername, sizeof(cfg->localusername));
|
||||||
gppi (sesskey, "NoPTY", 0, &cfg->nopty);
|
gppi (sesskey, "NoPTY", 0, &cfg->nopty);
|
||||||
gppi (sesskey, "Compression", 0, &cfg->compression);
|
gppi (sesskey, "Compression", 0, &cfg->compression);
|
||||||
gppi (sesskey, "AgentFwd", 0, &cfg->agentfwd);
|
gppi (sesskey, "AgentFwd", 0, &cfg->agentfwd);
|
||||||
|
2
ssh.c
2
ssh.c
@ -1184,7 +1184,7 @@ static char *connect_to_host(char *host, int port, char **realhost)
|
|||||||
/*
|
/*
|
||||||
* Open socket.
|
* Open socket.
|
||||||
*/
|
*/
|
||||||
s = sk_new(addr, port, ssh_receive);
|
s = sk_new(addr, port, 0, ssh_receive);
|
||||||
if ( (err = sk_socket_error(s)) )
|
if ( (err = sk_socket_error(s)) )
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
2
telnet.c
2
telnet.c
@ -495,7 +495,7 @@ static char *telnet_init (char *host, int port, char **realhost) {
|
|||||||
/*
|
/*
|
||||||
* Open socket.
|
* Open socket.
|
||||||
*/
|
*/
|
||||||
s = sk_new(addr, port, telnet_receive);
|
s = sk_new(addr, port, 0, telnet_receive);
|
||||||
if ( (err = sk_socket_error(s)) )
|
if ( (err = sk_socket_error(s)) )
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
66
windlg.c
66
windlg.c
@ -189,6 +189,7 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
|
|||||||
IDC_PROTSTATIC,
|
IDC_PROTSTATIC,
|
||||||
IDC_PROTRAW,
|
IDC_PROTRAW,
|
||||||
IDC_PROTTELNET,
|
IDC_PROTTELNET,
|
||||||
|
IDC_PROTRLOGIN,
|
||||||
IDC_PROTSSH,
|
IDC_PROTSSH,
|
||||||
IDC_SESSSTATIC,
|
IDC_SESSSTATIC,
|
||||||
IDC_SESSEDIT,
|
IDC_SESSEDIT,
|
||||||
@ -317,6 +318,16 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
|
|||||||
IDC_EMRFC,
|
IDC_EMRFC,
|
||||||
telnetpanelend,
|
telnetpanelend,
|
||||||
|
|
||||||
|
rloginpanelstart,
|
||||||
|
IDC_TITLE_RLOGIN,
|
||||||
|
IDC_BOX_RLOGIN1, IDC_BOXT_RLOGIN1,
|
||||||
|
IDC_BOX_RLOGIN2, IDC_BOXT_RLOGIN2,
|
||||||
|
IDC_R_TSSTATIC,
|
||||||
|
IDC_R_TSEDIT,
|
||||||
|
IDC_RLLUSERSTATIC,
|
||||||
|
IDC_RLLUSEREDIT,
|
||||||
|
rloginpanelend,
|
||||||
|
|
||||||
sshpanelstart,
|
sshpanelstart,
|
||||||
IDC_TITLE_SSH,
|
IDC_TITLE_SSH,
|
||||||
IDC_BOX_SSH1, IDC_BOXT_SSH1,
|
IDC_BOX_SSH1, IDC_BOXT_SSH1,
|
||||||
@ -433,7 +444,8 @@ static void init_dlg_ctrls(HWND hwnd) {
|
|||||||
SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
|
SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
|
||||||
CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
|
CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
|
||||||
cfg.protocol==PROT_SSH ? IDC_PROTSSH :
|
cfg.protocol==PROT_SSH ? IDC_PROTSSH :
|
||||||
cfg.protocol==PROT_TELNET ? IDC_PROTTELNET : IDC_PROTRAW );
|
cfg.protocol==PROT_TELNET ? IDC_PROTTELNET :
|
||||||
|
cfg.protocol==PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW );
|
||||||
SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
|
SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
|
||||||
|
|
||||||
CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
|
CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
|
||||||
@ -487,6 +499,8 @@ static void init_dlg_ctrls(HWND hwnd) {
|
|||||||
|
|
||||||
SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
|
SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
|
||||||
SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
|
SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
|
||||||
|
SetDlgItemText (hwnd, IDC_R_TSEDIT, cfg.termspeed);
|
||||||
|
SetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername);
|
||||||
SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
|
SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
|
||||||
SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
|
SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
|
||||||
CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
|
CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
|
||||||
@ -693,13 +707,15 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
|
|||||||
"&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
|
"&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
|
||||||
if (backends[2].backend == NULL) {
|
if (backends[2].backend == NULL) {
|
||||||
/* this is PuTTYtel, so only two protocols available */
|
/* this is PuTTYtel, so only two protocols available */
|
||||||
radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
|
radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
|
||||||
"&Raw", IDC_PROTRAW,
|
|
||||||
"&Telnet", IDC_PROTTELNET, NULL);
|
|
||||||
} else {
|
|
||||||
radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
|
|
||||||
"&Raw", IDC_PROTRAW,
|
"&Raw", IDC_PROTRAW,
|
||||||
"&Telnet", IDC_PROTTELNET,
|
"&Telnet", IDC_PROTTELNET,
|
||||||
|
"R&login", IDC_PROTRLOGIN, NULL);
|
||||||
|
} else {
|
||||||
|
radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
|
||||||
|
"&Raw", IDC_PROTRAW,
|
||||||
|
"&Telnet", IDC_PROTTELNET,
|
||||||
|
"R&login", IDC_PROTRLOGIN,
|
||||||
#ifdef FWHACK
|
#ifdef FWHACK
|
||||||
"SS&H/hack",
|
"SS&H/hack",
|
||||||
#else
|
#else
|
||||||
@ -993,6 +1009,23 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The Rlogin Panel */
|
||||||
|
{
|
||||||
|
struct ctlpos cp;
|
||||||
|
ctlposinit(&cp, hwnd, 80, 3, 13);
|
||||||
|
if (dlgtype == 0) {
|
||||||
|
bartitle(&cp, "Options controlling Rlogin connections", IDC_TITLE_RLOGIN);
|
||||||
|
beginbox(&cp, "Data to send to the server",
|
||||||
|
IDC_BOX_RLOGIN1, IDC_BOXT_RLOGIN1);
|
||||||
|
staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC, IDC_R_TSEDIT, 50);
|
||||||
|
staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC, IDC_RLLUSEREDIT, 50);
|
||||||
|
endbox(&cp);
|
||||||
|
|
||||||
|
treeview_insert(&tvfaff, 1, "Rlogin");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
|
/* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
|
||||||
if (backends[2].backend != NULL) {
|
if (backends[2].backend != NULL) {
|
||||||
struct ctlpos cp;
|
struct ctlpos cp;
|
||||||
@ -1095,6 +1128,8 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
|
|||||||
hide(hwnd, FALSE, connectionpanelstart, connectionpanelend);
|
hide(hwnd, FALSE, connectionpanelstart, connectionpanelend);
|
||||||
if (!strcmp(buffer, "Telnet"))
|
if (!strcmp(buffer, "Telnet"))
|
||||||
hide(hwnd, FALSE, telnetpanelstart, telnetpanelend);
|
hide(hwnd, FALSE, telnetpanelstart, telnetpanelend);
|
||||||
|
if (!strcmp(buffer, "Rlogin"))
|
||||||
|
hide(hwnd, FALSE, rloginpanelstart, rloginpanelend);
|
||||||
if (!strcmp(buffer, "SSH"))
|
if (!strcmp(buffer, "SSH"))
|
||||||
hide(hwnd, FALSE, sshpanelstart, sshpanelend);
|
hide(hwnd, FALSE, sshpanelstart, sshpanelend);
|
||||||
if (!strcmp(buffer, "Selection"))
|
if (!strcmp(buffer, "Selection"))
|
||||||
@ -1123,16 +1158,19 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
|
|||||||
EndDialog (hwnd, 0);
|
EndDialog (hwnd, 0);
|
||||||
return 0;
|
return 0;
|
||||||
case IDC_PROTTELNET:
|
case IDC_PROTTELNET:
|
||||||
|
case IDC_PROTRLOGIN:
|
||||||
case IDC_PROTSSH:
|
case IDC_PROTSSH:
|
||||||
case IDC_PROTRAW:
|
case IDC_PROTRAW:
|
||||||
if (HIWORD(wParam) == BN_CLICKED ||
|
if (HIWORD(wParam) == BN_CLICKED ||
|
||||||
HIWORD(wParam) == BN_DOUBLECLICKED) {
|
HIWORD(wParam) == BN_DOUBLECLICKED) {
|
||||||
int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
|
int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
|
||||||
int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
|
int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
|
||||||
cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
|
int k = IsDlgButtonChecked (hwnd, IDC_PROTRLOGIN);
|
||||||
if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
|
cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN : PROT_RAW ;
|
||||||
(cfg.protocol == PROT_TELNET && cfg.port == 22)) {
|
if ((cfg.protocol == PROT_SSH && cfg.port != 22) ||
|
||||||
cfg.port = i ? 22 : 23;
|
(cfg.protocol == PROT_TELNET && cfg.port != 23) ||
|
||||||
|
(cfg.protocol == PROT_RLOGIN && cfg.port != 513)) {
|
||||||
|
cfg.port = i ? 22 : j ? 23 : 513;
|
||||||
SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
|
SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1517,8 +1555,9 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IDC_TSEDIT:
|
case IDC_TSEDIT:
|
||||||
|
case IDC_R_TSEDIT:
|
||||||
if (HIWORD(wParam) == EN_CHANGE)
|
if (HIWORD(wParam) == EN_CHANGE)
|
||||||
GetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed,
|
GetDlgItemText (hwnd, LOWORD(wParam), cfg.termspeed,
|
||||||
sizeof(cfg.termspeed)-1);
|
sizeof(cfg.termspeed)-1);
|
||||||
break;
|
break;
|
||||||
case IDC_LOGEDIT:
|
case IDC_LOGEDIT:
|
||||||
@ -1526,6 +1565,11 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
|
|||||||
GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
|
GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
|
||||||
sizeof(cfg.username)-1);
|
sizeof(cfg.username)-1);
|
||||||
break;
|
break;
|
||||||
|
case IDC_RLLUSEREDIT:
|
||||||
|
if (HIWORD(wParam) == EN_CHANGE)
|
||||||
|
GetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername,
|
||||||
|
sizeof(cfg.localusername)-1);
|
||||||
|
break;
|
||||||
case IDC_EMBSD:
|
case IDC_EMBSD:
|
||||||
case IDC_EMRFC:
|
case IDC_EMRFC:
|
||||||
cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
|
cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
|
||||||
|
67
winnet.c
67
winnet.c
@ -288,7 +288,7 @@ void sk_addr_free(SockAddr addr) {
|
|||||||
sfree(addr);
|
sfree(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket sk_new(SockAddr addr, int port, sk_receiver_t receiver) {
|
Socket sk_new(SockAddr addr, int port, int privport, sk_receiver_t receiver) {
|
||||||
SOCKET s;
|
SOCKET s;
|
||||||
#ifdef IPV6
|
#ifdef IPV6
|
||||||
SOCKADDR_IN6 a6;
|
SOCKADDR_IN6 a6;
|
||||||
@ -298,6 +298,7 @@ Socket sk_new(SockAddr addr, int port, sk_receiver_t receiver) {
|
|||||||
char *errstr;
|
char *errstr;
|
||||||
Socket ret;
|
Socket ret;
|
||||||
extern char *do_select(SOCKET skt, int startup);
|
extern char *do_select(SOCKET skt, int startup);
|
||||||
|
short localport;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create Socket structure.
|
* Create Socket structure.
|
||||||
@ -325,28 +326,56 @@ Socket sk_new(SockAddr addr, int port, sk_receiver_t receiver) {
|
|||||||
/*
|
/*
|
||||||
* Bind to local address.
|
* Bind to local address.
|
||||||
*/
|
*/
|
||||||
#ifdef IPV6
|
if (privport)
|
||||||
if (addr->family == AF_INET6)
|
localport = 1023; /* count from 1023 downwards */
|
||||||
{
|
|
||||||
memset(&a6,0,sizeof(a6));
|
|
||||||
a6.sin6_family = AF_INET6;
|
|
||||||
/*a6.sin6_addr = in6addr_any;*/ /* == 0 */
|
|
||||||
a6.sin6_port = htons(0);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
localport = 0; /* just use port 0 (ie winsock picks) */
|
||||||
#endif
|
|
||||||
a.sin_family = AF_INET;
|
/* Loop round trying to bind */
|
||||||
a.sin_addr.s_addr = htonl(INADDR_ANY);
|
while (1) {
|
||||||
a.sin_port = htons(0);
|
int retcode;
|
||||||
|
|
||||||
#ifdef IPV6
|
#ifdef IPV6
|
||||||
}
|
if (addr->family == AF_INET6)
|
||||||
if (bind (s, (addr->family == AF_INET6) ? (struct sockaddr *)&a6 : (struct sockaddr *)&a, (addr->family == AF_INET6) ? sizeof(a6) : sizeof(a)) == SOCKET_ERROR)
|
{
|
||||||
#else
|
memset(&a6,0,sizeof(a6));
|
||||||
if (bind (s, (struct sockaddr *)&a, sizeof(a)) == SOCKET_ERROR)
|
a6.sin6_family = AF_INET6;
|
||||||
|
/*a6.sin6_addr = in6addr_any;*/ /* == 0 */
|
||||||
|
a6.sin6_port = htons(localport);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
#endif
|
#endif
|
||||||
|
a.sin_family = AF_INET;
|
||||||
|
a.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
a.sin_port = htons(localport);
|
||||||
|
#ifdef IPV6
|
||||||
|
}
|
||||||
|
retcode = bind (s, (addr->family == AF_INET6 ?
|
||||||
|
(struct sockaddr *)&a6 :
|
||||||
|
(struct sockaddr *)&a),
|
||||||
|
(addr->family == AF_INET6 ? sizeof(a6) : sizeof(a)));
|
||||||
|
#else
|
||||||
|
retcode = bind (s, (struct sockaddr *)&a, sizeof(a));
|
||||||
|
#endif
|
||||||
|
if (retcode != SOCKET_ERROR) {
|
||||||
|
err = 0;
|
||||||
|
break; /* done */
|
||||||
|
} else {
|
||||||
|
err = WSAGetLastError();
|
||||||
|
if (err != WSAEADDRINUSE) /* failed, for a bad reason */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localport == 0)
|
||||||
|
break; /* we're only looping once */
|
||||||
|
localport--;
|
||||||
|
if (localport == 0)
|
||||||
|
break; /* we might have got to the end */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
{
|
{
|
||||||
err = WSAGetLastError();
|
|
||||||
ret->error = winsock_error_string(err);
|
ret->error = winsock_error_string(err);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user