smbfile.java
来自「java ftp 操作代码,程序可以直接运行」· Java 代码 · 共 1,707 行 · 第 1/5 页
JAVA
1,707 行
request.flags2 &= ~ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS;
}
try {
tree.send( request, response );
break;
} catch( DfsReferral dr ) {
if( dr.resolveHashes ) {
throw dr;
}
request.reset();
}
}
}
static String queryLookup( String query, String param ) {
char in[] = query.toCharArray();
int i, ch, st, eq;
st = eq = 0;
for( i = 0; i < in.length; i++) {
ch = in[i];
if( ch == '&' ) {
if( eq > st ) {
String p = new String( in, st, eq - st );
if( p.equalsIgnoreCase( param )) {
eq++;
return new String( in, eq, i - eq );
}
}
st = i + 1;
} else if( ch == '=' ) {
eq = i;
}
}
if( eq > st ) {
String p = new String( in, st, eq - st );
if( p.equalsIgnoreCase( param )) {
eq++;
return new String( in, eq, in.length - eq );
}
}
return null;
}
UniAddress getAddress() throws UnknownHostException {
String host = url.getHost();
String path = url.getPath();
String query = url.getQuery();
if( query != null ) {
String server = queryLookup( query, "server" );
if( server != null && server.length() > 0 ) {
return UniAddress.getByName( server );
}
}
if( host.length() == 0 ) {
try {
NbtAddress addr = NbtAddress.getByName(
NbtAddress.MASTER_BROWSER_NAME, 0x01, null);
return UniAddress.getByName( addr.getHostAddress() );
} catch( UnknownHostException uhe ) {
NtlmPasswordAuthentication.initDefaults();
if( NtlmPasswordAuthentication.DEFAULT_DOMAIN.equals( "?" )) {
throw uhe;
}
return UniAddress.getByName( NtlmPasswordAuthentication.DEFAULT_DOMAIN, true );
}
} else if( path.length() == 0 || path.equals( "/" )) {
return UniAddress.getByName( host, true );
} else {
return UniAddress.getByName( host );
}
}
void connect0() throws SmbException {
try {
connect();
} catch( UnknownHostException uhe ) {
throw new SmbException( "Failed to connect to server", uhe );
} catch( SmbException se ) {
throw se;
} catch( IOException ioe ) {
throw new SmbException( "Failed to connect to server", ioe );
}
}
/**
* It is not necessary to call this method directly. This is the
* <tt>URLConnection</tt> implementation of <tt>connect()</tt>.
*/
public void connect() throws IOException {
SmbTransport trans;
SmbSession ssn;
UniAddress addr;
if( isConnected() ) {
return;
}
getUncPath0();
addr = getAddress();
trans = SmbTransport.getSmbTransport( addr, url.getPort() );
ssn = trans.getSmbSession( auth );
tree = ssn.getSmbTree( share, null );
try {
tree.treeConnect( null, null );
} catch( SmbAuthException sae ) {
NtlmPasswordAuthentication a;
if( share == null ) { // IPC$ - try "anonymous" credentials
ssn = trans.getSmbSession( NtlmPasswordAuthentication.NULL );
tree = ssn.getSmbTree( null, null );
tree.treeConnect( null, null );
} else if(( a = NtlmAuthenticator.requestNtlmPasswordAuthentication(
url.toString(), sae )) != null ) {
auth = a;
ssn = trans.getSmbSession( auth );
tree = ssn.getSmbTree( share, null );
tree.treeConnect( null, null );
} else {
throw sae;
}
}
}
boolean isConnected() {
return (connected = tree != null && tree.treeConnected);
}
int open0( int flags, int attrs, int options ) throws SmbException {
int f;
connect0();
if( log.level > 2 )
log.println( "open0: " + unc );
/*
* NT Create AndX / Open AndX Request / Response
*/
if( tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS )) {
SmbComNTCreateAndXResponse response = new SmbComNTCreateAndXResponse();
send( new SmbComNTCreateAndX( unc, flags, shareAccess,
attrs, options, null ), response );
f = response.fid;
attributes = response.extFileAttributes & ATTR_GET_MASK;
attrExpiration = System.currentTimeMillis() + attrExpirationPeriod;
isExists = true;
} else {
SmbComOpenAndXResponse response = new SmbComOpenAndXResponse();
send( new SmbComOpenAndX( unc, flags, null ), response );
f = response.fid;
}
return f;
}
void open( int flags, int attrs, int options ) throws SmbException {
if( isOpen() ) {
return;
}
fid = open0( flags, attrs, options );
opened = true;
tree_num = tree.tree_num;
}
boolean isOpen() {
return opened && isConnected() && tree_num == tree.tree_num;
}
void close( int f, long lastWriteTime ) throws SmbException {
if( log.level > 2 )
log.println( "close: " + f );
/*
* Close Request / Response
*/
send( new SmbComClose( f, lastWriteTime ), blank_resp() );
}
void close( long lastWriteTime ) throws SmbException {
if( isOpen() == false ) {
return;
}
close( fid, lastWriteTime );
opened = false;
}
void close() throws SmbException {
close( 0L );
}
/**
* Returns the <tt>NtlmPasswordAuthentication</tt> object used as
* credentials with this file or pipe. This can be used to retrieve the
* username for example:
* <tt>
* String username = f.getPrincipal().getName();
* </tt>
* The <tt>Principal</tt> object returned will never be <tt>null</tt>
* however the username can be <tt>null</tt> indication anonymous
* credentials were used (e.g. some IPC$ services).
*/
public Principal getPrincipal() {
return auth;
}
/**
* Returns the last component of the target URL. This will
* effectively be the name of the file or directory represented by this
* <code>SmbFile</code> or in the case of URLs that only specify a server
* or workgroup, the server or workgroup will be returned. The name of
* the root URL <code>smb://</code> is also <code>smb://</code>. If this
* <tt>SmbFile</tt> refers to a workgroup, server, share, or directory,
* the name will include a trailing slash '/' so that composing new
* <tt>SmbFile</tt>s will maintain the trailing slash requirement.
*
* @return The last component of the URL associated with this SMB
* resource or <code>smb://</code> if the resource is <code>smb://</code>
* itself.
*/
public String getName() {
getUncPath0();
if( canon.length() > 1 ) {
int i = canon.length() - 2;
while( canon.charAt( i ) != '/' ) {
i--;
}
return canon.substring( i + 1 );
} else if( share != null ) {
return share + '/';
} else if( url.getHost().length() > 0 ) {
return url.getHost() + '/';
} else {
return "smb://";
}
}
/**
* Everything but the last component of the URL representing this SMB
* resource is effectivly it's parent. The root URL <code>smb://</code>
* does not have a parent. In this case <code>smb://</code> is returned.
*
* @return The parent directory of this SMB resource or
* <code>smb://</code> if the resource refers to the root of the URL
* hierarchy which incedentally is also <code>smb://</code>.
*/
public String getParent() {
String str = url.getAuthority();
if( str.length() > 0 ) {
StringBuffer sb = new StringBuffer( "smb://" );
sb.append( str );
getUncPath0();
if( canon.length() > 1 ) {
sb.append( canon );
} else {
sb.append( '/' );
}
str = sb.toString();
int i = str.length() - 2;
while( str.charAt( i ) != '/' ) {
i--;
}
return str.substring( 0, i + 1 );
}
return "smb://";
}
/**
* Returns the full uncanonicalized URL of this SMB resource. An
* <code>SmbFile</code> constructed with the result of this method will
* result in an <code>SmbFile</code> that is equal to the original.
*
* @return The uncanonicalized full URL of this SMB resource.
*/
public String getPath() {
return url.toString();
}
String getUncPath0() {
if( unc == null ) {
char[] in = url.getPath().toCharArray();
char[] out = new char[in.length];
int length = in.length, i, o, state, s;
/* The canonicalization routine
*/
state = 0;
o = 0;
for( i = 0; i < length; i++ ) {
switch( state ) {
case 0:
if( in[i] != '/' ) {
return null;
}
out[o++] = in[i];
state = 1;
break;
case 1:
if( in[i] == '/' ) {
break;
} else if( in[i] == '.' &&
(( i + 1 ) >= length || in[i + 1] == '/' )) {
i++;
break;
} else if(( i + 1 ) < length &&
in[i] == '.' &&
in[i + 1] == '.' &&
(( i + 2 ) >= length || in[i + 2] == '/' )) {
i += 2;
if( o == 1 ) break;
do {
o--;
} while( o > 1 && out[o - 1] != '/' );
break;
}
state = 2;
case 2:
if( in[i] == '/' ) {
state = 1;
}
out[o++] = in[i];
break;
}
}
canon = new String( out, 0, o );
if( o > 1 ) {
o--;
i = canon.indexOf( '/', 1 );
if( i < 0 ) {
share = canon.substring( 1 );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?