#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory.h>

#include <sys/types.h>

#include <sys/time.h>
#include <sys/socket.h>
#include <sys/resource.h>

#include <netinet/in.h>

#include <arpa/inet.h>
#include <netdb.h>

struct sockaddr_in ssin;

int TryConnect(int i) {
    struct linger sl = { 0, 0 };
    fd_set fds;
    int sd;

    if ((sd = socket(AF_INET, SOCK_STREAM, 0))                            < 0) return -1;
    if (connect(sd, &ssin, sizeof(struct sockaddr_in))                    < 0) return -1;

    FD_ZERO(&fds);
    FD_SET(sd, &fds);
    
    if (select(sd+1, &fds, NULL, NULL, NULL)                              < 0) return -1;
    close(sd);

    fprintf(stderr, "%d ", i);
    fflush(stderr);

    return 0;
}

int main(int argc, char **argv) {
    u_long addr = inet_addr("127.0.0.1");
    char *ss = getenv("SOCKS_SERVER");
    struct timeval ds, de;
    struct rusage rs, re;
    struct hostent *hp;
    int ntrys = 100, i;

    if (argc > 1) ntrys = atoi(argv[1]);

    if (ss)
	if ((hp = gethostbyname(ss)) != NULL) memcpy(&addr, (char *)hp->h_addr_list[0], 4);
	else if (inet_addr(ss) != -1) addr = inet_addr(ss);

    memset((char *)&ssin, 0, sizeof(struct sockaddr_in));
    ssin.sin_family      = AF_INET;
    ssin.sin_port        = htons(1080);
    ssin.sin_addr.s_addr = addr;

    getrusage(RUSAGE_SELF, &rs);
    gettimeofday(&ds, NULL);
    
    for (i = 0; i < ntrys; i++) if (TryConnect(i)) break;

    getrusage(RUSAGE_SELF, &re);
    gettimeofday(&de, NULL);

    re.ru_utime.tv_sec  -= rs.ru_utime.tv_sec;
    re.ru_utime.tv_usec -= rs.ru_utime.tv_usec;

    if (re.ru_utime.tv_usec < 0) {
	re.ru_utime.tv_sec  -= 1;
	re.ru_utime.tv_usec += 1000000;
    }
    
    re.ru_stime.tv_sec  -= rs.ru_stime.tv_sec;
    re.ru_stime.tv_usec -= rs.ru_stime.tv_usec;

    if (re.ru_stime.tv_usec < 0) {
	re.ru_stime.tv_sec  -= 1;
	re.ru_stime.tv_usec += 1000000;
    }

    de.tv_sec  -= ds.tv_sec;
    de.tv_usec -= ds.tv_usec;

    if (de.tv_usec < 0) {
	de.tv_sec  -= 1;
	de.tv_usec += 1000000;
    }

    fprintf(stderr, "\n%d connects in %d.%du %d.%ds %d.%dt\n", i,
	    re.ru_utime.tv_sec, re.ru_utime.tv_usec,
	    re.ru_stime.tv_sec, re.ru_stime.tv_usec,
	    de.tv_sec,          de.tv_usec);

    exit(0);
}
