int OseGW_PLT_HuntReply_cbk(int skt, int len, char *payload,
                            struct ClientInfo *cinfo)
{
	OseGW_UL payload_len = sizeof(struct OseGW_HuntReply);
	struct OseGW_TransportData *reply = NULL;
	struct OseGW_HuntRequest *hunt_request =
		(struct OseGW_HuntRequest *) payload;
	union LINX_SIGNAL *hunt_sig = NULL;
	const LINX_SIGSELECT hunt_sigsel[] = { 1, LINX_OS_HUNT_SIG };
	LINX *gws_hunter;
	PROCESS pid = 0;
	int status = 0;
	int size = 0;

	/*Fill the header */
	size = sizeof(struct OseGW_TransportHdr) + payload_len;
	reply = (struct OseGW_TransportData *) malloc(size);
	if (reply == NULL) {
		syslog(LOG_ERR, "Malloc failure in Hunt reply");
		return -1;
	}
	reply->hdr.payload_type = htonl(OseGW_PLT_HuntReply);
	reply->hdr.payload_len = htonl(sizeof(struct OseGW_HuntReply));
	/* Fill the payload */
	hunt_request->user = ntohl(hunt_request->user);
	hunt_request->sig_len = ntohl(hunt_request->sig_len);
	hunt_request->name_index = ntohl(hunt_request->name_index);
	if (hunt_request->sig_len != 0) {
		hunt_sig = linx_alloc(cinfo->linx, hunt_request->sig_len,
				      ntohl(hunt_request->sig_no));
		if (hunt_sig == LINX_NIL) {
			syslog(LOG_ERR, "Linx alloc failed in Hunt reply");
			free(reply);
			return -1;
		}
		size = hunt_request->sig_len - sizeof(SIGSELECT);
		memcpy(&((char *) hunt_sig)[sizeof(SIGSELECT)],
		       &hunt_request->
		       data[ntohl(hunt_request->sig_index)], size);
		/*
		 * This hunt sig will be returned to caller or be cleaned
		 * up when caller closes the gateway socket.
		 */
		status = linx_hunt(cinfo->linx,
				   &hunt_request->data
				   [hunt_request->name_index],
				   &hunt_sig);

		if (status == -1) {
			free(reply);
			return status;
		}
	}

	/*
	 * The gateway hunt(...) returns the pid of the hunted process if the
	 * process exist when the hunt is done. The LINX hunt(...) does not so
	 * a hunt/receive_w_tmo/sender is done to get the pid. The gws_hunter
	 * socket is opened to prevent at client from flooding the gw server
	 * with hunt requests that could lead to out-of-memory in the LINX
	 * kernel module. If the hunted process does not exist the hunt is
	 * cleaned up when the gws_hunter socket is closed.
	 */

	gws_hunter = linx_open("gws_hunter", 0, NULL);
	status = linx_hunt(gws_hunter,
			   &hunt_request->data[hunt_request->name_index],
			   NULL);
	if (status == -1) {
	        free(reply);
	        return status;
	}

	status = linx_receive_w_tmo(gws_hunter, &hunt_sig, 0, hunt_sigsel);
	if (status == -1) {
		free(reply);
		return status;
	}

	if (hunt_sig != LINX_NIL) {
		pid = linx_sender(gws_hunter, &hunt_sig);
		if (pid == LINX_ILLEGAL_SPID) {
			free(reply);
			return -1;
		}
		linx_free_buf(gws_hunter, &hunt_sig);
	}
	/* free up the "hunt" */
	linx_close(gws_hunter);

	reply->payload.hunt_reply.status = htonl(cinfo->status);
	reply->payload.hunt_reply.pid = htonl(pid);
	/*Send */
	size = sizeof(struct OseGW_TransportHdr) + payload_len;
	status = send(skt, (void *) reply, size, 0);
	if (status == size) {
		LOG(LOG_INFO, "Gateway Client: replying HuntReply "
                    "on socket %d", skt);
	} else {
		syslog(LOG_INFO, "Gateway Clinet: failed replying "
		       "HuntReply on socket %d", skt);
		status = -1;
	}
	free(reply);
	return status;
}
int main(int argc, char *argv[])
{
	LINX *linx;
	LINX_SPID server_spid;
	union LINX_SIGNAL *sig;
	pthread_t server_th;
	int c;
	int loop_cnt = LOOP_CNT;
	int use_linx_api = LINX_SOCKET;
	size_t msg_size = BURST_SIZE;
	unsigned long burst_cnt = BURST_CNT;
	size_t start_msg_size = START_MSG_SIZE;
	size_t end_msg_size = END_MSG_SIZE;
	unsigned long throughput_instances = THROUGHPUT_INSTANCES;
	int iterations = ITERATIONS;
	LINX_SIGSELECT any_sig[] = { 0 };

	char *path = NULL;
	char *server_name = NULL;
	int run_attach_test = 0;
	int run_com_test = 0;
	int kill_server = 0;
	int all = 0;
	int use_pthreads = 0;

	if (argc < 2) {
		print_usage(argv[0]);
		return 0;
	}

	while ((c = getopt(argc, argv, "S?p:ac:n:m:b:i:s:e:Alt:qP")) != -1) {
		switch (c) {
		case 'S':
			/* Start server */
			server_name = (optarg == NULL ? SERVER_NAME : optarg);
			break;

		case 'P':
			/* Start server as posix thread */
			server_name = SERVER_NAME;
			use_pthreads = 1;
			break;

		case 'p':
			/* Hunt path */
			path = optarg;
			break;

		case 'a':
			/* Run attach test */
			run_attach_test = 1;
			break;

		case 'c':
			/* Connection test */
			run_com_test = atoi(optarg);
			break;

		case 'n':
			/* Loop count */
			loop_cnt = atoi(optarg);
			break;

		case 'm':
			/* Message size */
			msg_size = atol(optarg);
			break;

		case 'b':
			/* Burst count */
			burst_cnt = atol(optarg);
			break;

		case 'i':
			/* Iterations */
			iterations = atoi(optarg);
			break;

		case 's':
			/* Start message size */
			start_msg_size = atol(optarg);
			break;

		case 'e':
			/* End message size */
			end_msg_size = atol(optarg);
			break;

		case 'A':
			/* Run all tests */
			all = 1;
			break;

		case 'l':
			/* Use linx api in tests */
			use_linx_api = LINX_API;
			break;

		case 't':
			/* Number of instances in throughput */
			throughput_instances = atoi(optarg);
			break;

		case 'q':
			/* Quit the server */
			kill_server = 1;
			break;
		default:
			print_usage(argv[0]);
			return 0;
		}
	}

	if(use_pthreads) {
		kill_server = 1;
		if (pthread_create(&server_th, NULL, server,
				   (void *)server_name)) {
			fprintf(stderr, "pthread_create(): %d\n", errno);
			exit(errno);
		}
	} else if (server_name != NULL) {
		(void)server(server_name);
		return 0;
	}

	/* Path to server */
	path = path && *path ? path : CS_PATH SERVER_NAME;

	/* Hunt for server */
	linx = linx_open(CLIENT_NAME, 0, NULL);
	linx_hunt(linx, path, NULL);
	linx_receive_w_tmo(linx, &sig, 1000, any_sig);
	if (sig == NULL) {
		printf("Hunt failed. No server found at path '%s'.\n"
		       "Is the server started and path ok? "
		       "(Server started with -S option)\n", path);
		linx_close(linx);
		return 1;
	}
	if (sig->sigNo != LINX_OS_HUNT_SIG) {
		ERR("Failed to hunt for '%s'", path);
		linx_free_buf(linx, &sig);
		linx_close(linx);
		return 1;
	}
	server_spid = linx_sender(linx, &sig);
	linx_free_buf(linx, &sig);

	/* Attach to server */
	sig = linx_alloc(linx, sizeof(LINX_SIGSELECT), ATTACH_SERV_SIG);
	linx_attach(linx, &sig, server_spid);

	if (run_attach_test) {
		attach_test(linx, path, loop_cnt, server_spid, use_linx_api,
			    use_pthreads);
	}

	switch (run_com_test) {
	case 1:
		/* Start com test 1 */
		linx_bmark_latency(linx, path, loop_cnt, msg_size, msg_size,
				   ONE_ITERATION, server_spid, use_linx_api,
				   use_pthreads);
		break;
	case 2:
		/* Start com test 2 */
		linx_bmark_burst(linx, path, loop_cnt, msg_size,
				 msg_size, ONE_ITERATION,
				 burst_cnt, server_spid, use_linx_api,
				 use_pthreads);
		break;
	case 3:
		/* Start com test 3 */
		linx_bmark_latency(linx, path, loop_cnt, start_msg_size,
				   end_msg_size, iterations, server_spid,
				   use_linx_api, use_pthreads);
		break;
	case 4:
		/* Start com test 4 */
		linx_bmark_burst(linx, path, loop_cnt, start_msg_size,
				 end_msg_size, iterations, burst_cnt,
				 server_spid, use_linx_api, use_pthreads);
		break;
	case 5:
		/* Start com test 5 */
		linx_bmark_throughput(path, loop_cnt, msg_size,
				      server_spid, use_linx_api,
				      throughput_instances, use_pthreads);
		break;
	default:
		break;
	}

	if (all) {
		/* All tests  */
		attach_test(linx, path, loop_cnt, server_spid, use_linx_api,
			    use_pthreads);
		linx_bmark_latency(linx, path, loop_cnt, msg_size, msg_size,
				   ONE_ITERATION, server_spid, use_linx_api,
				   use_pthreads);
		linx_bmark_burst(linx, path, loop_cnt, msg_size, msg_size,
				 ONE_ITERATION, burst_cnt,
				 server_spid, use_linx_api, use_pthreads);
		linx_bmark_latency(linx, path, loop_cnt, start_msg_size,
				   end_msg_size, iterations,
				   server_spid, use_linx_api, use_pthreads);
		linx_bmark_burst(linx, path, loop_cnt, start_msg_size,
				 end_msg_size, iterations, burst_cnt,
				 server_spid, use_linx_api, use_pthreads);
		linx_bmark_throughput(path, loop_cnt, msg_size,
				      server_spid, use_linx_api,
				      throughput_instances, use_pthreads);
	}

	if (kill_server) {
		/* If no test argument specified, let server close */
		sig = linx_alloc(linx, sizeof(LINX_SIGSELECT), CONN_TERM);
		linx_send(linx, &sig, server_spid);
		printf("Waiting for attach from server.\n");
		linx_receive(linx, &sig, any_sig);
		if (sig == LINX_NIL) {
			ERR("No attach signal was received from the server.");
		}
		if (sig->sigNo != ATTACH_SERV_SIG) {
			ERR("Wrong signal received while waiting for "
			    "attach signal from server.");
		}
		linx_free_buf(linx, &sig);

		/* Close client spid */
		linx_close(linx);
	}

	if(use_pthreads)
		pthread_join(server_th, NULL);
	
	return 0;
}