]>
Commit | Line | Data |
---|---|---|
0763e16d JW |
1 | /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ |
2 | /* | |
3 | Copyright (c) 2002-2010 ymnk, JCraft,Inc. All rights reserved. | |
4 | ||
5 | Redistribution and use in source and binary forms, with or without | |
6 | modification, are permitted provided that the following conditions are met: | |
7 | ||
8 | 1. Redistributions of source code must retain the above copyright notice, | |
9 | this list of conditions and the following disclaimer. | |
10 | ||
11 | 2. Redistributions in binary form must reproduce the above copyright | |
12 | notice, this list of conditions and the following disclaimer in | |
13 | the documentation and/or other materials provided with the distribution. | |
14 | ||
15 | 3. The names of the authors may not be used to endorse or promote products | |
16 | derived from this software without specific prior written permission. | |
17 | ||
18 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, | |
19 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
20 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, | |
21 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, | |
22 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, | |
24 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | |
27 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 | */ | |
29 | ||
30 | package com.jcraft.jsch; | |
31 | import java.net.Socket; | |
32 | ||
33 | class Util{ | |
34 | ||
35 | private static final byte[] b64 =Util.str2byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="); | |
36 | private static byte val(byte foo){ | |
37 | if(foo == '=') return 0; | |
38 | for(int j=0; j<b64.length; j++){ | |
39 | if(foo==b64[j]) return (byte)j; | |
40 | } | |
41 | return 0; | |
42 | } | |
43 | static byte[] fromBase64(byte[] buf, int start, int length){ | |
44 | byte[] foo=new byte[length]; | |
45 | int j=0; | |
46 | for (int i=start;i<start+length;i+=4){ | |
47 | foo[j]=(byte)((val(buf[i])<<2)|((val(buf[i+1])&0x30)>>>4)); | |
48 | if(buf[i+2]==(byte)'='){ j++; break;} | |
49 | foo[j+1]=(byte)(((val(buf[i+1])&0x0f)<<4)|((val(buf[i+2])&0x3c)>>>2)); | |
50 | if(buf[i+3]==(byte)'='){ j+=2; break;} | |
51 | foo[j+2]=(byte)(((val(buf[i+2])&0x03)<<6)|(val(buf[i+3])&0x3f)); | |
52 | j+=3; | |
53 | } | |
54 | byte[] bar=new byte[j]; | |
55 | System.arraycopy(foo, 0, bar, 0, j); | |
56 | return bar; | |
57 | } | |
58 | static byte[] toBase64(byte[] buf, int start, int length){ | |
59 | ||
60 | byte[] tmp=new byte[length*2]; | |
61 | int i,j,k; | |
62 | ||
63 | int foo=(length/3)*3+start; | |
64 | i=0; | |
65 | for(j=start; j<foo; j+=3){ | |
66 | k=(buf[j]>>>2)&0x3f; | |
67 | tmp[i++]=b64[k]; | |
68 | k=(buf[j]&0x03)<<4|(buf[j+1]>>>4)&0x0f; | |
69 | tmp[i++]=b64[k]; | |
70 | k=(buf[j+1]&0x0f)<<2|(buf[j+2]>>>6)&0x03; | |
71 | tmp[i++]=b64[k]; | |
72 | k=buf[j+2]&0x3f; | |
73 | tmp[i++]=b64[k]; | |
74 | } | |
75 | ||
76 | foo=(start+length)-foo; | |
77 | if(foo==1){ | |
78 | k=(buf[j]>>>2)&0x3f; | |
79 | tmp[i++]=b64[k]; | |
80 | k=((buf[j]&0x03)<<4)&0x3f; | |
81 | tmp[i++]=b64[k]; | |
82 | tmp[i++]=(byte)'='; | |
83 | tmp[i++]=(byte)'='; | |
84 | } | |
85 | else if(foo==2){ | |
86 | k=(buf[j]>>>2)&0x3f; | |
87 | tmp[i++]=b64[k]; | |
88 | k=(buf[j]&0x03)<<4|(buf[j+1]>>>4)&0x0f; | |
89 | tmp[i++]=b64[k]; | |
90 | k=((buf[j+1]&0x0f)<<2)&0x3f; | |
91 | tmp[i++]=b64[k]; | |
92 | tmp[i++]=(byte)'='; | |
93 | } | |
94 | byte[] bar=new byte[i]; | |
95 | System.arraycopy(tmp, 0, bar, 0, i); | |
96 | return bar; | |
97 | ||
98 | // return sun.misc.BASE64Encoder().encode(buf); | |
99 | } | |
100 | ||
101 | static String[] split(String foo, String split){ | |
102 | if(foo==null) | |
103 | return null; | |
104 | byte[] buf=Util.str2byte(foo); | |
105 | java.util.Vector bar=new java.util.Vector(); | |
106 | int start=0; | |
107 | int index; | |
108 | while(true){ | |
109 | index=foo.indexOf(split, start); | |
110 | if(index>=0){ | |
111 | bar.addElement(Util.byte2str(buf, start, index-start)); | |
112 | start=index+1; | |
113 | continue; | |
114 | } | |
115 | bar.addElement(Util.byte2str(buf, start, buf.length-start)); | |
116 | break; | |
117 | } | |
118 | String[] result=new String[bar.size()]; | |
119 | for(int i=0; i<result.length; i++){ | |
120 | result[i]=(String)(bar.elementAt(i)); | |
121 | } | |
122 | return result; | |
123 | } | |
124 | static boolean glob(byte[] pattern, byte[] name){ | |
125 | return glob0(pattern, 0, name, 0); | |
126 | } | |
127 | static private boolean glob0(byte[] pattern, int pattern_index, | |
128 | byte[] name, int name_index){ | |
129 | if(name.length>0 && name[0]=='.'){ | |
130 | if(pattern.length>0 && pattern[0]=='.'){ | |
131 | if(pattern.length==2 && pattern[1]=='*') return true; | |
132 | return glob(pattern, pattern_index+1, name, name_index+1); | |
133 | } | |
134 | return false; | |
135 | } | |
136 | return glob(pattern, pattern_index, name, name_index); | |
137 | } | |
138 | static private boolean glob(byte[] pattern, int pattern_index, | |
139 | byte[] name, int name_index){ | |
140 | //System.err.println("glob: "+new String(pattern)+", "+pattern_index+" "+new String(name)+", "+name_index); | |
141 | ||
142 | int patternlen=pattern.length; | |
143 | if(patternlen==0) | |
144 | return false; | |
145 | ||
146 | int namelen=name.length; | |
147 | int i=pattern_index; | |
148 | int j=name_index; | |
149 | ||
150 | while(i<patternlen && j<namelen){ | |
151 | if(pattern[i]=='\\'){ | |
152 | if(i+1==patternlen) | |
153 | return false; | |
154 | i++; | |
155 | if(pattern[i]!=name[j]) | |
156 | return false; | |
157 | i+=skipUTF8Char(pattern[i]); | |
158 | j+=skipUTF8Char(name[j]); | |
159 | continue; | |
160 | } | |
161 | ||
162 | if(pattern[i]=='*'){ | |
163 | while(i<patternlen){ | |
164 | if(pattern[i]=='*'){ | |
165 | i++; | |
166 | continue; | |
167 | } | |
168 | break; | |
169 | } | |
170 | if(patternlen==i) | |
171 | return true; | |
172 | ||
173 | byte foo=pattern[i]; | |
174 | if(foo=='?'){ | |
175 | while(j<namelen){ | |
176 | if(glob(pattern, i, name, j)){ | |
177 | return true; | |
178 | } | |
179 | j+=skipUTF8Char(name[j]); | |
180 | } | |
181 | return false; | |
182 | } | |
183 | else if(foo=='\\'){ | |
184 | if(i+1==patternlen) | |
185 | return false; | |
186 | i++; | |
187 | foo=pattern[i]; | |
188 | while(j<namelen){ | |
189 | if(foo==name[j]){ | |
190 | if(glob(pattern, i+skipUTF8Char(foo), | |
191 | name, j+skipUTF8Char(name[j]))){ | |
192 | return true; | |
193 | } | |
194 | } | |
195 | j+=skipUTF8Char(name[j]); | |
196 | } | |
197 | return false; | |
198 | } | |
199 | ||
200 | while(j<namelen){ | |
201 | if(foo==name[j]){ | |
202 | if(glob(pattern, i, name, j)){ | |
203 | return true; | |
204 | } | |
205 | } | |
206 | j+=skipUTF8Char(name[j]); | |
207 | } | |
208 | return false; | |
209 | } | |
210 | ||
211 | if(pattern[i]=='?'){ | |
212 | i++; | |
213 | j+=skipUTF8Char(name[j]); | |
214 | continue; | |
215 | } | |
216 | ||
217 | if(pattern[i]!=name[j]) | |
218 | return false; | |
219 | ||
220 | i+=skipUTF8Char(pattern[i]); | |
221 | j+=skipUTF8Char(name[j]); | |
222 | ||
223 | if(!(j<namelen)){ // name is end | |
224 | if(!(i<patternlen)){ // pattern is end | |
225 | return true; | |
226 | } | |
227 | if(pattern[i]=='*'){ | |
228 | break; | |
229 | } | |
230 | } | |
231 | continue; | |
232 | } | |
233 | ||
234 | if(i==patternlen && j==namelen) | |
235 | return true; | |
236 | ||
237 | if(!(j<namelen) && // name is end | |
238 | pattern[i]=='*'){ | |
239 | boolean ok=true; | |
240 | while(i<patternlen){ | |
241 | if(pattern[i++]!='*'){ | |
242 | ok=false; | |
243 | break; | |
244 | } | |
245 | } | |
246 | return ok; | |
247 | } | |
248 | ||
249 | return false; | |
250 | } | |
251 | ||
252 | static String quote(String path){ | |
253 | byte[] _path=str2byte(path); | |
254 | int count=0; | |
255 | for(int i=0;i<_path.length; i++){ | |
256 | byte b=_path[i]; | |
257 | if(b=='\\' || b=='?' || b=='*') | |
258 | count++; | |
259 | } | |
260 | if(count==0) | |
261 | return path; | |
262 | byte[] _path2=new byte[_path.length+count]; | |
263 | for(int i=0, j=0; i<_path.length; i++){ | |
264 | byte b=_path[i]; | |
265 | if(b=='\\' || b=='?' || b=='*'){ | |
266 | _path2[j++]='\\'; | |
267 | } | |
268 | _path2[j++]=b; | |
269 | } | |
270 | return byte2str(_path2); | |
271 | } | |
272 | ||
273 | static String unquote(String path){ | |
274 | byte[] foo=str2byte(path); | |
275 | byte[] bar=unquote(foo); | |
276 | if(foo.length==bar.length) | |
277 | return path; | |
278 | return byte2str(bar); | |
279 | } | |
280 | static byte[] unquote(byte[] path){ | |
281 | int pathlen=path.length; | |
282 | int i=0; | |
283 | while(i<pathlen){ | |
284 | if(path[i]=='\\'){ | |
285 | if(i+1==pathlen) | |
286 | break; | |
287 | System.arraycopy(path, i+1, path, i, path.length-(i+1)); | |
288 | pathlen--; | |
289 | i++; | |
290 | continue; | |
291 | } | |
292 | i++; | |
293 | } | |
294 | if(pathlen==path.length) | |
295 | return path; | |
296 | byte[] foo=new byte[pathlen]; | |
297 | System.arraycopy(path, 0, foo, 0, pathlen); | |
298 | return foo; | |
299 | } | |
300 | ||
301 | private static String[] chars={ | |
302 | "0","1","2","3","4","5","6","7","8","9", "a","b","c","d","e","f" | |
303 | }; | |
304 | static String getFingerPrint(HASH hash, byte[] data){ | |
305 | try{ | |
306 | hash.init(); | |
307 | hash.update(data, 0, data.length); | |
308 | byte[] foo=hash.digest(); | |
309 | StringBuffer sb=new StringBuffer(); | |
310 | int bar; | |
311 | for(int i=0; i<foo.length;i++){ | |
312 | bar=foo[i]&0xff; | |
313 | sb.append(chars[(bar>>>4)&0xf]); | |
314 | sb.append(chars[(bar)&0xf]); | |
315 | if(i+1<foo.length) | |
316 | sb.append(":"); | |
317 | } | |
318 | return sb.toString(); | |
319 | } | |
320 | catch(Exception e){ | |
321 | return "???"; | |
322 | } | |
323 | } | |
324 | static boolean array_equals(byte[] foo, byte bar[]){ | |
325 | int i=foo.length; | |
326 | if(i!=bar.length) return false; | |
327 | for(int j=0; j<i; j++){ if(foo[j]!=bar[j]) return false; } | |
328 | //try{while(true){i--; if(foo[i]!=bar[i])return false;}}catch(Exception e){} | |
329 | return true; | |
330 | } | |
331 | static Socket createSocket(String host, int port, int timeout) throws JSchException{ | |
332 | Socket socket=null; | |
333 | if(timeout==0){ | |
334 | try{ | |
335 | socket=new Socket(host, port); | |
336 | return socket; | |
337 | } | |
338 | catch(Exception e){ | |
339 | String message=e.toString(); | |
340 | if(e instanceof Throwable) | |
341 | throw new JSchException(message, (Throwable)e); | |
342 | throw new JSchException(message); | |
343 | } | |
344 | } | |
345 | final String _host=host; | |
346 | final int _port=port; | |
347 | final Socket[] sockp=new Socket[1]; | |
348 | final Exception[] ee=new Exception[1]; | |
349 | String message=""; | |
350 | Thread tmp=new Thread(new Runnable(){ | |
351 | public void run(){ | |
352 | sockp[0]=null; | |
353 | try{ | |
354 | sockp[0]=new Socket(_host, _port); | |
355 | } | |
356 | catch(Exception e){ | |
357 | ee[0]=e; | |
358 | if(sockp[0]!=null && sockp[0].isConnected()){ | |
359 | try{ | |
360 | sockp[0].close(); | |
361 | } | |
362 | catch(Exception eee){} | |
363 | } | |
364 | sockp[0]=null; | |
365 | } | |
366 | } | |
367 | }); | |
368 | tmp.setName("Opening Socket "+host); | |
369 | tmp.start(); | |
370 | try{ | |
371 | tmp.join(timeout); | |
372 | message="timeout: "; | |
373 | } | |
374 | catch(java.lang.InterruptedException eee){ | |
375 | } | |
376 | if(sockp[0]!=null && sockp[0].isConnected()){ | |
377 | socket=sockp[0]; | |
378 | } | |
379 | else{ | |
380 | message+="socket is not established"; | |
381 | if(ee[0]!=null){ | |
382 | message=ee[0].toString(); | |
383 | } | |
384 | tmp.interrupt(); | |
385 | tmp=null; | |
386 | throw new JSchException(message); | |
387 | } | |
388 | return socket; | |
389 | } | |
390 | ||
391 | static byte[] str2byte(String str, String encoding){ | |
392 | if(str==null) | |
393 | return null; | |
394 | try{ return str.getBytes(encoding); } | |
395 | catch(java.io.UnsupportedEncodingException e){ | |
396 | return str.getBytes(); | |
397 | } | |
398 | } | |
399 | ||
400 | static byte[] str2byte(String str){ | |
401 | return str2byte(str, "UTF-8"); | |
402 | } | |
403 | ||
404 | static String byte2str(byte[] str, String encoding){ | |
405 | return byte2str(str, 0, str.length, encoding); | |
406 | } | |
407 | ||
408 | static String byte2str(byte[] str, int s, int l, String encoding){ | |
409 | try{ return new String(str, s, l, encoding); } | |
410 | catch(java.io.UnsupportedEncodingException e){ | |
411 | return new String(str, s, l); | |
412 | } | |
413 | } | |
414 | ||
415 | static String byte2str(byte[] str){ | |
416 | return byte2str(str, 0, str.length, "UTF-8"); | |
417 | } | |
418 | ||
419 | static String byte2str(byte[] str, int s, int l){ | |
420 | return byte2str(str, s, l, "UTF-8"); | |
421 | } | |
422 | ||
423 | static final byte[] empty = str2byte(""); | |
424 | ||
425 | /* | |
426 | static byte[] char2byte(char[] foo){ | |
427 | int len=0; | |
428 | for(int i=0; i<foo.length; i++){ | |
429 | if((foo[i]&0xff00)==0) len++; | |
430 | else len+=2; | |
431 | } | |
432 | byte[] bar=new byte[len]; | |
433 | for(int i=0, j=0; i<foo.length; i++){ | |
434 | if((foo[i]&0xff00)==0){ | |
435 | bar[j++]=(byte)foo[i]; | |
436 | } | |
437 | else{ | |
438 | bar[j++]=(byte)(foo[i]>>>8); | |
439 | bar[j++]=(byte)foo[i]; | |
440 | } | |
441 | } | |
442 | return bar; | |
443 | } | |
444 | */ | |
445 | static void bzero(byte[] foo){ | |
446 | if(foo==null) | |
447 | return; | |
448 | for(int i=0; i<foo.length; i++) | |
449 | foo[i]=0; | |
450 | } | |
451 | ||
452 | static String diffString(String str, String[] not_available){ | |
453 | String[] stra=Util.split(str, ","); | |
454 | String result=null; | |
455 | loop: | |
456 | for(int i=0; i<stra.length; i++){ | |
457 | for(int j=0; j<not_available.length; j++){ | |
458 | if(stra[i].equals(not_available[j])){ | |
459 | continue loop; | |
460 | } | |
461 | } | |
462 | if(result==null){ result=stra[i]; } | |
463 | else{ result=result+","+stra[i]; } | |
464 | } | |
465 | return result; | |
466 | } | |
467 | ||
468 | private static int skipUTF8Char(byte b){ | |
469 | if((byte)(b&0x80)==0) return 1; | |
470 | if((byte)(b&0xe0)==(byte)0xc0) return 2; | |
471 | if((byte)(b&0xf0)==(byte)0xe0) return 3; | |
472 | return 1; | |
473 | } | |
474 | } |