mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
... and there's a Unix port of PSCP. Ooh.
[originally from svn r3422]
This commit is contained in:
parent
4e8325c967
commit
d1e9569b05
6
psftp.h
6
psftp.h
@ -141,4 +141,10 @@ void finish_wildcard_matching(WildcardMatcher *dir);
|
||||
*/
|
||||
int create_directory(char *name);
|
||||
|
||||
/*
|
||||
* Concatenate a directory name and a file name. The way this is
|
||||
* done will depend on the OS.
|
||||
*/
|
||||
char *dir_file_cat(char *dir, char *file);
|
||||
|
||||
#endif /* PUTTY_PSFTP_H */
|
||||
|
2
scp.c
2
scp.c
@ -1711,7 +1711,7 @@ static void sink(char *targ, char *src)
|
||||
}
|
||||
|
||||
if (targ[0] != '\0')
|
||||
destfname = dupcat(targ, "\\", striptarget, NULL);
|
||||
destfname = dir_file_cat(targ, striptarget);
|
||||
else
|
||||
destfname = dupstr(striptarget);
|
||||
} else {
|
||||
|
210
unix/uxsftp.c
210
unix/uxsftp.c
@ -4,8 +4,13 @@
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "putty.h"
|
||||
#include "psftp.h"
|
||||
@ -109,6 +114,211 @@ char *psftp_getcwd(void)
|
||||
}
|
||||
}
|
||||
|
||||
struct RFile {
|
||||
int fd;
|
||||
};
|
||||
|
||||
RFile *open_existing_file(char *name, unsigned long *size,
|
||||
unsigned long *mtime, unsigned long *atime)
|
||||
{
|
||||
int fd;
|
||||
RFile *ret;
|
||||
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
ret = snew(RFile);
|
||||
ret->fd = fd;
|
||||
|
||||
if (size || mtime || atime) {
|
||||
struct stat statbuf;
|
||||
if (fstat(fd, &statbuf) < 0) {
|
||||
fprintf(stderr, "%s: stat: %s\n", name, strerror(errno));
|
||||
memset(&statbuf, 0, sizeof(statbuf));
|
||||
}
|
||||
|
||||
if (size)
|
||||
*size = statbuf.st_size;
|
||||
|
||||
if (mtime)
|
||||
*mtime = statbuf.st_mtime;
|
||||
|
||||
if (atime)
|
||||
*atime = statbuf.st_atime;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int read_from_file(RFile *f, void *buffer, int length)
|
||||
{
|
||||
return read(f->fd, buffer, length);
|
||||
}
|
||||
|
||||
void close_rfile(RFile *f)
|
||||
{
|
||||
close(f->fd);
|
||||
sfree(f);
|
||||
}
|
||||
|
||||
struct WFile {
|
||||
int fd;
|
||||
char *name;
|
||||
};
|
||||
|
||||
WFile *open_new_file(char *name)
|
||||
{
|
||||
int fd;
|
||||
WFile *ret;
|
||||
|
||||
fd = open(name, O_CREAT | O_TRUNC | O_WRONLY, 0666);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
ret = snew(WFile);
|
||||
ret->fd = fd;
|
||||
ret->name = dupstr(name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int write_to_file(WFile *f, void *buffer, int length)
|
||||
{
|
||||
char *p = (char *)buffer;
|
||||
int so_far = 0;
|
||||
|
||||
/* Keep trying until we've really written as much as we can. */
|
||||
while (length > 0) {
|
||||
int ret = write(f->fd, p, length);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ret == 0)
|
||||
break;
|
||||
|
||||
p += ret;
|
||||
length -= ret;
|
||||
so_far += ret;
|
||||
}
|
||||
|
||||
return so_far;
|
||||
}
|
||||
|
||||
void set_file_times(WFile *f, unsigned long mtime, unsigned long atime)
|
||||
{
|
||||
struct utimbuf ut;
|
||||
|
||||
ut.actime = atime;
|
||||
ut.modtime = mtime;
|
||||
|
||||
utime(f->name, &ut);
|
||||
}
|
||||
|
||||
/* Closes and frees the WFile */
|
||||
void close_wfile(WFile *f)
|
||||
{
|
||||
close(f->fd);
|
||||
sfree(f->name);
|
||||
sfree(f);
|
||||
}
|
||||
|
||||
int file_type(char *name)
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
if (stat(name, &statbuf) < 0) {
|
||||
if (errno != ENOENT)
|
||||
fprintf(stderr, "%s: stat: %s\n", name, strerror(errno));
|
||||
return FILE_TYPE_NONEXISTENT;
|
||||
}
|
||||
|
||||
if (S_ISREG(statbuf.st_mode))
|
||||
return FILE_TYPE_FILE;
|
||||
|
||||
if (S_ISDIR(statbuf.st_mode))
|
||||
return FILE_TYPE_DIRECTORY;
|
||||
|
||||
return FILE_TYPE_WEIRD;
|
||||
}
|
||||
|
||||
struct DirHandle {
|
||||
DIR *dir;
|
||||
};
|
||||
|
||||
DirHandle *open_directory(char *name)
|
||||
{
|
||||
DIR *dir;
|
||||
DirHandle *ret;
|
||||
|
||||
dir = opendir(name);
|
||||
if (!dir)
|
||||
return NULL;
|
||||
|
||||
ret = snew(DirHandle);
|
||||
ret->dir = dir;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *read_filename(DirHandle *dir)
|
||||
{
|
||||
struct dirent *de;
|
||||
|
||||
do {
|
||||
de = readdir(dir->dir);
|
||||
if (de == NULL)
|
||||
return NULL;
|
||||
} while ((de->d_name[0] == '.' &&
|
||||
(de->d_name[1] == '\0' ||
|
||||
(de->d_name[1] == '.' && de->d_name[2] == '\0'))));
|
||||
|
||||
return dupstr(de->d_name);
|
||||
}
|
||||
|
||||
void close_directory(DirHandle *dir)
|
||||
{
|
||||
closedir(dir->dir);
|
||||
sfree(dir);
|
||||
}
|
||||
|
||||
int test_wildcard(char *name, int cmdline)
|
||||
{
|
||||
/*
|
||||
* On Unix, we currently don't support local wildcards at all.
|
||||
* We will have to do so (FIXME) once PSFTP starts implementing
|
||||
* mput, but until then we can assume `cmdline' is always set.
|
||||
*/
|
||||
struct stat statbuf;
|
||||
|
||||
assert(cmdline);
|
||||
if (stat(name, &statbuf) < 0)
|
||||
return WCTYPE_NONEXISTENT;
|
||||
else
|
||||
return WCTYPE_FILENAME;
|
||||
}
|
||||
|
||||
/*
|
||||
* Actually return matching file names for a local wildcard. FIXME:
|
||||
* we currently don't support this at all.
|
||||
*/
|
||||
struct WildcardMatcher {
|
||||
int x;
|
||||
};
|
||||
WildcardMatcher *begin_wildcard_matching(char *name) { return NULL; }
|
||||
char *wildcard_get_filename(WildcardMatcher *dir) { return NULL; }
|
||||
void finish_wildcard_matching(WildcardMatcher *dir) {}
|
||||
|
||||
int create_directory(char *name)
|
||||
{
|
||||
return mkdir(name, 0777) == 0;
|
||||
}
|
||||
|
||||
char *dir_file_cat(char *dir, char *file)
|
||||
{
|
||||
return dupcat(dir, "/", file, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for some network data and process it.
|
||||
*/
|
||||
|
17
winsftp.c
17
winsftp.c
@ -303,6 +303,7 @@ DirHandle *open_directory(char *name)
|
||||
h = FindFirstFile(findfile, &fdat);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
return NULL;
|
||||
sfree(findfile);
|
||||
|
||||
ret = snew(DirHandle);
|
||||
ret->h = h;
|
||||
@ -312,11 +313,18 @@ DirHandle *open_directory(char *name)
|
||||
|
||||
char *read_filename(DirHandle *dir)
|
||||
{
|
||||
if (!dir->name) {
|
||||
while (!dir->name) {
|
||||
WIN32_FIND_DATA fdat;
|
||||
int ok = FindNextFile(dir->h, &fdat);
|
||||
|
||||
if (ok)
|
||||
if (!ok)
|
||||
return NULL;
|
||||
|
||||
if (fdat.cFileName[0] == '.' &&
|
||||
(fdat.cFileName[1] == '\0' ||
|
||||
(fdat.cFileName[1] == '.' && fdat.cFileName[2] == '\0')))
|
||||
dir->name = NULL;
|
||||
else
|
||||
dir->name = dupstr(fdat.cFileName);
|
||||
}
|
||||
|
||||
@ -449,6 +457,11 @@ int create_directory(char *name)
|
||||
return CreateDirectory(name, NULL) != 0;
|
||||
}
|
||||
|
||||
char *dir_file_cat(char *dir, char *file)
|
||||
{
|
||||
return dupcat(dir, "\\", file, NULL);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Platform-specific network handling.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user