|
Packit |
8f70b4 |
/*
|
|
Packit |
8f70b4 |
* lftp - file transfer program
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* Copyright (c) 1996-2012 by Alexander V. Lukyanov (lav@yars.free.net)
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
8f70b4 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
8f70b4 |
* the Free Software Foundation; either version 3 of the License, or
|
|
Packit |
8f70b4 |
* (at your option) any later version.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
8f70b4 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
8f70b4 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
8f70b4 |
* GNU General Public License for more details.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
8f70b4 |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
8f70b4 |
*/
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#ifndef SFTP_H
|
|
Packit |
8f70b4 |
#define SFTP_H
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include "SSH_Access.h"
|
|
Packit |
8f70b4 |
#include "StatusLine.h"
|
|
Packit |
8f70b4 |
#include <sys/types.h>
|
|
Packit |
8f70b4 |
#include <sys/stat.h>
|
|
Packit |
8f70b4 |
#include "FileSet.h"
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
class SFtp : public SSH_Access
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int protocol_version;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *lc_to_utf8(const char *);
|
|
Packit |
8f70b4 |
const char *utf8_to_lc(const char *);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
enum packet_type {
|
|
Packit |
8f70b4 |
SSH_FXP_INIT =1,
|
|
Packit |
8f70b4 |
SSH_FXP_VERSION =2,
|
|
Packit |
8f70b4 |
SSH_FXP_OPEN =3,
|
|
Packit |
8f70b4 |
SSH_FXP_CLOSE =4,
|
|
Packit |
8f70b4 |
SSH_FXP_READ =5,
|
|
Packit |
8f70b4 |
SSH_FXP_WRITE =6,
|
|
Packit |
8f70b4 |
SSH_FXP_LSTAT =7,
|
|
Packit |
8f70b4 |
SSH_FXP_FSTAT =8,
|
|
Packit |
8f70b4 |
SSH_FXP_SETSTAT =9,
|
|
Packit |
8f70b4 |
SSH_FXP_FSETSTAT =10,
|
|
Packit |
8f70b4 |
SSH_FXP_OPENDIR =11,
|
|
Packit |
8f70b4 |
SSH_FXP_READDIR =12,
|
|
Packit |
8f70b4 |
SSH_FXP_REMOVE =13,
|
|
Packit |
8f70b4 |
SSH_FXP_MKDIR =14,
|
|
Packit |
8f70b4 |
SSH_FXP_RMDIR =15,
|
|
Packit |
8f70b4 |
SSH_FXP_REALPATH =16,
|
|
Packit |
8f70b4 |
SSH_FXP_STAT =17,
|
|
Packit |
8f70b4 |
SSH_FXP_RENAME =18, // v>=2
|
|
Packit |
8f70b4 |
SSH_FXP_READLINK =19, // v>=3
|
|
Packit |
8f70b4 |
SSH_FXP_SYMLINK =20, // v<=5
|
|
Packit |
8f70b4 |
SSH_FXP_LINK =21, // v>=6
|
|
Packit |
8f70b4 |
SSH_FXP_BLOCK =22, // v>=6
|
|
Packit |
8f70b4 |
SSH_FXP_UNBLOCK =23, // v>=6
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
SSH_FXP_STATUS =101,
|
|
Packit |
8f70b4 |
SSH_FXP_HANDLE =102,
|
|
Packit |
8f70b4 |
SSH_FXP_DATA =103,
|
|
Packit |
8f70b4 |
SSH_FXP_NAME =104,
|
|
Packit |
8f70b4 |
SSH_FXP_ATTRS =105,
|
|
Packit |
8f70b4 |
SSH_FXP_EXTENDED =200,
|
|
Packit |
8f70b4 |
SSH_FXP_EXTENDED_REPLY=201
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_SIZE 0x00000001
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_UIDGID 0x00000002 // v<=3
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_ACCESSTIME 0x00000008
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008 // v<=3
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_CREATETIME 0x00000010
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_MODIFYTIME 0x00000020
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_ACL 0x00000040
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_OWNERGROUP 0x00000080
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_SUBSECOND_TIMES 0x00000100
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_BITS 0x00000200 // v>=5
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_ALLOCATION_SIZE 0x00000400 // v>=6
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_TEXT_HINT 0x00000800 // v>=6
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_MIME_TYPE 0x00001000 // v>=6
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_LINK_COUNT 0x00002000 // v>=6
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_UNTRANSLATED_NAME 0x00004000 // v>=6
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_CTIME 0x00008000 // v>=6
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_MASK_V3 0x8000000F
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_MASK_V4 0x800001FD
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_MASK_V5 0x800003FD
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_MASK_V6 0x8000FFFD
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// BITS values (v>=5)
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_FLAGS_READONLY 0x00000001
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_FLAGS_SYSTEM 0x00000002
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_FLAGS_HIDDEN 0x00000004
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_FLAGS_CASE_INSENSITIVE 0x00000008
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_FLAGS_ARCHIVE 0x00000010
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_FLAGS_ENCRYPTED 0x00000020
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_FLAGS_COMPRESSED 0x00000040
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_FLAGS_SPARSE 0x00000080
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_FLAGS_APPEND_ONLY 0x00000100
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_FLAGS_IMMUTABLE 0x00000200
|
|
Packit |
8f70b4 |
#define SSH_FILEXFER_ATTR_FLAGS_SYNC 0x00000400
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
enum sftp_file_type {
|
|
Packit |
8f70b4 |
SSH_FILEXFER_TYPE_REGULAR =1,
|
|
Packit |
8f70b4 |
SSH_FILEXFER_TYPE_DIRECTORY =2,
|
|
Packit |
8f70b4 |
SSH_FILEXFER_TYPE_SYMLINK =3,
|
|
Packit |
8f70b4 |
SSH_FILEXFER_TYPE_SPECIAL =4,
|
|
Packit |
8f70b4 |
SSH_FILEXFER_TYPE_UNKNOWN =5,
|
|
Packit |
8f70b4 |
SSH_FILEXFER_TYPE_SOCKET =6, // v>=5
|
|
Packit |
8f70b4 |
SSH_FILEXFER_TYPE_CHAR_DEVICE =7, // v>=5
|
|
Packit |
8f70b4 |
SSH_FILEXFER_TYPE_BLOCK_DEVICE=8, // v>=5
|
|
Packit |
8f70b4 |
SSH_FILEXFER_TYPE_FIFO =9 // v>=5
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// open modes (v<=4)
|
|
Packit |
8f70b4 |
#define SSH_FXF_READ 0x00000001
|
|
Packit |
8f70b4 |
#define SSH_FXF_WRITE 0x00000002
|
|
Packit |
8f70b4 |
#define SSH_FXF_APPEND 0x00000004
|
|
Packit |
8f70b4 |
#define SSH_FXF_CREAT 0x00000008
|
|
Packit |
8f70b4 |
#define SSH_FXF_TRUNC 0x00000010
|
|
Packit |
8f70b4 |
#define SSH_FXF_EXCL 0x00000020
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// open flags values (v>=5)
|
|
Packit |
8f70b4 |
#define SSH_FXF_ACCESS_DISPOSITION 0x00000007
|
|
Packit |
8f70b4 |
#define SSH_FXF_CREATE_NEW 0x00000000
|
|
Packit |
8f70b4 |
#define SSH_FXF_CREATE_TRUNCATE 0x00000001
|
|
Packit |
8f70b4 |
#define SSH_FXF_OPEN_EXISTING 0x00000002
|
|
Packit |
8f70b4 |
#define SSH_FXF_OPEN_OR_CREATE 0x00000003
|
|
Packit |
8f70b4 |
#define SSH_FXF_TRUNCATE_EXISTING 0x00000004
|
|
Packit |
8f70b4 |
#define SSH_FXF_ACCESS_APPEND_DATA 0x00000008
|
|
Packit |
8f70b4 |
#define SSH_FXF_ACCESS_APPEND_DATA_ATOMIC 0x00000010
|
|
Packit |
8f70b4 |
#define SSH_FXF_ACCESS_TEXT_MODE 0x00000020
|
|
Packit |
8f70b4 |
#define SSH_FXF_ACCESS_READ_LOCK 0x00000040
|
|
Packit |
8f70b4 |
#define SSH_FXF_ACCESS_WRITE_LOCK 0x00000080
|
|
Packit |
8f70b4 |
#define SSH_FXF_ACCESS_DELETE_LOCK 0x00000100
|
|
Packit |
8f70b4 |
#define SSH_FXF_ACCESS_BLOCK_ADVISORY 0x00000200 // v>=6
|
|
Packit |
8f70b4 |
#define SSH_FXF_ACCESS_NOFOLLOW 0x00000400 // v>=6
|
|
Packit |
8f70b4 |
#define SSH_FXF_ACCESS_DELETE_ON_CLOSE 0x00000800 // v>=6
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// ACL masks
|
|
Packit |
8f70b4 |
#define ACE4_READ_DATA 0x00000001
|
|
Packit |
8f70b4 |
#define ACE4_LIST_DIRECTORY 0x00000001
|
|
Packit |
8f70b4 |
#define ACE4_WRITE_DATA 0x00000002
|
|
Packit |
8f70b4 |
#define ACE4_ADD_FILE 0x00000002
|
|
Packit |
8f70b4 |
#define ACE4_APPEND_DATA 0x00000004
|
|
Packit |
8f70b4 |
#define ACE4_ADD_SUBDIRECTORY 0x00000004
|
|
Packit |
8f70b4 |
#define ACE4_READ_NAMED_ATTRS 0x00000008
|
|
Packit |
8f70b4 |
#define ACE4_WRITE_NAMED_ATTRS 0x00000010
|
|
Packit |
8f70b4 |
#define ACE4_EXECUTE 0x00000020
|
|
Packit |
8f70b4 |
#define ACE4_DELETE_CHILD 0x00000040
|
|
Packit |
8f70b4 |
#define ACE4_READ_ATTRIBUTES 0x00000080
|
|
Packit |
8f70b4 |
#define ACE4_WRITE_ATTRIBUTES 0x00000100
|
|
Packit |
8f70b4 |
#define ACE4_DELETE 0x00010000
|
|
Packit |
8f70b4 |
#define ACE4_READ_ACL 0x00020000
|
|
Packit |
8f70b4 |
#define ACE4_WRITE_ACL 0x00040000
|
|
Packit |
8f70b4 |
#define ACE4_WRITE_OWNER 0x00080000
|
|
Packit |
8f70b4 |
#define ACE4_SYNCHRONIZE 0x00100000
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// RENAME flags (v>=5)
|
|
Packit |
8f70b4 |
#define SSH_FXF_RENAME_OVERWRITE 0x00000001
|
|
Packit |
8f70b4 |
#define SSH_FXF_RENAME_ATOMIC 0x00000002
|
|
Packit |
8f70b4 |
#define SSH_FXF_RENAME_NATIVE 0x00000004
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
enum sftp_status_t {
|
|
Packit |
8f70b4 |
SSH_FX_OK =0,
|
|
Packit |
8f70b4 |
SSH_FX_EOF =1,
|
|
Packit |
8f70b4 |
SSH_FX_NO_SUCH_FILE =2,
|
|
Packit |
8f70b4 |
SSH_FX_PERMISSION_DENIED =3,
|
|
Packit |
8f70b4 |
SSH_FX_FAILURE =4,
|
|
Packit |
8f70b4 |
SSH_FX_BAD_MESSAGE =5,
|
|
Packit |
8f70b4 |
SSH_FX_NO_CONNECTION =6,
|
|
Packit |
8f70b4 |
SSH_FX_CONNECTION_LOST =7,
|
|
Packit |
8f70b4 |
SSH_FX_OP_UNSUPPORTED =8,
|
|
Packit |
8f70b4 |
SSH_FX_INVALID_HANDLE =9,
|
|
Packit |
8f70b4 |
SSH_FX_NO_SUCH_PATH =10,
|
|
Packit |
8f70b4 |
SSH_FX_FILE_ALREADY_EXISTS=11,
|
|
Packit |
8f70b4 |
SSH_FX_WRITE_PROTECT =12,
|
|
Packit |
8f70b4 |
SSH_FX_NO_MEDIA =13,
|
|
Packit |
8f70b4 |
SSH_FX_NO_SPACE_ON_FILESYSTEM =14,
|
|
Packit |
8f70b4 |
SSH_FX_QUOTA_EXCEEDED =15,
|
|
Packit |
8f70b4 |
SSH_FX_UNKNOWN_PRINCIPAL =16,
|
|
Packit |
8f70b4 |
SSH_FX_LOCK_CONFLICT =17,
|
|
Packit |
8f70b4 |
SSH_FX_DIR_NOT_EMPTY =18,
|
|
Packit |
8f70b4 |
SSH_FX_NOT_A_DIRECTORY =19,
|
|
Packit |
8f70b4 |
SSH_FX_INVALID_FILENAME =20,
|
|
Packit |
8f70b4 |
SSH_FX_LINK_LOOP =21,
|
|
Packit |
8f70b4 |
SSH_FX_CANNOT_DELETE =22,
|
|
Packit |
8f70b4 |
SSH_FX_INVALID_PARAMETER =23,
|
|
Packit |
8f70b4 |
SSH_FX_FILE_IS_A_DIRECTORY =24,
|
|
Packit |
8f70b4 |
SSH_FX_BYTE_RANGE_LOCK_CONFLICT =25,
|
|
Packit |
8f70b4 |
SSH_FX_BYTE_RANGE_LOCK_REFUSED =26,
|
|
Packit |
8f70b4 |
SSH_FX_DELETE_PENDING =27,
|
|
Packit |
8f70b4 |
SSH_FX_FILE_CORRUPT =28,
|
|
Packit |
8f70b4 |
SSH_FX_OWNER_INVALID =29,
|
|
Packit |
8f70b4 |
SSH_FX_GROUP_INVALID =30
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
private:
|
|
Packit |
8f70b4 |
enum state_t
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
DISCONNECTED,
|
|
Packit |
8f70b4 |
CONNECTING,
|
|
Packit |
8f70b4 |
CONNECTING_1,
|
|
Packit |
8f70b4 |
CONNECTING_2,
|
|
Packit |
8f70b4 |
CONNECTED,
|
|
Packit |
8f70b4 |
FILE_RECV,
|
|
Packit |
8f70b4 |
FILE_SEND,
|
|
Packit |
8f70b4 |
WAITING,
|
|
Packit |
8f70b4 |
DONE
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
state_t state;
|
|
Packit |
8f70b4 |
unsigned ssh_id;
|
|
Packit |
8f70b4 |
xstring handle;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Init();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SendMethod();
|
|
Packit |
8f70b4 |
void SendArrayInfoRequests();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Ref<DirectedBuffer> send_translate;
|
|
Packit |
8f70b4 |
Ref<DirectedBuffer> recv_translate;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Ref<Buffer> file_buf;
|
|
Packit |
8f70b4 |
Ref<FileSet> file_set;
|
|
Packit |
8f70b4 |
Timer flush_timer;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void DisconnectLL();
|
|
Packit |
8f70b4 |
int IsConnected() const
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(state==DISCONNECTED)
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
if(state==CONNECTING)
|
|
Packit |
8f70b4 |
return 1;
|
|
Packit |
8f70b4 |
return 2;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *SkipHome(const char *path);
|
|
Packit |
8f70b4 |
const char *WirePath(const char *path);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
enum unpack_status_t
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
UNPACK_SUCCESS=0,
|
|
Packit |
8f70b4 |
UNPACK_WRONG_FORMAT=-1,
|
|
Packit |
8f70b4 |
UNPACK_PREMATURE_EOF=-2,
|
|
Packit |
8f70b4 |
UNPACK_NO_DATA_YET=1
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Packet
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
static bool is_valid_reply(int p)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
return p==SSH_FXP_VERSION
|
|
Packit |
8f70b4 |
|| (p>=101 && p<=105)
|
|
Packit |
8f70b4 |
|| p==SSH_FXP_EXTENDED_REPLY;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
protected:
|
|
Packit |
8f70b4 |
int length;
|
|
Packit |
8f70b4 |
int unpacked;
|
|
Packit |
8f70b4 |
packet_type type;
|
|
Packit |
8f70b4 |
unsigned id;
|
|
Packit |
8f70b4 |
Packet(packet_type t)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
type=t;
|
|
Packit |
8f70b4 |
length=1;
|
|
Packit |
8f70b4 |
if(HasID())
|
|
Packit |
8f70b4 |
length+=4;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
bool HasID();
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Packet() { length=0; }
|
|
Packit |
8f70b4 |
virtual void ComputeLength() { length=1+4*HasID(); }
|
|
Packit |
8f70b4 |
virtual void Pack(Buffer *b)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
b->PackUINT32BE(length);
|
|
Packit |
8f70b4 |
b->PackUINT8(type);
|
|
Packit |
8f70b4 |
if(HasID())
|
|
Packit |
8f70b4 |
b->PackUINT32BE(id);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
virtual unpack_status_t Unpack(const Buffer *b);
|
|
Packit |
8f70b4 |
virtual ~Packet() {}
|
|
Packit |
8f70b4 |
int GetLength() { return length; }
|
|
Packit |
8f70b4 |
packet_type GetPacketType() { return type; }
|
|
Packit |
8f70b4 |
const char *GetPacketTypeText();
|
|
Packit |
8f70b4 |
unsigned GetID() const { return id; }
|
|
Packit |
8f70b4 |
const xstring& GetKey() { return xstring::get_tmp((const char*)&id,sizeof(id)); }
|
|
Packit |
8f70b4 |
void SetID(unsigned new_id) { id=new_id; }
|
|
Packit |
8f70b4 |
void DropData(Buffer *b) { b->Skip(4+(length>0?length:0)); }
|
|
Packit |
8f70b4 |
bool TypeIs(packet_type t) const { return type==t; }
|
|
Packit |
8f70b4 |
static unpack_status_t UnpackString(const Buffer *b,int *offset,int limit,xstring *str_out);
|
|
Packit |
8f70b4 |
static void PackString(Buffer *b,const char *str,int len=-1);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
private:
|
|
Packit |
8f70b4 |
unpack_status_t UnpackPacket(Buffer *,Packet **);
|
|
Packit |
8f70b4 |
class PacketUINT32 : public Packet
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
protected:
|
|
Packit |
8f70b4 |
unsigned data;
|
|
Packit |
8f70b4 |
PacketUINT32(packet_type t,unsigned d=0) : Packet(t)
|
|
Packit |
8f70b4 |
{ data=d; length+=4; }
|
|
Packit |
8f70b4 |
unpack_status_t Unpack(const Buffer *b)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
unpack_status_t res;
|
|
Packit |
8f70b4 |
res=Packet::Unpack(b);
|
|
Packit |
8f70b4 |
if(res!=UNPACK_SUCCESS)
|
|
Packit |
8f70b4 |
return res;
|
|
Packit |
8f70b4 |
data=b->UnpackUINT32BE(unpacked);
|
|
Packit |
8f70b4 |
unpacked+=4;
|
|
Packit |
8f70b4 |
return UNPACK_SUCCESS;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void ComputeLength() { Packet::ComputeLength(); length+=4; }
|
|
Packit |
8f70b4 |
void Pack(Buffer *b) { Packet::Pack(b); b->PackUINT32BE(data); }
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class PacketSTRING : public Packet
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
protected:
|
|
Packit |
8f70b4 |
xstring string;
|
|
Packit |
8f70b4 |
PacketSTRING(packet_type t) : Packet(t)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
length=4;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
PacketSTRING(packet_type t,const xstring &s) : Packet(t)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
string.set(s);
|
|
Packit |
8f70b4 |
length+=4+string.length();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
unpack_status_t Unpack(const Buffer *b);
|
|
Packit |
8f70b4 |
void ComputeLength() { Packet::ComputeLength(); length+=4+string.length(); }
|
|
Packit |
8f70b4 |
void Pack(Buffer *b)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
Packet::Pack(b);
|
|
Packit |
8f70b4 |
Packet::PackString(b,string,string.length());
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
const char *GetString() { return string; }
|
|
Packit |
8f70b4 |
int GetStringLength() { return string.length(); }
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_INIT : public PacketUINT32
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_INIT(int v) : PacketUINT32(SSH_FXP_INIT,v) {}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Reply_VERSION : public PacketUINT32
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
char **extension_name;
|
|
Packit |
8f70b4 |
char **extension_data;
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Reply_VERSION() : PacketUINT32(SSH_FXP_VERSION) {}
|
|
Packit |
8f70b4 |
unpack_status_t Unpack(const Buffer *b)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
unpack_status_t res;
|
|
Packit |
8f70b4 |
res=PacketUINT32::Unpack(b);
|
|
Packit |
8f70b4 |
if(res!=UNPACK_SUCCESS)
|
|
Packit |
8f70b4 |
return res;
|
|
Packit |
8f70b4 |
// FIXME: unpack extensions.
|
|
Packit |
8f70b4 |
return res;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
unsigned GetVersion() { return data; }
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_REALPATH : public PacketSTRING
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_REALPATH(const char *p) : PacketSTRING(SSH_FXP_REALPATH,p) {}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_FSTAT : public PacketSTRING
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
unsigned flags;
|
|
Packit |
8f70b4 |
int protocol_version;
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_FSTAT(const xstring &h,unsigned f,int pv) : PacketSTRING(SSH_FXP_FSTAT,h)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
flags=f;
|
|
Packit |
8f70b4 |
protocol_version=pv;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void ComputeLength()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
PacketSTRING::ComputeLength();
|
|
Packit |
8f70b4 |
if(protocol_version>=4)
|
|
Packit |
8f70b4 |
length+=4;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void Pack(Buffer *b)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
PacketSTRING::Pack(b);
|
|
Packit |
8f70b4 |
if(protocol_version>=4)
|
|
Packit |
8f70b4 |
b->PackUINT32BE(flags);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_STAT : public Request_FSTAT
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_STAT(const char *p,unsigned f,int pv) : Request_FSTAT(p,f,pv)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
type=SSH_FXP_STAT;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
const char *GetName() { return string; }
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
struct FileAttrs
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
struct ExtFileAttr
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring extended_type;
|
|
Packit |
8f70b4 |
xstring extended_data;
|
|
Packit |
8f70b4 |
unpack_status_t Unpack(const Buffer *b,int *offset,int limit);
|
|
Packit |
8f70b4 |
void Pack(Buffer *b);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
struct FileACE
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
unsigned ace_type;
|
|
Packit |
8f70b4 |
unsigned ace_flag;
|
|
Packit |
8f70b4 |
unsigned ace_mask;
|
|
Packit |
8f70b4 |
xstring who;
|
|
Packit |
8f70b4 |
FileACE() { ace_type=ace_flag=ace_mask=0; }
|
|
Packit |
8f70b4 |
unpack_status_t Unpack(const Buffer *b,int *offset,int limit);
|
|
Packit |
8f70b4 |
void Pack(Buffer *b);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
unsigned flags;
|
|
Packit |
8f70b4 |
int type; // v>=4
|
|
Packit |
8f70b4 |
off_t size; // present only if flag SIZE
|
|
Packit |
8f70b4 |
xstring owner; // present only if flag OWNERGROUP // v>=4
|
|
Packit |
8f70b4 |
xstring group; // present only if flag OWNERGROUP // v>=4
|
|
Packit |
8f70b4 |
unsigned uid; // present only if flag UIDGID // v<=3
|
|
Packit |
8f70b4 |
unsigned gid; // present only if flag UIDGID // v<=3
|
|
Packit |
8f70b4 |
unsigned permissions; // present only if flag PERMISSIONS
|
|
Packit |
8f70b4 |
time_t atime; // present only if flag ACCESSTIME (ACMODTIME)
|
|
Packit |
8f70b4 |
unsigned atime_nseconds; // present only if flag SUBSECOND_TIMES
|
|
Packit |
8f70b4 |
time_t createtime; // present only if flag CREATETIME
|
|
Packit |
8f70b4 |
unsigned createtime_nseconds; // present only if flag SUBSECOND_TIMES
|
|
Packit |
8f70b4 |
time_t mtime; // present only if flag MODIFYTIME (ACMODTIME)
|
|
Packit |
8f70b4 |
unsigned mtime_nseconds; // present only if flag SUBSECOND_TIMES
|
|
Packit |
8f70b4 |
time_t ctime; // present only if flag CTIME // v>=6
|
|
Packit |
8f70b4 |
unsigned ctime_nseconds; // present only if flag SUBSECOND_TIMES // v>=6
|
|
Packit |
8f70b4 |
unsigned ace_count; // present only if flag ACL
|
|
Packit |
8f70b4 |
FileACE *ace;
|
|
Packit |
8f70b4 |
unsigned attrib_bits; // if flag BITS // v>=5
|
|
Packit |
8f70b4 |
unsigned attrib_bits_valid; // if flag BITS // v>=6
|
|
Packit |
8f70b4 |
unsigned char text_hint; // if flag TEXT_HINT // v>=6
|
|
Packit |
8f70b4 |
xstring mime_type; // if flag MIME_TYPE // v>=6
|
|
Packit |
8f70b4 |
unsigned link_count; // if flag LINK_COUNT // v>=6
|
|
Packit |
8f70b4 |
xstring untranslated_name; // if flag UNTRANSLATED_NAME // v>=6
|
|
Packit |
8f70b4 |
unsigned extended_count; // present only if flag EXTENDED
|
|
Packit |
8f70b4 |
ExtFileAttr *extended_attrs;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileAttrs()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
flags=0; type=0; size=NO_SIZE; uid=gid=0;
|
|
Packit |
8f70b4 |
permissions=0;
|
|
Packit |
8f70b4 |
atime=createtime=mtime=ctime=NO_DATE;
|
|
Packit |
8f70b4 |
atime_nseconds=createtime_nseconds=mtime_nseconds=ctime_nseconds=0;
|
|
Packit |
8f70b4 |
extended_count=0; extended_attrs=0;
|
|
Packit |
8f70b4 |
ace_count=0; ace=0;
|
|
Packit |
8f70b4 |
attrib_bits=attrib_bits_valid=0; text_hint=0;
|
|
Packit |
8f70b4 |
link_count=0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
~FileAttrs();
|
|
Packit |
8f70b4 |
unpack_status_t Unpack(const Buffer *b,int *offset,int limit,int proto_version);
|
|
Packit |
8f70b4 |
void Pack(Buffer *b,int proto_version);
|
|
Packit |
8f70b4 |
int ComputeLength(int v);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
struct NameAttrs
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring name;
|
|
Packit |
8f70b4 |
xstring longname;
|
|
Packit |
8f70b4 |
FileAttrs attrs;
|
|
Packit |
8f70b4 |
unpack_status_t Unpack(const Buffer *b,int *offset,int limit,int proto_version);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
private:
|
|
Packit |
8f70b4 |
class Reply_NAME : public Packet
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int protocol_version;
|
|
Packit |
8f70b4 |
int count;
|
|
Packit |
8f70b4 |
NameAttrs *names;
|
|
Packit |
8f70b4 |
bool eof;
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Reply_NAME(int pv) : Packet(SSH_FXP_NAME) { protocol_version=pv; eof=false; }
|
|
Packit |
8f70b4 |
~Reply_NAME() { delete[] names; }
|
|
Packit |
8f70b4 |
unpack_status_t Unpack(const Buffer *b);
|
|
Packit |
8f70b4 |
int GetCount() { return count; }
|
|
Packit |
8f70b4 |
const NameAttrs *GetNameAttrs(int index)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(index>count)
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
return &names[index];
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
bool Eof() { return eof; }
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Reply_ATTRS : public Packet
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int protocol_version;
|
|
Packit |
8f70b4 |
FileAttrs attrs;
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Reply_ATTRS(int pv) : Packet(SSH_FXP_ATTRS) { protocol_version=pv; }
|
|
Packit |
8f70b4 |
unpack_status_t Unpack(const Buffer *b);
|
|
Packit |
8f70b4 |
const FileAttrs *GetAttrs() { return &attrs; }
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class PacketSTRING_ATTRS : public PacketSTRING
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
protected:
|
|
Packit |
8f70b4 |
int protocol_version;
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
FileAttrs attrs;
|
|
Packit |
8f70b4 |
PacketSTRING_ATTRS(packet_type type,const xstring &h,int pv)
|
|
Packit |
8f70b4 |
: PacketSTRING(type,h)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
protocol_version=pv;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void ComputeLength()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
PacketSTRING::ComputeLength();
|
|
Packit |
8f70b4 |
length+=attrs.ComputeLength(protocol_version);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void Pack(Buffer *b)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
PacketSTRING::Pack(b);
|
|
Packit |
8f70b4 |
attrs.Pack(b,protocol_version);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_FSETSTAT : public PacketSTRING_ATTRS
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_FSETSTAT(const xstring &h,int pv)
|
|
Packit |
8f70b4 |
: PacketSTRING_ATTRS(SSH_FXP_FSETSTAT,h,pv) {}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_OPEN : public PacketSTRING_ATTRS
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
unsigned pflags; // v<=4
|
|
Packit |
8f70b4 |
unsigned desired_access; // v>=5
|
|
Packit |
8f70b4 |
unsigned flags; // v>=5
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_OPEN(const char *fn,unsigned pf,unsigned da,unsigned f,int pv)
|
|
Packit |
8f70b4 |
: PacketSTRING_ATTRS(SSH_FXP_OPEN,fn,pv)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
pflags=pf;
|
|
Packit |
8f70b4 |
desired_access=da;
|
|
Packit |
8f70b4 |
flags=f;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void ComputeLength()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
PacketSTRING_ATTRS::ComputeLength();
|
|
Packit |
8f70b4 |
length+=4+4*(protocol_version>=5);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void Pack(Buffer *b);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Reply_HANDLE : public PacketSTRING
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Reply_HANDLE() : PacketSTRING(SSH_FXP_HANDLE) {}
|
|
Packit |
8f70b4 |
const xstring &GetHandle() { return string; }
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_CLOSE : public PacketSTRING
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_CLOSE(const xstring &h) : PacketSTRING(SSH_FXP_CLOSE,h) {}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_OPENDIR : public PacketSTRING
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_OPENDIR(const char *name) : PacketSTRING(SSH_FXP_OPENDIR,name) {}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_READDIR : public PacketSTRING
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_READDIR(const xstring &h) : PacketSTRING(SSH_FXP_READDIR,h) {}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Reply_STATUS : public Packet
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int protocol_version;
|
|
Packit |
8f70b4 |
unsigned code;
|
|
Packit |
8f70b4 |
xstring message;
|
|
Packit |
8f70b4 |
xstring language;
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Reply_STATUS(int pv) { protocol_version=pv; code=0; }
|
|
Packit |
8f70b4 |
unpack_status_t Unpack(const Buffer *b);
|
|
Packit |
8f70b4 |
int GetCode() { return code; }
|
|
Packit |
8f70b4 |
const char *GetCodeText();
|
|
Packit |
8f70b4 |
const char *GetMessage() { return message; }
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_READ : public PacketSTRING
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
off_t pos;
|
|
Packit |
8f70b4 |
unsigned len;
|
|
Packit |
8f70b4 |
Request_READ(const xstring &h,off_t p,unsigned l)
|
|
Packit |
8f70b4 |
: PacketSTRING(SSH_FXP_READ,h) { pos=p; len=l; }
|
|
Packit |
8f70b4 |
void ComputeLength() { PacketSTRING::ComputeLength(); length+=8+4; }
|
|
Packit |
8f70b4 |
void Pack(Buffer *b);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Reply_DATA : public PacketSTRING
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
bool eof;
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Reply_DATA() : PacketSTRING(SSH_FXP_DATA) { eof=false; }
|
|
Packit |
8f70b4 |
void GetData(const char **b,int *s) { *b=string; *s=string.length(); }
|
|
Packit |
8f70b4 |
unpack_status_t Unpack(const Buffer *b);
|
|
Packit |
8f70b4 |
bool Eof() { return eof; }
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_WRITE : public PacketSTRING
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
off_t pos;
|
|
Packit |
8f70b4 |
xstring data;
|
|
Packit |
8f70b4 |
Request_WRITE(const xstring &h,off_t p,const char *d,unsigned l)
|
|
Packit |
8f70b4 |
: PacketSTRING(SSH_FXP_WRITE,h) { pos=p; data.nset(d,l); }
|
|
Packit |
8f70b4 |
void ComputeLength() { PacketSTRING::ComputeLength(); length+=8+4+data.length(); }
|
|
Packit |
8f70b4 |
void Pack(Buffer *b);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_MKDIR : public PacketSTRING_ATTRS
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_MKDIR(const char *fn,int pv)
|
|
Packit |
8f70b4 |
: PacketSTRING_ATTRS(SSH_FXP_MKDIR,fn,pv) {}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_SETSTAT : public PacketSTRING_ATTRS
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_SETSTAT(const char *fn,int pv)
|
|
Packit |
8f70b4 |
: PacketSTRING_ATTRS(SSH_FXP_SETSTAT,fn,pv) {}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_RMDIR : public PacketSTRING
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_RMDIR(const char *fn) : PacketSTRING(SSH_FXP_RMDIR,fn) {}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_REMOVE : public PacketSTRING
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_REMOVE(const char *fn) : PacketSTRING(SSH_FXP_REMOVE,fn) {}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_RENAME : public Packet
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int protocol_version;
|
|
Packit |
8f70b4 |
xstring oldpath;
|
|
Packit |
8f70b4 |
xstring newpath;
|
|
Packit |
8f70b4 |
unsigned flags;
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_RENAME(const char *o,const char *n,unsigned f,int pv)
|
|
Packit |
8f70b4 |
: Packet(SSH_FXP_RENAME), oldpath(o), newpath(n)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
protocol_version=pv;
|
|
Packit |
8f70b4 |
flags=f;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void ComputeLength();
|
|
Packit |
8f70b4 |
void Pack(Buffer *b);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_READLINK : public PacketSTRING
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_READLINK(const char *name) : PacketSTRING(SSH_FXP_READLINK,name) {}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_SYMLINK : public Packet
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring oldpath;
|
|
Packit |
8f70b4 |
xstring newpath;
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_SYMLINK(const char *o,const char *n)
|
|
Packit |
8f70b4 |
: Packet(SSH_FXP_SYMLINK), oldpath(o), newpath(n) {}
|
|
Packit |
8f70b4 |
void ComputeLength()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
Packet::ComputeLength();
|
|
Packit |
8f70b4 |
length+=4+strlen(oldpath)+4+strlen(newpath);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void Pack(Buffer *b);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class Request_LINK : public Packet
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring oldpath;
|
|
Packit |
8f70b4 |
xstring newpath;
|
|
Packit |
8f70b4 |
bool symbolic;
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
Request_LINK(const char *o,const char *n,bool s)
|
|
Packit |
8f70b4 |
: Packet(SSH_FXP_LINK), oldpath(o), newpath(n), symbolic(s) {}
|
|
Packit |
8f70b4 |
void ComputeLength()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
Packet::ComputeLength();
|
|
Packit |
8f70b4 |
length+=4+strlen(oldpath)+4+strlen(newpath)+1;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void Pack(Buffer *b);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
struct Expect;
|
|
Packit |
8f70b4 |
friend struct SFtp::Expect; // grant access to Packet.
|
|
Packit |
8f70b4 |
struct Expect
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
enum expect_t
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
HOME_PATH,
|
|
Packit |
8f70b4 |
FXP_VERSION,
|
|
Packit |
8f70b4 |
CWD,
|
|
Packit |
8f70b4 |
HANDLE,
|
|
Packit |
8f70b4 |
HANDLE_STALE,
|
|
Packit |
8f70b4 |
DATA,
|
|
Packit |
8f70b4 |
INFO,
|
|
Packit |
8f70b4 |
INFO_READLINK,
|
|
Packit |
8f70b4 |
DEFAULT,
|
|
Packit |
8f70b4 |
WRITE_STATUS,
|
|
Packit |
8f70b4 |
IGNORE
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Ref<Packet> request;
|
|
Packit |
8f70b4 |
Ref<Packet> reply;
|
|
Packit |
8f70b4 |
int i;
|
|
Packit |
8f70b4 |
expect_t tag;
|
|
Packit |
8f70b4 |
Expect(Packet *req,expect_t t,int j=0) : request(req), i(j), tag(t) {}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool has_data_at_pos(off_t pos) const {
|
|
Packit |
8f70b4 |
if(!reply->TypeIs(SSH_FXP_DATA) || !request->TypeIs(SSH_FXP_READ))
|
|
Packit |
8f70b4 |
return false;
|
|
Packit |
8f70b4 |
return request.Cast<Request_READ>()->pos==pos;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void PushExpect(Expect *);
|
|
Packit |
8f70b4 |
int HandleReplies();
|
|
Packit |
8f70b4 |
int HandlePty();
|
|
Packit |
8f70b4 |
void HandleExpect(Expect *);
|
|
Packit |
8f70b4 |
void CloseExpectQueue();
|
|
Packit |
8f70b4 |
int GetExpectCount(Expect::expect_t tag);
|
|
Packit |
8f70b4 |
void CloseHandle(Expect::expect_t e);
|
|
Packit |
8f70b4 |
int ReplyLogPriority(int);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
xmap_p<Expect> expect_queue;
|
|
Packit |
8f70b4 |
const xstring& expect_key(unsigned id);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Expect *FindExpectExclusive(Packet *reply);
|
|
Packit |
8f70b4 |
xarray_p<Expect> ooo_chain; // out of order replies buffered
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int RespQueueSize() const { return expect_queue.count(); }
|
|
Packit |
8f70b4 |
int RespQueueIsEmpty() const { return RespQueueSize()==0; }
|
|
Packit |
8f70b4 |
void EmptyRespQueue() {
|
|
Packit |
8f70b4 |
expect_queue.empty();
|
|
Packit |
8f70b4 |
ooo_chain.truncate();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool GetBetterConnection(int level,bool limit_reached);
|
|
Packit |
8f70b4 |
void MoveConnectionHere(SFtp *o);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool eof;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SendRequest();
|
|
Packit |
8f70b4 |
void SendRequest(Packet *req,Expect::expect_t exp,int i=0);
|
|
Packit |
8f70b4 |
void SendRequestGeneric(int type);
|
|
Packit |
8f70b4 |
void RequestMoreData();
|
|
Packit |
8f70b4 |
off_t request_pos;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void MergeAttrs(FileInfo *fi,const FileAttrs *a);
|
|
Packit |
8f70b4 |
FileInfo *MakeFileInfo(const NameAttrs *a);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int max_packets_in_flight;
|
|
Packit |
8f70b4 |
int max_packets_in_flight_slow_start;
|
|
Packit |
8f70b4 |
int size_read;
|
|
Packit |
8f70b4 |
int size_write;
|
|
Packit |
8f70b4 |
bool use_full_path;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
protected:
|
|
Packit |
8f70b4 |
void SetError(int code,const Packet *reply);
|
|
Packit |
8f70b4 |
void SetError(int code,const char *mess=0) { FA::SetError(code,mess); }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
static void ClassInit();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
SFtp();
|
|
Packit |
8f70b4 |
SFtp(const SFtp*);
|
|
Packit |
8f70b4 |
~SFtp();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *GetProto() const { return "sftp"; }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileAccess *Clone() const { return new SFtp(this); }
|
|
Packit |
8f70b4 |
static FileAccess *New();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int Do();
|
|
Packit |
8f70b4 |
int Done();
|
|
Packit |
8f70b4 |
int Read(Buffer *,int);
|
|
Packit |
8f70b4 |
int Write(const void *,int);
|
|
Packit |
8f70b4 |
int StoreStatus();
|
|
Packit |
8f70b4 |
int Buffered();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Close();
|
|
Packit |
8f70b4 |
const char *CurrentStatus();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Reconfig(const char *name=0);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool SameSiteAs(const FileAccess *fa) const;
|
|
Packit |
8f70b4 |
bool SameLocationAs(const FileAccess *fa) const;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
DirList *MakeDirList(ArgV *args);
|
|
Packit |
8f70b4 |
Glob *MakeGlob(const char *pattern);
|
|
Packit |
8f70b4 |
ListInfo *MakeListInfo(const char *dir);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool NeedSizeDateBeforehand() { return false; }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SuspendInternal();
|
|
Packit |
8f70b4 |
void ResumeInternal();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileSet *GetFileSet();
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
class SFtpDirList : public DirList
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
SMTaskRef<IOBuffer> ubuf;
|
|
Packit |
8f70b4 |
const char *dir;
|
|
Packit |
8f70b4 |
bool use_file_set;
|
|
Packit |
8f70b4 |
Ref<FileSet> fset;
|
|
Packit |
8f70b4 |
LsOptions ls_options;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
SFtpDirList(SFtp *s,ArgV *a);
|
|
Packit |
8f70b4 |
const char *Status();
|
|
Packit |
8f70b4 |
int Do();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SuspendInternal();
|
|
Packit |
8f70b4 |
void ResumeInternal();
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
class SFtpListInfo : public ListInfo
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
SMTaskRef<IOBuffer> ubuf;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
SFtpListInfo(SFtp *session,const char *dir)
|
|
Packit |
8f70b4 |
: ListInfo(session,dir) {}
|
|
Packit |
8f70b4 |
int Do();
|
|
Packit |
8f70b4 |
const char *Status();
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#endif
|