diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 04b5f0a30c..68924ce1ca 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.32 1998/01/25 05:13:53 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.33 1998/02/02 13:16:31 scrappy Exp $ * *------------------------------------------------------------------------- */ @@ -1532,6 +1532,7 @@ PrintBufferDescs() if (IsUnderPostmaster) { SpinAcquire(BufMgrLock); +#if 0 for (i = 0; i < NBuffers; ++i, ++buf) { elog(NOTICE, "[%02d] (freeNext=%d, freePrev=%d, relname=%s, \ @@ -1540,6 +1541,7 @@ blockNum=%d, flags=0x%x, refcount=%d %d)", buf->sb_relname, buf->tag.blockNum, buf->flags, buf->refcount, PrivateRefCount[i]); } +#endif SpinRelease(BufMgrLock); } else diff --git a/src/interfaces/jdbc/Makefile b/src/interfaces/jdbc/Makefile index 1065dcec4f..44a9ca3290 100644 --- a/src/interfaces/jdbc/Makefile +++ b/src/interfaces/jdbc/Makefile @@ -4,7 +4,7 @@ # Makefile for Java JDBC interface # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/Makefile,v 1.4 1998/01/13 02:19:10 scrappy Exp $ +# $Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/Makefile,v 1.5 1998/02/02 13:16:38 scrappy Exp $ # #------------------------------------------------------------------------- @@ -33,8 +33,9 @@ all: postgresql.jar @echo @echo Then either add -Djdbc.drivers=postgresql.Driver to the @echo commandline when running your application, or edit the - @echo "properties file (~/.hotjava/properties under unix), and" - @echo add a line containing jdbc.drivers=postgresql.Driver + @echo "properties file for your application (~/.hotjava/properties" + @echo "under unix for HotJava), and add a line containing" + @echo jdbc.drivers=postgresql.Driver @echo @echo More details are in the README file. @echo ------------------------------------------------------------ @@ -76,8 +77,12 @@ OBJS= postgresql/CallableStatement.class \ postgresql/util/PGobject.class \ postgresql/util/PGtokenizer.class +# If you have problems with the first line, try the second one. +# This is needed when compiling under Solaris, as the solaris sh doesn't +# recognise $( ) postgresql.jar: $(OBJS) - $(JAR) -c0vf $@ $$($(FIND) postgresql -name "*.class" -print) + $(JAR) -c0f $@ $$($(FIND) postgresql -name "*.class" -print) +# $(JAR) -c0f $@ `$(FIND) postgresql -name "*.class" -print` # This rule removes any temporary and compiled files from the source tree. clean: diff --git a/src/interfaces/jdbc/postgresql/Connection.java b/src/interfaces/jdbc/postgresql/Connection.java index 1c13b520d5..074a3d5579 100644 --- a/src/interfaces/jdbc/postgresql/Connection.java +++ b/src/interfaces/jdbc/postgresql/Connection.java @@ -43,16 +43,16 @@ public class Connection implements java.sql.Connection public boolean CONNECTION_OK = true; public boolean CONNECTION_BAD = false; - private static final int STARTUP_LEN = 288; // Length of a startup packet + //private static final int STARTUP_LEN = 288; // Length of a startup packet // These are defined in src/include/libpq/pqcomm.h - private int STARTUP_CODE = STARTUP_USER; - private static final int STARTUP_USER = 7; // User auth - private static final int STARTUP_KRB4 = 10; // Kerberos 4 (unused) - private static final int STARTUP_KRB5 = 11; // Kerberos 5 (unused) - private static final int STARTUP_HBA = 12; // Host Based - private static final int STARTUP_NONE = 13; // Unauthenticated (unused) - private static final int STARTUP_PASS = 14; // Password auth + //private int STARTUP_CODE = STARTUP_USER; + //private static final int STARTUP_USER = 7; // User auth + //private static final int STARTUP_KRB4 = 10; // Kerberos 4 (unused) + //private static final int STARTUP_KRB5 = 11; // Kerberos 5 (unused) + //private static final int STARTUP_HBA = 12; // Host Based + //private static final int STARTUP_NONE = 13; // Unauthenticated (unused) + //private static final int STARTUP_PASS = 14; // Password auth private boolean autoCommit = true; private boolean readOnly = false; @@ -61,8 +61,25 @@ public class Connection implements java.sql.Connection private String this_url; private String cursor = null; // The positioned update cursor name - // This is false for US, true for European date formats - //protected boolean europeanDates = false; + // These are new for v6.3, they determine the current protocol versions + // supported by this version of the driver. They are defined in + // src/include/libpq/pqcomm.h + protected static final int PG_PROTOCOL_LATEST_MAJOR = 1; + protected static final int PG_PROTOCOL_LATEST_MINOR = 0; + private static final int SM_DATABASE = 64; + private static final int SM_USER = 32; + private static final int SM_OPTIONS = 64; + private static final int SM_UNUSED = 64; + private static final int SM_TTY = 64; + + private static final int AUTH_REQ_OK = 0; + private static final int AUTH_REQ_KRB4 = 1; + private static final int AUTH_REQ_KRB5 = 2; + private static final int AUTH_REQ_PASSWORD = 3; + private static final int AUTH_REQ_CRYPT = 4; + + // New for 6.3, salt value for crypt authorisation + private String salt; /** * This is the current date style of the backend @@ -120,7 +137,7 @@ public class Connection implements java.sql.Connection */ public Connection(String host, int port, Properties info, String database, String url, Driver d) throws SQLException { - int len = STARTUP_LEN; // Length of a startup packet + //int len = STARTUP_LEN; // Length of a startup packet this_driver = d; this_url = new String(url); @@ -131,6 +148,7 @@ public class Connection implements java.sql.Connection PG_HOST = new String(host); PG_STATUS = CONNECTION_BAD; + // Pre 6.3 code // This handles the auth property. Any value begining with p enables // password authentication, while anything begining with i enables // ident (RFC 1413) authentication. Any other values default to trust. @@ -138,17 +156,17 @@ public class Connection implements java.sql.Connection // Also, the postgresql.auth system property can be used to change the // local default, if the auth property is not present. // - String auth = info.getProperty("auth",System.getProperty("postgresql.auth","trust")).toLowerCase(); - if(auth.startsWith("p")) { - // Password authentication - STARTUP_CODE=STARTUP_PASS; - } else if(auth.startsWith("i")) { - // Ident (RFC 1413) authentication - STARTUP_CODE=STARTUP_HBA; - } else { - // Anything else defaults to trust authentication - STARTUP_CODE=STARTUP_USER; - } + //String auth = info.getProperty("auth",System.getProperty("postgresql.auth","trust")).toLowerCase(); + //if(auth.startsWith("p")) { + //// Password authentication + //STARTUP_CODE=STARTUP_PASS; + //} else if(auth.startsWith("i")) { + //// Ident (RFC 1413) authentication + //STARTUP_CODE=STARTUP_HBA; + //} else { + //// Anything else defaults to trust authentication + //STARTUP_CODE=STARTUP_USER; + //} // Now make the initial connection try @@ -161,21 +179,94 @@ public class Connection implements java.sql.Connection // Now we need to construct and send a startup packet try { - pg_stream.SendInteger(len, 4); len -= 4; - pg_stream.SendInteger(STARTUP_CODE, 4); len -= 4; - pg_stream.Send(database.getBytes(), 64); len -= 64; - pg_stream.Send(PG_USER.getBytes(), len); + // Pre 6.3 code + //pg_stream.SendInteger(len, 4); len -= 4; + //pg_stream.SendInteger(STARTUP_CODE, 4); len -= 4; + //pg_stream.Send(database.getBytes(), 64); len -= 64; + //pg_stream.Send(PG_USER.getBytes(), len); + // + //// Send the password packet if required + //if(STARTUP_CODE == STARTUP_PASS) { + //len=STARTUP_LEN; + //pg_stream.SendInteger(len, 4); len -= 4; + //pg_stream.SendInteger(STARTUP_PASS, 4); len -= 4; + //pg_stream.Send(PG_USER.getBytes(), PG_USER.length()); + //len-=PG_USER.length(); + //pg_stream.SendInteger(0,1); len -= 1; + //pg_stream.Send(PG_PASSWORD.getBytes(), len); + //} - // Send the password packet if required - if(STARTUP_CODE == STARTUP_PASS) { - len=STARTUP_LEN; - pg_stream.SendInteger(len, 4); len -= 4; - pg_stream.SendInteger(STARTUP_PASS, 4); len -= 4; - pg_stream.Send(PG_USER.getBytes(), PG_USER.length()); - len-=PG_USER.length(); - pg_stream.SendInteger(0,1); len -= 1; - pg_stream.Send(PG_PASSWORD.getBytes(), len); - } + // Ver 6.3 code + pg_stream.SendInteger(4+4+SM_DATABASE+SM_USER+SM_OPTIONS+SM_UNUSED+SM_TTY,4); + pg_stream.SendInteger(PG_PROTOCOL_LATEST_MAJOR,2); + pg_stream.SendInteger(PG_PROTOCOL_LATEST_MINOR,2); + pg_stream.Send(database.getBytes(),SM_DATABASE); + pg_stream.Send(PG_USER.getBytes(),SM_USER+SM_OPTIONS+SM_UNUSED+SM_TTY); + // The last send includes the unused fields + + // Now get the response from the backend, either an error message + // or an authentication request + int areq = -1; // must have a value here + do { + int beresp = pg_stream.ReceiveChar(); + switch(beresp) + { + case 'E': + throw new SQLException(pg_stream.ReceiveString(4096)); + + case 'R': + // Get the type of request + areq = pg_stream.ReceiveIntegerR(4); + + // Get the password salt if there is one + if(areq == AUTH_REQ_CRYPT) { + byte[] rst = new byte[2]; + rst[0] = (byte)pg_stream.ReceiveChar(); + rst[1] = (byte)pg_stream.ReceiveChar(); + salt = new String(rst,0,2); + DriverManager.println("Salt="+salt); + } + + // now send the auth packet + switch(areq) + { + case AUTH_REQ_OK: + break; + + case AUTH_REQ_KRB4: + DriverManager.println("postgresql: KRB4"); + throw new SQLException("Kerberos 4 not supported"); + + case AUTH_REQ_KRB5: + DriverManager.println("postgresql: KRB5"); + throw new SQLException("Kerberos 5 not supported"); + + case AUTH_REQ_PASSWORD: + DriverManager.println("postgresql: PASSWORD"); + pg_stream.SendInteger(5+PG_PASSWORD.length(),4); + pg_stream.Send(PG_PASSWORD.getBytes()); + pg_stream.SendInteger(0,1); + //pg_stream.SendPacket(PG_PASSWORD.getBytes()); + break; + + case AUTH_REQ_CRYPT: + DriverManager.println("postgresql: CRYPT"); + String crypted = UnixCrypt.crypt(salt,PG_PASSWORD); + pg_stream.SendInteger(5+crypted.length(),4); + pg_stream.Send(crypted.getBytes()); + pg_stream.SendInteger(0,1); + //pg_stream.SendPacket(UnixCrypt.crypt(salt,PG_PASSWORD).getBytes()); + break; + + default: + throw new SQLException("Authentication type "+areq+" not supported"); + } + break; + + default: + throw new SQLException("error getting authentication request"); + } + } while(areq != AUTH_REQ_OK); } catch (IOException e) { throw new SQLException("Connection failed: " + e.toString()); @@ -671,14 +762,14 @@ public class Connection implements java.sql.Connection */ private Field[] ReceiveFields() throws SQLException { - int nf = pg_stream.ReceiveInteger(2), i; + int nf = pg_stream.ReceiveIntegerR(2), i; Field[] fields = new Field[nf]; for (i = 0 ; i < nf ; ++i) { String typname = pg_stream.ReceiveString(8192); - int typid = pg_stream.ReceiveInteger(4); - int typlen = pg_stream.ReceiveInteger(2); + int typid = pg_stream.ReceiveIntegerR(4); + int typlen = pg_stream.ReceiveIntegerR(2); fields[i] = new Field(this, typname, typid, typlen); } return fields; diff --git a/src/interfaces/jdbc/postgresql/DatabaseMetaData.java b/src/interfaces/jdbc/postgresql/DatabaseMetaData.java index 4e3894f66b..47c257e782 100644 --- a/src/interfaces/jdbc/postgresql/DatabaseMetaData.java +++ b/src/interfaces/jdbc/postgresql/DatabaseMetaData.java @@ -1925,30 +1925,28 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData */ public java.sql.ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException { - // XXX-Not Implemented as grant is broken - return null; - //Field f[] = new Field[8]; - //Vector v = new Vector(); - // - //f[0] = new Field(connection,new String("TABLE_CAT"),iVarcharOid,32); - //f[1] = new Field(connection,new String("TABLE_SCHEM"),iVarcharOid,32); - //f[2] = new Field(connection,new String("TABLE_NAME"),iVarcharOid,32); - //f[3] = new Field(connection,new String("COLUMN_NAME"),iVarcharOid,32); - //f[4] = new Field(connection,new String("GRANTOR"),iVarcharOid,32); - //f[5] = new Field(connection,new String("GRANTEE"),iVarcharOid,32); - //f[6] = new Field(connection,new String("PRIVILEGE"),iVarcharOid,32); - //f[7] = new Field(connection,new String("IS_GRANTABLE"),iVarcharOid,32); - // - //// This is taken direct from the psql source - //ResultSet r = connection.ExecSQL("SELECT relname, relacl FROM pg_class, pg_user WHERE ( relkind = 'r' OR relkind = 'i') and relname !~ '^pg_' and relname !~ '^xin[vx][0-9]+' and usesysid = relowner ORDER BY relname"); - //while(r.next()) { - //byte[][] tuple = new byte[8][0]; - //tuple[0] = tuple[1]= "default".getBytes(); - // - //v.addElement(tuple); - //} - // - //return new ResultSet(connection,f,v,"OK",1); + Field f[] = new Field[8]; + Vector v = new Vector(); + + f[0] = new Field(connection,new String("TABLE_CAT"),iVarcharOid,32); + f[1] = new Field(connection,new String("TABLE_SCHEM"),iVarcharOid,32); + f[2] = new Field(connection,new String("TABLE_NAME"),iVarcharOid,32); + f[3] = new Field(connection,new String("COLUMN_NAME"),iVarcharOid,32); + f[4] = new Field(connection,new String("GRANTOR"),iVarcharOid,32); + f[5] = new Field(connection,new String("GRANTEE"),iVarcharOid,32); + f[6] = new Field(connection,new String("PRIVILEGE"),iVarcharOid,32); + f[7] = new Field(connection,new String("IS_GRANTABLE"),iVarcharOid,32); + + // This is taken direct from the psql source + ResultSet r = connection.ExecSQL("SELECT relname, relacl FROM pg_class, pg_user WHERE ( relkind = 'r' OR relkind = 'i') and relname !~ '^pg_' and relname !~ '^xin[vx][0-9]+' and usesysid = relowner ORDER BY relname"); + while(r.next()) { + byte[][] tuple = new byte[8][0]; + tuple[0] = tuple[1]= "".getBytes(); + DriverManager.println("relname=\""+r.getString(1)+"\" relacl=\""+r.getString(2)+"\""); + //v.addElement(tuple); + } + + return new ResultSet(connection,f,v,"OK",1); } /** diff --git a/src/interfaces/jdbc/postgresql/PG_Stream.java b/src/interfaces/jdbc/postgresql/PG_Stream.java index 8c5f521561..f786b507d1 100644 --- a/src/interfaces/jdbc/postgresql/PG_Stream.java +++ b/src/interfaces/jdbc/postgresql/PG_Stream.java @@ -76,6 +76,8 @@ public class PG_Stream * This is required when the backend uses the routines in the * src/backend/libpq/pqcomprim.c module. * + * As time goes by, this should become obsolete. + * * @param val the integer to be sent * @param siz the length of the integer in bytes (size of structure) * @exception IOException if an I/O error occurs @@ -139,6 +141,17 @@ public class PG_Stream } } + /** + * Sends a packet, prefixed with the packet's length + * @param buf buffer to send + * @exception SQLException if an I/O Error returns + */ + public void SendPacket(byte[] buf) throws IOException + { + SendInteger(buf.length+4,4); + Send(buf); + } + /** * Receives a single character from the backend * @@ -186,6 +199,33 @@ public class PG_Stream return n; } + /** + * Receives an integer from the backend + * + * @param siz length of the integer in bytes + * @return the integer received from the backend + * @exception SQLException if an I/O error occurs + */ + public int ReceiveIntegerR(int siz) throws SQLException + { + int n = 0; + + try + { + for (int i = 0 ; i < siz ; i++) + { + int b = pg_input.read(); + + if (b < 0) + throw new IOException("EOF"); + n = b | (n << 8); + } + } catch (IOException e) { + throw new SQLException("Error reading from backend: " + e.toString()); + } + return n; + } + /** * Receives a null-terminated string from the backend. Maximum of * maxsiz bytes - if we don't see a null, then we assume something @@ -253,7 +293,7 @@ public class PG_Stream answer[i] = null; else { - int len = ReceiveInteger(4); + int len = ReceiveIntegerR(4); if (!bin) len -= 4; if (len < 0) diff --git a/src/interfaces/jdbc/postgresql/fastpath/Fastpath.java b/src/interfaces/jdbc/postgresql/fastpath/Fastpath.java index ce278acef7..fdb6868655 100644 --- a/src/interfaces/jdbc/postgresql/fastpath/Fastpath.java +++ b/src/interfaces/jdbc/postgresql/fastpath/Fastpath.java @@ -75,8 +75,10 @@ public class Fastpath stream.SendInteger(70,1); stream.SendInteger(0,1); - stream.SendIntegerReverse(fnid,4); - stream.SendIntegerReverse(args.length,4); + //stream.SendIntegerReverse(fnid,4); + //stream.SendIntegerReverse(args.length,4); + stream.SendInteger(fnid,4); + stream.SendInteger(args.length,4); for(int i=0;i