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 jcifs.netbios;
021:
022: import java.io.UnsupportedEncodingException;
023: import jcifs.Config;
024: import jcifs.util.Hexdump;
025:
026: class Name {
027:
028: private static final int TYPE_OFFSET = 31;
029: private static final int SCOPE_OFFSET = 33;
030: private static final String DEFAULT_SCOPE = Config
031: .getProperty("jcifs.netbios.scope");
032:
033: static final String OEM_ENCODING = Config.getProperty(
034: "jcifs.encoding", System.getProperty("file.encoding"));
035:
036: String name, scope;
037: int hexCode;
038: int srcHashCode; /* srcHashCode must be set by name resolution
039: * routines before entry into addressCache
040: */
041:
042: Name() {
043: }
044:
045: Name(String name, int hexCode, String scope) {
046: if (name.length() > 15) {
047: name = name.substring(0, 15);
048: }
049: this .name = name.toUpperCase();
050: this .hexCode = hexCode;
051: this .scope = scope != null && scope.length() > 0 ? scope
052: : DEFAULT_SCOPE;
053: this .srcHashCode = 0;
054: }
055:
056: int writeWireFormat(byte[] dst, int dstIndex) {
057: // write 0x20 in first byte
058: dst[dstIndex] = 0x20;
059:
060: // write name
061: try {
062: byte tmp[] = name.getBytes(Name.OEM_ENCODING);
063: int i;
064: for (i = 0; i < tmp.length; i++) {
065: dst[dstIndex + (2 * i + 1)] = (byte) (((tmp[i] & 0xF0) >> 4) + 0x41);
066: dst[dstIndex + (2 * i + 2)] = (byte) ((tmp[i] & 0x0F) + 0x41);
067: }
068: for (; i < 15; i++) {
069: dst[dstIndex + (2 * i + 1)] = (byte) 0x43;
070: dst[dstIndex + (2 * i + 2)] = (byte) 0x41;
071: }
072: dst[dstIndex + TYPE_OFFSET] = (byte) (((hexCode & 0xF0) >> 4) + 0x41);
073: dst[dstIndex + TYPE_OFFSET + 1] = (byte) ((hexCode & 0x0F) + 0x41);
074: } catch (UnsupportedEncodingException uee) {
075: }
076: return SCOPE_OFFSET
077: + writeScopeWireFormat(dst, dstIndex + SCOPE_OFFSET);
078: }
079:
080: int readWireFormat(byte[] src, int srcIndex) {
081:
082: byte tmp[] = new byte[SCOPE_OFFSET];
083: int length = 15;
084: for (int i = 0; i < 15; i++) {
085: tmp[i] = (byte) (((src[srcIndex + (2 * i + 1)] & 0xFF) - 0x41) << 4);
086: tmp[i] |= (byte) (((src[srcIndex + (2 * i + 2)] & 0xFF) - 0x41) & 0x0F);
087: if (tmp[i] != (byte) ' ') {
088: length = i + 1;
089: }
090: }
091: try {
092: name = new String(tmp, 0, length, Name.OEM_ENCODING);
093: } catch (UnsupportedEncodingException uee) {
094: }
095: hexCode = ((src[srcIndex + TYPE_OFFSET] & 0xFF) - 0x41) << 4;
096: hexCode |= ((src[srcIndex + TYPE_OFFSET + 1] & 0xFF) - 0x41) & 0x0F;
097: return SCOPE_OFFSET
098: + readScopeWireFormat(src, srcIndex + SCOPE_OFFSET);
099: }
100:
101: int writeScopeWireFormat(byte[] dst, int dstIndex) {
102: if (scope == null) {
103: dst[dstIndex] = (byte) 0x00;
104: return 1;
105: }
106:
107: // copy new scope in
108: dst[dstIndex++] = (byte) '.';
109: try {
110: System.arraycopy(scope.getBytes(Name.OEM_ENCODING), 0, dst,
111: dstIndex, scope.length());
112: } catch (UnsupportedEncodingException uee) {
113: }
114: dstIndex += scope.length();
115:
116: dst[dstIndex++] = (byte) 0x00;
117:
118: // now go over scope backwards converting '.' to label length
119:
120: int i = dstIndex - 2;
121: int e = i - scope.length();
122: int c = 0;
123:
124: do {
125: if (dst[i] == '.') {
126: dst[i] = (byte) c;
127: c = 0;
128: } else {
129: c++;
130: }
131: } while (i-- > e);
132: return scope.length() + 2;
133: }
134:
135: int readScopeWireFormat(byte[] src, int srcIndex) {
136: int start = srcIndex;
137: int n;
138: StringBuffer sb;
139:
140: if ((n = src[srcIndex++] & 0xFF) == 0) {
141: scope = null;
142: return 1;
143: }
144:
145: try {
146: sb = new StringBuffer(new String(src, srcIndex, n,
147: Name.OEM_ENCODING));
148: srcIndex += n;
149: while ((n = src[srcIndex++] & 0xFF) != 0) {
150: sb.append('.')
151: .append(
152: new String(src, srcIndex, n,
153: Name.OEM_ENCODING));
154: srcIndex += n;
155: }
156: scope = sb.toString();
157: } catch (UnsupportedEncodingException uee) {
158: }
159:
160: return srcIndex - start;
161: }
162:
163: public int hashCode() {
164: int result;
165:
166: result = name.hashCode();
167: result += 65599 * hexCode;
168: result += 65599 * srcHashCode; /* hashCode is different depending
169: * on where it came from
170: */
171: if (scope != null && scope.length() != 0) {
172: result += scope.hashCode();
173: }
174: return result;
175: }
176:
177: public boolean equals(Object obj) {
178: Name n;
179:
180: if (!(obj instanceof Name)) {
181: return false;
182: }
183: n = (Name) obj;
184: if (scope == null && n.scope == null) {
185: return name.equals(n.name) && hexCode == n.hexCode;
186: }
187: return name.equals(n.name) && hexCode == n.hexCode
188: && scope.equals(n.scope);
189: }
190:
191: public String toString() {
192: StringBuffer sb = new StringBuffer();
193: String n = name;
194:
195: // fix MSBROWSE name
196: if (n == null) {
197: n = "null";
198: } else if (n.charAt(0) == 0x01) {
199: char c[] = n.toCharArray();
200: c[0] = '.';
201: c[1] = '.';
202: c[14] = '.';
203: n = new String(c);
204: }
205:
206: sb.append(n).append("<")
207: .append(Hexdump.toHexString(hexCode, 2)).append(">");
208: if (scope != null) {
209: sb.append(".").append(scope);
210: }
211: return sb.toString();
212: }
213: }
|