📄 tds.java
字号:
// App name
comm.appendTdsShort(curPos);
comm.appendTdsShort((short)appName.length());
curPos += appName.length() * 2;
// Server name
comm.appendTdsShort(curPos);
comm.appendTdsShort((short)serverName.length());
curPos += serverName.length() * 2;
// Another unknown value
comm.appendTdsShort((short)0);
comm.appendTdsShort((short)0);
// Library name
comm.appendTdsShort(curPos);
comm.appendTdsShort((short)libName.length());
curPos += libName.length() * 2;
// Two more unknowns
comm.appendTdsShort(curPos);
comm.appendTdsShort((short)0);
comm.appendTdsShort(curPos);
comm.appendTdsShort((short)0);
// More magic.
comm.appendBytes(magic2, 6, pad);
comm.appendTdsShort(len);
comm.appendTdsShort((short)0x30);
comm.appendTdsShort(packSize);
comm.appendTdsShort((short)0);
// Pack up the login values.
String scrambledPw = tds7CryptPass(password);
comm.appendChars(user);
comm.appendChars(scrambledPw);
comm.appendChars(appName);
comm.appendChars(serverName);
comm.appendChars(libName);
// Still more magic!
comm.appendBytes(magic3, 7, pad);
comm.appendByte((byte)0);
comm.appendByte((byte)1);
comm.appendBytes(empty, 3, pad);
comm.appendByte((byte)6);
comm.appendByte((byte)130);
comm.appendBytes(empty, 22, pad);
comm.appendByte((byte)48);
comm.appendBytes(empty, 7, pad);
comm.appendByte((byte)48);
comm.appendBytes(empty, 3, pad);
}
/**
* This is a <B>very</B> poor man's "encryption."
*/
private static String tds7CryptPass(String pw) {
int xormask = 0x5A5A;
int len = pw.length();
char[] chars = new char[len];
for (int i = 0; i < len; ++i) {
int c = (int)(pw.charAt(i)) ^ xormask;
int m1 = (c >> 4) & 0x0F0F;
int m2 = (c << 4) & 0xF0F0;
chars[i] = (char)(m1 | m2);
}
return new String(chars);
}
/**
* change the connection level settings for this connection
* stream to the database.
*
* @return true if the database accepted the changes, false if rejected.
*/
synchronized public boolean changeSettings(
String database,
String settings)
throws java.sql.SQLException
{
boolean isOkay = true;
try
{
PacketResult result;
if (database != null)
{
isOkay = changeDB(database);
}
if (isOkay && (settings!=null && settings.length()>0))
{
String query = settings;
comm.startPacket(TdsComm.QUERY);
if (tdsVer == Tds.TDS70)
comm.appendChars(query);
else
{
byte[] queryBytes = encoder.getBytes(query);
comm.appendBytes(queryBytes, queryBytes.length, (byte)0);
}
moreResults2=true; //JJ 1999-01-10
comm.sendPacket();
boolean done = false;
while (! done)
{
result = processSubPacket();
done = ( result instanceof PacketEndTokenResult ) &&
! ((PacketEndTokenResult)result).moreResults() ;
if (result instanceof PacketErrorResult)
{
isOkay = false;
}
// XXX Should really process some more types of packets.
}
}
}
catch (com.internetcds.jdbc.tds.TdsUnknownPacketSubType e)
{
throw new SQLException("Unknown response. " + e.getMessage());
}
catch (java.io.IOException e)
{
throw new SQLException("Network problem. " + e.getMessage());
}
catch (com.internetcds.jdbc.tds.TdsException e)
{
throw new SQLException(e.getMessage());
}
return isOkay;
} // changeSettings
/**
* Select a new database to use.
*
* @param database Name of the database to use.
*
* @return true if the change was accepted, false otherwise
*/
synchronized private boolean changeDB(String database)
throws java.sql.SQLException
{
boolean isOkay = true;;
try
{
PacketResult result;
int i;
// XXX Check to make sure the database name
// doesn't have funny characters.
// if (database name has funny characters)
if (database.length()>32)
{
throw new SQLException("Name too long " + database);
}
for(i=0; i<database.length(); i++)
{
char ch;
ch = database.charAt(i);
if (!
((ch=='_' && i!=0)
|| (ch >= 'a' && ch<='z')
|| (ch >= 'A' && ch<='Z')
|| (ch >='0' && ch<='9')))
{
throw new SQLException("Bad database name- "
+ database);
}
}
String query = "use " + database;
comm.startPacket(TdsComm.QUERY);
if (tdsVer == Tds.TDS70)
comm.appendChars(query);
else
{
byte[] queryBytes = encoder.getBytes(query);
comm.appendBytes(queryBytes, queryBytes.length, (byte)0);
}
moreResults2=true; //JJ 1999-01-10
comm.sendPacket();
// XXX Should we check that the change actual was okay
// and throw some sort of exception if it wasn't?
// Get the reply to the change database request.
while (! ((result = processSubPacket())
instanceof PacketEndTokenResult))
{
if (result instanceof PacketErrorResult)
{
isOkay = false;
}
// XXX Should really process some more types of packets.
}
}
catch (com.internetcds.jdbc.tds.TdsUnknownPacketSubType e)
{
throw new SQLException("Unknown response. " + e.getMessage());
}
catch (java.io.IOException e)
{
throw new SQLException("Network problem. " + e.getMessage());
}
catch (com.internetcds.jdbc.tds.TdsException e)
{
throw new SQLException(e.getMessage());
}
return isOkay;
} // changeDB()
public void cancel()
throws java.io.IOException, com.internetcds.jdbc.tds.TdsException
{
// XXX How should this be synchronized? What sort of deadlock
// conditions do we need to consider?
cancelController.doCancel(comm);
}
public boolean moreResults()
{
return moreResults2;
}
/**
* Get the length of the current subpacket.
* <p>
* This will eat two bytes from the input socket.
*
* @return length of the current subpacket.
*/
private int getSubPacketLength()
throws java.io.IOException, com.internetcds.jdbc.tds.TdsException
{
return comm.getTdsShort();
}
/**
* This will read a error (or warning) message from the SQLServer and
* create a SqlMessage object from that message.
* <p>
* <b> Warning! </b> This is not synchronized because it assumes
* it will only be called by processSubPacket() which is synchronized.
*
* @param packetSubType type of the current subpacket
*
* @return The message returned by the SQLServer.
*
*/
private PacketMsgResult processMsg(byte packetSubType)
throws java.io.IOException, com.internetcds.jdbc.tds.TdsException
{
SqlMessage msg = new SqlMessage();
int len = getSubPacketLength();
msg.number = comm.getTdsInt();
msg.state = comm.getByte();
msg.level = comm.getByte(); // ?class?
int msgLen = comm.getTdsShort();
msg.message = comm.getString(msgLen);
// RMK 2000-06-08: the getWarnings() methods aren't implemented, so we
// need to do something with these.
if (showWarnings && msg.message != null) {
String warn = msg.message.trim();
if (warn.length() > 0)
System.err.println("Server message: " + warn);
}
int srvNameLen = comm.getByte() & 0xFF;
msg.server = comm.getString(srvNameLen);
if (packetSubType == TDS_MSG_TOKEN || packetSubType==TDS_ERR_TOKEN)
{
// nop
int procNameLen = comm.getByte() & 0xFF;
msg.procName = comm.getString(procNameLen);
}
else
{
throw new TdsConfused("Was expecting a msg or error token. " +
"Found 0x" +
Integer.toHexString(packetSubType & 0xff));
}
msg.line = comm.getByte();
// unknonw byte
comm.getByte();
lastServerMessage = msg;
if (packetSubType == TDS_ERR_TOKEN)
{
return new PacketErrorResult(packetSubType, msg);
}
else
{
return new PacketMsgResult(packetSubType, msg);
}
}
/**
* Process an env change message (TDS_ENV_CHG_TOKEN)
* <p>
* <b> Warning! </b> This is not synchronized because it assumes
* it will only be called by processSubPacket() which is synchronized.
*
* @exception java.io.IOException
* @exception com.internetcds.jdbc.tds.TdsException
*/
private PacketResult processEnvChange()
throws java.io.IOException, com.internetcds.jdbc.tds.TdsException
{
final byte CHARSET_CHANGE = (byte)3;
int len = getSubPacketLength();
int type = comm.getByte();
switch (type)
{
case CHARSET_CHANGE:
{
int clen = comm.getByte()&0xFF;
String charset;
if (tdsVer == TDS70)
{
charset = comm.getString(clen);
comm.skip(len-2-clen*2);
}
else
{
charset = encoder.getString(comm.getBytes(clen));
comm.skip(len-2-clen);
}
setCharset(charset);
break;
}
default:
{
// XXX Should actually look at the env change
// instead of ignoring it.
comm.skip(len-1);
break;
}
}
return new PacketResult(TDS_ENV_CHG_TOKEN);
}
/**
* Process an column name subpacket.
* <p>
* <p>
* <b> Warning! </b> This is not synchronized because it assumes
* it will only be called by processSubPacket() which is synchronized.
*
*/
private PacketColumnNamesResult processColumnNames()
throws java.io.IOException, com.internetcds.jdbc.tds.TdsException
{
Columns columns = new Columns();
int totalLen = comm.getTdsShort();
int bytesRead = 0;
int i = 0;
while (bytesRead < totalLen)
{
int colNameLen = comm.getByte();
String colName = encoder.getString(comm.getBytes(colNameLen));
bytesRead = bytesRead + 1 + colNameLen;
i++;
columns.setName(i, colName);
columns.setLabel(i, colName);
}
return new PacketColumnNamesResult(columns);
} // processColumnNames()
/**
* Process the columns information subpacket.
* <p>
* <b> Warning! </b> This is not synchronized because it assumes
* it will only be called by processSubPacket() which is synchronized.
*
*/
private PacketColumnInfoResult processColumnInfo()
throws java.io.IOException, com.internetcds.jdbc.tds.TdsException
{
Columns columns = new Columns();
int precision;
int scale;
int totalLen = comm.getTdsShort();
int bytesRead = 0;
int numColumns = 0;
while (bytesRead < totalLen)
{
scale = -1;
precision = -1;
int sizeOfColumn = -1;
byte flagData[] = new byte[4];
for (int i = 0; i < 4; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -