mirror of https://github.com/cy384/ssheven.git
initial libvterm integration
This commit is contained in:
parent
c29c1a2935
commit
1351b96ca7
|
@ -10,11 +10,11 @@ IF(CMAKE_SYSTEM_NAME MATCHES Retro68)
|
||||||
#add_compile_options(-mcpu=68020)
|
#add_compile_options(-mcpu=68020)
|
||||||
#add_compile_options(-O2 -flto)
|
#add_compile_options(-O2 -flto)
|
||||||
set_target_properties(ssheven PROPERTIES LINK_FLAGS "-Wl,-gc-sections -Wl,--mac-segments -Wl,${CMAKE_CURRENT_SOURCE_DIR}/ssheven.segmap")
|
set_target_properties(ssheven PROPERTIES LINK_FLAGS "-Wl,-gc-sections -Wl,--mac-segments -Wl,${CMAKE_CURRENT_SOURCE_DIR}/ssheven.segmap")
|
||||||
target_link_libraries(ssheven ssh2 mbedtls mbedx509 mbedcrypto OpenTransportApp OpenTransport OpenTptInet)
|
target_link_libraries(ssheven ssh2 mbedtls mbedx509 mbedcrypto OpenTransportApp OpenTransport OpenTptInet vterm)
|
||||||
ELSE()
|
ELSE()
|
||||||
# for PPC
|
# for PPC
|
||||||
add_compile_options(-O2 -flto)
|
add_compile_options(-O2 -flto)
|
||||||
set_target_properties(ssheven PROPERTIES LINK_FLAGS "-Wl,-gc-sections")
|
set_target_properties(ssheven PROPERTIES LINK_FLAGS "-Wl,-gc-sections")
|
||||||
target_link_libraries(ssheven ThreadsLib ssh2 mbedtls mbedx509 mbedcrypto OpenTransportAppPPC OpenTransportLib OpenTptInternetLib)
|
target_link_libraries(ssheven ThreadsLib ssh2 mbedtls mbedx509 mbedcrypto OpenTransportAppPPC OpenTransportLib OpenTptInternetLib vterm)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|
12
README.md
12
README.md
|
@ -4,13 +4,13 @@ ssheven
|
||||||
-------
|
-------
|
||||||
A modern SSH client for Mac OS 7/8/9.
|
A modern SSH client for Mac OS 7/8/9.
|
||||||
|
|
||||||
Project status: as of 0.3.0 (see github releases), an actual SSH client with a zero-features "vanilla" fixed-size terminal
|
Project status: as of 0.4.0 (see github releases), an actual SSH client with a fixed-size terminal, good enough to run `top`.
|
||||||
|
|
||||||
![ssheven screenshot](http://www.cy384.com/media/img/ssheven-screenshot.png)
|
![ssheven screenshot](http://www.cy384.com/media/img/ssheven-screenshot.png)
|
||||||
|
|
||||||
system requirements
|
system requirements
|
||||||
-------------------
|
-------------------
|
||||||
* CPU: Any PPC processor. Maybe a 33 or 40 MHz 68040 (or 68LC040). 68030 is too slow (for now).
|
* CPU: Any PPC processor, or a 33 MHz 68040 (maybe a 68LC040, maybe 25 MHz).
|
||||||
* RAM: 2MB
|
* RAM: 2MB
|
||||||
* Disk space: 1MB for the fat binary
|
* Disk space: 1MB for the fat binary
|
||||||
* System 7.5 recommended, earlier System 7 versions possible with the Thread Manager extension installed
|
* System 7.5 recommended, earlier System 7 versions possible with the Thread Manager extension installed
|
||||||
|
@ -18,7 +18,9 @@ system requirements
|
||||||
|
|
||||||
to do
|
to do
|
||||||
-----
|
-----
|
||||||
* escape codes and related console emulation features (via libvterm)
|
* hook in more libvterm callbacks (output, termprops)
|
||||||
|
* feed keyboard input to libvterm (esp. for arrow keys)
|
||||||
|
* bold/underline/italic in character drawing code
|
||||||
* refactor libssh2 usage to handle errors and centralize network ops
|
* refactor libssh2 usage to handle errors and centralize network ops
|
||||||
* terminal window resizing
|
* terminal window resizing
|
||||||
* nicer connection dialog
|
* nicer connection dialog
|
||||||
|
@ -28,9 +30,9 @@ to do
|
||||||
* key authentication
|
* key authentication
|
||||||
* check server keys/known hosts/keys
|
* check server keys/known hosts/keys
|
||||||
* text selection + copy
|
* text selection + copy
|
||||||
* improve 68k performance (rewrite `mbedtls_mpi_exp_mod` in assembly)
|
* figure out retro68 mcpu issue, improve 68k performance (rewrite `mbedtls_mpi_exp_mod` in assembly)
|
||||||
* font size options
|
* font size options
|
||||||
* color/bold/underline/italic etc. fancy console features
|
* color
|
||||||
|
|
||||||
build
|
build
|
||||||
-----
|
-----
|
||||||
|
|
|
@ -55,11 +55,15 @@ void draw_screen(Rect* r)
|
||||||
TextSize(9);
|
TextSize(9);
|
||||||
TextFace(normal);
|
TextFace(normal);
|
||||||
|
|
||||||
|
VTermScreenCell vtsc;
|
||||||
|
|
||||||
for(int i = minRow; i < maxRow; i++)
|
for(int i = minRow; i < maxRow; i++)
|
||||||
{
|
{
|
||||||
for (int j = minCol; j < maxCol; j++)
|
for (int j = minCol; j < maxCol; j++)
|
||||||
{
|
{
|
||||||
draw_char(j, i, r, con.data[j][i]);
|
vterm_screen_get_cell(con.vts, (VTermPos){.row = i, .col = j}, &vtsc);
|
||||||
|
char c = (char)vtsc.chars[0];
|
||||||
|
draw_char(j, i, r, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,89 +92,11 @@ void ruler(Rect* r)
|
||||||
draw_char(x, y, r, itoc[x%10]);
|
draw_char(x, y, r, itoc[x%10]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bump_up_line()
|
|
||||||
{
|
|
||||||
for (int y = 0; y < 23; y++)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < 80; x++)
|
|
||||||
{
|
|
||||||
con.data[x][y] = con.data[x][y+1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int x = 0; x < 80; x++) con.data[x][23] = ' ';
|
|
||||||
|
|
||||||
InvalRect(&(con.win->portRect));
|
|
||||||
}
|
|
||||||
|
|
||||||
int is_printable(char c)
|
int is_printable(char c)
|
||||||
{
|
{
|
||||||
if (c >= 32 && c <= 126) return 1; else return 0;
|
if (c >= 32 && c <= 126) return 1; else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_char(char c)
|
|
||||||
{
|
|
||||||
if (con.cursor_state == 1)
|
|
||||||
{
|
|
||||||
con.cursor_state = 0;
|
|
||||||
Rect cursor = cell_rect(con.cursor_x, con.cursor_y, con.win->portRect);
|
|
||||||
//InvertRect(&cursor);
|
|
||||||
InvalRect(&cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// backspace
|
|
||||||
if ('\b' == c)
|
|
||||||
{
|
|
||||||
// erase current location
|
|
||||||
con.data[con.cursor_x][con.cursor_y] = ' ';
|
|
||||||
Rect inval = cell_rect(con.cursor_x, con.cursor_y, (con.win->portRect));
|
|
||||||
InvalRect(&inval);
|
|
||||||
|
|
||||||
// wrap back to the previous line if possible and necessary
|
|
||||||
if (con.cursor_x == 0 && con.cursor_y != 0)
|
|
||||||
{
|
|
||||||
con.cursor_x = 79;
|
|
||||||
con.cursor_y--;
|
|
||||||
}
|
|
||||||
// otherwise just move back a spot
|
|
||||||
else if (con.cursor_x > 0)
|
|
||||||
{
|
|
||||||
con.cursor_x--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// got a bell, give em a system beep (value of 30 recommended by docs)
|
|
||||||
if ('\a' == c) SysBeep(30);
|
|
||||||
|
|
||||||
if ('\n' == c)
|
|
||||||
{
|
|
||||||
con.cursor_y++;
|
|
||||||
con.cursor_x = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_printable(c))
|
|
||||||
{
|
|
||||||
con.data[con.cursor_x][con.cursor_y] = c;
|
|
||||||
Rect inval = cell_rect(con.cursor_x, con.cursor_y, (con.win->portRect));
|
|
||||||
InvalRect(&inval);
|
|
||||||
con.cursor_x++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (con.cursor_x == 80)
|
|
||||||
{
|
|
||||||
con.cursor_x = 0;
|
|
||||||
con.cursor_y++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (con.cursor_y == 24)
|
|
||||||
{
|
|
||||||
bump_up_line();
|
|
||||||
con.cursor_y = 23;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_int(int d)
|
void print_int(int d)
|
||||||
{
|
{
|
||||||
char itoc[] = {'0','1','2','3','4','5','6','7','8','9'};
|
char itoc[] = {'0','1','2','3','4','5','6','7','8','9'};
|
||||||
|
@ -204,10 +130,7 @@ void print_int(int d)
|
||||||
|
|
||||||
void print_string(const char* c)
|
void print_string(const char* c)
|
||||||
{
|
{
|
||||||
while (*c != '\0')
|
vterm_input_write(con.vterm, c, strlen(c));
|
||||||
{
|
|
||||||
print_char(*c++);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void printf_i(const char* str, ...)
|
void printf_i(const char* str, ...)
|
||||||
|
@ -227,16 +150,19 @@ void printf_i(const char* str, ...)
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
print_string(va_arg(args, char*));
|
print_string(va_arg(args, char*));
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
vterm_input_write(con.vterm, str-1, 1);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
va_arg(args, int); // ignore
|
va_arg(args, int); // ignore
|
||||||
print_char('%');
|
vterm_input_write(con.vterm, str-1, 2);
|
||||||
print_char(*str);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
print_char(*str);
|
vterm_input_write(con.vterm, str, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
str++;
|
str++;
|
||||||
|
@ -254,6 +180,58 @@ void set_window_title(WindowPtr w, const char* c_name)
|
||||||
SetWTitle(w, pascal_name);
|
SetWTitle(w, pascal_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bell(void* user)
|
||||||
|
{
|
||||||
|
SysBeep(30);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user)
|
||||||
|
{
|
||||||
|
// if the cursor is dark, invalidate that location
|
||||||
|
if (con.cursor_state == 1)
|
||||||
|
{
|
||||||
|
Rect inval = cell_rect(con.cursor_x, con.cursor_y, (con.win->portRect));
|
||||||
|
InvalRect(&inval);
|
||||||
|
}
|
||||||
|
|
||||||
|
con.cursor_x = pos.col;
|
||||||
|
con.cursor_y = pos.row;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect cell_rect(int x, int y, Rect bounds)
|
||||||
|
{
|
||||||
|
Rect r = { (short) (bounds.top + y * con.cell_height), (short) (bounds.left + x * con.cell_width + 2),
|
||||||
|
(short) (bounds.top + (y+1) * con.cell_height), (short) (bounds.left + (x+1) * con.cell_width + 2) };
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int damage(VTermRect rect, void *user)
|
||||||
|
{
|
||||||
|
Rect topleft = cell_rect(rect.start_col, rect.start_row, (con.win->portRect));
|
||||||
|
Rect bottomright = cell_rect(rect.end_col, rect.end_row, (con.win->portRect));
|
||||||
|
|
||||||
|
UnionRect(&topleft, &bottomright, &topleft);
|
||||||
|
InvalRect(&topleft);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const VTermScreenCallbacks vtscrcb =
|
||||||
|
{
|
||||||
|
.damage = damage,
|
||||||
|
.moverect = NULL,
|
||||||
|
.movecursor = movecursor,
|
||||||
|
.settermprop = NULL,
|
||||||
|
.bell = bell,
|
||||||
|
.resize = NULL,
|
||||||
|
.sb_pushline = NULL,
|
||||||
|
.sb_popline = NULL
|
||||||
|
};
|
||||||
|
|
||||||
void console_setup(void)
|
void console_setup(void)
|
||||||
{
|
{
|
||||||
|
@ -303,12 +281,14 @@ void console_setup(void)
|
||||||
|
|
||||||
con.cursor_x = 0;
|
con.cursor_x = 0;
|
||||||
con.cursor_y = 0;
|
con.cursor_y = 0;
|
||||||
|
|
||||||
|
con.vterm = vterm_new(24, 80);
|
||||||
|
vterm_set_utf8(con.vterm, 0);
|
||||||
|
VTermState* vtermstate = vterm_obtain_state(con.vterm);
|
||||||
|
vterm_state_reset(vtermstate, 1);
|
||||||
|
|
||||||
|
con.vts = vterm_obtain_screen(con.vterm);
|
||||||
|
vterm_screen_reset(con.vts, 1);
|
||||||
|
vterm_screen_set_callbacks(con.vts, &vtscrcb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect cell_rect(int x, int y, Rect bounds)
|
|
||||||
{
|
|
||||||
Rect r = { (short) (bounds.top + y * con.cell_height), (short) (bounds.left + x * con.cell_width + 2),
|
|
||||||
(short) (bounds.top + (y+1) * con.cell_height), (short) (bounds.left + (x+1) * con.cell_width + 2) };
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
#define SSHEVEN_BUFFER_SIZE 4096
|
#define SSHEVEN_BUFFER_SIZE 4096
|
||||||
|
|
||||||
/* terminal type to send over ssh, determines features etc.
|
/* terminal type to send over ssh, determines features etc.
|
||||||
* "vanilla" supports basically nothing, which is good for us here */
|
* "vanilla" supports basically nothing, "vt100" as per the... vt100 */
|
||||||
#define SSHEVEN_TERMINAL_TYPE "vanilla"
|
#define SSHEVEN_TERMINAL_TYPE "vt100"
|
||||||
|
|
||||||
/* dialog for getting connection info */
|
/* dialog for getting connection info */
|
||||||
#define DLOG_CONNECT 128
|
#define DLOG_CONNECT 128
|
||||||
|
|
89
ssheven.c
89
ssheven.c
|
@ -12,11 +12,11 @@
|
||||||
#include "ssheven-debug.c"
|
#include "ssheven-debug.c"
|
||||||
|
|
||||||
// error checking convenience macros
|
// error checking convenience macros
|
||||||
#define OT_CHECK(X) err = (X); if (err != noErr) { printf_i("" #X " failed\n"); return 0; };
|
#define OT_CHECK(X) err = (X); if (err != noErr) { printf_i("" #X " failed\r\n"); return 0; };
|
||||||
#define SSH_CHECK(X) rc = (X); if (rc != LIBSSH2_ERROR_NONE) { printf_i("" #X " failed: %s\n", libssh2_error_string(rc)); return 0;};
|
#define SSH_CHECK(X) rc = (X); if (rc != LIBSSH2_ERROR_NONE) { printf_i("" #X " failed: %s\r\n", libssh2_error_string(rc)); return 0;};
|
||||||
|
|
||||||
// sinful globals
|
// sinful globals
|
||||||
struct ssheven_console con = { NULL, {0}, 0, 0, 0, 0, 0, 0};
|
struct ssheven_console con = { NULL, {0}, 0, 0, 0, 0, 0, 0, NULL};
|
||||||
struct ssheven_ssh_connection ssh_con = { NULL, NULL, kOTInvalidEndpointRef, NULL, NULL };
|
struct ssheven_ssh_connection ssh_con = { NULL, NULL, kOTInvalidEndpointRef, NULL, NULL };
|
||||||
|
|
||||||
enum { WAIT, READ, EXIT } read_thread_command = WAIT;
|
enum { WAIT, READ, EXIT } read_thread_command = WAIT;
|
||||||
|
@ -57,17 +57,18 @@ static pascal void yield_notifier(void* contextPtr, OTEventCode code, OTResult r
|
||||||
// read from the channel and print to console
|
// read from the channel and print to console
|
||||||
void ssh_read(void)
|
void ssh_read(void)
|
||||||
{
|
{
|
||||||
int rc = libssh2_channel_read(ssh_con.channel, ssh_con.recv_buffer, SSHEVEN_BUFFER_SIZE);
|
size_t rc = libssh2_channel_read(ssh_con.channel, ssh_con.recv_buffer, SSHEVEN_BUFFER_SIZE);
|
||||||
|
|
||||||
if (rc == 0) return;
|
if (rc == 0) return;
|
||||||
|
|
||||||
if (rc > 0)
|
if (rc <= 0)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < rc; ++i) print_char(ssh_con.recv_buffer[i]);
|
printf_i("channel read error: %s\r\n", libssh2_error_string(rc));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
while (rc > 0)
|
||||||
{
|
{
|
||||||
printf_i("channel read error: %s\n", libssh2_error_string(rc));
|
rc -= vterm_input_write(con.vterm, ssh_con.recv_buffer, rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,16 +120,16 @@ int end_connection(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf_i("unexpected OTLook result while closing: %s\n", OT_event_string(result));
|
printf_i("unexpected OTLook result while closing: %s\r\n", OT_event_string(result));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// release endpoint
|
// release endpoint
|
||||||
err = OTUnbind(ssh_con.endpoint);
|
err = OTUnbind(ssh_con.endpoint);
|
||||||
if (err != noErr) printf_i("OTUnbind failed\n");
|
if (err != noErr) printf_i("OTUnbind failed\r\n");
|
||||||
|
|
||||||
err = OTCloseProvider(ssh_con.endpoint);
|
err = OTCloseProvider(ssh_con.endpoint);
|
||||||
if (err != noErr) printf_i("OTCloseProvider failed\n");
|
if (err != noErr) printf_i("OTCloseProvider failed\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
read_thread_state = DONE;
|
read_thread_state = DONE;
|
||||||
|
@ -198,8 +199,8 @@ void ssh_write(char* buf, int len)
|
||||||
int r = libssh2_channel_write(ssh_con.channel, buf, len);
|
int r = libssh2_channel_write(ssh_con.channel, buf, len);
|
||||||
if (r < 1)
|
if (r < 1)
|
||||||
{
|
{
|
||||||
printf_i("failed to write to channel!\n");
|
printf_i("failed to write to channel!\r\n");
|
||||||
printf_i("closing connection!\n");
|
printf_i("closing connection!\r\n");
|
||||||
read_thread_command = EXIT;
|
read_thread_command = EXIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,7 +384,7 @@ int init_connection(char* hostname)
|
||||||
|
|
||||||
if (err != noErr || ssh_con.endpoint == kOTInvalidEndpointRef)
|
if (err != noErr || ssh_con.endpoint == kOTInvalidEndpointRef)
|
||||||
{
|
{
|
||||||
printf_i("failed to open OT TCP endpoint\n");
|
printf_i("failed to open OT TCP endpoint\r\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +397,7 @@ int init_connection(char* hostname)
|
||||||
|
|
||||||
OT_CHECK(OTSetNonBlocking(ssh_con.endpoint));
|
OT_CHECK(OTSetNonBlocking(ssh_con.endpoint));
|
||||||
|
|
||||||
printf_i("done.\n"); YieldToAnyThread();
|
printf_i("done.\r\n"); YieldToAnyThread();
|
||||||
|
|
||||||
// set up address struct, do the DNS lookup, and connect
|
// set up address struct, do the DNS lookup, and connect
|
||||||
OTMemzero(&sndCall, sizeof(TCall));
|
OTMemzero(&sndCall, sizeof(TCall));
|
||||||
|
@ -407,28 +408,28 @@ int init_connection(char* hostname)
|
||||||
printf_i("connecting endpoint... "); YieldToAnyThread();
|
printf_i("connecting endpoint... "); YieldToAnyThread();
|
||||||
OT_CHECK(OTConnect(ssh_con.endpoint, &sndCall, nil));
|
OT_CHECK(OTConnect(ssh_con.endpoint, &sndCall, nil));
|
||||||
|
|
||||||
printf_i("done.\n"); YieldToAnyThread();
|
printf_i("done.\r\n"); YieldToAnyThread();
|
||||||
|
|
||||||
printf_i("initializing SSH... "); YieldToAnyThread();
|
printf_i("initializing SSH... "); YieldToAnyThread();
|
||||||
// init libssh2
|
// init libssh2
|
||||||
SSH_CHECK(libssh2_init(0));
|
SSH_CHECK(libssh2_init(0));
|
||||||
|
|
||||||
printf_i("done.\n"); YieldToAnyThread();
|
printf_i("done.\r\n"); YieldToAnyThread();
|
||||||
|
|
||||||
printf_i("opening SSH session... "); YieldToAnyThread();
|
printf_i("opening SSH session... "); YieldToAnyThread();
|
||||||
ssh_con.session = libssh2_session_init();
|
ssh_con.session = libssh2_session_init();
|
||||||
if (ssh_con.session == 0)
|
if (ssh_con.session == 0)
|
||||||
{
|
{
|
||||||
printf_i("failed to initialize SSH library\n");
|
printf_i("failed to initialize SSH library\r\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
printf_i("done.\n"); YieldToAnyThread();
|
printf_i("done.\r\n"); YieldToAnyThread();
|
||||||
|
|
||||||
long s = TickCount();
|
long s = TickCount();
|
||||||
printf_i("beginning SSH session handshake... "); YieldToAnyThread();
|
printf_i("beginning SSH session handshake... "); YieldToAnyThread();
|
||||||
SSH_CHECK(libssh2_session_handshake(ssh_con.session, ssh_con.endpoint));
|
SSH_CHECK(libssh2_session_handshake(ssh_con.session, ssh_con.endpoint));
|
||||||
|
|
||||||
printf_i("done. (%d ticks)\n", TickCount() - s); YieldToAnyThread();
|
printf_i("done. (%d ticks)\r\n", TickCount() - s); YieldToAnyThread();
|
||||||
|
|
||||||
read_thread_state = OPEN;
|
read_thread_state = OPEN;
|
||||||
|
|
||||||
|
@ -532,7 +533,7 @@ void* read_thread(void* arg)
|
||||||
{
|
{
|
||||||
printf_i("authenticating... "); YieldToAnyThread();
|
printf_i("authenticating... "); YieldToAnyThread();
|
||||||
ok = ssh_password_auth(username+1, password+1);
|
ok = ssh_password_auth(username+1, password+1);
|
||||||
printf_i("done.\n"); YieldToAnyThread();
|
printf_i("done.\r\n"); YieldToAnyThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
|
@ -565,7 +566,7 @@ void* read_thread(void* arg)
|
||||||
|
|
||||||
int safety_checks(void)
|
int safety_checks(void)
|
||||||
{
|
{
|
||||||
OSStatus err;
|
OSStatus err = noErr;
|
||||||
|
|
||||||
// check for thread manager
|
// check for thread manager
|
||||||
long int thread_manager_gestalt = 0;
|
long int thread_manager_gestalt = 0;
|
||||||
|
@ -575,7 +576,7 @@ int safety_checks(void)
|
||||||
if (err != noErr || (thread_manager_gestalt & (1 << gestaltThreadMgrPresent)) == 0)
|
if (err != noErr || (thread_manager_gestalt & (1 << gestaltThreadMgrPresent)) == 0)
|
||||||
{
|
{
|
||||||
StopAlert(ALRT_TM, nil);
|
StopAlert(ALRT_TM, nil);
|
||||||
printf_i("Thread Manager not available!\n");
|
printf_i("Thread Manager not available!\r\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,7 +592,7 @@ int safety_checks(void)
|
||||||
|
|
||||||
if (err != noErr)
|
if (err != noErr)
|
||||||
{
|
{
|
||||||
printf_i("Failed to check for Open Transport!\n");
|
printf_i("Failed to check for Open Transport!\r\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,13 +600,13 @@ int safety_checks(void)
|
||||||
|
|
||||||
if (err != noErr)
|
if (err != noErr)
|
||||||
{
|
{
|
||||||
printf_i("Failed to check for Open Transport!\n");
|
printf_i("Failed to check for Open Transport!\r\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open_transport_any_version == 0 && open_transport_new_version == 0)
|
if (open_transport_any_version == 0 && open_transport_new_version == 0)
|
||||||
{
|
{
|
||||||
printf_i("Open Transport required but not found!\n");
|
printf_i("Open Transport required but not found!\r\n");
|
||||||
StopAlert(ALRT_OT, nil);
|
StopAlert(ALRT_OT, nil);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -613,12 +614,12 @@ int safety_checks(void)
|
||||||
if (open_transport_any_version != 0 && open_transport_new_version == 0)
|
if (open_transport_any_version != 0 && open_transport_new_version == 0)
|
||||||
{
|
{
|
||||||
printf_i("Early version of Open Transport detected!");
|
printf_i("Early version of Open Transport detected!");
|
||||||
printf_i(" Attempting to continue anyway.\n");
|
printf_i(" Attempting to continue anyway.\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
NumVersion* ot_version = (NumVersion*) &open_transport_new_version;
|
NumVersion* ot_version = (NumVersion*) &open_transport_new_version;
|
||||||
|
|
||||||
printf_i("Detected Open Transport version: %d.%d.%d\n",
|
printf_i("Detected Open Transport version: %d.%d.%d\r\n",
|
||||||
(int)ot_version->majorRev,
|
(int)ot_version->majorRev,
|
||||||
(int)((ot_version->minorAndBugRev & 0xF0) >> 4),
|
(int)((ot_version->minorAndBugRev & 0xF0) >> 4),
|
||||||
(int)(ot_version->minorAndBugRev & 0x0F));
|
(int)(ot_version->minorAndBugRev & 0x0F));
|
||||||
|
@ -635,7 +636,7 @@ int safety_checks(void)
|
||||||
if (err != noErr || cpu_type == 0)
|
if (err != noErr || cpu_type == 0)
|
||||||
{
|
{
|
||||||
cpu_slow = 1;
|
cpu_slow = 1;
|
||||||
printf_i("Failed to detect CPU type, continuing anyway.\n");
|
printf_i("Failed to detect CPU type, continuing anyway.\r\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -702,15 +703,21 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
console_setup();
|
console_setup();
|
||||||
|
|
||||||
char* logo = " _____ _____ _ _\n"
|
char* logo = " _____ _____ _ _\r\n"
|
||||||
" / ____/ ____| | | |\n"
|
" / ____/ ____| | | |\r\n"
|
||||||
" | (___| (___ | |__| | _____ _____ _ __\n"
|
" | (___| (___ | |__| | _____ _____ _ __\r\n"
|
||||||
" \\___ \\\\___ \\| __ |/ _ \\ \\ / / _ \\ '_ \\\n"
|
" \\___ \\\\___ \\| __ |/ _ \\ \\ / / _ \\ '_ \\\r\n"
|
||||||
" ____) |___) | | | | __/\\ V / __/ | | |\n"
|
" ____) |___) | | | | __/\\ V / __/ | | |\r\n"
|
||||||
" |_____/_____/|_| |_|\\___| \\_/ \\___|_| |_|\n";
|
" |_____/_____/|_| |_|\\___| \\_/ \\___|_| |_|]\r\n";
|
||||||
|
|
||||||
printf_i(logo);
|
printf_i(logo);
|
||||||
printf_i("by cy384, version " SSHEVEN_VERSION "\n");
|
printf_i("by cy384, version " SSHEVEN_VERSION "\r\n");
|
||||||
|
|
||||||
|
#if defined(__ppc__)
|
||||||
|
printf_i("Running in PPC mode.\r\n");
|
||||||
|
#else
|
||||||
|
printf_i("Running in 68k mode.\r\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
BeginUpdate(con.win);
|
BeginUpdate(con.win);
|
||||||
draw_screen(&(con.win->portRect));
|
draw_screen(&(con.win->portRect));
|
||||||
|
@ -725,13 +732,13 @@ int main(int argc, char** argv)
|
||||||
EndUpdate(con.win);
|
EndUpdate(con.win);
|
||||||
|
|
||||||
if (!intro_dialog(hostname, username, password)) ok = 0;
|
if (!intro_dialog(hostname, username, password)) ok = 0;
|
||||||
if (!ok) printf_i("Cancelled, not connecting.\n");
|
if (!ok) printf_i("Cancelled, not connecting.\r\n");
|
||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
if (InitOpenTransport() != noErr)
|
if (InitOpenTransport() != noErr)
|
||||||
{
|
{
|
||||||
printf_i("failed to initialize OT\n");
|
printf_i("failed to initialize OT\r\n");
|
||||||
ok = 0;
|
ok = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -743,7 +750,7 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
if (ssh_con.recv_buffer == NULL || ssh_con.send_buffer == NULL)
|
if (ssh_con.recv_buffer == NULL || ssh_con.send_buffer == NULL)
|
||||||
{
|
{
|
||||||
printf_i("failed to allocate network buffers\n");
|
printf_i("failed to allocate network buffers\r\n");
|
||||||
ok = 0;
|
ok = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -760,7 +767,7 @@ int main(int argc, char** argv)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
{
|
{
|
||||||
ok = 0;
|
ok = 0;
|
||||||
printf_i("failed to create network read thread\n");
|
printf_i("failed to create network read thread\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -788,6 +795,8 @@ int main(int argc, char** argv)
|
||||||
if (ssh_con.recv_buffer != NULL) OTFreeMem(ssh_con.recv_buffer);
|
if (ssh_con.recv_buffer != NULL) OTFreeMem(ssh_con.recv_buffer);
|
||||||
if (ssh_con.send_buffer != NULL) OTFreeMem(ssh_con.send_buffer);
|
if (ssh_con.send_buffer != NULL) OTFreeMem(ssh_con.send_buffer);
|
||||||
|
|
||||||
|
if (con.vterm != NULL) vterm_free(con.vterm);
|
||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
err = OTCancelSynchronousCalls(ssh_con.endpoint, kOTCanceledErr);
|
err = OTCancelSynchronousCalls(ssh_con.endpoint, kOTCanceledErr);
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
// ssheven constants
|
// ssheven constants
|
||||||
#include "ssheven-constants.r"
|
#include "ssheven-constants.r"
|
||||||
|
|
||||||
|
#include <vterm.h>
|
||||||
|
#include <vterm_keycodes.h>
|
||||||
|
|
||||||
// sinful globals
|
// sinful globals
|
||||||
struct ssheven_console
|
struct ssheven_console
|
||||||
{
|
{
|
||||||
|
@ -43,6 +46,9 @@ struct ssheven_console
|
||||||
|
|
||||||
int cursor_state;
|
int cursor_state;
|
||||||
long int last_cursor_blink;
|
long int last_cursor_blink;
|
||||||
|
|
||||||
|
VTerm* vterm;
|
||||||
|
VTermScreen* vts;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct ssheven_console con;
|
extern struct ssheven_console con;
|
||||||
|
|
Loading…
Reference in New Issue