/* Copyright (c) 1996-1999 NEC USA, Inc.  All rights reserved.               */
/*                                                                           */
/* The redistribution, use and modification in source or binary forms of     */
/* this software is subject to the conditions set forth in the copyright     */
/* document ("COPYRIGHT") included with this distribution.                   */
#include "socks5p.h"
#include "wrap.h"
#include "libproto.h"
#include "protocol.h"
#include "addr.h"
#include "share.h"

#define EXITERROR(err)	( perror("ping"), exit((err)) )

int main(int argc, char *argv[]) {
    S5IOHandle fd;
    S5NetAddr rsin;
    lsSocksInfo *pcon;
    struct hostent *rhp;

    if (argc != 2 || *argv[1] == '-') {
	fprintf(stderr, "Usage: %s host\n", argv[0]);
	exit(-1);
    }

    if (LIBPREFIX2(init)(NULL) != 0) EXITERROR(-1);

    memset((char *)&rsin, 0, sizeof(S5NetAddr));
    rsin.sin.sin_family = AF_INET;

    if ((rsin.sin.sin_addr.s_addr = inet_addr(argv[1])) == INVALIDADDR) {
        if ((rhp = LIBPREFIX(gethostbyname)(argv[1])) == NULL) EXITERROR(-1);

        memcpy((char *)&rsin.sin.sin_addr.s_addr, (char *)rhp->h_addr_list[0], rhp->h_length);
        rsin.sin.sin_family = rhp->h_addrtype;
    }

    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == S5InvalidIOHandle) return -1;
    Signal(SIGPIPE, SIG_IGN);

    if ((pcon = lsLibProtoExchg(fd, &rsin, SOCKS_PING)) == NULL) {
        fprintf(stderr, "lsLibProtoExchg: Protocol exchange failed. \n");
	CLOSESOCKET(fd);
        return -1;
    }

    if (!pcon->pri || pcon->pri->how == DIRECT || !lsAddrAddrComp(&rsin, &pcon->pri->prxyin)) {
	LIBPREFIX(close)(fd);
#ifndef PINGPROG
	fprintf(stderr, "Real ping unavailable.\n");
	exit(0);
#else
	execlp(PINGPROG, "ping", argv[1], NULL);
	_exit(0);
#endif
    }

    DataRelay(fd, &pcon->pri->cinfo, 0);
    LIBPREFIX(close)(fd);

    exit(0);
}
