Example #1
0
int
main(int argc, char * argv[])
{
	/* Command-line parameters. */
	int opt_f = 0;
	int opt_j = 0;
	const char * opt_k = NULL;
	double opt_o = 0.0;
	const char * opt_t = NULL;

	/* Working variables. */
	struct sock_addr ** sas_t;
	struct proto_secret * K;
	int ch;
	int s[2];

	WARNP_INIT;

	/* Parse the command line. */
	while ((ch = getopt(argc, argv, "fjk:o:t:")) != -1) {
		switch (ch) {
		case 'f':
			if (opt_f)
				usage();
			opt_f = 1;
			break;
		case 'j':
			if (opt_j)
				usage();
			opt_j = 1;
			break;
		case 'k':
			if (opt_k)
				usage();
			opt_k = optarg;
			break;
		case 'o':
			if (opt_o != 0.0)
				usage();
			if ((opt_o = strtod(optarg, NULL)) == 0.0) {
				warn0("Invalid option: -o %s", optarg);
				exit(1);
			}
			break;
		case 't':
			if (opt_t)
				usage();
			opt_t = optarg;
			break;
		default:
			usage();
		}
	}

	/* We should have processed all the arguments. */
	if (argc != optind)
		usage();

	/* Set defaults. */
	if (opt_o == 0.0)
		opt_o = 5.0;

	/* Sanity-check options. */
	if (opt_k == NULL)
		usage();
	if (!(opt_o > 0.0))
		usage();
	if (opt_t == NULL)
		usage();

	/* Resolve target address. */
	if ((sas_t = sock_resolve(opt_t)) == NULL) {
		warnp("Error resolving socket address: %s", opt_t);
		exit(1);
	}
	if (sas_t[0] == NULL) {
		warn0("No addresses found for %s", opt_t);
		exit(1);
	}

	/* Load the keying data. */
	if ((K = proto_crypt_secret(opt_k)) == NULL) {
		warnp("Error reading shared secret");
		exit(1);
	}

	/*
	 * Create a socket pair to push bits through.  The spiped protocol
	 * code expects to be handed a socket to read/write bits to, and our
	 * stdin/stdout might not be sockets (in fact, almost certainly aren't
	 * sockets); so we'll hand one end of the socket pair to the spiped
	 * protocol code and shuttle bits between stdin/stdout and the other
	 * end of the socket pair ourselves.
	 */
	if (socketpair(AF_UNIX, SOCK_STREAM, 0, s)) {
		warnp("socketpair");
		exit(1);
	}

	/* Set up a connection. */
	if (proto_conn_create(s[1], sas_t, 0, opt_f, opt_j, K, opt_o,
	    callback_conndied, NULL)) {
		warnp("Could not set up connection");
		exit(1);
	}

	/* Push bits from stdin into the socket. */
	if (pushbits(STDIN_FILENO, s[0]) || pushbits(s[0], STDOUT_FILENO)) {
		warnp("Could not push bits");
		exit(1);
	}

	/* Loop until we die. */
	do {
		if (events_run()) {
			warnp("Error running event loop");
			exit(1);
		}
	} while(1);

	/* NOTREACHED */
	/*
	 * If we could reach this point, we would free memory, close sockets,
	 * and otherwise clean up here.
	 */
}
Example #2
0
int
main(int argc, char * argv[])
{
	/* Command-line parameters. */
	int opt_f = 0;
	int opt_g = 0;
	int opt_j = 0;
	const char * opt_k = NULL;
	int opt_o_set = 0;
	double opt_o = 0.0;
	const char * opt_t = NULL;

	/* Working variables. */
	struct sock_addr ** sas_t;
	struct proto_secret * K;
	const char * ch;
	int s[2];
	int conndone = 0;
	void * conn_cookie;

	WARNP_INIT;

	/* Parse the command line. */
	while ((ch = GETOPT(argc, argv)) != NULL) {
		GETOPT_SWITCH(ch) {
		GETOPT_OPT("-f"):
			if (opt_f)
				usage();
			opt_f = 1;
			break;
		GETOPT_OPT("-g"):
			if (opt_g)
				usage();
			opt_g = 1;
			break;
		GETOPT_OPT("-j"):
			if (opt_j)
				usage();
			opt_j = 1;
			break;
		GETOPT_OPTARG("-k"):
			if (opt_k)
				usage();
			opt_k = optarg;
			break;
		GETOPT_OPTARG("-o"):
			if (opt_o_set)
				usage();
			opt_o_set = 1;
			if (PARSENUM(&opt_o, optarg, 0, INFINITY))
				OPT_EPARSE(ch, optarg);
			break;
		GETOPT_OPTARG("-t"):
			if (opt_t)
				usage();
			opt_t = optarg;
			break;
		GETOPT_OPT("-v"):
			fprintf(stderr, "spipe @VERSION@\n");
			exit(0);
		GETOPT_MISSING_ARG:
			warn0("Missing argument to %s", ch);
			usage();
		GETOPT_DEFAULT:
			warn0("illegal option -- %s", ch);
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	/* We should have processed all the arguments. */
	if (argc != 0)
		usage();
	(void)argv; /* argv is not used beyond this point. */

	/* Set defaults. */
	if (opt_o == 0.0)
		opt_o = 5.0;

	/* Sanity-check options. */
	if (opt_f && opt_g)
		usage();
	if (opt_k == NULL)
		usage();
	if (!(opt_o > 0.0))
		usage();
	if (opt_t == NULL)
		usage();

	/* Resolve target address. */
	if ((sas_t = sock_resolve(opt_t)) == NULL) {
		warnp("Error resolving socket address: %s", opt_t);
		goto err0;
	}
	if (sas_t[0] == NULL) {
		warn0("No addresses found for %s", opt_t);
		goto err1;
	}

	/* Load the keying data. */
	if ((K = proto_crypt_secret(opt_k)) == NULL) {
		warnp("Error reading shared secret");
		goto err1;
	}

	/*
	 * Create a socket pair to push bits through.  The spiped protocol
	 * code expects to be handed a socket to read/write bits to, and our
	 * stdin/stdout might not be sockets (in fact, almost certainly aren't
	 * sockets); so we'll hand one end of the socket pair to the spiped
	 * protocol code and shuttle bits between stdin/stdout and the other
	 * end of the socket pair ourselves.
	 */
	if (socketpair(AF_UNIX, SOCK_STREAM, 0, s)) {
		warnp("socketpair");
		goto err2;
	}

	/* Set up a connection. */
	if ((conn_cookie = proto_conn_create(s[1], sas_t, 0, opt_f, opt_g,
	    opt_j, K, opt_o, callback_conndied, &conndone)) == NULL) {
		warnp("Could not set up connection");
		goto err2;
	}

	/* Push bits from stdin into the socket. */
	if (pushbits(STDIN_FILENO, s[0])) {
		warnp("Could not push bits");
		goto err3;
	}

	/* Push bits from the socket to stdout. */
	if (pushbits(s[0], STDOUT_FILENO)) {
		warnp("Could not push bits");
		goto err3;
	}

	/* Loop until we're done with the connection. */
	if (events_spin(&conndone)) {
		warnp("Error running event loop");
		exit(1);
	}

	/* Clean up. */
	events_shutdown();
	free(K);

	/* Success! */
	exit(0);

err3:
	proto_conn_drop(conn_cookie);
	sas_t = NULL;
	events_shutdown();
err2:
	free(K);
err1:
	sock_addr_freelist(sas_t);
err0:
	/* Failure! */
	exit(1);
}