Esempio n. 1
0
func New(rwc io.ReadWriteCloser, params proto.Values, pw string) (*Conn, error) {
	notifies := make(chan *proto.Notify, 5) // 5 should be enough to prevent simple blocking

	cn := &Conn{
		Notifies: notifies,
		Settings: make(proto.Values),
		User:     params.Get("user"),
		p:        proto.New(rwc, notifies),
	}

	err := cn.p.Startup(params)
	if err != nil {
		return nil, err
	}

	for {
		m, err := cn.p.Next()
		if err != nil {
			return nil, err
		}

		if m.Err != nil {
			return nil, m.Err
		}

		switch m.Type {
		default:
			notExpected(m.Type)
		case 'R':
			switch m.Auth {
			case proto.AuthOk:
				continue
			case proto.AuthPlain:
				err := cn.p.Password(pw)
				if err != nil {
					rwc.Close()
					return nil, err
				}
			case proto.AuthMd5:
				err := cn.p.PasswordMd5(m.Salt, cn.User, pw)
				if err != nil {
					rwc.Close()
					return nil, err
				}
			default:
				return nil, fmt.Errorf("pq: unknown authentication type (%d)", m.Auth)
			}
		case 'S':
			cn.Settings.Set(m.Key, m.Val)
		case 'K':
			cn.Pid = m.Pid
			cn.Secret = m.Secret
		case 'Z':
			return cn, nil
		}
	}

	panic("not reached")
}
Esempio n. 2
0
func New(rwc io.ReadWriteCloser, params proto.Values) (*Conn, os.Error) {
	notifies := make(chan *proto.Notify, 5) // 5 should be enough to prevent simple blocking

	cn := &Conn{
		Notifies: notifies,
		Settings: make(proto.Values),
		p:        proto.New(rwc, notifies),
	}

	err := cn.p.Startup(params)
	if err != nil {
		return nil, err
	}

	for {
		m, err := cn.p.Next()
		if err != nil {
			return nil, err
		}

		if m.Err != nil {
			return nil, m.Err
		}

		switch m.Type {
		default:
			notExpected(m.Type)
		case 'R':
			switch m.Auth {
			default:
				return nil, fmt.Errorf("pq: unknown authentication type (%d)", m.Status)
			case 0:
				continue
			}
		case 'S':
			cn.Settings.Set(m.Key, m.Val)
		case 'K':
			cn.Pid = m.Pid
			cn.Secret = m.Secret
		case 'Z':
			return cn, nil
		}
	}

	panic("not reached")
}