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