1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
|
* Example: print a remote ascii file using sftp
*
h DFTACTGRP(*NO) ACTGRP(*NEW)
h OPTION(*NOSHOWCPY)
h BNDDIR('LIBSSH2')
h BNDDIR('QC2LE')
*
* Copyright (C) The libssh2 project and its contributors.
*
* Usage:
*
* CALL SFTPXMPLE ('<host>' '<port>' '<user>' '<password>' '<filepath>')
*
* SPDX-License-Identifier: BSD-3-Clause
*
fQPRINT o f 120 printer
*
/include LIBSSH2RPG,SSH2_SFTP
/include LIBSSH2RPG,SSH2_CCSID
*
d pi
d host 120
d port 5
d user 20
d password 120
d filepath 120
*
**************************************************************************
* External definitions
**************************************************************************
*
d atoi pr 10i 0 extproc('atoi')
d numstr * value options(*string)
*
d inet_addr pr 10u 0 extproc('inet_addr')
d char_addr * value options(*string)
*
d socket pr 10i 0 extproc('socket')
d domain 10i 0 value
d type 10i 0 value
d protocol 10i 0 value
*
d AF_INET c 2
d SOCK_STREAM c 1
d IPPROTO_IP c 0
*
d connect pr 10i 0 extproc('connect')
d sockfd 10i 0 value
d addr * value
d addrlen 10u 0 value
*
d sockaddr_in ds based(######typedef######)
d align qualified
d sin_family 5i 0
d sin_port 5i 0
d sin_addr 10u 0
d sin_zero 8
*
d shutdown pr 10i 0 extproc('shutdown')
d socket 10i 0 value
d how 10i 0 value
*
d SHUT_RDWR c 2
*
d qmhsndpm pr extpgm('QMHSNDPM')
d msgid 7 const
d qmsgfn 20 const
d data 999999 const options(*varsize)
d datalength 10u 0 const
d msgtype 10 const
d csentry 999999 const options(*varsize)
d cscounter 10u 0 const
d msgkey 4
d errcode 999999 options(*varsize)
d csentrylen 10u 0 const options(*nopass)
d csqual 20 const options(*nopass)
d waittime 10u 0 const options(*nopass)
d csentrytype 10 const options(*nopass)
d ccsid 10u 0 const options(*nopass)
*
**************************************************************************
* Constants
**************************************************************************
*
d EBCDIC_CR c X'0D'
d EBCDIC_LF c X'25'
*
**************************************************************************
* Global storage
**************************************************************************
*
d sc s * inz(*NULL) String cache
d session s * inz(*NULL) Session
d sftp_session s * inz(*NULL) LIBSSH2_SFTP *
d sftp_handle s * inz(*NULL) LIBSSH2_SFTP_HANDLE*
d sin ds likeds(sockaddr_in) Remote IP address
d sock s 10i 0 inz(LIBSSH2_INVALID_SOCKET) Socket descriptor
d rc s 10i 0 Result code
d hostlen s 10u 0 Host name length
*
**************************************************************************
* Main program
**************************************************************************
// Initialize ssh lbrary
rc = libssh2_init(0);
if rc <> 0;
error('libssh2 initialization failed (' + %trim(%char(rc)) + ')');
else;
// Build remote address
sin.sin_family = AF_INET;
hostlen = trimmed_length(host: %len(host): %addr(port));
if hostlen <> 0;
sin.sin_addr = inet_addr(%subst(host: 1: hostlen));
else;
sin.sin_addr = inet_addr('127.0.0.1');
endif;
sin.sin_port = atoi(port);
if sin.sin_port <= 0;
sin.sin_port = 22;
endif;
sin.sin_zero = *ALLX'00';
main();
cleanout();
endif;
*inlr = *on;
/space 3
begsr *pssr;
cleanout();
endsr;
/eject
**************************************************************************
* Main procedure
**************************************************************************
*
p main b
*
d buf s 1024 Data buffer
d nread s 10i 0 Read bytes count
// Connect to remote server
sock = socket(AF_INET: SOCK_STREAM: IPPROTO_IP);
if sock = LIBSSH2_INVALID_SOCKET;
error('failed to create socket');
return;
endif;
if connect(sock: %addr(sin): %size(sin)) <> 0;
error('failed to connect');
return;
endif;
// Create a session instance
session = libssh2_session_init();
if session = *NULL;
error('Could not initialize SSH session');
return;
endif;
// Since we have set non-blocking, tell libssh2 we are blocking
libssh2_session_set_blocking(session: 1);
// ... start it up. This will trade welcome banners, exchange keys,
// and setup crypto, compression, and MAC layers
rc = libssh2_session_handshake(session: sock);
if rc <> 0;
error('Failure establishing SSH session: ' + %trim(%char(rc)));
return;
endif;
// Authenticate
if libssh2_userauth_password(session:
libssh2_from_ccsid(session: sc: 0: user:
trimmed_length(user: %size(user):
%addr(password)): *omit):
libssh2_from_ccsid(session: sc: 0: password:
trimmed_length(password: %size(password):
%addr(filepath)): *omit)) <> 0;
error('Authentication by password failed');
return;
endif;
// Request a file via SFTP
sftp_session = libssh2_sftp_init(session);
if sftp_session = *NULL;
error('Unable to init SFTP session');
return;
endif;
sftp_handle = libssh2_sftp_open(sftp_session:
libssh2_from_ccsid(session: sc: 0: filepath:
trimmed_length(filepath: %size(filepath): *null):
*omit): LIBSSH2_FXF_READ: 0);
if sftp_handle = *NULL;
error('Unable to open file with SFTP: ' +
%trim(%char(libssh2_sftp_last_error(sftp_session))));
return;
endif;
// Download and display the remote file
nread = libssh2_sftp_read(sftp_handle: %addr(buf): %size(buf));
dow nread > 0; // loop until we fail
print(libssh2_to_ccsid(session: sc: 0: %addr(buf): nread: *omit):
-1);
libssh2_release_string_cache(session: sc);
nread = libssh2_sftp_read(sftp_handle: %addr(buf): %size(buf));
enddo;
p main e
/eject
**************************************************************************
* Release all allocated resources
**************************************************************************
*
p cleanout b
*
if sftp_handle <> *NULL;
libssh2_sftp_close(sftp_handle);
endif;
if sftp_session <> *NULL;
libssh2_sftp_shutdown(sftp_session);
endif;
if session <> *NULL;
libssh2_session_disconnect(session: libssh2_from_ccsid(session: sc:
0: 'Normal shutdown': -1: *omit));
libssh2_release_string_cache(session: sc);
libssh2_session_free(session);
endif;
if sock <> LIBSSH2_INVALID_SOCKET;
shutdown(sock: SHUT_RDWR);
LIBSSH2_SOCKET_CLOSE(sock);
endif;
libssh2_exit();
p cleanout e
/eject
**************************************************************************
* Print data line by line
**************************************************************************
*
p print b
d pi
d string * value options(*string)
d len 10i 0 value
*
d recout ds Output line buffer
d lineout 120 inz(*blanks)
*
d i s 10u 0
d j s 10u 0 inz(0)
if len < 0;
len = %len(%str(string));
endif;
for i = 0 to len - 1;
if %str(string + i: 1) <> EBCDIC_CR;
if %str(string + i: 1) = EBCDIC_LF;
write QPRINT recout;
lineout = *blanks;
j = 0;
else;
if j >= %size(lineout);
write QPRINT recout;
lineout = *blanks;
j = 0;
endif;
j = j + 1;
%subst(lineout: j: 1) = %str(string + i: 1);
endif;
endif;
endfor;
if j > 0;
write QPRINT recout;
endif;
p print e
/eject
**************************************************************************
* Error procedure
**************************************************************************
*
p error b
d pi
d message * value options(*string)
*
d errcode ds qualified
d provided 10u 0 inz(0)
d available 10u 0
*
d msgkey s 4
// Send error as an exception to the calling level.
qmhsndpm('CPF9898': 'QCPFMSG QSYS':
%str(message): %len(%str(message)): '*ESCAPE':
'* ': 1: msgkey: errcode);
p error e
/eject
**************************************************************************
* Get the length of right-trimmed string
**************************************************************************
*
p trimmed_length b
d pi 10u 0
d string 999999 options(*varsize)
d length 10u 0 value
d nextarg * value
*
d len s 10u 0
if nextarg <> *null;
len = nextarg - %addr(string);
if length > len;
length = len;
endif;
endif;
len = %scan(X'00': string: 1: length); // Maybe zero-terminated
if len = 0;
len = length + 1;
endif;
return %checkr(' ': string: len - 1); // Trim right
p trimmed_length e
|