/* -------------------------------- * pcp_connect - open connection to pgpool using given arguments * * return 0 on success, -1 otherwise * -------------------------------- */ int pcp_connect(char *hostname, int port, char *username, char *password) { struct sockaddr_in addr; struct sockaddr_un unix_addr; struct hostent *hp; int fd; int on = 1; int len; if (pc != NULL) { if (debug) fprintf(stderr, "DEBUG: connection to backend \"%s\" already exists\n", hostname); return 0; } if (hostname == NULL || *hostname == '\0' || *hostname == '/') { char *path; fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) { if (debug) fprintf(stderr, "DEBUG: could not create socket\n"); errorcode = SOCKERR; return -1; } memset(&unix_addr, 0, sizeof(unix_addr)); unix_addr.sun_family = AF_UNIX; if (hostname == NULL || *hostname == '\0') { path = UNIX_DOMAIN_PATH; } else { path = hostname; } snprintf(unix_addr.sun_path, sizeof(unix_addr.sun_path), "%s/.s.PGSQL.%d", path, port); if (connect(fd, (struct sockaddr *) &unix_addr, sizeof(unix_addr)) < 0) { if (debug) fprintf(stderr, "DEBUG: could not connect to \"%s\"\n", unix_addr.sun_path); close(fd); errorcode = CONNERR; return -1; } } else { fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { if (debug) fprintf(stderr, "DEBUG: could not create socket\n"); errorcode = SOCKERR; return -1; } if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0) { if (debug) fprintf(stderr, "DEBUG: could not set socket option\n"); close(fd); errorcode = SOCKERR; return -1; } memset((char *) &addr, 0, sizeof(addr)); addr.sin_family = AF_INET; hp = gethostbyname(hostname); if ((hp == NULL) || (hp->h_addrtype != AF_INET)) { if (debug) fprintf(stderr, "DEBUG: could not retrieve hostname\n"); close(fd); errorcode = HOSTERR; return -1; } memmove((char *) &(addr.sin_addr), (char *) hp->h_addr, hp->h_length); addr.sin_port = htons(port); len = sizeof(struct sockaddr_in); if (connect(fd, (struct sockaddr *) &addr, len) < 0) { if (debug) fprintf(stderr, "DEBUG: could not connect to \"%s\"\n", hostname); close(fd); errorcode = CONNERR; return -1; } } pc = pcp_open(fd); if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: could not allocate buffer space\n"); close(fd); return -1; } if (pcp_authorize(username, password) < 0) { pcp_close(pc); pc = NULL; return -1; } return 0; }
PCPConnInfo* pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfdebug) { struct sockaddr_in addr; struct sockaddr_un unix_addr; struct hostent *hp; char *password_fron_file = NULL; char os_user[256]; PCPConnInfo* pcpConn = palloc0(sizeof(PCPConnInfo)); int fd; int on = 1; int len; pcpConn->connState = PCP_CONNECTION_NOT_CONNECTED; pcpConn->Pfdebug = Pfdebug; if (hostname == NULL || *hostname == '\0' || *hostname == '/') { char *path; fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) { pcp_internal_error(pcpConn, "ERROR: failed to create UNIX domain socket. socket error \"%s\"",strerror(errno)); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; } memset(&unix_addr, 0, sizeof(unix_addr)); unix_addr.sun_family = AF_UNIX; if (hostname == NULL || *hostname == '\0') { path = UNIX_DOMAIN_PATH; hostname = path; } else { path = hostname; } snprintf(unix_addr.sun_path, sizeof(unix_addr.sun_path), "%s/.s.PGSQL.%d", path, port); if (connect(fd, (struct sockaddr *) &unix_addr, sizeof(unix_addr)) < 0) { close(fd); pcp_internal_error(pcpConn, "ERROR: connection to socket \"%s\" failed with error \"%s\"",unix_addr.sun_path,strerror(errno)); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; } } else { fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { pcp_internal_error(pcpConn, "ERROR: failed to create INET domain socket with error \"%s\"",strerror(errno)); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; } if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0) { close(fd); pcp_internal_error(pcpConn, "ERROR: set socket option failed with error \"%s\"",strerror(errno)); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; } memset((char *) &addr, 0, sizeof(addr)); addr.sin_family = AF_INET; hp = gethostbyname(hostname); if ((hp == NULL) || (hp->h_addrtype != AF_INET)) { close(fd); pcp_internal_error(pcpConn, "ERROR: could not retrieve hostname. gethostbyname failed with error \"%s\"",strerror(errno)); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; } memmove((char *) &(addr.sin_addr), (char *) hp->h_addr, hp->h_length); addr.sin_port = htons(port); len = sizeof(struct sockaddr_in); if (connect(fd, (struct sockaddr *) &addr, len) < 0) { close(fd); pcp_internal_error(pcpConn, "ERROR: connection to host \"%s\" failed with error \"%s\"",hostname,strerror(errno)); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; } } pcpConn->pcpConn = pcp_open(fd); if (pcpConn->pcpConn == NULL) { close(fd); pcp_internal_error(pcpConn, "ERROR: failed to allocate memory"); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; } pcpConn->connState = PCP_CONNECTION_CONNECTED; /* * If username is not provided. Use the os user name * and do not complain if it (getting os user name) gets failed */ if (username == NULL && get_os_username(os_user, sizeof(os_user))) username = os_user; /* * If password is not provided. lookup in pcppass file */ if (password == NULL || *password == '\0') { char port_str[100]; snprintf(port_str, sizeof(port_str), "%d",port); password_fron_file = PasswordFromFile(pcpConn, hostname, port_str, username); password = password_fron_file; } if (pcp_authorize(pcpConn,username, password) < 0) { pcp_close(pcpConn->pcpConn); pcpConn->pcpConn = NULL; pcpConn->connState = PCP_CONNECTION_AUTH_ERROR; } else pcpConn->connState = PCP_CONNECTION_OK; if(password_fron_file) pfree(password_fron_file); return pcpConn; }