1 18 19 package 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 import java.security.Principal ; 30 import jcifs.Config; 31 import jcifs.util.LogStream; 32 import jcifs.UniAddress; 33 import 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 = 0x7FFF; 350 static final int ATTR_SET_MASK = 0x30A7; 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 LogStream log = LogStream.getInstance(); 358 static long attrExpirationPeriod; 359 360 static { 361 try { 362 Class.forName( "jcifs.Config" ); 363 } catch( ClassNotFoundException cnfe ) { 364 cnfe.printStackTrace(); 365 } 366 attrExpirationPeriod = Config.getLong( "jcifs.smb.client.attrExpirationPeriod", DEFAULT_ATTR_EXPIRATION_PERIOD ); 367 } 368 369 373 public static final int TYPE_FILESYSTEM = 0x01; 374 378 public static final int TYPE_WORKGROUP = 0x02; 379 383 public static final int TYPE_SERVER = 0x04; 384 388 public static final int TYPE_SHARE = 0x08; 389 393 public static final int TYPE_NAMED_PIPE = 0x10; 394 398 public static final int TYPE_PRINTER = 0x20; 399 403 public static final int TYPE_COMM = 0x40; 404 405 406 private String canon; private String share; private long createTime; 409 private long lastModified; 410 private int attributes; 411 private long attrExpiration; 412 private long size; 413 private long sizeExpiration; 414 private NtlmPasswordAuthentication auth; private boolean isExists; 416 private int shareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; 417 private SmbComBlankResponse blank_resp = null; 418 private DfsReferral dfsReferral = null; 420 SmbTree tree = null; String unc; int fid; int type; 424 boolean opened; 425 int tree_num; 426 427 436 437 public SmbFile( String url ) throws MalformedURLException { 438 this( new URL ( null, url, Handler.SMB_HANDLER )); 439 } 440 441 455 456 public SmbFile( SmbFile context, String name ) 457 throws MalformedURLException , UnknownHostException { 458 this( context.isWorkgroup0() ? 459 new URL ( null, "smb://" + name, Handler.SMB_HANDLER ) : 460 new URL ( context.url, name, Handler.SMB_HANDLER ), context.auth ); 461 } 462 463 475 476 public SmbFile( String context, String name ) throws MalformedURLException { 477 this( new URL ( new URL ( null, context, Handler.SMB_HANDLER ), 478 name, Handler.SMB_HANDLER )); 479 } 480 481 490 public SmbFile( String url, NtlmPasswordAuthentication auth ) 491 throws MalformedURLException { 492 this( new URL ( null, url, Handler.SMB_HANDLER ), auth ); 493 } 494 508 public SmbFile( String url, NtlmPasswordAuthentication auth, int shareAccess ) 509 throws MalformedURLException { 510 this( new URL ( null, url, Handler.SMB_HANDLER ), auth ); 511 if ((shareAccess & ~(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)) != 0) { 512 throw new RuntimeException ( "Illegal shareAccess parameter" ); 513 } 514 this.shareAccess = shareAccess; 515 } 516 529 public SmbFile( String context, String name, NtlmPasswordAuthentication auth ) 530 throws MalformedURLException { 531 this( new URL ( new URL ( null, context, Handler.SMB_HANDLER ), name, Handler.SMB_HANDLER ), auth ); 532 } 533 552 public SmbFile( String context, String name, NtlmPasswordAuthentication auth, int shareAccess ) 553 throws MalformedURLException { 554 this( new URL ( new URL ( null, context, Handler.SMB_HANDLER ), name, Handler.SMB_HANDLER ), auth ); 555 if ((shareAccess & ~(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)) != 0) { 556 throw new RuntimeException ( "Illegal shareAccess parameter" ); 557 } 558 this.shareAccess = shareAccess; 559 } 560 578 public SmbFile( SmbFile context, String name, int shareAccess ) 579 throws MalformedURLException , UnknownHostException { 580 this( context.isWorkgroup0() ? 581 new URL ( null, "smb://" + name, Handler.SMB_HANDLER ) : 582 new URL ( context.url, name, Handler.SMB_HANDLER ), context.auth ); 583 if ((shareAccess & ~(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)) != 0) { 584 throw new RuntimeException ( "Illegal shareAccess parameter" ); 585 } 586 this.shareAccess = shareAccess; 587 } 588 594 public SmbFile( URL url ) { 595 this( url, new NtlmPasswordAuthentication( url.getUserInfo() )); 596 } 597 605 public SmbFile( URL url, NtlmPasswordAuthentication auth ) { 606 super( url ); 607 this.auth = auth == null ? new NtlmPasswordAuthentication( url.getUserInfo() ) : auth; 608 609 getUncPath0(); 610 } 611 SmbFile( SmbFile context, String name, int type, 612 int attributes, long createTime, long lastModified, long size ) 613 throws MalformedURLException , UnknownHostException { 614 this( context.isWorkgroup0() ? 615 new URL ( null, "smb://" + name + "/", Handler.SMB_HANDLER ) : 616 new URL ( context.url, name + (( attributes & ATTR_DIRECTORY ) > 0 ? "/" : "" ))); 617 618 619 620 auth = context.auth; 621 622 623 if( context.share != null ) { 624 this.tree = context.tree; 625 } 626 int last = name.length() - 1; 627 if( name.charAt( last ) == '/' ) { 628 name = name.substring( 0, last ); 629 } 630 if( context.share == null ) { 631 this.unc = "\\"; 632 } else if( context.unc.equals( "\\" )) { 633 this.unc = '\\' + name; 634 } else { 635 this.unc = context.unc + '\\' + name; 636 } 637 640 this.type = type; 641 this.attributes = attributes; 642 this.createTime = createTime; 643 this.lastModified = lastModified; 644 this.size = size; 645 isExists = true; 646 647 attrExpiration = sizeExpiration = 648 System.currentTimeMillis() + attrExpirationPeriod; 649 } 650 651 private SmbComBlankResponse blank_resp() { 652 if( blank_resp == null ) { 653 blank_resp = new SmbComBlankResponse(); 654 } 655 return blank_resp; 656 } 657 void send( ServerMessageBlock request, 658 ServerMessageBlock response ) throws SmbException { 659 for( ;; ) { 660 connect0(); 661 if( tree.inDfs ) { 662 DfsReferral dr = tree.session.transport.lookupReferral( unc ); 663 if( dr != null ) { 664 UniAddress addr; 665 SmbTransport trans; 666 667 try { 668 addr = UniAddress.getByName( dr.server ); 669 } catch( UnknownHostException uhe ) { 670 throw new SmbException( dr.server, uhe ); 671 } 672 673 trans = SmbTransport.getSmbTransport( addr, url.getPort() ); 674 tree = trans.getSmbSession( auth ).getSmbTree( dr.share, null ); 675 unc = dr.nodepath + unc.substring( dr.path.length() ); 676 if( request.path.charAt( request.path.length() - 1 ) == '\\' ) { 677 request.path = unc + '\\'; 678 } else { 679 request.path = unc; 680 } 681 dfsReferral = dr; 682 } 683 request.flags2 |= ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS; 684 } else { 685 request.flags2 &= ~ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS; 686 } 687 try { 688 tree.send( request, response ); 689 break; 690 } catch( DfsReferral dr ) { 691 if( dr.resolveHashes ) { 692 throw dr; 693 } 694 request.reset(); 695 } 696 } 697 } 698 699 static String queryLookup( String query, String param ) { 700 char in[] = query.toCharArray(); 701 int i, ch, st, eq; 702 703 st = eq = 0; 704 for( i = 0; i < in.length; i++) { 705 ch = in[i]; 706 if( ch == '&' ) { 707 if( eq > st ) { 708 String p = new String ( in, st, eq - st ); 709 if( p.equalsIgnoreCase( param )) { 710 eq++; 711 return new String ( in, eq, i - eq ); 712 } 713 } 714 st = i + 1; 715 } else if( ch == '=' ) { 716 eq = i; 717 } 718 } 719 if( eq > st ) { 720 String p = new String ( in, st, eq - st ); 721 if( p.equalsIgnoreCase( param )) { 722 eq++; 723 return new String ( in, eq, in.length - eq ); 724 } 725 } 726 727 return null; 728 } 729 730 UniAddress getAddress() throws UnknownHostException { 731 String host = url.getHost(); 732 String path = url.getPath(); 733 String query = url.getQuery(); 734 735 if( query != null ) { 736 String server = queryLookup( query, "server" ); 737 if( server != null && server.length() > 0 ) { 738 return UniAddress.getByName( server ); 739 } 740 } 741 742 if( host.length() == 0 ) { 743 try { 744 NbtAddress addr = NbtAddress.getByName( 745 NbtAddress.MASTER_BROWSER_NAME, 0x01, null); 746 return UniAddress.getByName( addr.getHostAddress() ); 747 } catch( UnknownHostException uhe ) { 748 NtlmPasswordAuthentication.initDefaults(); 749 if( NtlmPasswordAuthentication.DEFAULT_DOMAIN.equals( "?" )) { 750 throw uhe; 751 } 752 return UniAddress.getByName( NtlmPasswordAuthentication.DEFAULT_DOMAIN, true ); 753 } 754 } else if( path.length() == 0 || path.equals( "/" )) { 755 return UniAddress.getByName( host, true ); 756 } else { 757 return UniAddress.getByName( host ); 758 } 759 } 760 void connect0() throws SmbException { 761 try { 762 connect(); 763 } catch( UnknownHostException uhe ) { 764 throw new SmbException( "Failed to connect to server", uhe ); 765 } catch( SmbException se ) { 766 throw se; 767 } catch( IOException ioe ) { 768 throw new SmbException( "Failed to connect to server", ioe ); 769 } 770 } 771 775 public void connect() throws IOException { 776 SmbTransport trans; 777 SmbSession ssn; 778 UniAddress addr; 779 780 if( isConnected() ) { 781 return; 782 } 783 784 getUncPath0(); 785 addr = getAddress(); 786 787 trans = SmbTransport.getSmbTransport( addr, url.getPort() ); 788 ssn = trans.getSmbSession( auth ); 789 tree = ssn.getSmbTree( share, null ); 790 791 try { 792 tree.treeConnect( null, null ); 793 } catch( SmbAuthException sae ) { 794 NtlmPasswordAuthentication a; 795 796 if( share == null ) { ssn = trans.getSmbSession( NtlmPasswordAuthentication.NULL ); 798 tree = ssn.getSmbTree( null, null ); 799 tree.treeConnect( null, null ); 800 } else if(( a = NtlmAuthenticator.requestNtlmPasswordAuthentication( 801 url.toString(), sae )) != null ) { 802 auth = a; 803 ssn = trans.getSmbSession( auth ); 804 tree = ssn.getSmbTree( share, null ); 805 tree.treeConnect( null, null ); 806 } else { 807 throw sae; 808 } 809 } 810 } 811 boolean isConnected() { 812 return (connected = tree != null && tree.treeConnected); 813 } 814 int open0( int flags, int attrs, int options ) throws SmbException { 815 int f; 816 817 connect0(); 818 819 if( log.level > 2 ) 820 log.println( "open0: " + unc ); 821 822 825 826 if( tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS )) { 827 SmbComNTCreateAndXResponse response = new SmbComNTCreateAndXResponse(); 828 send( new SmbComNTCreateAndX( unc, flags, shareAccess, 829 attrs, options, null ), response ); 830 f = response.fid; 831 attributes = response.extFileAttributes & ATTR_GET_MASK; 832 attrExpiration = System.currentTimeMillis() + attrExpirationPeriod; 833 isExists = true; 834 } else { 835 SmbComOpenAndXResponse response = new SmbComOpenAndXResponse(); 836 send( new SmbComOpenAndX( unc, flags, null ), response ); 837 f = response.fid; 838 } 839 840 return f; 841 } 842 void open( int flags, int attrs, int options ) throws SmbException { 843 if( isOpen() ) { 844 return; 845 } 846 fid = open0( flags, attrs, options ); 847 opened = true; 848 tree_num = tree.tree_num; 849 } 850 boolean isOpen() { 851 return opened && isConnected() && tree_num == tree.tree_num; 852 } 853 void close( int f, long lastWriteTime ) throws SmbException { 854 855 if( log.level > 2 ) 856 log.println( "close: " + f ); 857 858 861 862 send( new SmbComClose( f, lastWriteTime ), blank_resp() ); 863 } 864 void close( long lastWriteTime ) throws SmbException { 865 if( isOpen() == false ) { 866 return; 867 } 868 close( fid, lastWriteTime ); 869 opened = false; 870 } 871 void close() throws SmbException { 872 close( 0L ); 873 } 874 875 886 887 public Principal getPrincipal() { 888 return auth; 889 } 890 891 905 906 public String getName() { 907 getUncPath0(); 908 if( canon.length() > 1 ) { 909 int i = canon.length() - 2; 910 while( canon.charAt( i ) != '/' ) { 911 i--; 912 } 913 return canon.substring( i + 1 ); 914 } else if( share != null ) { 915 return share + '/'; 916 } else if( url.getHost().length() > 0 ) { 917 return url.getHost() + '/'; 918 } else { 919 return "smb://"; 920 } 921 } 922 923 932 933 public String getParent() { 934 String str = url.getAuthority(); 935 936 if( str.length() > 0 ) { 937 StringBuffer sb = new StringBuffer ( "smb://" ); 938 939 sb.append( str ); 940 941 getUncPath0(); 942 if( canon.length() > 1 ) { 943 sb.append( canon ); 944 } else { 945 sb.append( '/' ); 946 } 947 948 str = sb.toString(); 949 950 int i = str.length() - 2; 951 while( str.charAt( i ) != '/' ) { 952 i--; 953 } 954 955 return str.substring( 0, i + 1 ); 956 } 957 958 return "smb://"; 959 } 960 961 968 969 public String getPath() { 970 return url.toString(); 971 } 972 973 String getUncPath0() { 974 if( unc == null ) { 975 char[] in = url.getPath().toCharArray(); 976 char[] out = new char[in.length]; 977 int length = in.length, i, o, state, s; 978 979 981 state = 0; 982 o = 0; 983 for( i = 0; i < length; i++ ) { 984 switch( state ) { 985 case 0: 986 if( in[i] != '/' ) { 987 return null; 988 } 989 out[o++] = in[i]; 990 state = 1; 991 break; 992 case 1: 993 if( in[i] == '/' ) { 994 break; 995 } else if( in[i] == '.' && 996 (( i + 1 ) >= length || in[i + 1] == '/' )) { 997 i++; 998 break; 999 } else if(( i + 1 ) < length && 1000 in[i] == '.' && 1001 in[i + 1] == '.' && 1002 (( i + 2 ) >= length || in[i + 2] == '/' )) { 1003 i += 2; 1004 if( o == 1 ) break; 1005 do { 1006 o--; 1007 } while( o > 1 && out[o - 1] != '/' ); 1008 break; 1009 } 1010 state = 2; 1011 case 2: 1012 if( in[i] == '/' ) { 1013 state = 1; 1014 } 1015 out[o++] = in[i]; 1016 break; 1017 } 1018 } 1019 1020 canon = new String ( out, 0, o ); 1021 1022 if( o > 1 ) { 1023 o--; 1024 i = canon.indexOf( '/', 1 ); 1025 if( i < 0 ) { 1026 share = canon.substring( 1 ); 1027 unc = "\\"; 1028 } else if( i == o ) { 1029 share = canon.substring( 1, i ); 1030 unc = "\\"; 1031 } else { 1032 share = canon.substring( 1, i ); 1033 unc = canon.substring( i, out[o] == '/' ? o : o + 1 ); 1034 unc = unc.replace( '/', '\\' ); 1035 } 1036 } else { 1037 share = null; 1038 unc = "\\"; 1039 } 1040 } 1041 return unc; 1042 } 1043 1048 public String getUncPath() { 1049 getUncPath0(); 1050 if( share == null ) { 1051 return "\\\\" + url.getHost(); 1052 } 1053 return "\\\\" + url.getHost() + canon.replace( '/', '\\' ); 1054 } 1055 1063 1064 public String getCanonicalPath() { 1065 String str = url.getAuthority(); 1066 getUncPath0(); 1067 if( str.length() > 0 ) { 1068 return "smb://" + url.getAuthority() + canon; 1069 } 1070 return "smb://"; 1071 } 1072 1073 1081 1082 public String getShare() { 1083 return share; 1084 } 1085 1086 1095 1096 public String getServer() { 1097 String str = url.getHost(); 1098 if( str.length() == 0 ) { 1099 return null; 1100 } 1101 return str; 1102 } 1103 1104 1109 public int getType() throws SmbException { 1110 if( type == 0 ) { 1111 if( getUncPath0().length() > 1 ) { 1112 type = TYPE_FILESYSTEM; 1113 } else if( share != null ) { 1114 connect0(); 1116 if( share.equals( "IPC$" )) { 1117 type = TYPE_NAMED_PIPE; 1118 } else if( tree.service.equals( "LPT1:" )) { 1119 type = TYPE_PRINTER; 1120 } else if( tree.service.equals( "COMM" )) { 1121 type = TYPE_COMM; 1122 } else { 1123 type = TYPE_SHARE; 1124 } 1125 } else if( url.getAuthority().length() == 0 ) { 1126 type = TYPE_WORKGROUP; 1127 } else { 1128 UniAddress addr; 1129 try { 1130 addr = getAddress(); 1131 } catch( UnknownHostException uhe ) { 1132 throw new SmbException( url.toString(), uhe ); 1133 } 1134 if( addr.getAddress() instanceof NbtAddress ) { 1135 int code = ((NbtAddress)addr.getAddress()).getNameType(); 1136 if( code == 0x1d || code == 0x1b ) { 1137 type = TYPE_WORKGROUP; 1138 return type; 1139 } 1140 } 1141 type = TYPE_SERVER; 1142 } 1143 } 1144 return type; 1145 } 1146 boolean isWorkgroup0() throws UnknownHostException { 1147 if( type == TYPE_WORKGROUP || url.getHost().length() == 0 ) { 1148 type = TYPE_WORKGROUP; 1149 return true; 1150 } else { 1151 getUncPath0(); 1152 if( share == null ) { 1153 UniAddress addr = getAddress(); 1154 if( addr.getAddress() instanceof NbtAddress ) { 1155 int code = ((NbtAddress)addr.getAddress()).getNameType(); 1156 if( code == 0x1d || code == 0x1b ) { 1157 type = TYPE_WORKGROUP; 1158 return true; 1159 } 1160 } 1161 type = TYPE_SERVER; 1162 } 1163 } 1164 return false; 1165 } 1166 1167 Info queryPath( String path, int infoLevel ) throws SmbException { 1168 connect0(); 1169 1170 if( log.level > 2 ) 1171 log.println( "queryPath: " + path ); 1172 1173 1180 1181 1187 1188 if( tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS )) { 1189 1190 1193 1194 Trans2QueryPathInformationResponse response = 1195 new Trans2QueryPathInformationResponse( infoLevel ); 1196 send( new Trans2QueryPathInformation( path, infoLevel ), response ); 1197 1198 return response.info; 1199 } else { 1200 1201 1204 1205 SmbComQueryInformationResponse response = 1206 new SmbComQueryInformationResponse( 1207 tree.session.transport.server.serverTimeZone * 1000 * 60L ); 1208 send( new SmbComQueryInformation( path ), response ); 1209 return response; 1210 } 1211 } 1212 1213 1226 1227 public boolean exists() throws SmbException { 1228 1229 if( attrExpiration > System.currentTimeMillis() ) { 1230 return isExists; 1231 } 1232 1233 attributes = ATTR_READONLY | ATTR_DIRECTORY; 1234 createTime = 0L; 1235 lastModified = 0L; 1236 isExists = false; 1237 1238 try { 1239 if( url.getHost().length() == 0 ) { 1240 } else if( share == null ) { 1241 if( getType() == TYPE_WORKGROUP ) { 1242 UniAddress.getByName( url.getHost(), true ); 1243 } else { 1244 UniAddress.getByName( url.getHost() ).getHostName(); 1245 } 1246 } else if( getUncPath0().length() == 1 || 1247 share.equalsIgnoreCase( "IPC$" )) { 1248 connect0(); } else { 1250 Info info = queryPath( getUncPath0(), 1251 Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO ); 1252 attributes = info.getAttributes(); 1253 createTime = info.getCreateTime(); 1254 lastModified = info.getLastWriteTime(); 1255 } 1256 1257 1259 1260 isExists = true; 1261 1262 } catch( UnknownHostException uhe ) { 1263 } catch( SmbException se ) { 1264 switch (se.getNtStatus()) { 1265 case NtStatus.NT_STATUS_NO_SUCH_FILE: 1266 case NtStatus.NT_STATUS_OBJECT_NAME_INVALID: 1267 case NtStatus.NT_STATUS_OBJECT_NAME_NOT_FOUND: 1268 case NtStatus.NT_STATUS_OBJECT_PATH_NOT_FOUND: 1269 break; 1270 default: 1271 throw se; 1272 } 1273 } 1274 1275 attrExpiration = System.currentTimeMillis() + attrExpirationPeriod; 1276 1277 return isExists; 1278 } 1279 1280 1287 1288 public boolean canRead() throws SmbException { 1289 if( getType() == TYPE_NAMED_PIPE ) { return true; 1291 } 1292 return exists(); } 1294 1295 1305 1306 public boolean canWrite() throws SmbException { 1307 if( getType() == TYPE_NAMED_PIPE ) { return true; 1309 } 1310 return exists() && ( attributes & ATTR_READONLY ) == 0; 1311 } 1312 1313 1318 1319 public boolean isDirectory() throws SmbException { 1320 if( getUncPath0().length() == 1 ) { 1321 return true; 1322 } 1323 if (!exists()) return false; 1324 return ( attributes & ATTR_DIRECTORY ) == ATTR_DIRECTORY; 1325 } 1326 1327 1332 1333 public boolean isFile() throws SmbException { 1334 if( getUncPath0().length() == 1 ) { 1335 return false; 1336 } 1337 exists(); 1338 return ( attributes & ATTR_DIRECTORY ) == 0; 1339 } 1340 1341 1348 1349 public boolean isHidden() throws SmbException { 1350 if( share == null ) { 1351 return false; 1352 } else if( getUncPath0().length() == 1 ) { 1353 if( share.endsWith( "$" )) { 1354 return true; 1355 } 1356 return false; 1357 } 1358 exists(); 1359 return ( attributes & ATTR_HIDDEN ) == ATTR_HIDDEN; 1360 } 1361 1362 1367 1368 public String getDfsPath() throws SmbException { 1369 connect0(); 1370 if( tree.inDfs ) { 1371 exists(); 1372 } 1373 if( dfsReferral == null ) { 1374 return null; 1375 } 1376 String path = "smb:/" + (new String ( dfsReferral.node + unc )).replace( '\\', '/' ); 1377 if (isDirectory()) { 1378 path += '/'; 1379 } 1380 return path; 1381 } 1382 1383 1395 public long createTime() throws SmbException { 1396 if( getUncPath0().length() > 1 ) { 1397 exists(); 1398 return createTime; 1399 } 1400 return 0L; 1401 } 1402 1412 public long lastModified() throws SmbException { 1413 if( getUncPath0().length() > 1 ) { 1414 exists(); 1415 return lastModified; 1416 } 1417 return 0L; 1418 } 1419 1440 public String [] list() throws SmbException { 1441 return list( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); 1442 } 1443 1444 1453 public String [] list( SmbFilenameFilter filter ) throws SmbException { 1454 return list( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, filter, null ); 1455 } 1456 1457 1482 public SmbFile[] listFiles() throws SmbException { 1483 return listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); 1484 } 1485 1486 1514 1515 public SmbFile[] listFiles( String wildcard ) throws SmbException { 1516 return listFiles( wildcard, ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); 1517 } 1518 1527 public SmbFile[] listFiles( SmbFilenameFilter filter ) throws SmbException { 1528 return listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, filter, null ); 1529 } 1530 1538 public SmbFile[] listFiles( SmbFileFilter filter ) throws SmbException { 1539 return listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, filter ); 1540 } 1541 String [] list( String wildcard, int searchAttributes, 1542 SmbFilenameFilter fnf, SmbFileFilter ff ) throws SmbException { 1543 ArrayList list = new ArrayList (); 1544 1545 try { 1546 if( url.getHost().length() == 0 || share == null ) { 1547 doNetEnum( list, false, wildcard, searchAttributes, fnf, ff ); 1548 } else { 1549 doFindFirstNext( list, false, wildcard, searchAttributes, fnf, ff ); 1550 } 1551 } catch( UnknownHostException uhe ) { 1552 throw new SmbException( url.toString(), uhe ); 1553 } catch( MalformedURLException mue ) { 1554 throw new SmbException( url.toString(), mue ); 1555 } 1556 1557 return (String [])list.toArray(new String [list.size()]); 1558 } 1559 SmbFile[] listFiles( String wildcard, int searchAttributes, 1560 SmbFilenameFilter fnf, SmbFileFilter ff ) throws SmbException { 1561 ArrayList list = new ArrayList (); 1562 1563 if( ff != null && ff instanceof DosFileFilter ) { 1564 DosFileFilter dff = (DosFileFilter)ff; 1565 if( dff.wildcard != null ) { 1566 wildcard = dff.wildcard; 1567 } 1568 searchAttributes = dff.attributes; 1569 } 1570 1571 try { 1572 if( url.getHost().length() == 0 || share == null ) { 1573 doNetEnum( list, true, wildcard, searchAttributes, fnf, ff ); 1574 } else { 1575 doFindFirstNext( list, true, wildcard, searchAttributes, fnf, ff ); 1576 } 1577 } catch( UnknownHostException uhe ) { 1578 throw new SmbException( url.toString(), uhe ); 1579 } catch( MalformedURLException mue ) { 1580 throw new SmbException( url.toString(), mue ); 1581 } 1582 1583 return (SmbFile[])list.toArray(new SmbFile[list.size()]); 1584 } 1585 void doNetEnum( ArrayList list, 1586 boolean files, 1587 String wildcard, 1588 int searchAttributes, 1589 SmbFilenameFilter fnf, 1590 SmbFileFilter ff ) throws SmbException, 1591 UnknownHostException , MalformedURLException { 1592 SmbComTransaction req; 1593 SmbComTransactionResponse resp; 1594 int listType = url.getHost().length() == 0 ? 0 : getType(); 1595 String p = url.getPath(); 1596 1597 if( p.lastIndexOf( '/' ) != ( p.length() - 1 )) { 1598 throw new SmbException( url.toString() + " directory must end with '/'" ); 1599 } 1600 1601 switch( listType ) { 1602 case 0: 1603 connect0(); 1604 req = new NetServerEnum2( tree.session.transport.server.oemDomainName, 1605 NetServerEnum2.SV_TYPE_DOMAIN_ENUM ); 1606 resp = new NetServerEnum2Response(); 1607 break; 1608 case TYPE_WORKGROUP: 1609 req = new NetServerEnum2( url.getHost(), NetServerEnum2.SV_TYPE_ALL ); 1610 resp = new NetServerEnum2Response(); 1611 break; 1612 case TYPE_SERVER: 1613 req = new NetShareEnum(); 1614 resp = new NetShareEnumResponse(); 1615 break; 1616 default: 1617 throw new SmbException( "The requested list operations is invalid: " + url.toString() ); 1618 } 1619 1620 boolean more; 1621 do { 1622 int n; 1623 1624 send( req, resp ); 1625 1626 more = resp.status == SmbException.ERROR_MORE_DATA; 1627 1628 if( resp.status != SmbException.ERROR_SUCCESS && 1629 resp.status != SmbException.ERROR_MORE_DATA ) { 1630 throw new SmbException( resp.status, true ); 1631 } 1632 1633 n = more ? resp.numEntries - 1 : resp.numEntries; 1634 for( int i = 0; i < n; i++ ) { 1635 FileEntry e = resp.results[i]; 1636 String name = e.getName(); 1637 if( fnf != null && fnf.accept( this, name ) == false ) { 1638 continue; 1639 } 1640 if( name.length() > 0 ) { 1641 SmbFile f = new SmbFile( this, name, 1642 e.getType(), 1643 ATTR_READONLY | ATTR_DIRECTORY, 0L, 0L, 0L ); 1644 if( ff != null && ff.accept( f ) == false ) { 1645 continue; 1646 } 1647 if( files ) { 1648 list.add( f ); 1649 } else { 1650 list.add( name ); 1651 } 1652 } 1653 } 1654 if( listType != 0 && listType != TYPE_WORKGROUP ) { 1655 break; 1656 } 1657 req.subCommand = (byte)SmbComTransaction.NET_SERVER_ENUM3; 1658 req.reset( 0, ((NetServerEnum2Response)resp).lastName ); 1659 resp.reset(); 1660 } while( more ); 1661 } 1662 void doFindFirstNext( ArrayList list, 1663 boolean files, 1664 String wildcard, 1665 int searchAttributes, 1666 SmbFilenameFilter fnf, 1667 SmbFileFilter ff ) throws SmbException, UnknownHostException , MalformedURLException { 1668 SmbComTransaction req; 1669 Trans2FindFirst2Response resp; 1670 int sid; 1671 String path = getUncPath0(); 1672 String p = url.getPath(); 1673 1674 if( p.lastIndexOf( '/' ) != ( p.length() - 1 )) { 1675 throw new SmbException( url.toString() + " directory must end with '/'" ); 1676 } 1677 1678 req = new Trans2FindFirst2( path, wildcard, searchAttributes ); 1679 resp = new Trans2FindFirst2Response(); 1680 1681 if( log.level > 2 ) 1682 log.println( "doFindFirstNext: " + req.path ); 1683 1684 send( req, resp ); 1685 1686 sid = resp.sid; 1687 req = new Trans2FindNext2( sid, resp.resumeKey, resp.lastName ); 1688 1689 1692 resp.subCommand = SmbComTransaction.TRANS2_FIND_NEXT2; 1693 1694 for( ;; ) { 1695 for( int i = 0; i < resp.numEntries; i++ ) { 1696 FileEntry e = resp.results[i]; 1697 String name = e.getName(); 1698 if( name.length() < 3 ) { 1699 int h = name.hashCode(); 1700 if( h == HASH_DOT || h == HASH_DOT_DOT ) { 1701 continue; 1702 } 1703 } 1704 if( fnf != null && fnf.accept( this, name ) == false ) { 1705 continue; 1706 } 1707 if( name.length() > 0 ) { 1708 SmbFile f = new SmbFile( this, name, TYPE_FILESYSTEM, 1709 e.getAttributes(), e.createTime(), e.lastModified(), e.length() ); 1710 if( ff != null && ff.accept( f ) == false ) { 1711 continue; 1712 } 1713 if( files ) { 1714 list.add( f ); 1715 } else { 1716 list.add( name ); 1717 } 1718 } 1719 } 1720 1721 if( resp.isEndOfSearch || resp.numEntries == 0 ) { 1722 break; 1723 } 1724 1725 req.reset( resp.resumeKey, resp.lastName ); 1726 resp.reset(); 1727 send( req, resp ); 1728 } 1729 1730 send( new SmbComFindClose2( sid ), blank_resp() ); 1731 } 1732 1733 1747 public void renameTo( SmbFile dest ) throws SmbException { 1748 if( getUncPath0().length() == 1 || dest.getUncPath0().length() == 1 ) { 1749 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 1750 } 1751 connect0(); 1752 dest.connect0(); 1753 1754 if( tree.inDfs ) { 1762 exists(); 1763 dest.exists(); 1764 } 1765 if( tree != dest.tree ) { 1766 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 1767 } 1768 1769 if( log.level > 2 ) 1770 log.println( "renameTo: " + unc + " -> " + dest.unc ); 1771 1772 attrExpiration = sizeExpiration = 0; 1773 dest.attrExpiration = 0; 1774 1775 1778 1779 send( new SmbComRename( unc, dest.unc ), blank_resp() ); 1780 } 1781 1782 class WriterThread extends Thread { 1783 byte[] b; 1784 int n, off; 1785 boolean ready; 1786 SmbFile dest; 1787 SmbException e = null; 1788 boolean useNTSmbs; 1789 SmbComWriteAndX reqx; 1790 SmbComWrite req; 1791 ServerMessageBlock resp; 1792 1793 WriterThread() throws SmbException { 1794 super( "JCIFS-WriterThread" ); 1795 useNTSmbs = tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS ); 1796 if( useNTSmbs ) { 1797 reqx = new SmbComWriteAndX(); 1798 resp = new SmbComWriteAndXResponse(); 1799 } else { 1800 req = new SmbComWrite(); 1801 resp = new SmbComWriteResponse(); 1802 } 1803 ready = false; 1804 } 1805 1806 synchronized void write( byte[] b, int n, SmbFile dest, int off ) { 1807 this.b = b; 1808 this.n = n; 1809 this.dest = dest; 1810 this.off = off; 1811 ready = false; 1812 notify(); 1813 } 1814 1815 public void run() { 1816 synchronized( this ) { 1817 try { 1818 for( ;; ) { 1819 notify(); 1820 ready = true; 1821 while( ready ) { 1822 wait(); 1823 } 1824 if( n == -1 ) { 1825 return; 1826 } 1827 if( useNTSmbs ) { 1828 reqx.setParam( dest.fid, off, n, b, 0, n ); 1829 dest.send( reqx, resp ); 1830 } else { 1831 req.setParam( dest.fid, off, n, b, 0, n ); 1832 dest.send( req, resp ); 1833 } 1834 } 1835 } catch( SmbException e ) { 1836 this.e = e; 1837 } catch( Exception x ) { 1838 this.e = new SmbException( "WriterThread", x ); 1839 } 1840 notify(); 1841 } 1842 } 1843 } 1844 void copyTo0( SmbFile dest, byte[][] b, int bsize, WriterThread w, 1845 SmbComReadAndX req, SmbComReadAndXResponse resp ) throws SmbException { 1846 int i; 1847 1848 if( attrExpiration < System.currentTimeMillis() ) { 1849 attributes = ATTR_READONLY | ATTR_DIRECTORY; 1850 createTime = 0L; 1851 lastModified = 0L; 1852 isExists = false; 1853 1854 Info info = queryPath( getUncPath0(), 1855 Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO ); 1856 attributes = info.getAttributes(); 1857 createTime = info.getCreateTime(); 1858 lastModified = info.getLastWriteTime(); 1859 1860 1862 1863 isExists = true; 1864 attrExpiration = System.currentTimeMillis() + attrExpirationPeriod; 1865 } 1866 1867 if( isDirectory() ) { 1868 SmbFile[] files; 1869 SmbFile ndest; 1870 1871 String path = dest.getUncPath0(); 1872 if( path.length() > 1 ) { 1873 try { 1874 dest.mkdir(); 1875 dest.setPathInformation( attributes, createTime, lastModified ); 1876 } catch( SmbException se ) { 1877 if( se.getNtStatus() != NtStatus.NT_STATUS_ACCESS_DENIED && 1878 se.getNtStatus() != NtStatus.NT_STATUS_OBJECT_NAME_COLLISION ) { 1879 throw se; 1880 } 1881 } 1882 } 1883 1884 files = listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); 1885 try { 1886 for( i = 0; i < files.length; i++ ) { 1887 ndest = new SmbFile( dest, 1888 files[i].getName(), 1889 files[i].type, 1890 files[i].attributes, 1891 files[i].createTime, 1892 files[i].lastModified, 1893 files[i].size ); 1894 files[i].copyTo0( ndest, b, bsize, w, req, resp ); 1895 } 1896 } catch( UnknownHostException uhe ) { 1897 throw new SmbException( url.toString(), uhe ); 1898 } catch( MalformedURLException mue ) { 1899 throw new SmbException( url.toString(), mue ); 1900 } 1901 } else { 1902 int off; 1903 1904try { 1905 open( SmbFile.O_RDONLY, ATTR_NORMAL, 0 ); 1906 try { 1907 dest.open( SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_TRUNC | 1908 SmbComNTCreateAndX.FILE_WRITE_ATTRIBUTES << 16, attributes, 0 ); 1909 } catch( SmbAuthException sae ) { 1910 if(( dest.attributes & ATTR_READONLY ) != 0 ) { 1911 1913 dest.setPathInformation( dest.attributes & ~ATTR_READONLY, 0L, 0L ); 1914 dest.open( SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_TRUNC | 1915 SmbComNTCreateAndX.FILE_WRITE_ATTRIBUTES << 16, attributes, 0 ); 1916 } else { 1917 throw sae; 1918 } 1919 } 1920 1921 i = off = 0; 1922 for( ;; ) { 1923 req.setParam( fid, off, bsize ); 1924 resp.setParam( b[i], 0 ); 1925 send( req, resp ); 1926 1927 synchronized( w ) { 1928 while( !w.ready ) { 1929 try { 1930 w.wait(); 1931 } catch( InterruptedException ie ) { 1932 throw new SmbException( dest.url.toString(), ie ); 1933 } 1934 } 1935 if( w.e != null ) { 1936 throw w.e; 1937 } 1938 if( resp.dataLength <= 0 ) { 1939 break; 1940 } 1941 w.write( b[i], resp.dataLength, dest, off ); 1942 } 1943 1944 i = i == 1 ? 0 : 1; 1945 off += resp.dataLength; 1946 } 1947 1948 dest.send( new Trans2SetFileInformation( 1949 dest.fid, attributes, createTime, lastModified ), 1950 new Trans2SetFileInformationResponse() ); 1951 dest.close( 0L ); 1952 close(); 1953} catch( Exception ex ) { 1954 if( log.level > 1 ) 1955 ex.printStackTrace( log ); 1956} 1957 } 1958 } 1959 1975 public void copyTo( SmbFile dest ) throws SmbException { 1976 SmbComReadAndX req; 1977 SmbComReadAndXResponse resp; 1978 WriterThread w; 1979 int bsize; 1980 byte[][] b; 1981 1982 1984 if( share == null || dest.share == null) { 1985 throw new SmbException( "Invalid operation for workgroups or servers" ); 1986 } 1987 1988 req = new SmbComReadAndX(); 1989 resp = new SmbComReadAndXResponse(); 1990 1991 connect0(); 1992 dest.connect0(); 1993 1994 if( tree.inDfs ) { 1995 2004 exists(); 2005 dest.exists(); 2006 } 2007 2008 2011 try { 2012 if (getAddress().equals( dest.getAddress() ) && 2013 canon.regionMatches( true, 0, dest.canon, 0, 2014 Math.min( canon.length(), dest.canon.length() ))) { 2015 throw new SmbException( "Source and destination paths overlap." ); 2016 } 2017 } catch (UnknownHostException uhe) { 2018 } 2019 2020 w = new WriterThread(); 2021 w.setDaemon( true ); 2022 w.start(); 2023 2024 2027 2028 SmbTransport t1 = tree.session.transport; 2029 SmbTransport t2 = dest.tree.session.transport; 2030 2031 if( t1.snd_buf_size < t2.snd_buf_size ) { 2032 t2.snd_buf_size = t1.snd_buf_size; 2033 } else { 2034 t1.snd_buf_size = t2.snd_buf_size; 2035 } 2036 2037 bsize = Math.min( t1.rcv_buf_size - 70, t1.snd_buf_size - 70 ); 2038 b = new byte[2][bsize]; 2039 2040 copyTo0( dest, b, bsize, w, req, resp ); 2041 w.write( null, -1, null, 0 ); 2042 } 2043 2044 2053 public void delete() throws SmbException { 2054 if( tree == null || tree.inDfs ) { 2055 exists(); 2057 } 2058 getUncPath0(); 2059 delete( unc ); 2060 } 2061 void delete( String fileName ) throws SmbException { 2062 if( getUncPath0().length() == 1 ) { 2063 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 2064 } 2065 2066 if( System.currentTimeMillis() > attrExpiration ) { 2067 attributes = ATTR_READONLY | ATTR_DIRECTORY; 2068 createTime = 0L; 2069 lastModified = 0L; 2070 isExists = false; 2071 2072 Info info = queryPath( getUncPath0(), 2073 Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO ); 2074 attributes = info.getAttributes(); 2075 createTime = info.getCreateTime(); 2076 lastModified = info.getLastWriteTime(); 2077 2078 attrExpiration = System.currentTimeMillis() + attrExpirationPeriod; 2079 isExists = true; 2080 } 2081 2082 if(( attributes & ATTR_READONLY ) != 0 ) { 2083 setReadWrite(); 2084 } 2085 2086 2089 2090 if( log.level > 2 ) 2091 log.println( "delete: " + fileName ); 2092 2093 if(( attributes & ATTR_DIRECTORY ) != 0 ) { 2094 2095 2097 2098 try { 2099 SmbFile[] l = listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null ); 2100 for( int i = 0; i < l.length; i++ ) { 2101 l[i].delete(); 2102 } 2103 } catch( SmbException se ) { 2104 2108 if( se.getNtStatus() != SmbException.NT_STATUS_NO_SUCH_FILE ) { 2109 throw se; 2110 } 2111 } 2112 2113 send( new SmbComDeleteDirectory( fileName ), blank_resp() ); 2114 } else { 2115 send( new SmbComDelete( fileName ), blank_resp() ); 2116 } 2117 2118 attrExpiration = sizeExpiration = 0; 2119 } 2120 2121 2131 2132 public long length() throws SmbException { 2133 if( sizeExpiration > System.currentTimeMillis() ) { 2134 return size; 2135 } 2136 2137 if( getType() == TYPE_SHARE ) { 2138 Trans2QueryFSInformationResponse response; 2139 int level = Trans2QueryFSInformationResponse.SMB_INFO_ALLOCATION; 2140 2141 response = new Trans2QueryFSInformationResponse( level ); 2142 send( new Trans2QueryFSInformation( level ), response ); 2143 2144 size = response.info.getCapacity(); 2145 } else if( getUncPath0().length() > 1 && type != TYPE_NAMED_PIPE ) { 2146 Info info = queryPath( getUncPath0(), 2147 Trans2QueryPathInformationResponse.SMB_QUERY_FILE_STANDARD_INFO ); 2148 size = info.getSize(); 2149 } else { 2150 size = 0L; 2151 } 2152 sizeExpiration = System.currentTimeMillis() + attrExpirationPeriod; 2153 return size; 2154 } 2155 2156 2165 public long getDiskFreeSpace() throws SmbException { 2166 if( getType() == TYPE_SHARE || type == TYPE_FILESYSTEM ) { 2167 int level = Trans2QueryFSInformationResponse.SMB_FS_FULL_SIZE_INFORMATION; 2168 try { 2169 return queryFSInformation(level); 2170 } catch( SmbException ex ) { 2171 switch (ex.getNtStatus()) { 2172 case NtStatus.NT_STATUS_INVALID_INFO_CLASS: 2173 case NtStatus.NT_STATUS_UNSUCCESSFUL: level = Trans2QueryFSInformationResponse.SMB_INFO_ALLOCATION; 2176 return queryFSInformation(level); 2177 } 2178 throw ex; 2179 } 2180 } 2181 return 0L; 2182 } 2183 2184 private long queryFSInformation( int level ) throws SmbException { 2185 Trans2QueryFSInformationResponse response; 2186 2187 response = new Trans2QueryFSInformationResponse( level ); 2188 send( new Trans2QueryFSInformation( level ), response ); 2189 2190 if( type == TYPE_SHARE ) { 2191 size = response.info.getCapacity(); 2192 sizeExpiration = System.currentTimeMillis() + attrExpirationPeriod; 2193 } 2194 2195 return response.info.getFree(); 2196 } 2197 2198 2209 public void mkdir() throws SmbException { 2210 String path = getUncPath0(); 2211 2212 if( path.length() == 1 ) { 2213 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 2214 } 2215 2216 2219 2220 if( log.level > 2 ) 2221 log.println( "mkdir: " + path ); 2222 2223 send( new SmbComCreateDirectory( path ), blank_resp() ); 2224 2225 attrExpiration = sizeExpiration = 0; 2226 } 2227 2228 2238 public void mkdirs() throws SmbException { 2239 SmbFile parent; 2240 2241 try { 2242 parent = new SmbFile( getParent(), auth ); 2243 } catch( IOException ioe ) { 2244 return; 2245 } 2246 if( parent.exists() == false ) { 2247 parent.mkdirs(); 2248 } 2249 mkdir(); 2250 } 2251 2252 2257 public void createNewFile() throws SmbException { 2258 if( getUncPath0().length() == 1 ) { 2259 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 2260 } 2261 close( open0( O_RDWR | O_CREAT | O_EXCL, ATTR_NORMAL, 0 ), 0L ); 2262 } 2263 2264 void setPathInformation( int attrs, long ctime, long mtime ) throws SmbException { 2265 int f, dir; 2266 2267 exists(); 2268 dir = attributes & ATTR_DIRECTORY; 2269 2270 f = open0( O_RDONLY | SmbComNTCreateAndX.FILE_WRITE_ATTRIBUTES << 16, 2271 dir, dir != 0 ? 0x0001 : 0x0040 ); 2272 send( new Trans2SetFileInformation( f, attrs | dir, ctime, mtime ), 2273 new Trans2SetFileInformationResponse() ); 2274 close( f, 0L ); 2275 2276 attrExpiration = 0; 2277 } 2278 2279 2288 public void setCreateTime( long time ) throws SmbException { 2289 if( getUncPath0().length() == 1 ) { 2290 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 2291 } 2292 2293 setPathInformation( 0, time, 0L ); 2294 } 2295 2304 public void setLastModified( long time ) throws SmbException { 2305 if( getUncPath0().length() == 1 ) { 2306 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 2307 } 2308 2309 setPathInformation( 0, 0L, time ); 2310 } 2311 2312 2321 public int getAttributes() throws SmbException { 2322 if( getUncPath0().length() == 1 ) { 2323 return 0; 2324 } 2325 exists(); 2326 return attributes & ATTR_GET_MASK; 2327 } 2328 2329 2336 public void setAttributes( int attrs ) throws SmbException { 2337 if( getUncPath0().length() == 1 ) { 2338 throw new SmbException( "Invalid operation for workgroups, servers, or shares" ); 2339 } 2340 setPathInformation( attrs & ATTR_SET_MASK, 0L, 0L ); 2341 } 2342 2343 2349 public void setReadOnly() throws SmbException { 2350 setAttributes( getAttributes() | ATTR_READONLY ); 2351 } 2352 2353 2359 public void setReadWrite() throws SmbException { 2360 setAttributes( getAttributes() & ~ATTR_READONLY ); 2361 } 2362 2363 2373 public URL toURL() throws MalformedURLException { 2374 return url; 2375 } 2376 2377 2389 2390 public int hashCode() { 2391 int hash; 2392 try { 2393 hash = getAddress().hashCode(); 2394 } catch( UnknownHostException uhe ) { 2395 hash = getServer().toUpperCase().hashCode(); 2396 } 2397 getUncPath0(); 2398 return hash + canon.toUpperCase().hashCode(); 2399 } 2400 2401 2423 2424 public boolean equals( Object obj ) { 2425 return obj instanceof SmbFile && obj.hashCode() == hashCode(); 2426 } 2427 2428 2437 2438 public String toString() { 2439 return url.toString(); 2440 } 2441 2442 2443 2448 2449 public int getContentLength() { 2450 try { 2451 return (int)(length() & 0xFFFFFFFFL); 2452 } catch( SmbException se ) { 2453 } 2454 return 0; 2455 } 2456 2457 2462 public long getDate() { 2463 try { 2464 return lastModified(); 2465 } catch( SmbException se ) { 2466 } 2467 return 0L; 2468 } 2469 2470 2475 public long getLastModified() { 2476 try { 2477 return lastModified(); 2478 } catch( SmbException se ) { 2479 } 2480 return 0L; 2481 } 2482 2483 2488 public InputStream getInputStream() throws IOException { 2489 return new SmbFileInputStream( this ); 2490 } 2491 2492 2497 public OutputStream getOutputStream() throws IOException { 2498 return new SmbFileOutputStream( this ); 2499 } 2500} 2501 | Popular Tags |