int console_batch_mode = FALSE;
+/*
+ * Clean up and exit.
+ */
+void cleanup_exit(int code)
+{
+ /*
+ * Clean up.
+ */
+ sk_cleanup();
+ WSACleanup();
+
+ if (cfg.protocol == PROT_SSH) {
+ random_save_seed();
+#ifdef MSCRYPTOAPI
+ crypto_wrapup();
+#endif
+ }
+
+ exit(code);
+}
+
void verify_ssh_host_key(char *host, int port, char *keytype,
char *keystr, char *fingerprint)
{
if (ret == 2) { /* key was different */
if (console_batch_mode) {
fprintf(stderr, wrongmsg_batch, fingerprint);
- exit(1);
+ cleanup_exit(1);
}
fprintf(stderr, wrongmsg, fingerprint);
fflush(stderr);
if (ret == 1) { /* key was absent */
if (console_batch_mode) {
fprintf(stderr, absentmsg_batch, fingerprint);
- exit(1);
+ cleanup_exit(1);
}
fprintf(stderr, absentmsg, fingerprint);
fflush(stderr);
store_host_key(host, port, keytype, keystr);
} else {
fprintf(stderr, abandoned);
- exit(0);
+ cleanup_exit(0);
}
}
(cs == 0) ? "" :
(cs == 1) ? "client-to-server " : "server-to-client ",
ciphername);
- exit(1);
+ cleanup_exit(1);
}
fprintf(stderr, msg,
return;
} else {
fprintf(stderr, abandoned);
- exit(0);
+ cleanup_exit(0);
}
}
hout = GetStdHandle(STD_OUTPUT_HANDLE);
if (hin == INVALID_HANDLE_VALUE || hout == INVALID_HANDLE_VALUE) {
fprintf(stderr, "Cannot get standard input/output handles\n");
- exit(1);
+ cleanup_exit(1);
}
GetConsoleMode(hin, &savemode);
#endif
MessageBox(NULL, str, "PuTTY Fatal Error",
MB_SYSTEMMODAL | MB_ICONERROR | MB_OK);
- exit(1);
+ cleanup_exit(1);
}
#ifdef MALLOC_LOG
if (fp)
#endif
MessageBox(NULL, str, "PuTTY Fatal Error",
MB_SYSTEMMODAL | MB_ICONERROR | MB_OK);
- exit(1);
+ cleanup_exit(1);
}
#ifdef MALLOC_LOG
if (fp)
void sk_init(void); /* called once at program startup */
+void sk_cleanup(void); /* called just before program exit */
SockAddr sk_namelookup(char *host, char **canonicalname);
void sk_getaddr(SockAddr addr, char *buf, int buflen);
int len;
void *data;
- random_get_savedata(&data, &len);
- write_random_seed(data, len);
+ if (random_active) {
+ random_get_savedata(&data, &len);
+ write_random_seed(data, len);
+ }
}
/*
}
}
+void cleanup_exit(int code) { exit(code); }
+
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
{
WNDCLASS wndclass;
va_end(ap);
fputc('\n', stderr);
WSACleanup();
- exit(1);
+ cleanup_exit(1);
}
void connection_fatal(char *p, ...)
{
va_end(ap);
fputc('\n', stderr);
WSACleanup();
- exit(1);
+ cleanup_exit(1);
}
static char *password = NULL;
if (!CreateThread(NULL, 0, stdout_write_thread,
&odata, 0, &out_threadid)) {
fprintf(stderr, "Unable to create output thread\n");
- exit(1);
+ cleanup_exit(1);
}
edata.event = stderrevent;
edata.eventback = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!CreateThread(NULL, 0, stdout_write_thread,
&edata, 0, &err_threadid)) {
fprintf(stderr, "Unable to create error output thread\n");
- exit(1);
+ cleanup_exit(1);
}
while (1) {
if (!CreateThread(NULL, 0, stdin_read_thread,
&idata, 0, &in_threadid)) {
fprintf(stderr, "Unable to create input thread\n");
- exit(1);
+ cleanup_exit(1);
}
sending = TRUE;
}
odata.busy = 0;
if (!odata.writeret) {
fprintf(stderr, "Unable to write to standard output\n");
- exit(0);
+ cleanup_exit(0);
}
bufchain_consume(&stdout_data, odata.lenwritten);
if (bufchain_size(&stdout_data) > 0)
edata.busy = 0;
if (!edata.writeret) {
fprintf(stderr, "Unable to write to standard output\n");
- exit(0);
+ cleanup_exit(0);
}
bufchain_consume(&stderr_data, edata.lenwritten);
if (bufchain_size(&stderr_data) > 0)
strcat(str, "\n");
fputs(str, stderr);
- exit(1);
+ cleanup_exit(1);
}
void connection_fatal(char *fmt, ...)
{
strcat(str, "\n");
fputs(str, stderr);
- exit(1);
+ cleanup_exit(1);
}
void ldisc_send(char *buf, int len, int interactive)
winsock_ver = MAKEWORD(1, 1);
if (WSAStartup(winsock_ver, &wsadata)) {
fprintf(stderr, "Unable to initialise WinSock");
- exit(1);
+ cleanup_exit(1);
}
if (LOBYTE(wsadata.wVersion) != 1 || HIBYTE(wsadata.wVersion) != 1) {
fprintf(stderr, "WinSock version is incompatible with 1.1");
- exit(1);
+ cleanup_exit(1);
}
}
printf(" -v show verbose messages\n");
printf(" -P port connect to specified port\n");
printf(" -pw passw login with specified password\n");
- exit(1);
+ cleanup_exit(1);
}
/*
printf("login as: ");
if (!fgets(cfg.username, sizeof(cfg.username), stdin)) {
fprintf(stderr, "psftp: aborting\n");
- exit(1);
+ cleanup_exit(1);
} else {
int len = strlen(cfg.username);
if (cfg.username[len - 1] == '\n')
void get_window_pixels(int *x, int *y);
char *get_window_title(int icon);
+void cleanup_exit(int);
+
/*
* Exports from noise.c.
*/
void random_init(void);
int random_byte(void);
void random_get_savedata(void **data, int *len);
+extern int random_active;
/*
* Exports from misc.c.
return 0;
}
+void cleanup_exit(int code) { exit(code); }
+
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
{
InitCommonControls();
0 /*lParam */ ))SleepEx(1000, TRUE);
}
- exit(1);
+ cleanup_exit(1);
}
void connection_fatal(char *fmt, ...)
{
0 /*lParam */ ))SleepEx(1000, TRUE);
}
- exit(1);
+ cleanup_exit(1);
}
/*
0 /*lParam */ ))SleepEx(1000, TRUE);
}
- exit(1);
+ cleanup_exit(1);
}
/*
printf
(" -gui hWnd GUI mode with the windows handle for receiving messages\n");
#endif
- exit(1);
+ cleanup_exit(1);
}
/*
break;
case 3:
case 4:
- random_save_seed();
- exit(0);
+ cleanup_exit(0);
break;
default:
if (((c >= ' ' && c <= '~') ||
break;
case 3:
case 4:
- random_save_seed();
- exit(0);
+ cleanup_exit(0);
break;
default:
if (pos < sizeof(password)-1)
break;
case 3:
case 4:
- random_save_seed();
- exit(0);
+ cleanup_exit(0);
break;
default:
if (((c >= ' ' && c <= '~') ||
break;
case 3:
case 4:
- random_save_seed();
- exit(0);
+ cleanup_exit(0);
break;
default:
if (pos < sizeof(password)-1)
};
static struct RandPool pool;
-static int random_active = 0;
+int random_active = 0;
void random_stir(void)
{
if (mbret == IDYES)
store_host_key(host, port, keytype, keystr);
if (mbret == IDCANCEL)
- exit(0);
+ cleanup_exit(0);
}
if (ret == 1) { /* key was absent */
int mbret;
if (mbret == IDYES)
store_host_key(host, port, keytype, keystr);
if (mbret == IDCANCEL)
- exit(0);
+ cleanup_exit(0);
}
}
if (mbret == IDYES)
return;
else
- exit(0);
+ cleanup_exit(0);
}
/*
static int compose_state = 0;
+static int wsa_started = 0;
+
static OSVERSIONINFO osVersion;
static UINT wm_mousewheel = WM_MOUSEWHEEL;
WSACleanup();
return 1;
}
+ wsa_started = 1;
/* WISHLIST: maybe allow config tweaking even if winsock not present? */
sk_init();
}
}
+ cleanup_exit(msg.wParam);
+}
+
+/*
+ * Clean up and exit.
+ */
+void cleanup_exit(int code)
+{
/*
* Clean up.
*/
sfree(logpal);
if (pal)
DeleteObject(pal);
- WSACleanup();
+ sk_cleanup();
+ if (wsa_started)
+ WSACleanup();
if (cfg.protocol == PROT_SSH) {
random_save_seed();
#endif
}
- return msg.wParam;
+ exit(code);
}
/*
vsprintf(stuff, fmt, ap);
va_end(ap);
MessageBox(hwnd, stuff, "PuTTY Fatal Error", MB_ICONERROR | MB_OK);
- exit(1);
+ cleanup_exit(1);
}
/*
sktree = newtree234(cmpfortree);
}
+void sk_cleanup(void)
+{
+ Actual_Socket s;
+ int i;
+
+ if (sktree) {
+ for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
+ closesocket(s->s);
+ }
+ }
+}
+
char *winsock_error_string(int error)
{
switch (error) {