mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-03-22 06:38:37 -05:00
Next phase of general SFTP reworking: psftp.c is now a platform-
independent source file. All Windowsisms have been moved out to winsftp.c. [originally from svn r3418]
This commit is contained in:
parent
40dc8b940c
commit
e0801815c8
4
Recipe
4
Recipe
@ -140,7 +140,7 @@ puttytel : [G] GUITERM NONSSH be_nossh WINMISC win_res.res LIBS1
|
|||||||
plink : [C] plink console NONSSH WINSSH be_all logging WINMISC
|
plink : [C] plink console NONSSH WINSSH be_all logging WINMISC
|
||||||
+ plink.res LIBS2
|
+ plink.res LIBS2
|
||||||
pscp : [C] scp console WINSSH be_none SFTP wildcard WINMISC scp.res LIBS1
|
pscp : [C] scp console WINSSH be_none SFTP wildcard WINMISC scp.res LIBS1
|
||||||
psftp : [C] psftp console WINSSH be_none SFTP WINMISC scp.res LIBS1
|
psftp : [C] psftp winsftp console WINSSH be_none SFTP WINMISC scp.res LIBS1
|
||||||
|
|
||||||
pageant : [G] pageant sshrsa sshpubk sshdes sshbn sshmd5 version tree234
|
pageant : [G] pageant sshrsa sshpubk sshdes sshbn sshmd5 version tree234
|
||||||
+ misc sshaes sshsha pageantc sshdss sshsh512 winutils winmisc
|
+ misc sshaes sshsha pageantc sshdss sshsh512 winutils winmisc
|
||||||
@ -159,6 +159,8 @@ puttytel : [X] UXTERM uxmisc misc ldisc settings pty uxsel be_nossh uxstore
|
|||||||
|
|
||||||
plink : [U] uxplink uxcons NONSSH UXSSH be_all logging UXMISC signal ux_x11
|
plink : [U] uxplink uxcons NONSSH UXSSH be_all logging UXMISC signal ux_x11
|
||||||
|
|
||||||
|
# psftp : [U] psftp uxsftp console UXSSH be_none SFTP UXMISC
|
||||||
|
|
||||||
PuTTY : [M] terminal wcwidth ldiscucs logging be_all mac macdlg macevlog
|
PuTTY : [M] terminal wcwidth ldiscucs logging be_all mac macdlg macevlog
|
||||||
+ macterm macucs mac_res.rsrc testback NONSSH MACSSH MACMISC CHARSET
|
+ macterm macucs mac_res.rsrc testback NONSSH MACSSH MACMISC CHARSET
|
||||||
+ stricmp vsnprint dialog config macctrls
|
+ stricmp vsnprint dialog config macctrls
|
||||||
|
108
psftp.c
108
psftp.c
@ -2,8 +2,6 @@
|
|||||||
* psftp.c: front end for PSFTP.
|
* psftp.c: front end for PSFTP.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -12,6 +10,7 @@
|
|||||||
|
|
||||||
#define PUTTY_DO_GLOBALS
|
#define PUTTY_DO_GLOBALS
|
||||||
#include "putty.h"
|
#include "putty.h"
|
||||||
|
#include "psftp.h"
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
#include "sftp.h"
|
#include "sftp.h"
|
||||||
@ -1024,34 +1023,21 @@ static int sftp_cmd_open(struct sftp_command *cmd)
|
|||||||
|
|
||||||
static int sftp_cmd_lcd(struct sftp_command *cmd)
|
static int sftp_cmd_lcd(struct sftp_command *cmd)
|
||||||
{
|
{
|
||||||
char *currdir;
|
char *currdir, *errmsg;
|
||||||
int len;
|
|
||||||
|
|
||||||
if (cmd->nwords < 2) {
|
if (cmd->nwords < 2) {
|
||||||
printf("lcd: expects a local directory name\n");
|
printf("lcd: expects a local directory name\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SetCurrentDirectory(cmd->words[1])) {
|
errmsg = psftp_lcd(cmd->words[1]);
|
||||||
LPVOID message;
|
if (errmsg) {
|
||||||
int i;
|
printf("lcd: unable to change directory: %s\n", errmsg);
|
||||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
sfree(errmsg);
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
NULL, GetLastError(),
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
||||||
(LPTSTR)&message, 0, NULL);
|
|
||||||
i = strcspn((char *)message, "\n");
|
|
||||||
printf("lcd: unable to change directory: %.*s\n", i, (LPCTSTR)message);
|
|
||||||
LocalFree(message);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
currdir = snewn(256, char);
|
currdir = psftp_getcwd();
|
||||||
len = GetCurrentDirectory(256, currdir);
|
|
||||||
if (len > 256)
|
|
||||||
currdir = sresize(currdir, len, char);
|
|
||||||
GetCurrentDirectory(len, currdir);
|
|
||||||
printf("New local directory is %s\n", currdir);
|
printf("New local directory is %s\n", currdir);
|
||||||
sfree(currdir);
|
sfree(currdir);
|
||||||
|
|
||||||
@ -1061,13 +1047,8 @@ static int sftp_cmd_lcd(struct sftp_command *cmd)
|
|||||||
static int sftp_cmd_lpwd(struct sftp_command *cmd)
|
static int sftp_cmd_lpwd(struct sftp_command *cmd)
|
||||||
{
|
{
|
||||||
char *currdir;
|
char *currdir;
|
||||||
int len;
|
|
||||||
|
|
||||||
currdir = snewn(256, char);
|
currdir = psftp_getcwd();
|
||||||
len = GetCurrentDirectory(256, currdir);
|
|
||||||
if (len > 256)
|
|
||||||
currdir = sresize(currdir, len, char);
|
|
||||||
GetCurrentDirectory(len, currdir);
|
|
||||||
printf("Current local directory is %s\n", currdir);
|
printf("Current local directory is %s\n", currdir);
|
||||||
sfree(currdir);
|
sfree(currdir);
|
||||||
|
|
||||||
@ -1108,9 +1089,10 @@ static struct sftp_cmd_lookup {
|
|||||||
* in ASCII order.
|
* in ASCII order.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
"!", TRUE, "run a local Windows command",
|
"!", TRUE, "run a local command",
|
||||||
"<command>\n"
|
"<command>\n"
|
||||||
" Runs a local Windows command. For example, \"!del myfile\".\n",
|
/* FIXME: this example is crap for non-Windows. */
|
||||||
|
" Runs a local command. For example, \"!del myfile\".\n",
|
||||||
sftp_cmd_pling
|
sftp_cmd_pling
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1620,20 +1602,6 @@ void ldisc_send(void *handle, char *buf, int len, int interactive)
|
|||||||
assert(len == 0);
|
assert(len == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Be told what socket we're supposed to be using.
|
|
||||||
*/
|
|
||||||
static SOCKET sftp_ssh_socket;
|
|
||||||
char *do_select(SOCKET skt, int startup)
|
|
||||||
{
|
|
||||||
if (startup)
|
|
||||||
sftp_ssh_socket = skt;
|
|
||||||
else
|
|
||||||
sftp_ssh_socket = INVALID_SOCKET;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
extern int select_result(WPARAM, LPARAM);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In psftp, all agent requests should be synchronous, so this is a
|
* In psftp, all agent requests should be synchronous, so this is a
|
||||||
* never-called stub.
|
* never-called stub.
|
||||||
@ -1729,13 +1697,8 @@ int sftp_recvdata(char *buf, int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (outlen > 0) {
|
while (outlen > 0) {
|
||||||
fd_set readfds;
|
if (ssh_sftp_loop_iteration() < 0)
|
||||||
|
|
||||||
FD_ZERO(&readfds);
|
|
||||||
FD_SET(sftp_ssh_socket, &readfds);
|
|
||||||
if (select(1, &readfds, NULL, NULL, NULL) < 0)
|
|
||||||
return 0; /* doom */
|
return 0; /* doom */
|
||||||
select_result((WPARAM) sftp_ssh_socket, (LPARAM) FD_READ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -1746,42 +1709,6 @@ int sftp_senddata(char *buf, int len)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Loop through the ssh connection and authentication process.
|
|
||||||
*/
|
|
||||||
static void ssh_sftp_init(void)
|
|
||||||
{
|
|
||||||
if (sftp_ssh_socket == INVALID_SOCKET)
|
|
||||||
return;
|
|
||||||
while (!back->sendok(backhandle)) {
|
|
||||||
fd_set readfds;
|
|
||||||
FD_ZERO(&readfds);
|
|
||||||
FD_SET(sftp_ssh_socket, &readfds);
|
|
||||||
if (select(1, &readfds, NULL, NULL, NULL) < 0)
|
|
||||||
return; /* doom */
|
|
||||||
select_result((WPARAM) sftp_ssh_socket, (LPARAM) FD_READ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize the Win$ock driver.
|
|
||||||
*/
|
|
||||||
static void init_winsock(void)
|
|
||||||
{
|
|
||||||
WORD winsock_ver;
|
|
||||||
WSADATA wsadata;
|
|
||||||
|
|
||||||
winsock_ver = MAKEWORD(1, 1);
|
|
||||||
if (WSAStartup(winsock_ver, &wsadata)) {
|
|
||||||
fprintf(stderr, "Unable to initialise WinSock");
|
|
||||||
cleanup_exit(1);
|
|
||||||
}
|
|
||||||
if (LOBYTE(wsadata.wVersion) != 1 || HIBYTE(wsadata.wVersion) != 1) {
|
|
||||||
fprintf(stderr, "WinSock version is incompatible with 1.1");
|
|
||||||
cleanup_exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Short description of parameters.
|
* Short description of parameters.
|
||||||
*/
|
*/
|
||||||
@ -1963,7 +1890,12 @@ static int psftp_connect(char *userhost, char *user, int portnumber)
|
|||||||
logctx = log_init(NULL, &cfg);
|
logctx = log_init(NULL, &cfg);
|
||||||
back->provide_logctx(backhandle, logctx);
|
back->provide_logctx(backhandle, logctx);
|
||||||
console_provide_logctx(logctx);
|
console_provide_logctx(logctx);
|
||||||
ssh_sftp_init();
|
while (!back->sendok(backhandle)) {
|
||||||
|
if (ssh_sftp_loop_iteration() < 0) {
|
||||||
|
fprintf(stderr, "ssh_init: error during SSH connection setup\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (verbose && realhost != NULL)
|
if (verbose && realhost != NULL)
|
||||||
printf("Connected to %s\n", realhost);
|
printf("Connected to %s\n", realhost);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1983,7 +1915,7 @@ void cmdline_error(char *p, ...)
|
|||||||
/*
|
/*
|
||||||
* Main program. Parse arguments etc.
|
* Main program. Parse arguments etc.
|
||||||
*/
|
*/
|
||||||
int main(int argc, char *argv[])
|
int psftp_main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int portnumber = 0;
|
int portnumber = 0;
|
||||||
@ -1996,7 +1928,6 @@ int main(int argc, char *argv[])
|
|||||||
flags = FLAG_STDERR | FLAG_INTERACTIVE | FLAG_SYNCAGENT;
|
flags = FLAG_STDERR | FLAG_INTERACTIVE | FLAG_SYNCAGENT;
|
||||||
cmdline_tooltype = TOOLTYPE_FILETRANSFER;
|
cmdline_tooltype = TOOLTYPE_FILETRANSFER;
|
||||||
ssh_get_line = &console_get_line;
|
ssh_get_line = &console_get_line;
|
||||||
init_winsock();
|
|
||||||
sk_init();
|
sk_init();
|
||||||
|
|
||||||
userhost = user = NULL;
|
userhost = user = NULL;
|
||||||
@ -2064,7 +1995,6 @@ int main(int argc, char *argv[])
|
|||||||
back->special(backhandle, TS_EOF);
|
back->special(backhandle, TS_EOF);
|
||||||
sftp_recvdata(&ch, 1);
|
sftp_recvdata(&ch, 1);
|
||||||
}
|
}
|
||||||
WSACleanup();
|
|
||||||
random_save_seed();
|
random_save_seed();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
28
psftp.h
Normal file
28
psftp.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* psftp.h: interface between psftp.c and each platform-specific
|
||||||
|
* SFTP module.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PUTTY_PSFTP_H
|
||||||
|
#define PUTTY_PSFTP_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* psftp_getcwd returns the local current directory. The returned
|
||||||
|
* string must be freed by the caller.
|
||||||
|
*/
|
||||||
|
char *psftp_getcwd(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* psftp_lcd changes the local current directory. The return value
|
||||||
|
* is NULL on success, or else an error message which must be freed
|
||||||
|
* by the caller.
|
||||||
|
*/
|
||||||
|
char *psftp_lcd(char *newdir);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One iteration of the PSFTP event loop: wait for network data and
|
||||||
|
* process it, once.
|
||||||
|
*/
|
||||||
|
int ssh_sftp_loop_iteration(void);
|
||||||
|
|
||||||
|
#endif /* PUTTY_PSFTP_H */
|
113
winsftp.c
Normal file
113
winsftp.c
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* winsftp.c: the Windows-specific parts of PSFTP.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "putty.h"
|
||||||
|
#include "psftp.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Be told what socket we're supposed to be using.
|
||||||
|
*/
|
||||||
|
static SOCKET sftp_ssh_socket;
|
||||||
|
char *do_select(SOCKET skt, int startup)
|
||||||
|
{
|
||||||
|
if (startup)
|
||||||
|
sftp_ssh_socket = skt;
|
||||||
|
else
|
||||||
|
sftp_ssh_socket = INVALID_SOCKET;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
extern int select_result(WPARAM, LPARAM);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the WinSock driver.
|
||||||
|
*/
|
||||||
|
static void init_winsock(void)
|
||||||
|
{
|
||||||
|
WORD winsock_ver;
|
||||||
|
WSADATA wsadata;
|
||||||
|
|
||||||
|
winsock_ver = MAKEWORD(1, 1);
|
||||||
|
if (WSAStartup(winsock_ver, &wsadata)) {
|
||||||
|
fprintf(stderr, "Unable to initialise WinSock");
|
||||||
|
cleanup_exit(1);
|
||||||
|
}
|
||||||
|
if (LOBYTE(wsadata.wVersion) != 1 || HIBYTE(wsadata.wVersion) != 1) {
|
||||||
|
fprintf(stderr, "WinSock version is incompatible with 1.1");
|
||||||
|
cleanup_exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set local current directory. Returns NULL on success, or else an
|
||||||
|
* error message which must be freed after printing.
|
||||||
|
*/
|
||||||
|
char *psftp_lcd(char *dir)
|
||||||
|
{
|
||||||
|
char *ret = NULL;
|
||||||
|
|
||||||
|
if (!SetCurrentDirectory(dir)) {
|
||||||
|
LPVOID message;
|
||||||
|
int i;
|
||||||
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL, GetLastError(),
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
(LPTSTR)&message, 0, NULL);
|
||||||
|
i = strcspn((char *)message, "\n");
|
||||||
|
ret = dupprintf("%.*s", i, (LPCTSTR)message);
|
||||||
|
LocalFree(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get local current directory. Returns a string which must be
|
||||||
|
* freed.
|
||||||
|
*/
|
||||||
|
char *psftp_getcwd(void)
|
||||||
|
{
|
||||||
|
char *ret = snewn(256, char);
|
||||||
|
int len = GetCurrentDirectory(256, ret);
|
||||||
|
if (len > 256)
|
||||||
|
ret = sresize(ret, len, char);
|
||||||
|
GetCurrentDirectory(len, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for some network data and process it.
|
||||||
|
*/
|
||||||
|
int ssh_sftp_loop_iteration(void)
|
||||||
|
{
|
||||||
|
fd_set readfds;
|
||||||
|
|
||||||
|
if (sftp_ssh_socket == INVALID_SOCKET)
|
||||||
|
return -1; /* doom */
|
||||||
|
|
||||||
|
FD_ZERO(&readfds);
|
||||||
|
FD_SET(sftp_ssh_socket, &readfds);
|
||||||
|
if (select(1, &readfds, NULL, NULL, NULL) < 0)
|
||||||
|
return -1; /* doom */
|
||||||
|
|
||||||
|
select_result((WPARAM) sftp_ssh_socket, (LPARAM) FD_READ);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main program. Parse arguments etc.
|
||||||
|
*/
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
init_winsock();
|
||||||
|
ret = psftp_main(argc, argv);
|
||||||
|
WSACleanup();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user