📄 smbfile.java
字号:
* @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 );
unc = "\\";
} else if( i == o ) {
share = canon.substring( 1, i );
unc = "\\";
} else {
share = canon.substring( 1, i );
unc = canon.substring( i, out[o] == '/' ? o : o + 1 );
unc = unc.replace( '/', '\\' );
}
} else {
share = null;
unc = "\\";
}
}
return unc;
}
/**
* Retuns the Windows UNC style path with backslashs intead of forward slashes.
*
* @return The UNC path.
*/
public String getUncPath() {
getUncPath0();
if( share == null ) {
return "\\\\" + url.getHost();
}
return "\\\\" + url.getHost() + canon.replace( '/', '\\' );
}
/**
* Returns the full URL of this SMB resource with '.' and '..' components
* factored out. 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 canonicalized URL of this SMB resource.
*/
public String getCanonicalPath() {
String str = url.getAuthority();
getUncPath0();
if( str.length() > 0 ) {
return "smb://" + url.getAuthority() + canon;
}
return "smb://";
}
/**
* Retrieves the share associated with this SMB resource. In
* the case of <code>smb://</code>, <code>smb://workgroup/</code>,
* and <code>smb://server/</code> URLs which do not specify a share,
* <code>null</code> will be returned.
*
* @return The share component or <code>null</code> if there is no share
*/
public String getShare() {
return share;
}
String getServerWithDfs() {
if (dfsReferral != null) {
return dfsReferral.server;
}
return getServer();
}
/**
* Retrieve the hostname of the server for this SMB resource. If this
* <code>SmbFile</code> references a workgroup, the name of the workgroup
* is returned. If this <code>SmbFile</code> refers to the root of this
* SMB network hierarchy, <code>null</code> is returned.
*
* @return The server or workgroup name or <code>null</code> if this
* <code>SmbFile</code> refers to the root <code>smb://</code> resource.
*/
public String getServer() {
String str = url.getHost();
if( str.length() == 0 ) {
return null;
}
return str;
}
/**
* Returns type of of object this <tt>SmbFile</tt> represents.
* @return <tt>TYPE_FILESYSTEM, TYPE_WORKGROUP, TYPE_SERVER, TYPE_SHARE,
* TYPE_PRINTER, TYPE_NAMED_PIPE</tt>, or <tt>TYPE_COMM</tt>.
*/
public int getType() throws SmbException {
if( type == 0 ) {
if( getUncPath0().length() > 1 ) {
type = TYPE_FILESYSTEM;
} else if( share != null ) {
// treeConnect good enough to test service type
connect0();
if( share.equals( "IPC$" )) {
type = TYPE_NAMED_PIPE;
} else if( tree.service.equals( "LPT1:" )) {
type = TYPE_PRINTER;
} else if( tree.service.equals( "COMM" )) {
type = TYPE_COMM;
} else {
type = TYPE_SHARE;
}
} else if( url.getAuthority() == null || url.getAuthority().length() == 0 ) {
type = TYPE_WORKGROUP;
} else {
UniAddress addr;
try {
addr = getAddress();
} catch( UnknownHostException uhe ) {
throw new SmbException( url.toString(), uhe );
}
if( addr.getAddress() instanceof NbtAddress ) {
int code = ((NbtAddress)addr.getAddress()).getNameType();
if( code == 0x1d || code == 0x1b ) {
type = TYPE_WORKGROUP;
return type;
}
}
type = TYPE_SERVER;
}
}
return type;
}
boolean isWorkgroup0() throws UnknownHostException {
if( type == TYPE_WORKGROUP || url.getHost().length() == 0 ) {
type = TYPE_WORKGROUP;
return true;
} else {
getUncPath0();
if( share == null ) {
UniAddress addr = getAddress();
if( addr.getAddress() instanceof NbtAddress ) {
int code = ((NbtAddress)addr.getAddress()).getNameType();
if( code == 0x1d || code == 0x1b ) {
type = TYPE_WORKGROUP;
return true;
}
}
type = TYPE_SERVER;
}
}
return false;
}
Info queryPath( String path, int infoLevel ) throws SmbException {
connect0();
if (log.level >= 3)
log.println( "queryPath: " + path );
/* normally we'd check the negotiatedCapabilities for CAP_NT_SMBS
* however I can't seem to get a good last modified time from
* SMB_COM_QUERY_INFORMATION so if NT_SMBs are requested
* by the server than in this case that's what it will get
* regardless of what jcifs.smb.client.useNTSmbs is set
* to(overrides negotiatedCapabilities).
*/
/* We really should do the referral before this in case
* the redirected target has different capabilities. But
* the way we have been doing that is to call exists() which
* calls this method so another technique will be necessary
* to support DFS referral _to_ Win95/98/ME.
*/
if( tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS )) {
/*
* Trans2 Query Path Information Request / Response
*/
Trans2QueryPathInformationResponse response =
new Trans2QueryPathInformationResponse( infoLevel );
send( new Trans2QueryPathInformation( path, infoLevel ), response );
return response.info;
} else {
/*
* Query Information Request / Response
*/
SmbComQueryInformationResponse response =
new SmbComQueryInformationResponse(
tree.session.transport.server.serverTimeZone * 1000 * 60L );
send( new SmbComQueryInformation( path ), response );
return response;
}
}
/**
* Tests to see if the SMB resource exists. If the resource refers
* only to a server, this method determines if the server exists on the
* network and is advertising SMB services. If this resource refers to
* a workgroup, this method determines if the workgroup name is valid on
* the local SMB network. If this <code>SmbFile</code> refers to the root
* <code>smb://</code> resource <code>true</code> is always returned. If
* this <code>SmbFile</code> is a traditional file or directory, it will
* be queried for on the specified server as expected.
*
* @return <code>true</code> if the resource exists or is alive or
* <code>false</code> otherwise
*/
public boolean exists() throws SmbException {
if( attrExpiration > System.currentTimeMillis() ) {
return isExists;
}
attributes = ATTR_READONLY | ATTR_DIRECTORY;
createTime = 0L;
lastModified = 0L;
isExists = false;
try {
if( url.getHost().length() == 0 ) {
} else if( share == null ) {
if( getType() == TYPE_WORKGROUP ) {
UniAddress.getByName( url.getHost(), true );
} else {
UniAddress.getByName( url.getHost() ).getHostName();
}
} else if( getUncPath0().length() == 1 ||
share.equalsIgnoreCase( "IPC$" )) {
connect0(); // treeConnect is good enough
} else {
Info info = queryPath( getUncPath0(),
Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO );
attributes = info.getAttributes();
createTime = info.getCreateTime();
lastModified = info.getLastWriteTime();
}
/* If any of the above fail, isExists will not be set true
*/
isExists = true;
} catch( UnknownHostException uhe ) {
} catch( SmbException se ) {
switch (se.getNtStatus()) {
case NtStatus.NT_STATUS_NO_SUCH_FILE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -