1 module libssh.scp; 2 3 import libssh.c_bindings.libssh; 4 import libssh.errors; 5 import libssh.utils; 6 import libssh.session; 7 8 enum SCPMode : int { 9 Write = SSH_SCP_WRITE, 10 Read = SSH_SCP_READ, 11 Recursive = SSH_SCP_RECURSIVE, 12 } 13 14 enum SCPRequest : int { 15 NewDir = ssh_scp_request_types.SSH_SCP_REQUEST_NEWDIR, 16 NewFile = ssh_scp_request_types.SSH_SCP_REQUEST_NEWFILE, 17 EOF = ssh_scp_request_types.SSH_SCP_REQUEST_EOF, 18 EndDir = ssh_scp_request_types.SSH_SCP_REQUEST_ENDDIR, 19 Warning = ssh_scp_request_types.SSH_SCP_REQUEST_WARNING, 20 } 21 22 class SSHSCP : Disposable { 23 24 @property string requestFilename() { 25 auto result = ssh_scp_request_get_filename(this._scp); 26 checkForNullError(result, "Error while getting request file name"); 27 return copyFromStrZ(result); 28 } 29 30 @property uint requestPermissions() { 31 auto result = ssh_scp_request_get_permissions(this._scp); 32 if (result < 0) { 33 throw new SSHException(result); 34 } 35 return cast(uint) result; 36 } 37 38 @property size_t requestSize() { 39 return ssh_scp_request_get_size(this._scp); 40 } 41 42 @property ulong requestSize64() { 43 return ssh_scp_request_get_size64(this._scp); 44 } 45 46 @property string requestWarning() { 47 auto result = ssh_scp_request_get_warning(this._scp); 48 checkForNullError(result, "Error while getting request warning"); 49 return copyFromStrZ(result); 50 } 51 52 void acceptRequest() { 53 auto rc = ssh_scp_accept_request(this._scp); 54 checkForRCError(rc, rc, "Error while accept request"); 55 } 56 57 void denyRequest(string reason) { 58 auto rc = ssh_scp_deny_request(this._scp, toStrZ(reason)); 59 checkForRCError(rc, rc, "Error while deny request"); 60 } 61 62 void leaveDirectory() { 63 auto rc = ssh_scp_leave_directory(this._scp); 64 checkForRCError(rc, rc, "Error while leave directory"); 65 } 66 67 SCPRequest pullRequest() { 68 auto rc = ssh_scp_pull_request(this._scp); 69 if (rc < 0) { 70 throw new SSHException(rc, "Error while pull request"); 71 } 72 return cast(SCPRequest) rc; 73 } 74 75 void pushDirectory(string dirName, int mode) { 76 auto rc = ssh_scp_push_directory(this._scp, toStrZ(dirName), mode); 77 checkForRCError(rc, rc, "Error while pushing directory"); 78 } 79 80 void pushFile(string fileName, size_t size, uint mode) { 81 auto rc = ssh_scp_push_file(this._scp, toStrZ(fileName), size, cast(uint) mode); 82 checkForRCError(rc, rc, "Error while pushing file"); 83 } 84 85 void pushFile64(string fileName, ulong size, uint mode) { 86 auto rc = ssh_scp_push_file64(this._scp, toStrZ(fileName), size, cast(uint) mode); 87 checkForRCError(rc, rc, "Error while pushing file"); 88 } 89 90 int read(void[] buffer) { 91 auto rc = ssh_scp_read(this._scp, buffer.ptr, buffer.length); 92 if (rc < 0) { 93 throw new SSHException(rc, "Error while reading"); 94 } 95 return rc; 96 } 97 98 void write(const void[] buffer) { 99 auto rc = ssh_scp_write(this._scp, buffer.ptr, buffer.length); 100 checkForRCError(rc, rc, "Error while writing"); 101 } 102 103 void init() { 104 auto rc = ssh_scp_init(this._scp); 105 checkForRCError(rc, rc, "Error while initializing scp"); 106 } 107 108 void close() { 109 auto rc = ssh_scp_close(this._scp); 110 checkForRCError(rc, rc, "Error while closing"); 111 } 112 113 ~this() { 114 this._dispose(true); 115 } 116 117 override void dispose() { 118 this._dispose(false); 119 } 120 121 package { 122 this(SSHSession parent, ssh_scp scp) { 123 this._session = parent; 124 this._scp = scp; 125 } 126 } 127 128 private { 129 void _dispose(bool fromDtor) { 130 if (this._scp !is null) { 131 ssh_scp_free(this._scp); 132 this._session = null; 133 this._scp = null; 134 } 135 } 136 137 SSHSession _session; 138 ssh_scp _scp; 139 } 140 }