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 + -
显示快捷键?