001: /* jcifs smb client library in Java
002: * Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018:
019: package jcifs.smb;
020:
021: import java.io.IOException;
022: import java.net.UnknownHostException;
023: import jcifs.UniAddress;
024: import jcifs.netbios.NbtAddress;
025: import jcifs.Config;
026:
027: class SmbTree {
028:
029: private static final String DEFAULT_SERVICE = Config.getProperty(
030: "jcifs.smb.client.serviceType", "?????");
031:
032: private int tid;
033: private String share;
034:
035: String service = DEFAULT_SERVICE;
036: SmbSession session;
037: boolean treeConnected, inDfs;
038:
039: SmbTree(SmbSession session, String share, String service) {
040: this .session = session;
041: this .share = share.toUpperCase();
042: if (service != null && service.startsWith("??") == false) {
043: this .service = service;
044: }
045: }
046:
047: boolean matches(String share, String service) {
048: return this .share.equalsIgnoreCase(share)
049: && (service == null || service.startsWith("??") || this .service
050: .equalsIgnoreCase(service));
051: }
052:
053: void sendTransaction(SmbComTransaction request,
054: SmbComTransactionResponse response) throws SmbException {
055: // transactions are not batchable
056: treeConnect(null, null);
057: if (service.equals("A:") == false) {
058: switch (((SmbComTransaction) request).subCommand & 0xFF) {
059: case SmbComTransaction.NET_SHARE_ENUM:
060: case SmbComTransaction.NET_SERVER_ENUM2:
061: case SmbComTransaction.NET_SERVER_ENUM3:
062: case SmbComTransaction.TRANS_PEEK_NAMED_PIPE:
063: case SmbComTransaction.TRANS_WAIT_NAMED_PIPE:
064: case SmbComTransaction.TRANS_CALL_NAMED_PIPE:
065: case SmbComTransaction.TRANS_TRANSACT_NAMED_PIPE:
066: case SmbComTransaction.TRANS2_GET_DFS_REFERRAL:
067: break;
068: default:
069: throw new SmbException("Invalid operation for "
070: + service + " service");
071: }
072: }
073: request.tid = tid;
074: if (inDfs && request.path != null && request.path.length() > 0) {
075: request.path = '\\' + session.transport().tconHostName
076: + '\\' + share + request.path;
077: }
078: session.sendTransaction(request, response);
079: }
080:
081: void send(ServerMessageBlock request, ServerMessageBlock response)
082: throws SmbException {
083: if (response != null) {
084: response.received = false;
085: }
086: treeConnect(request, response);
087: if (request == null || (response != null && response.received)) {
088: return;
089: }
090: if (service.equals("A:") == false) {
091: switch (request.command) {
092: case ServerMessageBlock.SMB_COM_OPEN_ANDX:
093: case ServerMessageBlock.SMB_COM_NT_CREATE_ANDX:
094: case ServerMessageBlock.SMB_COM_READ_ANDX:
095: case ServerMessageBlock.SMB_COM_WRITE_ANDX:
096: case ServerMessageBlock.SMB_COM_CLOSE:
097: case ServerMessageBlock.SMB_COM_TREE_DISCONNECT:
098: break;
099: default:
100: throw new SmbException("Invalid operation for "
101: + service + " service");
102: }
103: }
104: request.tid = tid;
105: if (inDfs && request.path != null && request.path.length() > 0) {
106: request.flags2 = ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS;
107: request.path = '\\' + session.transport().tconHostName
108: + '\\' + share + request.path;
109: }
110: session.send(request, response);
111: }
112:
113: void treeConnect(ServerMessageBlock andx,
114: ServerMessageBlock andxResponse) throws SmbException {
115: String unc;
116: synchronized (session.transport()) {
117:
118: if (treeConnected) {
119: return;
120: }
121:
122: /* The hostname to use in the path is only known for
123: * sure if the NetBIOS session has been successfully
124: * established.
125: */
126:
127: session.transport.negotiate();
128:
129: unc = "\\\\" + session.transport.tconHostName + '\\'
130: + share;
131:
132: /*
133: * Tree Connect And X Request / Response
134: */
135:
136: if (session.transport.log.level > 2)
137: session.transport.log.println("treeConnect: unc=" + unc
138: + ",service=" + service);
139:
140: SmbComTreeConnectAndXResponse response = new SmbComTreeConnectAndXResponse(
141: andxResponse);
142: SmbComTreeConnectAndX request = new SmbComTreeConnectAndX(
143: session, unc, service, andx);
144: session.send(request, response);
145:
146: tid = response.tid;
147: service = response.service;
148: inDfs = response.shareIsInDfs;
149: treeConnected = true;
150: }
151: }
152:
153: void treeDisconnect(boolean inError) {
154: synchronized (session.transport) {
155: if (treeConnected == false) {
156: return;
157: }
158: if (!inError) {
159: try {
160: send(new SmbComTreeDisconnect(), null);
161: } catch (SmbException se) {
162: }
163: }
164: treeConnected = false;
165: }
166: }
167:
168: public String toString() {
169: return "SmbTree[share=" + share + ",service=" + service
170: + ",tid=" + tid + ",inDfs=" + inDfs + ",treeConnected="
171: + treeConnected + "]";
172: }
173: }
|