001: /* jcifs smb client library in Java
002: * Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
003: * "Christopher R. Hertel" <jcifs at samba dot org>
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package com.knowgate.jcifs.netbios;
021:
022: import java.io.UnsupportedEncodingException;
023:
024: import com.knowgate.jcifs.Config;
025: import com.knowgate.misc.Gadgets;
026:
027: class Name {
028:
029: private static final int TYPE_OFFSET = 31;
030: private static final int SCOPE_OFFSET = 33;
031: private static final String DEFAULT_SCOPE = Config
032: .getProperty("jcifs.netbios.scope");
033:
034: static final String OEM_ENCODING = Config.getProperty(
035: "jcifs.encoding", System.getProperty("file.encoding"));
036:
037: String name, scope;
038: int hexCode;
039: int srcHashCode; /* srcHashCode must be set by name resolution
040: * routines before entry into addressCache
041: */
042:
043: Name() {
044: }
045:
046: Name(String name, int hexCode, String scope) {
047: if (name.length() > 15) {
048: name = name.substring(0, 15);
049: }
050: this .name = name.toUpperCase();
051: this .hexCode = hexCode;
052: this .scope = scope != null && scope.length() > 0 ? scope
053: : DEFAULT_SCOPE;
054: this .srcHashCode = 0;
055: }
056:
057: int writeWireFormat(byte[] dst, int dstIndex) {
058: // write 0x20 in first byte
059: dst[dstIndex] = 0x20;
060:
061: // write name
062: try {
063: byte tmp[] = name.getBytes(Name.OEM_ENCODING);
064: int i;
065: for (i = 0; i < tmp.length; i++) {
066: dst[dstIndex + (2 * i + 1)] = (byte) (((tmp[i] & 0xF0) >> 4) + 0x41);
067: dst[dstIndex + (2 * i + 2)] = (byte) ((tmp[i] & 0x0F) + 0x41);
068: }
069: for (; i < 15; i++) {
070: dst[dstIndex + (2 * i + 1)] = (byte) 0x43;
071: dst[dstIndex + (2 * i + 2)] = (byte) 0x41;
072: }
073: dst[dstIndex + TYPE_OFFSET] = (byte) (((hexCode & 0xF0) >> 4) + 0x41);
074: dst[dstIndex + TYPE_OFFSET + 1] = (byte) ((hexCode & 0x0F) + 0x41);
075: } catch (UnsupportedEncodingException uee) {
076: }
077: return SCOPE_OFFSET
078: + writeScopeWireFormat(dst, dstIndex + SCOPE_OFFSET);
079: }
080:
081: int readWireFormat(byte[] src, int srcIndex) {
082:
083: byte tmp[] = new byte[SCOPE_OFFSET];
084: int length = 15;
085: for (int i = 0; i < 15; i++) {
086: tmp[i] = (byte) (((src[srcIndex + (2 * i + 1)] & 0xFF) - 0x41) << 4);
087: tmp[i] |= (byte) (((src[srcIndex + (2 * i + 2)] & 0xFF) - 0x41) & 0x0F);
088: if (tmp[i] != (byte) ' ') {
089: length = i + 1;
090: }
091: }
092: try {
093: name = new String(tmp, 0, length, Name.OEM_ENCODING);
094: } catch (UnsupportedEncodingException uee) {
095: }
096: hexCode = ((src[srcIndex + TYPE_OFFSET] & 0xFF) - 0x41) << 4;
097: hexCode |= ((src[srcIndex + TYPE_OFFSET + 1] & 0xFF) - 0x41) & 0x0F;
098: return SCOPE_OFFSET
099: + readScopeWireFormat(src, srcIndex + SCOPE_OFFSET);
100: }
101:
102: int writeScopeWireFormat(byte[] dst, int dstIndex) {
103: if (scope == null) {
104: dst[dstIndex] = (byte) 0x00;
105: return 1;
106: }
107:
108: // copy new scope in
109: dst[dstIndex++] = (byte) '.';
110: try {
111: System.arraycopy(scope.getBytes(Name.OEM_ENCODING), 0, dst,
112: dstIndex, scope.length());
113: } catch (UnsupportedEncodingException uee) {
114: }
115: dstIndex += scope.length();
116:
117: dst[dstIndex++] = (byte) 0x00;
118:
119: // now go over scope backwards converting '.' to label length
120:
121: int i = dstIndex - 2;
122: int e = i - scope.length();
123: int c = 0;
124:
125: do {
126: if (dst[i] == '.') {
127: dst[i] = (byte) c;
128: c = 0;
129: } else {
130: c++;
131: }
132: } while (i-- > e);
133: return scope.length() + 2;
134: }
135:
136: int readScopeWireFormat(byte[] src, int srcIndex) {
137: int start = srcIndex;
138: int n;
139: StringBuffer sb;
140:
141: if ((n = src[srcIndex++] & 0xFF) == 0) {
142: scope = null;
143: return 1;
144: }
145:
146: try {
147: sb = new StringBuffer(new String(src, srcIndex, n,
148: Name.OEM_ENCODING));
149: srcIndex += n;
150: while ((n = src[srcIndex++] & 0xFF) != 0) {
151: sb.append('.')
152: .append(
153: new String(src, srcIndex, n,
154: Name.OEM_ENCODING));
155: srcIndex += n;
156: }
157: scope = sb.toString();
158: } catch (UnsupportedEncodingException uee) {
159: }
160:
161: return srcIndex - start;
162: }
163:
164: public int hashCode() {
165: int result;
166:
167: result = name.hashCode();
168: result += 65599 * hexCode;
169: result += 65599 * srcHashCode; /* hashCode is different depending
170: * on where it came from
171: */
172: if (scope != null && scope.length() != 0) {
173: result += scope.hashCode();
174: }
175: return result;
176: }
177:
178: public boolean equals(Object obj) {
179: Name n;
180:
181: if (!(obj instanceof Name)) {
182: return false;
183: }
184: n = (Name) obj;
185: if (scope == null && n.scope == null) {
186: return name.equals(n.name) && hexCode == n.hexCode;
187: }
188: return name.equals(n.name) && hexCode == n.hexCode
189: && scope.equals(n.scope);
190: }
191:
192: public String toString() {
193: StringBuffer sb = new StringBuffer();
194: String n = name;
195:
196: // fix MSBROWSE name
197: if (n == null) {
198: n = "null";
199: } else if (n.charAt(0) == 0x01) {
200: char c[] = n.toCharArray();
201: c[0] = '.';
202: c[1] = '.';
203: c[14] = '.';
204: n = new String(c);
205: }
206:
207: sb.append(n).append("<")
208: .append(Gadgets.toHexString(hexCode, 2)).append(">");
209: if (scope != null) {
210: sb.append(".").append(scope);
211: }
212: return sb.toString();
213: }
214: }
|