- int fd = -1;
-
- if (strlen(sess->socksproxy.server)) { /* connecting via proxy */
- int i;
- unsigned char buf[512];
- struct sockaddr_in sa;
- struct hostent *hp;
- char *proxy;
- unsigned short proxyport = 1080;
-
- for(i=0;i<(int)strlen(sess->socksproxy.server);i++) {
- if (sess->socksproxy.server[i] == ':') {
- proxyport = atoi(&(sess->socksproxy.server[i+1]));
- break;
- }
- }
- proxy = (char *)malloc(i+1);
- strncpy(proxy, sess->socksproxy.server, i);
- proxy[i] = '\0';
-
- if (!(hp = gethostbyname(proxy))) {
- printf("proxyconnect: unable to resolve proxy name\n");
- *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR);
- return -1;
- }
- free(proxy);
-
- memset(&sa.sin_zero, 0, 8);
- sa.sin_port = htons(proxyport);
- memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
- sa.sin_family = hp->h_addrtype;
-
- fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
- if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) {
- printf("proxyconnect: unable to connect to proxy\n");
- close(fd);
- return -1;
- }
-
- i = 0;
- buf[0] = 0x05; /* SOCKS version 5 */
- if (strlen(sess->socksproxy.username)) {
- buf[1] = 0x02; /* two methods */
- buf[2] = 0x00; /* no authentication */
- buf[3] = 0x02; /* username/password authentication */
- i = 4;
- } else {
- buf[1] = 0x01;
- buf[2] = 0x00;
- i = 3;
- }
-
- if (write(fd, buf, i) < i) {
- *statusret = errno;
- close(fd);
- return -1;
- }
-
- if (read(fd, buf, 2) < 2) {
- *statusret = errno;
- close(fd);
- return -1;
- }
-
- if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
- *statusret = EINVAL;
- close(fd);
- return -1;
- }
-
- /* check if we're doing username authentication */
- if (buf[1] == 0x02) {
- i = aimutil_put8(buf, 0x01); /* version 1 */
- i += aimutil_put8(buf+i, strlen(sess->socksproxy.username));
- i += aimutil_putstr(buf+i, sess->socksproxy.username, strlen(sess->socksproxy.username));
- i += aimutil_put8(buf+i, strlen(sess->socksproxy.password));
- i += aimutil_putstr(buf+i, sess->socksproxy.password, strlen(sess->socksproxy.password));
- if (write(fd, buf, i) < i) {
- *statusret = errno;
- close(fd);
- return -1;
- }
- if (read(fd, buf, 2) < 2) {
- *statusret = errno;
- close(fd);
- return -1;
- }
- if ((buf[0] != 0x01) || (buf[1] != 0x00)) {
- *statusret = EINVAL;
- close(fd);
- return -1;
- }
- }
-
- i = aimutil_put8(buf, 0x05);
- i += aimutil_put8(buf+i, 0x01); /* CONNECT */
- i += aimutil_put8(buf+i, 0x00); /* reserved */
- i += aimutil_put8(buf+i, 0x03); /* address type: host name */
- i += aimutil_put8(buf+i, strlen(host));
- i += aimutil_putstr(buf+i, host, strlen(host));
- i += aimutil_put16(buf+i, port);
-
- if (write(fd, buf, i) < i) {
- *statusret = errno;
- close(fd);
- return -1;
- }
- if (read(fd, buf, 10) < 10) {
- *statusret = errno;
- close(fd);
- return -1;
- }
- if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
- *statusret = EINVAL;
- close(fd);
- return -1;
- }
-
- } else { /* connecting directly */
- struct sockaddr_in sa;
- struct hostent *hp;
-
- if (!(hp = gethostbyname(host))) {
- *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR);
- return -1;
- }
-
- memset(&sa, 0, sizeof(struct sockaddr_in));
- sa.sin_port = htons(port);
- memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
- sa.sin_family = hp->h_addrtype;
-
- fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
-
- if (sess->flags & AIM_SESS_FLAGS_NONBLOCKCONNECT)
- fcntl(fd, F_SETFL, O_NONBLOCK); /* XXX save flags */
-
- if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) {
- if (sess->flags & AIM_SESS_FLAGS_NONBLOCKCONNECT) {
- if ((errno == EINPROGRESS) || (errno == EINTR)) {
- if (statusret)
- *statusret |= AIM_CONN_STATUS_INPROGRESS;
- return fd;
+ int fd = -1;
+
+ if (strlen(sess->socksproxy.server)) { /* connecting via proxy */
+ int i;
+ unsigned char buf[512];
+ struct sockaddr_in sa;
+ struct hostent *hp;
+ char *proxy;
+ unsigned short proxyport = 1080;
+
+ for(i=0;i<(int)strlen(sess->socksproxy.server);i++) {
+ if (sess->socksproxy.server[i] == ':') {
+ proxyport = atoi(&(sess->socksproxy.server[i+1]));
+ break;
+ }
+ }
+
+ proxy = (char *)malloc(i+1);
+ strncpy(proxy, sess->socksproxy.server, i);
+ proxy[i] = '\0';
+
+ if (!(hp = gethostbyname(proxy))) {
+ faimdprintf(sess, 0, "proxyconnect: unable to resolve proxy name\n");
+ *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR);
+ return -1;
+ }
+ free(proxy);
+
+ memset(&sa.sin_zero, 0, 8);
+ sa.sin_port = htons(proxyport);
+ memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
+ sa.sin_family = hp->h_addrtype;
+
+ fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
+ if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) {
+ faimdprintf(sess, 0, "proxyconnect: unable to connect to proxy\n");
+ close(fd);
+ return -1;
+ }
+
+ i = 0;
+ buf[0] = 0x05; /* SOCKS version 5 */
+ if (strlen(sess->socksproxy.username)) {
+ buf[1] = 0x02; /* two methods */
+ buf[2] = 0x00; /* no authentication */
+ buf[3] = 0x02; /* username/password authentication */
+ i = 4;
+ } else {
+ buf[1] = 0x01;
+ buf[2] = 0x00;
+ i = 3;
+ }
+
+ if (write(fd, buf, i) < i) {
+ *statusret = errno;
+ close(fd);
+ return -1;
+ }
+
+ if (read(fd, buf, 2) < 2) {
+ *statusret = errno;
+ close(fd);
+ return -1;
+ }
+
+ if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
+ *statusret = EINVAL;
+ close(fd);
+ return -1;
+ }
+
+ /* check if we're doing username authentication */
+ if (buf[1] == 0x02) {
+ i = aimutil_put8(buf, 0x01); /* version 1 */
+ i += aimutil_put8(buf+i, strlen(sess->socksproxy.username));
+ i += aimutil_putstr(buf+i, sess->socksproxy.username, strlen(sess->socksproxy.username));
+ i += aimutil_put8(buf+i, strlen(sess->socksproxy.password));
+ i += aimutil_putstr(buf+i, sess->socksproxy.password, strlen(sess->socksproxy.password));
+ if (write(fd, buf, i) < i) {
+ *statusret = errno;
+ close(fd);
+ return -1;
+ }
+ if (read(fd, buf, 2) < 2) {
+ *statusret = errno;
+ close(fd);
+ return -1;
+ }
+ if ((buf[0] != 0x01) || (buf[1] != 0x00)) {
+ *statusret = EINVAL;
+ close(fd);
+ return -1;
+ }
+ }
+
+ i = aimutil_put8(buf, 0x05);
+ i += aimutil_put8(buf+i, 0x01); /* CONNECT */
+ i += aimutil_put8(buf+i, 0x00); /* reserved */
+ i += aimutil_put8(buf+i, 0x03); /* address type: host name */
+ i += aimutil_put8(buf+i, strlen(host));
+ i += aimutil_putstr(buf+i, host, strlen(host));
+ i += aimutil_put16(buf+i, port);
+
+ if (write(fd, buf, i) < i) {
+ *statusret = errno;
+ close(fd);
+ return -1;
+ }
+ if (read(fd, buf, 10) < 10) {
+ *statusret = errno;
+ close(fd);
+ return -1;
+ }
+ if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
+ *statusret = EINVAL;
+ close(fd);
+ return -1;
+ }
+
+ } else { /* connecting directly */
+ struct sockaddr_in sa;
+ struct hostent *hp;
+
+ if (!(hp = gethostbyname(host))) {
+ *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR);
+ return -1;
+ }
+
+ memset(&sa, 0, sizeof(struct sockaddr_in));
+ sa.sin_port = htons(port);
+ memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
+ sa.sin_family = hp->h_addrtype;
+
+ fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
+
+ if (sess->flags & AIM_SESS_FLAGS_NONBLOCKCONNECT)
+ fcntl(fd, F_SETFL, O_NONBLOCK); /* XXX save flags */
+
+ if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) {
+ if (sess->flags & AIM_SESS_FLAGS_NONBLOCKCONNECT) {
+ if ((errno == EINPROGRESS) || (errno == EINTR)) {
+ if (statusret)
+ *statusret |= AIM_CONN_STATUS_INPROGRESS;
+ return fd;
+ }
+ }
+ close(fd);
+ fd = -1;
+ }