1 18 19 package com.knowgate.jcifs.smb; 20 21 import java.net.URLConnection ; 22 import java.net.URL ; 23 import java.net.MalformedURLException ; 24 import java.net.UnknownHostException ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.io.OutputStream ; 28 import java.util.ArrayList ; 29 30 import com.knowgate.debug.*; 31 import com.knowgate.jcifs.Config; 32 import com.knowgate.jcifs.UniAddress; 33 import com.knowgate.jcifs.netbios.NbtAddress; 34 35 import java.util.Date ; 36 37 265 266 public class SmbFile extends URLConnection { 267 268 static final int O_RDONLY = 0x010000; 270 static final int O_WRONLY = 0x020000; 271 static final int O_RDWR = 0x030000; 272 static final int O_APPEND = 0x040000; 273 274 281 public static final int FILE_NO_SHARE = 0x00; 282 288 public static final int FILE_SHARE_READ = 0x01; 289 295 public static final int FILE_SHARE_WRITE = 0x02; 296 302 public static final int FILE_SHARE_DELETE = 0x04; 303 304 static final int O_CREAT = 0x0010; 307 static final int O_EXCL = 0x0001; 309 static final int O_TRUNC = 0x0002; 311 312 317 public static final int ATTR_READONLY = 0x01; 318 322 public static final int ATTR_HIDDEN = 0x02; 323 327 public static final int ATTR_SYSTEM = 0x04; 328 332 public static final int ATTR_VOLUME = 0x08; 333 337 public static final int ATTR_DIRECTORY = 0x10; 338 342 public static final int ATTR_ARCHIVE = 0x20; 343 344 static final int ATTR_COMPRESSED = 0x800; 346 static final int ATTR_NORMAL = 0x080; 347 static final int ATTR_TEMPORARY = 0x100; 348 349 static final int ATTR_GET_MASK = 0x3F; 350 static final int ATTR_SET_MASK = 0x27; 351 352 static final int DEFAULT_ATTR_EXPIRATION_PERIOD = 5000; 353 354 static final int HASH_DOT = ".".hashCode(); 355 static final int HASH_DOT_DOT = "..".hashCode(); 356 357 static long attrExpirationPeriod; 358 359 static { 360 try { 361 Class.forName( "jcifs.Config" ); 362 } catch( ClassNotFoundException cnfe ) { 363 cnfe.printStackTrace(); 364 } 365 attrExpirationPeriod = Config.getLong( "jcifs.smb.client.attrExpirationPeriod", DEFAULT_ATTR_EXPIRATION_PERIOD ); 366 } 367 368 372 public static final int TYPE_FILESYSTEM = 0x01; 373 377 public static final int TYPE_WORKGROUP = 0x02; 378 382 public static final int TYPE_SERVER = 0x04; 383 387 public static final int TYPE_SHARE = 0x08; 388 392 public static final int TYPE_NAMED_PIPE = 0x10; 393 397 public static final int TYPE_PRINTER = 0x20; 398 402 public static final int TYPE_COMM = 0x40; 403 404 405 private String canon; private String share; private long createTime; 408 private long lastModified; 409 private int attributes; 410 private long attrExpiration; 411 private long size; 412 private long sizeExpiration; 413 private NtlmPasswordAuthentication auth; private boolean isExists; 415 private int shareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; 416 private SmbComBlankResponse blank_resp = null; 417 private DfsReferral dfsReferral = null; 419 SmbTree tree = null; String unc; int fid; int type; 423 boolean opened; 424 425 434 435 public SmbFile( String url ) throws MalformedURLException { 436 this( new URL ( null, url, Handler.SMB_HANDLER )); 437 } 438 439 453 454 public SmbFile( SmbFile context, String name ) 455 throws MalformedURLException , UnknownHostException { 456 this( context.isWorkgroup0() ? 457 new URL ( null, "smb://" + name, Handler.SMB_HANDLER ) : 458 new URL ( context.url, name, Handler.SMB_HANDLER ), context.auth ); 459 } 460 461 473 474 public SmbFile( String context, String name ) throws MalformedURLException { 475 this( new URL ( new URL ( null, context, Handler.SMB_HANDLER ), 476 name, Handler.SMB_HANDLER )); 477 } 478 479 488 public SmbFile( String url, NtlmPasswordAuthentication auth ) 489 throws MalformedURLException { 490 this( new URL ( null, url, Handler.SMB_HANDLER ), auth ); 491 } 492 506 public SmbFile( String url, NtlmPasswordAuthentication auth, int shareAccess ) 507 throws MalformedURLException { 508 this( new URL ( null, url, Handler.SMB_HANDLER ), auth ); 509 if ((shareAccess & ~(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)) != 0) { 510 throw new RuntimeException ( "Illegal shareAccess parameter" ); 511 } 512 this.shareAccess = shareAccess; 513 } 514 527 public SmbFile( String context, String name, NtlmPasswordAuthentication auth ) 528 throws MalformedURLException { 529 this( new URL ( new URL ( null, context, Handler.SMB_HANDLER ), name, Handler.SMB_HANDLER ), auth ); 530 } 531 550 public SmbFile( String context, String name, NtlmPasswordAuthentication auth, int shareAccess ) 551 throws MalformedURLException { 552 this( new URL ( new URL ( null, context, Handler.SMB_HANDLER ), name, Handler.SMB_HANDLER ), auth ); 553 if ((shareAccess & ~(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)) != 0) { 554 throw new RuntimeException ( "Illegal shareAccess parameter" ); 555 } 556 this.shareAccess = shareAccess; 557 } 558 564 public SmbFile( URL url ) { 565 this( url, new NtlmPasswordAuthentication( url.getUserInfo() )); 566 } 567 575 public SmbFile( URL url, NtlmPasswordAuthentication auth ) { 576 super( url ); 577 this.auth = auth == null ? new NtlmPasswordAuthentication( url.getUserInfo() ) : auth; 578 579 getUncPath0(); 580 } 581 SmbFile( SmbFile context, String name, int type, 582 int attributes, long createTime, long lastModified, long size ) 583 throws MalformedURLException , UnknownHostException { 584 this( context.isWorkgroup0() ? 585 new URL ( null, "smb://" + name + "/", Handler.SMB_HANDLER ) : 586 new URL ( context.url, name + (( attributes & ATTR_DIRECTORY ) > 0 ? "/" : "" ))); 587 588 if( context.share != null ) { 589 this.tree = context.tree; 590 } 591 int last = name.length() - 1; 592 if( name.charAt( last ) == '/' ) { 593 name = name.substring( 0, last ); 594 } 595 if( context.share == null ) { 596 this.unc = "\\"; 597 } else if( context.unc.equals( "\\" )) { 598 this.unc = '\\' + name; 599 } else { 600 this.unc = context.unc + '\\' + name; 601 } 602 605 this.type = type; 606 this.attributes = attributes; 607 this.createTime = createTime; 608 this.lastModified = lastModified; 609 this.size = size; 610 isExists = true; 611 612 attrExpiration = sizeExpiration = 613 System.currentTimeMillis() + attrExpirationPeriod; 614 } 615 616 private SmbComBlankResponse blank_resp() { 617 if( blank_resp == null ) { 618 blank_resp = new SmbComBlankResponse(); 619 } 620 return blank_resp; 621 } 622 void sendTransaction( SmbComTransaction request, 623 SmbComTransactionResponse response ) throws SmbException { 624 for( ;; ) { 625 connect0(); 626 if( tree.inDfs ) { 627 DfsReferral dr = tree.session.transport.lookupReferral( unc ); 628 if( dr != null ) { 629 UniAddress addr; 630 SmbTransport trans; 631 632 try { 633 addr = UniAddress.getByName( dr.server ); 634 } catch( UnknownHostException uhe ) { 635 throw new SmbException( dr.server, uhe ); 636 } 637 638 trans = SmbTransport.getSmbTransport( addr, 0 ); 639 tree = trans.getSmbSession( auth ).getSmbTree( dr.share, null ); 640 unc = dr.nodepath + unc.substring( dr.path.length() ); 641 if( request.path.charAt( request.path.length() - 1 ) == '\\' ) { 642 request.path = unc + '\\'; 643 } else { 644 request.path = unc; 645 } 646 dfsReferral = dr; 647 } 648 } 649 if( tree.inDfs ) { 650 request.flags2 |= ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS; 651 } else { 652 request.flags2 &= ~ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS; 653 } 654 try { 655 tree.sendTransaction( request, response ); 656 break; 657 } catch( DfsReferral dr ) { 658 if( dr.resolveHashes ) { 659 throw dr; 660 } 661 request.reset(); 662 } 663 } 664 } 665 void send( ServerMessageBlock request, 666 ServerMessageBlock response ) throws SmbException { 667 for( ;; ) { 668 connect0(); 669 if( tree.inDfs ) { 670 DfsReferral dr = tree.session.transport.lookupReferral( unc ); 671 if( dr != null ) { 672 UniAddress addr; 673 SmbTransport trans; 674 675 try { 676 addr = UniAddress.getByName( dr.server ); 677 } catch( UnknownHostException uhe ) { 678 throw new SmbException( dr.server, uhe ); 679 } 680 681 trans = SmbTransport.getSmbTransport( addr, 0 ); 682 tree = trans.getSmbSession( auth ).getSmbTree( dr.share, null ); 683 unc = request.path = dr.nodepath + unc.substring( dr.path.length() ); 684 dfsReferral = dr; 685 } 686 request.flags2 |= ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS; 687 } else { 688 request.flags2 &= ~ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS; 689 } 690 try { 691 tree.send( request, response ); 692 break; 693 } catch( DfsReferral dr ) { 694 if( dr.resolveHashes ) { 695 throw dr; 696 } 697 } 698 } 699 } 700 701 static String queryLookup( String query, String param ) { 702 char in[] = query.toCharArray(); 703 int i, ch, st, eq; 704 705 st = eq = 0; 706 for( i = 0; i < in.length; i++) { 707 ch = in[i]; 708 if( ch == '&' ) { 709 if( eq > st ) { 710 String p = new String ( in, st, eq - st ); 711 if( p.equalsIgnoreCase( param )) { 712 eq++; 713 return new String ( in, eq, i - eq ); 714 } 715 } 716 st = i + 1; 717 } else if( ch == '=' ) { 718 eq = i; 719 } 720 } 721 if( eq > st ) { 722 String p = new String ( in, st, eq - st ); 723 if( p.equalsIgnoreCase( param )) { 724 eq++; 725 return new String ( in, eq, in.length - eq ); 726 } 727 } 728 729 return null; 730 } 731 732 UniAddress getAddress() throws UnknownHostException { 733 String host = url.getHost(); 734 String path = url.getPath(); 735 String query = url.getQuery(); 736 737 if( query != null ) { 738 String server = queryLookup( query, "server" ); 739 if( server != null && server.length() > 0 ) { 740 return UniAddress.getByName( server ); 741 } 742 } 743 744 if( host.length() == 0 ) { 745 return UniAddress.getByName( NbtAddress.getByName( 746 NbtAddress.MASTER_BROWSER_NAME, 0x01, null).getHostAddress() ); 747 } else if( path.length() == 0 || path.equals( "/" )) { 748 return UniAddress.getByName( host, true ); 749 } else { 750 return UniAddress.getByName( host ); 751 } 752 } 753 void connect0() throws SmbException { 754 try { 755 connect(); 756 } catch( UnknownHostException uhe ) { 757 throw new SmbException( "Failed to connect to server", uhe ); 758 } catch( SmbException se ) { 759 throw se; 760 } catch( IOException ioe ) { 761 throw new SmbException( "Failed to connect to server", ioe ); 762 } 763 } 764 768 public void connect() throws IOException { 769 SmbTransport trans; 770 SmbSession ssn; 771 UniAddress addr; 772 773 if( isConnected() ) { 774 return; 775 } 776 777 getUncPath0(); 778 addr = getAddress(); 779 780 trans = SmbTransport.getSmbTransport( addr, url.getPort() ); 781 ssn = trans.getSmbSession( auth ); 782 tree = ssn.getSmbTree( share, null ); 783 784 try { 785 tree.treeConnect( null, null ); 786 } catch( SmbAuthException sae ) { 787 NtlmPasswordAuthentication a; 788 789 if( share == null ) { ssn = trans.getSmbSession( NtlmPasswordAuthentication.NULL ); 791 tree = ssn.getSmbTree( null, null ); 792 tree.treeConnect( null, null ); 793 } else if(( a = NtlmAuthenticator.requestNtlmPasswordAuthentication( 794 url.toString(), sae )) != null ) { 795 auth = a; 796 ssn = trans.getSmbSession( auth ); 797 tree = ssn.getSmbTree( share, null ); 798 tree.treeConnect( null, null ); 799 } else { 800 throw sae; 801 } 802 } 803 } 804 boolean isConnected() { 805 return (connected = tree != null && tree.treeConnected); 806 } 807 int open0( int flags, int attrs, int options ) throws SmbException { 808 int f; 809 810 connect0(); 811 812 if( DebugFile.trace ) 813 DebugFile.writeln( "open0: " + unc ); 814 815 818 819 if( tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS )) { 820 SmbComNTCreateAndXResponse response = new SmbComNTCreateAndXResponse(); 821 send( new SmbComNTCreateAndX( unc, flags, shareAccess, 822 attrs, options, null ), response ); 823 f = response.fid; 824 attributes = response.extFileAttributes & ATTR_GET_MASK; 825 attrExpiration = System.currentTimeMillis() + attrExpirationPeriod; 826 isExists = true; 827 } else { 828 SmbComOpenAndXResponse response = new SmbComOpenAndXResponse(); 829 send( new SmbComOpenAndX( unc, flags, null ), response ); 830 f = response.fid; 831 } 832 833 return f; 834 } 835 void open( int flags, int attrs, int options ) throws SmbException { 836 if( isOpen() ) { 837 return; 838 } 839 fid = open0( flags, attrs, options ); 840 opened = true; 841 } 842 boolean isOpen() { 843 return opened && isConnected(); 844 } 845 void close( int f, long lastWriteTime ) throws SmbException { 846 847 if( DebugFile.trace ) 848 DebugFile.writeln( "close: " + f ); 849 850 853 854 send( new SmbComClose( f, lastWriteTime ), blank_resp() ); 855 } 856 void close( long lastWriteTime ) throws SmbException { 857 if( isOpen() == false ) { 858 return; 859 } 860 close( fid, lastWriteTime ); 861 opened = false; 862 } 863 void close() throws SmbException { 864 close( 0L ); 865 } 866 867 881 882 public String getName() { 883 getUncPath0(); 884 if( canon.length() > 1 ) { 885 int i = canon.length() - 2; 886 while( canon.charAt( i ) != '/' ) { 887 i--; 888 } 889 return canon.substring( i + 1 ); 890 } else if( share != null ) { 891 return share + '/'; 892 } else if( url.getHost().length() > 0 ) { 893 return url.getHost() + '/'; 894 } else { 895 return "smb://"; 896 } 897 } 898 899 908 909 public String getParent() { 910 String str = url.getAuthority(); 911 912 if( str.length() > 0 ) { 913 StringBuffer sb = new StringBuffer ( "smb://" ); 914 915 sb.append( str ); 916 917 getUncPath0(); 918 if( canon.length() > 1 ) { 919 sb.append( canon ); 920 } else { 921 sb.append( '/' ); 922 } 923 924 str = sb.toString(); 925 926 int i = str.length() - 2; 927 while( str.charAt( i ) != '/' ) { 928 i--; 929 } 930 931 return str.substring( 0, i + 1 ); 932 } 933 934 return "smb://"; 935 } 936 937 944 945 public String getPath() { 946 return url.toString(); 947 } 948 949 String getUncPath0() { 950 if( unc == null ) { 951 char[] in = url.getPath().toCharArray(); 952 char[] out = new char[in.length]; 953 int length = in.length, i, o, state, s; 954 955 957 state = 0; 958 o = 0; 959 for( i = 0; i < length; i++ ) { 960 switch( state ) { 961 case 0: 962 if( in[i] != '/' ) { 963 return null; 964 } 965 out[o++] = in[i]; 966 state = 1; 967 break; 968 case 1: 969 if( in[i] == '/' ) { 970 break; 971 } else if( in[i] == '.' && 972 (( i + 1 ) >= length || in[i + 1] == '/' )) { 973 i++; 974 break; 975 } else if(( i + 1 ) < length && 976 in[i] == '.' && 977 in[i + 1] == '.' && 978 (( i + 2 ) >= length || in[i + 2] == '/' )) { 979 i += 2; 980 if( o == 1 ) break; 981 do { 982 o--; 983 } while( o > 1 && out[o - 1] != '/' ); 984 break; 985 } 986 state = 2; 987 case 2: 988 if( in[i] == '/' ) { 989 state = 1; 990 } 991 out[o++] = in[i]; 992 break; 993 } 994 } 995 996 canon = new String ( out, 0, o ); 997 998 if( o > 1 ) { 999 o--; 1000 i = canon.indexOf( '/', 1 ); 1001 if( i < 0 ) { 1002 share = canon.substring( 1 ); 1003 unc = "\\"; 1004 } else if( i == o ) { 1005 share = canon.substring( 1, i ); 1006 unc = "\\"; 1007 } else { 1008 share = canon.substring( 1, i ); 1009 unc = canon.substring( i, out[o] == '/' ? o : o + 1 ); 1010 unc = unc.replace( '/', '\\' ); 1011 } 1012 } else { 1013 share = null; 1014 unc = "\\"; 1015 } 1016 } 1017 return unc; 1018 } 1019 1024 public String getUncPath() { 1025 getUncPath0(); 1026 if( share == null ) { 1027 return "\\\\" + url.getHost(); 1028 } 1029 return "\\\\" + url.getHost() + canon.replace( '/', '\\' ); 1030 } 1031 1039 1040 public String getCanonicalPath() { 1041 String str = url.getAuthority(); 1042 getUncPath0(); 1043 if( str.length() > 0 ) { 1044 return "smb://" + url.getAuthority() + canon; 1045 } 1046 return "smb://"; 1047 } 1048 1049 1057 1058 public String getShare() { 1059 return share; 1060 } 1061 1062 1071 1072 public String getServer() { 1073 String str = url.getHost(); 1074 if( str.length() == 0 ) { 1075 return null; 1076 } 1077 return str; 1078 } 1079 1080 1085 public int getType() throws SmbException { 1086 if( type == 0 ) { 1087 if( getUncPath0().length() > 1 ) { 1088 type = TYPE_FILESYSTEM; 1089 } else if( share != null ) { 1090 connect0(); 1092 if( share.equals( "IPC$" )) { 1093 type = TYPE_NAMED_PIPE; 1094 } else if( tree.service.equals( "LPT1:" )) { 1095 type = TYPE_PRINTER; 1096 } else if( tree.service.equals( "COMM" )) { 1097 type = TYPE_COMM; 1098 } else { 1099 type = TYPE_SHARE; 1100 } 1101 } else if( url.getAuthority().length() == 0 ) { 1102 type = TYPE_WORKGROUP; 1103 } else { 1104 UniAddress addr; 1105 try { 1106 addr = getAddress(); 1107 } catch( UnknownHostException uhe ) { 1108 throw new SmbException( url.toString(), uhe ); 1109 } 1110 if( addr.getAddress() instanceof NbtAddress ) { 1111 int code = ((NbtAddress)addr.getAddress()).getNameType(); 1112 if( code == 0x1d || code == 0x1b ) { 1113 type = TYPE_WORKGROUP; 1114 return type; 1115 } 1116 } 1117 type = TYPE_SERVER; 1118 } 1119 } 1120 return type; 1121 } 1122 boolean isWorkgroup0() throws UnknownHostException { 1123 if( type == TYPE_WORKGROUP || url.getHost().length() == 0 ) { 1124 type = TYPE_WORKGROUP; 1125 return true; 1126 } else { 1127 getUncPath0(); 1128 if( share == null ) { 1129 UniAddress addr = getAddress(); 1130 if( addr.getAddress() instanceof NbtAddress ) { 1131 int code = ((NbtAddress)addr.getAddress()).getNameType(); 1132 if( code == 0x1d || code == 0x1b ) { 1133 type = TYPE_WORKGROUP; 1134 return true; 1135 } 1136 } 1137 type = TYPE_SERVER; 1138 } 1139 } 1140 return false; 1141 } 1142 1143 Info queryPath( String path, int infoLevel ) throws SmbException { 1144 connect0(); 1145 1146 if( DebugFile.trace ) 1147 DebugFile.writeln( "queryPath: " + path ); 1148 1149 1156 1157 1163 1164 if( tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS )) { 1165 1166 1169 1170 Trans2QueryPathInformationResponse response = 1171 new Trans2QueryPathInformationResponse( infoLevel ); 1172 sendTransaction( new Trans2QueryPathInformation( path, 1173 infoLevel ), response ); 1174 1175 return response.info; 1176 } else { 1177 1178 1181 1182 SmbComQueryInformationResponse response = 1183 new SmbComQueryInformationResponse( 1184 tree.session.transport.server.serverTimeZone * 1000 * 60L ); 1185 send( new SmbComQueryInformation( path ), response ); 1186 return response; 1187 } 1188 } 1189 1190 1203 1204 public boolean exists() throws SmbException { 1205 1206 if( attrExpiration > System.currentTimeMillis() ) { 1207 return isExists; 1208 } 1209 1210 attributes = ATTR_READONLY | ATTR_DIRECTORY; 1211 createTime = 0L; 1212 lastModified = 0L; 1213 isExists = false; 1214 1215 try { 1216 if( url.getHost().length() == 0 ) { 1217 } else if( share == null ) { 1218 if( getType() == TYPE_WORKGROUP ) { 1219 UniAddress.getByName( url.getHost(), true ); 1220 } else { 1221 UniAddress.getByName( url.getHost() ).getHostName(); 1222 } 1223 } else if( getUncPath0().length() == 1 || 1224 share.equalsIgnoreCase( "IPC$" )) { 1225 connect0(); } else { 1227 Info info = queryPath( getUncPath0(), 1228 Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO ); 1229 attributes = info.getAttributes(); 1230 createTime = info.getCreateTime(); 1231 lastModified = info.getLastWriteTime(); 1232 } 1233 1234 1236 1237 isExists = true; 1238 1239 } catch( UnknownHostException uhe ) { 1240 } catch( SmbException se ) { 1241 switch (se.getNtStatus()) { 1242 case NtStatus.NT_STATUS_NO_SUCH_FILE: 1243 case NtStatus.NT_STATUS_OBJECT_NAME_INVALID: 1244 case NtStatus.NT_STATUS_OBJECT_NAME_NOT_FOUND: 1245 case NtStatus.NT_STATUS_OBJECT_PATH_NOT_FOUND: 1246 break; 1247 default: 1248 throw se; 1249 } 1250 } 1251 1252 attrExpiration = System.currentTimeMillis() + attrExpirationPeriod; 1253 1254 return isExists; 1255 } 1256 1257 1264 1265 public boolean canRead() throws SmbException { 1266 if( getType() == TYPE_NAMED_PIPE ) { return true; 1268 } 1269 return exists(); } 1271 1272 1282 1283 public boolean canWrite() throws SmbException { 1284 if( getType() == TYPE_NAMED_PIPE ) { return true; 1286 } 1287 return exists() && ( attributes & ATTR_READONLY ) == 0; 1288 } 1289 1290 1295 1296 public boolean isDirectory() throws SmbException { 1297 if( getUncPath0().length() == 1 ) { 1298 return true; 1299 } 1300 if (!exists()) return false; 1301 return ( attributes & ATTR_DIRECTORY ) == ATTR_DIRECTORY; 1302 } 1303 1304 1309 1310 public boolean isFile() throws SmbException { 1311 if( getUncPath0().length() == 1 ) { 1312 return false; 1313 } 1314 exists(); 1315 return ( attributes & ATTR_DIRECTORY ) == 0; 1316 } 1317 1318 1325 1326 public boolean isHidden() throws SmbException { 1327 if( share == null ) { 1328 return false; 1329 } else if( getUncPath0().length() == 1 ) { 1330 if( share.endsWith( "$" )) { 1331 return true; 1332 } 1333 return false; 1334 } 1335 exists(); 1336 return ( attributes & ATTR_HIDDEN ) == ATTR_HIDDEN; 1337 } 1338 1339 1344 1345 public String getDfsPath() throws SmbException { 1346 connect0(); 1347 if( tree.inDfs ) { 1348 exists(); 1349 } 1350 if( dfsReferral == null ) { 1351 return null; 1352 } 1353 return "smb:/" + (new String ( dfsReferral.node + unc )).replace( '\\', '/' ); 1354 } 1355 1356 1368 public long createTime() throws SmbException { 1369 if( getUncPath0().length() > 1 ) { 1370 exists(); 1371 return createTime; 1372 } 1373 return 0L; 1374 } 1375 1385 public long lastModified() throws SmbException { 1386 if( getUncPath0().length() > 1 ) { 1387 exists(); 1388 return lastModified; 1389 } 1390 return 0L; 1391 } 1392 1413 public String [] list() throws SmbException { 1414 return list( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); 1415 } 1416 1417 1426 public String [] list( SmbFilenameFilter filter ) throws SmbException { 1427 return list( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, filter, null ); 1428 } 1429 1430 1455 public SmbFile[] listFiles() throws SmbException { 1456 return listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); 1457 } 1458 1459 1487 1488 public SmbFile[] listFiles( String wildcard ) throws SmbException { 1489 return listFiles( wildcard, ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); 1490 } 1491 1500 public SmbFile[] listFiles( SmbFilenameFilter filter ) throws SmbException { 1501 return listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, filter, null ); 1502 } 1503 1511 public SmbFile[] listFiles( SmbFileFilter filter ) throws SmbException { 1512 return listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, filter ); 1513 } 1514 String [] list( String wildcard, int searchAttributes, 1515 SmbFilenameFilter fnf, SmbFileFilter ff ) throws SmbException { 1516 ArrayList list = new ArrayList (); 1517 1518 try { 1519 if( url.getHost().length() == 0 || share == null ) { 1520 doNetEnum( list, false, wildcard, searchAttributes, fnf, ff ); 1521 } else { 1522 doFindFirstNext( list, false, wildcard, searchAttributes, fnf, ff ); 1523 } 1524 } catch( UnknownHostException uhe ) { 1525 throw new SmbException( url.toString(), uhe ); 1526 } catch( MalformedURLException mue ) { 1527 throw new SmbException( url.toString(), mue ); 1528 } 1529 1530 return (String [])list.toArray(new String [list.size()]); 1531 } 1532 SmbFile[] listFiles( String wildcard, int searchAttributes, 1533 SmbFilenameFilter fnf, SmbFileFilter ff ) throws SmbException { 1534 ArrayList list = new ArrayList (); 1535 1536 if( ff != null && ff instanceof DosFileFilter ) { 1537 DosFileFilter dff = (DosFileFilter)ff; 1538 if( dff.wildcard != null ) { 1539 wildcard = dff.wildcard; 1540 } 1541 searchAttributes = dff.attributes; 1542 } 1543 1544 try { 1545 if( url.getHost().length() == 0 || share == null ) { 1546 doNetEnum( list, true, wildcard, searchAttributes, fnf, ff ); 1547 } else { 1548 doFindFirstNext( list, true, wildcard, searchAttributes, fnf, ff ); 1549 } 1550 } catch( UnknownHostException uhe ) { 1551 throw new SmbException( url.toString(), uhe ); 1552 } catch( MalformedURLException mue ) { 1553 throw new SmbException( url.toString(), mue ); 1554 } 1555 1556 return (SmbFile[])list.toArray(new SmbFile[list.size()]); 1557 } 1558 void doNetEnum( ArrayList list, 1559 boolean files, 1560 String wildcard, 1561 int searchAttributes, 1562 SmbFilenameFilter fnf, 1563 SmbFileFilter ff ) throws SmbException, 1564 UnknownHostException , MalformedURLException { 1565 SmbComTransaction req; 1566 SmbComTransactionResponse resp; 1567 int listType = url.getAuthority().length() == 0 ? 0 : getType(); 1568 String p = url.getPath(); 1569 1570 if( p.lastIndexOf( '/' ) != ( p.length() - 1 )) { 1571 throw new SmbException( url.toString() + " directory must end with '/'" ); 1572 } 1573 1574 switch( listType ) { 1575 case 0: 1576 connect0(); 1577 req = new NetServerEnum2( tree.session.transport.server.oemDomainName, 1578 NetServerEnum2.SV_TYPE_DOMAIN_ENUM ); 1579 resp = new NetServerEnum2Response(); 1580 break; 1581 case TYPE_WORKGROUP: 1582 req = new NetServerEnum2( url.getHost(), NetServerEnum2.SV_TYPE_ALL ); 1583 resp = new NetServerEnum2Response(); 1584 break; 1585 case TYPE_SERVER: 1586 req = new NetShareEnum(); 1587 resp = new NetShareEnumResponse(); 1588 break; 1589 default: 1590 throw new SmbException( "The requested list operations is invalid: " + url.toString() ); 1591 } 1592 1593 do { 1594 sendTransaction( req, resp ); 1595 1596 if( resp.status != SmbException.ERROR_SUCCESS && 1597 resp.status != SmbException.ERROR_MORE_DATA ) { 1598 throw new SmbException( resp.status, true ); 1599 } 1600 1601 for( int i = 0; i < resp.numEntries; i++ ) { 1602 FileEntry e = resp.results[i]; 1603 String name = e.getName(); 1604 if( fnf != null && fnf.accept( this, name ) == false ) { 1605 continue; 1606 } 1607 if( name.length() > 0 ) { 1608 SmbFile f = new SmbFile( this, name, 1609 listType == 0 ? TYPE_WORKGROUP : (listType << 1), 1610 ATTR_READONLY | ATTR_DIRECTORY, 0L, 0L, 0L ); 1611 if( ff != null && ff.accept( f ) == false ) { 1612 continue; 1613 } 1614 if( files ) { 1615 list.add( f ); 1616 } else { 1617 list.add( name ); 1618 } 1619 } 1620 } 1621 if( listType != 0 || listType != TYPE_WORKGROUP ) { 1622 break; 1623 } 1624 req.subCommand = (byte)SmbComTransaction.NET_SERVER_ENUM3; 1625 req.reset( 0, ((NetServerEnum2Response)resp).lastName ); 1626 } while( resp.status == SmbException.ERROR_MORE_DATA ); 1627 } 1628 void doFindFirstNext( ArrayList list, 1629 boolean files, 1630 String wildcard, 1631 int searchAttributes, 1632 SmbFilenameFilter fnf, 1633 SmbFileFilter ff ) throws SmbException, UnknownHostException , MalformedURLException { 1634 SmbComTransaction req; 1635 Trans2FindFirst2Response resp; 1636 int sid; 1637 String path = getUncPath0(); 1638 String p = url.getPath(); 1639 1640 if( p.lastIndexOf( '/' ) != ( p.length() - 1 )) { 1641 throw new SmbException( url.toString() + " directory must end with '/'" ); 1642 } 1643 1644 req = new Trans2FindFirst2( path, wildcard, searchAttributes ); 1645 resp = new Trans2FindFirst2Response(); 1646 1647 if( DebugFile.trace ) 1648 DebugFile.writeln( "doFindFirstNext: " + req.path ); 1649 1650 sendTransaction( req, resp ); 1651 1652 sid = resp.sid; 1653 req = new Trans2FindNext2( sid, resp.resumeKey, resp.lastName ); 1654 1655 1658 resp.subCommand = SmbComTransaction.TRANS2_FIND_NEXT2; 1659 1660 for( ;; ) { 1661 for( int i = 0; i < resp.numEntries; i++ ) { 1662 FileEntry e = resp.results[i]; 1663 String name = e.getName(); 1664 if( name.length() < 3 ) { 1665 int h = name.hashCode(); 1666 if( h == HASH_DOT || h == HASH_DOT_DOT ) { 1667 continue; 1668 } 1669 } 1670 if( fnf != null && fnf.accept( this, name ) == false ) { 1671 continue; 1672 } 1673 if( name.length() > 0 ) { 1674 SmbFile f = new SmbFile( this, name, TYPE_FILESYSTEM, 1675 e.getAttributes(), e.createTime(), e.lastModified(), e.length() ); 1676 if( ff != null && ff.accept( f ) == false ) { 1677 continue; 1678 } 1679 if( files ) { 1680 list.add( f ); 1681 } else { 1682 list.add( name ); 1683 } 1684 } 1685 } 1686 1687 if( resp.isEndOfSearch || resp.numEntries == 0 ) { 1688 break; 1689 } 1690 1691 req.reset( resp.resumeKey, resp.lastName ); 1692 resp.reset(); 1693 sendTransaction( req, resp ); 1694 } 1695 1696 send( new SmbComFindClose2( sid ), blank_resp() ); 1697 } 1698 1699 1713 public void renameTo( SmbFile dest ) throws SmbException { 1714 if( getUncPath0().length() == 1 || dest.getUncPath0().length() == 1 ) { 1715 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 1716 } 1717 connect0(); 1718 dest.connect0(); 1719 1720 if( tree.inDfs ) { 1728 exists(); 1729 dest.exists(); 1730 } 1731 if( tree != dest.tree ) { 1732 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 1733 } 1734 1735 if( DebugFile.trace ) 1736 DebugFile.writeln( "renameTo: " + unc + " -> " + dest.unc ); 1737 1738 attrExpiration = sizeExpiration = 0; 1739 dest.attrExpiration = 0; 1740 1741 1744 1745 send( new SmbComRename( unc, dest.unc ), blank_resp() ); 1746 } 1747 1748 class WriterThread extends Thread { 1749 byte[] b; 1750 int n, off; 1751 boolean ready = true; 1752 SmbFile dest; 1753 SmbException e = null; 1754 boolean useNTSmbs; 1755 SmbComWriteAndX reqx; 1756 SmbComWrite req; 1757 ServerMessageBlock resp; 1758 1759 WriterThread() throws SmbException { 1760 super( "JCIFS-WriterThread" ); 1761 useNTSmbs = tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS ); 1762 if( useNTSmbs ) { 1763 reqx = new SmbComWriteAndX(); 1764 resp = new SmbComWriteAndXResponse(); 1765 } else { 1766 req = new SmbComWrite(); 1767 resp = new SmbComWriteResponse(); 1768 } 1769 } 1770 1771 synchronized void write( byte[] b, int n, SmbFile dest, int off ) { 1772 this.b = b; 1773 this.n = n; 1774 this.dest = dest; 1775 this.off = off; 1776 ready = false; 1777 notify(); 1778 } 1779 1780 public void run() { 1781 synchronized( this ) { 1782 try { 1783 for( ;; ) { 1784 ready = true; 1785 while( ready ) { 1786 wait(); 1787 } 1788 if( n == -1 ) { 1789 return; 1790 } 1791 if( useNTSmbs ) { 1792 reqx.setParam( dest.fid, off, n, b, 0, n ); 1793 dest.send( reqx, resp ); 1794 } else { 1795 req.setParam( dest.fid, off, n, b, 0, n ); 1796 dest.send( req, resp ); 1797 } 1798 notify(); 1799 } 1800 } catch( SmbException e ) { 1801 this.e = e; 1802 } catch( Exception x ) { 1803 this.e = new SmbException( "WriterThread", x ); 1804 } 1805 notify(); 1806 } 1807 } 1808 } 1809 void copyTo0( SmbFile dest, byte[][] b, int bsize, WriterThread w, 1810 SmbComReadAndX req, SmbComReadAndXResponse resp ) throws SmbException { 1811 int i; 1812 1813 if( attrExpiration < System.currentTimeMillis() ) { 1814 attributes = ATTR_READONLY | ATTR_DIRECTORY; 1815 createTime = 0L; 1816 lastModified = 0L; 1817 isExists = false; 1818 1819 Info info = queryPath( getUncPath0(), 1820 Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO ); 1821 attributes = info.getAttributes(); 1822 createTime = info.getCreateTime(); 1823 lastModified = info.getLastWriteTime(); 1824 1825 1827 1828 isExists = true; 1829 attrExpiration = System.currentTimeMillis() + attrExpirationPeriod; 1830 } 1831 1832 if( isDirectory() ) { 1833 SmbFile[] files; 1834 SmbFile ndest; 1835 1836 try { 1837 dest.mkdir(); 1838 dest.setPathInformation( attributes, createTime, lastModified ); 1839 } catch( SmbException se ) { 1840 if( se.getNtStatus() != NtStatus.NT_STATUS_ACCESS_DENIED && 1841 se.getNtStatus() != NtStatus.NT_STATUS_OBJECT_NAME_COLLISION ) { 1842 throw se; 1843 } 1844 } 1845 1846 files = listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); 1847 try { 1848 for( i = 0; i < files.length; i++ ) { 1849 ndest = new SmbFile( dest, 1850 files[i].getName(), 1851 files[i].type, 1852 files[i].attributes, 1853 files[i].createTime, 1854 files[i].lastModified, 1855 files[i].size ); 1856 files[i].copyTo0( ndest, b, bsize, w, req, resp ); 1857 } 1858 } catch( UnknownHostException uhe ) { 1859 throw new SmbException( url.toString(), uhe ); 1860 } catch( MalformedURLException mue ) { 1861 throw new SmbException( url.toString(), mue ); 1862 } 1863 } else { 1864 int off; 1865 1866 open( SmbFile.O_RDONLY, ATTR_NORMAL, 0 ); 1867 try { 1868 dest.open( SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_TRUNC | 1869 SmbComNTCreateAndX.FILE_WRITE_ATTRIBUTES << 16, attributes, 0 ); 1870 } catch( SmbAuthException sae ) { 1871 if(( dest.attributes & ATTR_READONLY ) != 0 ) { 1872 1874 dest.setPathInformation( dest.attributes & ~ATTR_READONLY, 0L, 0L ); 1875 dest.open( SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_TRUNC | 1876 SmbComNTCreateAndX.FILE_WRITE_ATTRIBUTES << 16, attributes, 0 ); 1877 } else { 1878 throw sae; 1879 } 1880 } 1881 1882 i = off = 0; 1883 for( ;; ) { 1884 req.setParam( fid, off, bsize ); 1885 resp.setParam( b[i], 0 ); 1886 send( req, resp ); 1887 1888 synchronized( w ) { 1889 while( !w.ready ) { 1890 try { 1891 w.wait(); 1892 } catch( InterruptedException ie ) { 1893 throw new SmbException( dest.url.toString(), ie ); 1894 } 1895 } 1896 if( w.e != null ) { 1897 throw w.e; 1898 } 1899 if( resp.dataLength <= 0 ) { 1900 break; 1901 } 1902 w.write( b[i], resp.dataLength, dest, off ); 1903 } 1904 1905 i = i == 1 ? 0 : 1; 1906 off += resp.dataLength; 1907 } 1908 1909 dest.sendTransaction( new Trans2SetFileInformation( 1910 dest.fid, attributes, createTime, lastModified ), 1911 new Trans2SetFileInformationResponse() ); 1912 dest.close( 0L ); 1913 close(); 1914 } 1915 } 1916 1932 public void copyTo( SmbFile dest ) throws SmbException { 1933 SmbComReadAndX req; 1934 SmbComReadAndXResponse resp; 1935 WriterThread w; 1936 int bsize; 1937 byte[][] b; 1938 1939 1941 if( share == null || dest.share == null) { 1942 throw new SmbException( "Invalid operation for workgroups or servers" ); 1943 } 1944 1945 req = new SmbComReadAndX(); 1946 resp = new SmbComReadAndXResponse(); 1947 1948 connect0(); 1949 dest.connect0(); 1950 1951 if( tree.inDfs ) { 1952 1961 exists(); 1962 dest.exists(); 1963 } 1964 1965 w = new WriterThread(); 1966 w.setDaemon( true ); 1967 w.start(); 1968 1969 bsize = Math.min( tree.session.transport.rcv_buf_size - 70, 1970 tree.session.transport.snd_buf_size - 70 ); 1971 b = new byte[2][bsize]; 1972 1973 copyTo0( dest, b, bsize, w, req, resp ); 1974 w.write( null, -1, null, 0 ); 1975 } 1976 1977 1986 public void delete() throws SmbException { 1987 if( tree == null || tree.inDfs ) { 1988 exists(); 1990 } 1991 getUncPath0(); 1992 delete( unc ); 1993 } 1994 void delete( String fileName ) throws SmbException { 1995 if( getUncPath0().length() == 1 ) { 1996 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 1997 } 1998 1999 if( System.currentTimeMillis() > attrExpiration ) { 2000 attributes = ATTR_READONLY | ATTR_DIRECTORY; 2001 createTime = 0L; 2002 lastModified = 0L; 2003 isExists = false; 2004 2005 Info info = queryPath( getUncPath0(), 2006 Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO ); 2007 attributes = info.getAttributes(); 2008 createTime = info.getCreateTime(); 2009 lastModified = info.getLastWriteTime(); 2010 2011 attrExpiration = System.currentTimeMillis() + attrExpirationPeriod; 2012 isExists = true; 2013 } 2014 2015 if(( attributes & ATTR_READONLY ) != 0 ) { 2016 setReadWrite(); 2017 } 2018 2019 2022 2023 if( DebugFile.trace ) 2024 DebugFile.writeln( "delete: " + fileName ); 2025 2026 if(( attributes & ATTR_DIRECTORY ) != 0 ) { 2027 2028 2030 2031 SmbFile[] l = listFiles( "*", 2032 ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); 2033 2034 for( int i = 0; i < l.length; i++ ) { 2035 l[i].delete(); 2036 } 2037 2038 send( new SmbComDeleteDirectory( fileName ), blank_resp() ); 2039 } else { 2040 send( new SmbComDelete( fileName ), blank_resp() ); 2041 } 2042 2043 attrExpiration = sizeExpiration = 0; 2044 } 2045 2046 2056 2057 public long length() throws SmbException { 2058 if( sizeExpiration > System.currentTimeMillis() ) { 2059 return size; 2060 } 2061 2062 if( getType() == TYPE_SHARE ) { 2063 Trans2QueryFSInformationResponse response; 2064 int level = Trans2QueryFSInformationResponse.SMB_INFO_ALLOCATION; 2065 2066 response = new Trans2QueryFSInformationResponse( level ); 2067 sendTransaction( new Trans2QueryFSInformation( level ), response ); 2068 2069 size = response.info.getCapacity(); 2070 } else if( getUncPath0().length() > 1 && type != TYPE_NAMED_PIPE ) { 2071 Info info = queryPath( getUncPath0(), 2072 Trans2QueryPathInformationResponse.SMB_QUERY_FILE_STANDARD_INFO ); 2073 size = info.getSize(); 2074 } else { 2075 size = 0L; 2076 } 2077 sizeExpiration = System.currentTimeMillis() + attrExpirationPeriod; 2078 return size; 2079 } 2080 2081 2090 public long getDiskFreeSpace() throws SmbException { 2091 if( getType() == TYPE_SHARE || type == TYPE_FILESYSTEM ) { 2092 Trans2QueryFSInformationResponse response; 2093 int level = Trans2QueryFSInformationResponse.SMB_INFO_ALLOCATION; 2094 2095 response = new Trans2QueryFSInformationResponse( level ); 2096 sendTransaction( new Trans2QueryFSInformation( level ), response ); 2097 2098 if( type == TYPE_SHARE ) { 2099 size = response.info.getCapacity(); 2100 sizeExpiration = System.currentTimeMillis() + attrExpirationPeriod; 2101 } 2102 2103 return response.info.getFree(); 2104 } 2105 return 0L; 2106 } 2107 2108 2119 public void mkdir() throws SmbException { 2120 String path = getUncPath0(); 2121 2122 if( path.length() == 1 ) { 2123 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 2124 } 2125 2126 2129 2130 if( DebugFile.trace ) 2131 DebugFile.writeln( "mkdir: " + path ); 2132 2133 send( new SmbComCreateDirectory( path ), blank_resp() ); 2134 2135 attrExpiration = sizeExpiration = 0; 2136 } 2137 2138 2148 public void mkdirs() throws SmbException { 2149 SmbFile parent; 2150 2151 try { 2152 parent = new SmbFile( new URL ( null, getParent(), Handler.SMB_HANDLER )); 2153 } catch( IOException ioe ) { 2154 return; 2155 } 2156 if( parent.exists() == false ) { 2157 parent.mkdirs(); 2158 } 2159 mkdir(); 2160 } 2161 2162 2167 public void createNewFile() throws SmbException { 2168 if( getUncPath0().length() == 1 ) { 2169 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 2170 } 2171 close( open0( O_RDWR | O_CREAT | O_EXCL, ATTR_NORMAL, 0 ), 0L ); 2172 } 2173 2174 void setPathInformation( int attrs, long ctime, long mtime ) throws SmbException { 2175 int f, options = 0; 2176 2177 if(( attrs & ATTR_DIRECTORY ) != 0 ) { 2178 options = 1; 2179 } 2180 2181 f = open0( O_RDONLY | SmbComNTCreateAndX.FILE_WRITE_ATTRIBUTES << 16, attrs, options ); 2182 sendTransaction( new Trans2SetFileInformation( f, attrs, ctime, mtime ), 2183 new Trans2SetFileInformationResponse() ); 2184 close( f, 0L ); 2185 2186 attrExpiration = 0; 2187 } 2188 2189 2198 public void setCreateTime( long time ) throws SmbException { 2199 if( getUncPath0().length() == 1 ) { 2200 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 2201 } 2202 2203 setPathInformation( 0, time, 0L ); 2204 } 2205 2214 public void setLastModified( long time ) throws SmbException { 2215 if( getUncPath0().length() == 1 ) { 2216 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 2217 } 2218 2219 setPathInformation( 0, 0L, time ); 2220 } 2221 2222 2231 public int getAttributes() throws SmbException { 2232 if( getUncPath0().length() == 1 ) { 2233 return 0; 2234 } 2235 exists(); 2236 return attributes & ATTR_GET_MASK; 2237 } 2238 2239 2246 public void setAttributes( int attrs ) throws SmbException { 2247 if( getUncPath0().length() == 1 ) { 2248 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 2249 } 2250 2251 setPathInformation( attrs & ATTR_SET_MASK, 0L, 0L ); 2252 } 2253 2254 2260 public void setReadOnly() throws SmbException { 2261 setAttributes( getAttributes() | ATTR_READONLY ); 2262 } 2263 2264 2270 public void setReadWrite() throws SmbException { 2271 setAttributes( getAttributes() & ~ATTR_READONLY ); 2272 } 2273 2274 2284 public URL toURL() throws MalformedURLException { 2285 return url; 2286 } 2287 2288 2300 2301 public int hashCode() { 2302 int hash; 2303 try { 2304 hash = getAddress().hashCode(); 2305 } catch( UnknownHostException uhe ) { 2306 hash = getServer().toUpperCase().hashCode(); 2307 } 2308 getUncPath0(); 2309 return hash + canon.toUpperCase().hashCode(); 2310 } 2311 2312 2334 2335 public boolean equals( Object obj ) { 2336 return obj instanceof SmbFile && obj.hashCode() == hashCode(); 2337 } 2338 2339 2348 2349 public String toString() { 2350 return url.toString(); 2351 } 2352 2353 2354 2359 2360 public int getContentLength() { 2361 try { 2362 return (int)(length() & 0xFFFFFFFFL); 2363 } catch( SmbException se ) { 2364 } 2365 return 0; 2366 } 2367 2368 2373 public long getDate() { 2374 try { 2375 return lastModified(); 2376 } catch( SmbException se ) { 2377 } 2378 return 0L; 2379 } 2380 2381 2386 public long getLastModified() { 2387 try { 2388 return lastModified(); 2389 } catch( SmbException se ) { 2390 } 2391 return 0L; 2392 } 2393 2394 2399 public InputStream getInputStream() throws IOException { 2400 return new SmbFileInputStream( this ); 2401 } 2402} 2403 | Popular Tags |