~pbms-core/pbms/async_read

« back to all changes in this revision

Viewing changes to mybs/java/src/com/mysql/jdbc/Util.java

  • Committer: paul-mccullagh
  • Date: 2008-03-26 11:35:17 UTC
  • Revision ID: paul-mccullagh-afb1610c21464a577ae428d72fc725eb986c05a5
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 Copyright (C) 2002-2007 MySQL AB
 
3
 
 
4
 This program is free software; you can redistribute it and/or modify
 
5
 it under the terms of version 2 of the GNU General Public License as 
 
6
 published by the Free Software Foundation.
 
7
 
 
8
 There are special exceptions to the terms and conditions of the GPL 
 
9
 as it is applied to this software. View the full text of the 
 
10
 exception in file EXCEPTIONS-CONNECTOR-J in the directory of this 
 
11
 software distribution.
 
12
 
 
13
 This program is distributed in the hope that it will be useful,
 
14
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 GNU General Public License for more details.
 
17
 
 
18
 You should have received a copy of the GNU General Public License
 
19
 along with this program; if not, write to the Free Software
 
20
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
21
 
 
22
 
 
23
 
 
24
 */
 
25
package com.mysql.jdbc;
 
26
 
 
27
import java.io.ObjectInputStream;
 
28
import java.io.PrintWriter;
 
29
import java.io.StringWriter;
 
30
import java.lang.reflect.InvocationTargetException;
 
31
import java.lang.reflect.Method;
 
32
import java.util.TimeZone;
 
33
 
 
34
/**
 
35
 * Various utility methods for the driver.
 
36
 * 
 
37
 * @author Mark Matthews
 
38
 */
 
39
public class Util {
 
40
 
 
41
        protected static Method systemNanoTimeMethod;
 
42
            
 
43
        private static boolean isColdFusion = false;
 
44
 
 
45
        static {
 
46
                try {
 
47
                        systemNanoTimeMethod = System.class.getMethod("nanoTime", null);
 
48
                } catch (SecurityException e) {
 
49
                        systemNanoTimeMethod = null;
 
50
                } catch (NoSuchMethodException e) {
 
51
                        systemNanoTimeMethod = null;
 
52
                }
 
53
                
 
54
                //
 
55
                // Detect the ColdFusion MX environment
 
56
                // 
 
57
                // Unfortunately, no easy-to-discern classes are available
 
58
                // to our classloader to check...
 
59
                //
 
60
                
 
61
                String loadedFrom = stackTraceToString(new Throwable());
 
62
                
 
63
                if (loadedFrom != null) {
 
64
                        isColdFusion = loadedFrom.indexOf("coldfusion") != -1;
 
65
                } else {
 
66
                        isColdFusion = false;
 
67
                }
 
68
        }
 
69
        
 
70
        public static boolean isColdFusion() {
 
71
                return isColdFusion;
 
72
        }
 
73
        
 
74
        protected static boolean nanoTimeAvailable() {
 
75
                return systemNanoTimeMethod != null;
 
76
        }
 
77
        
 
78
        // cache this ourselves, as the method call is statically-synchronized in all but JDK6!
 
79
        
 
80
        private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getDefault();
 
81
        
 
82
        static final TimeZone getDefaultTimeZone() {
 
83
                return (TimeZone)DEFAULT_TIMEZONE.clone();
 
84
        }
 
85
        
 
86
        class RandStructcture {
 
87
                long maxValue;
 
88
 
 
89
                double maxValueDbl;
 
90
 
 
91
                long seed1;
 
92
 
 
93
                long seed2;
 
94
        }
 
95
 
 
96
        
 
97
        private static Util enclosingInstance = new Util();
 
98
 
 
99
        // Right from Monty's code
 
100
        static String newCrypt(String password, String seed) {
 
101
                byte b;
 
102
                double d;
 
103
 
 
104
                if ((password == null) || (password.length() == 0)) {
 
105
                        return password;
 
106
                }
 
107
 
 
108
                long[] pw = newHash(seed);
 
109
                long[] msg = newHash(password);
 
110
                long max = 0x3fffffffL;
 
111
                long seed1 = (pw[0] ^ msg[0]) % max;
 
112
                long seed2 = (pw[1] ^ msg[1]) % max;
 
113
                char[] chars = new char[seed.length()];
 
114
 
 
115
                for (int i = 0; i < seed.length(); i++) {
 
116
                        seed1 = ((seed1 * 3) + seed2) % max;
 
117
                        seed2 = (seed1 + seed2 + 33) % max;
 
118
                        d = (double) seed1 / (double) max;
 
119
                        b = (byte) java.lang.Math.floor((d * 31) + 64);
 
120
                        chars[i] = (char) b;
 
121
                }
 
122
 
 
123
                seed1 = ((seed1 * 3) + seed2) % max;
 
124
                seed2 = (seed1 + seed2 + 33) % max;
 
125
                d = (double) seed1 / (double) max;
 
126
                b = (byte) java.lang.Math.floor(d * 31);
 
127
 
 
128
                for (int i = 0; i < seed.length(); i++) {
 
129
                        chars[i] ^= (char) b;
 
130
                }
 
131
 
 
132
                return new String(chars);
 
133
        }
 
134
 
 
135
        static long[] newHash(String password) {
 
136
                long nr = 1345345333L;
 
137
                long add = 7;
 
138
                long nr2 = 0x12345671L;
 
139
                long tmp;
 
140
 
 
141
                for (int i = 0; i < password.length(); ++i) {
 
142
                        if ((password.charAt(i) == ' ') || (password.charAt(i) == '\t')) {
 
143
                                continue; // skip spaces
 
144
                        }
 
145
 
 
146
                        tmp = (0xff & password.charAt(i));
 
147
                        nr ^= ((((nr & 63) + add) * tmp) + (nr << 8));
 
148
                        nr2 += ((nr2 << 8) ^ nr);
 
149
                        add += tmp;
 
150
                }
 
151
 
 
152
                long[] result = new long[2];
 
153
                result[0] = nr & 0x7fffffffL;
 
154
                result[1] = nr2 & 0x7fffffffL;
 
155
 
 
156
                return result;
 
157
        }
 
158
 
 
159
        static String oldCrypt(String password, String seed) {
 
160
                long hp;
 
161
                long hm;
 
162
                long s1;
 
163
                long s2;
 
164
                long max = 0x01FFFFFF;
 
165
                double d;
 
166
                byte b;
 
167
 
 
168
                if ((password == null) || (password.length() == 0)) {
 
169
                        return password;
 
170
                }
 
171
 
 
172
                hp = oldHash(seed);
 
173
                hm = oldHash(password);
 
174
 
 
175
                long nr = hp ^ hm;
 
176
                nr %= max;
 
177
                s1 = nr;
 
178
                s2 = nr / 2;
 
179
 
 
180
                char[] chars = new char[seed.length()];
 
181
 
 
182
                for (int i = 0; i < seed.length(); i++) {
 
183
                        s1 = ((s1 * 3) + s2) % max;
 
184
                        s2 = (s1 + s2 + 33) % max;
 
185
                        d = (double) s1 / max;
 
186
                        b = (byte) java.lang.Math.floor((d * 31) + 64);
 
187
                        chars[i] = (char) b;
 
188
                }
 
189
 
 
190
                return new String(chars);
 
191
        }
 
192
 
 
193
        static long oldHash(String password) {
 
194
                long nr = 1345345333;
 
195
                long nr2 = 7;
 
196
                long tmp;
 
197
 
 
198
                for (int i = 0; i < password.length(); i++) {
 
199
                        if ((password.charAt(i) == ' ') || (password.charAt(i) == '\t')) {
 
200
                                continue;
 
201
                        }
 
202
 
 
203
                        tmp = password.charAt(i);
 
204
                        nr ^= ((((nr & 63) + nr2) * tmp) + (nr << 8));
 
205
                        nr2 += tmp;
 
206
                }
 
207
 
 
208
                return nr & ((1L << 31) - 1L);
 
209
        }
 
210
 
 
211
        private static RandStructcture randomInit(long seed1, long seed2) {
 
212
                RandStructcture randStruct = enclosingInstance.new RandStructcture();
 
213
 
 
214
                randStruct.maxValue = 0x3FFFFFFFL;
 
215
                randStruct.maxValueDbl = randStruct.maxValue;
 
216
                randStruct.seed1 = seed1 % randStruct.maxValue;
 
217
                randStruct.seed2 = seed2 % randStruct.maxValue;
 
218
 
 
219
                return randStruct;
 
220
        }
 
221
 
 
222
        /**
 
223
         * Given a ResultSet and an index into the columns of that ResultSet, read
 
224
         * binary data from the column which represents a serialized object, and
 
225
         * re-create the object.
 
226
         * 
 
227
         * @param resultSet
 
228
         *            the ResultSet to use.
 
229
         * @param index
 
230
         *            an index into the ResultSet.
 
231
         * @return the object if it can be de-serialized
 
232
         * @throws Exception
 
233
         *             if an error occurs
 
234
         */
 
235
        public static Object readObject(java.sql.ResultSet resultSet, int index)
 
236
                        throws Exception {
 
237
                ObjectInputStream objIn = new ObjectInputStream(resultSet
 
238
                                .getBinaryStream(index));
 
239
                Object obj = objIn.readObject();
 
240
                objIn.close();
 
241
 
 
242
                return obj;
 
243
        }
 
244
 
 
245
        private static double rnd(RandStructcture randStruct) {
 
246
                randStruct.seed1 = ((randStruct.seed1 * 3) + randStruct.seed2)
 
247
                                % randStruct.maxValue;
 
248
                randStruct.seed2 = (randStruct.seed1 + randStruct.seed2 + 33)
 
249
                                % randStruct.maxValue;
 
250
 
 
251
                return ((randStruct.seed1) / randStruct.maxValueDbl);
 
252
        }
 
253
 
 
254
        /**
 
255
         * DOCUMENT ME!
 
256
         * 
 
257
         * @param message
 
258
         *            DOCUMENT ME!
 
259
         * @param password
 
260
         *            DOCUMENT ME!
 
261
         * 
 
262
         * @return DOCUMENT ME!
 
263
         */
 
264
        public static String scramble(String message, String password) {
 
265
                long[] hashPass;
 
266
                long[] hashMessage;
 
267
                byte[] to = new byte[8];
 
268
                String val = ""; //$NON-NLS-1$
 
269
 
 
270
                message = message.substring(0, 8);
 
271
 
 
272
                if ((password != null) && (password.length() > 0)) {
 
273
                        hashPass = newHash(password);
 
274
                        hashMessage = newHash(message);
 
275
 
 
276
                        RandStructcture randStruct = randomInit(hashPass[0]
 
277
                                        ^ hashMessage[0], hashPass[1] ^ hashMessage[1]);
 
278
 
 
279
                        int msgPos = 0;
 
280
                        int msgLength = message.length();
 
281
                        int toPos = 0;
 
282
 
 
283
                        while (msgPos++ < msgLength) {
 
284
                                to[toPos++] = (byte) (Math.floor(rnd(randStruct) * 31) + 64);
 
285
                        }
 
286
 
 
287
                        /* Make it harder to break */
 
288
                        byte extra = (byte) (Math.floor(rnd(randStruct) * 31));
 
289
 
 
290
                        for (int i = 0; i < to.length; i++) {
 
291
                                to[i] ^= extra;
 
292
                        }
 
293
 
 
294
                        val = new String(to);
 
295
                }
 
296
 
 
297
                return val;
 
298
        }
 
299
 
 
300
        // ~ Inner Classes
 
301
        // ----------------------------------------------------------
 
302
 
 
303
        /**
 
304
         * Converts a nested exception into a nicer message
 
305
         * 
 
306
         * @param ex
 
307
         *            the exception to expand into a message.
 
308
         * 
 
309
         * @return a message containing the exception, the message (if any), and a
 
310
         *         stacktrace.
 
311
         */
 
312
        public static String stackTraceToString(Throwable ex) {
 
313
                StringBuffer traceBuf = new StringBuffer();
 
314
                traceBuf.append(Messages.getString("Util.1")); //$NON-NLS-1$
 
315
 
 
316
                if (ex != null) {
 
317
                        traceBuf.append(ex.getClass().getName());
 
318
 
 
319
                        String message = ex.getMessage();
 
320
 
 
321
                        if (message != null) {
 
322
                                traceBuf.append(Messages.getString("Util.2")); //$NON-NLS-1$
 
323
                                traceBuf.append(message);
 
324
                        }
 
325
 
 
326
                        StringWriter out = new StringWriter();
 
327
 
 
328
                        PrintWriter printOut = new PrintWriter(out);
 
329
 
 
330
                        ex.printStackTrace(printOut);
 
331
 
 
332
                        traceBuf.append(Messages.getString("Util.3")); //$NON-NLS-1$
 
333
                        traceBuf.append(out.toString());
 
334
                }
 
335
 
 
336
                traceBuf.append(Messages.getString("Util.4")); //$NON-NLS-1$
 
337
 
 
338
                return traceBuf.toString();
 
339
        }
 
340
        
 
341
        /**
 
342
         * Does a network interface exist locally with the given hostname?
 
343
         * 
 
344
         * @param hostname the hostname (or IP address in string form) to check
 
345
         * @return true if it exists, false if no, or unable to determine due to VM version support
 
346
         *         of java.net.NetworkInterface
 
347
         */
 
348
        public static boolean interfaceExists(String hostname) {
 
349
                try {
 
350
                        Class networkInterfaceClass = Class.forName("java.net.NetworkInterface");
 
351
                        return networkInterfaceClass.getMethod("getByName", null).invoke(networkInterfaceClass, new Object[] { hostname }) != null;
 
352
                } catch (Throwable t) {
 
353
                        return false;
 
354
                }
 
355
        }
 
356
 
 
357
        public static long getCurrentTimeNanosOrMillis() {
 
358
                if (systemNanoTimeMethod != null) {
 
359
                        try {
 
360
                                return ((Long)systemNanoTimeMethod.invoke(null, null)).longValue();
 
361
                        } catch (IllegalArgumentException e) {
 
362
                                // ignore - fall through to currentTimeMillis()
 
363
                        } catch (IllegalAccessException e) {
 
364
                                // ignore - fall through to currentTimeMillis()
 
365
                        } catch (InvocationTargetException e) {
 
366
                                // ignore - fall through to currentTimeMillis()
 
367
                        }
 
368
                }
 
369
                
 
370
                return System.currentTimeMillis();
 
371
        }
 
372
}