Ejemplo n.º 1
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);
}
Ejemplo n.º 2
0
int
main(int argc, char * argv[])
{
	/* State variables. */
	int * socks_s;
	int sock_t;
	struct wire_requestqueue * Q_t;
	struct dispatch_state * dstate;

	/* Command-line parameters. */
	intmax_t opt_n = 0;
	char * opt_p = NULL;
	char * opt_t = NULL;
	ADDRLIST opt_s;
	char * opt_s_1 = NULL;

	/* Working variables. */
	size_t opt_s_size;
	struct sock_addr ** sas;
	size_t i;
	const char * ch;

	WARNP_INIT;

	/* We have no addresses to listen on yet. */
	if ((opt_s = addrlist_init(0)) == NULL) {
		warnp("addrlist_init");
		exit(1);
	}

	/* Parse the command line. */
	while ((ch = GETOPT(argc, argv)) != NULL) {
		GETOPT_SWITCH(ch) {
		GETOPT_OPTARG("-n"):
			if (opt_n != 0)
				usage();
			if (PARSENUM(&opt_n, optarg, 0, 65535)) {
				warn0("Invalid option: -n %s", optarg);
				usage();
			}
			break;
		GETOPT_OPTARG("-p"):
			if (opt_p != NULL)
				usage();
			if ((opt_p = strdup(optarg)) == NULL)
				OPT_EPARSE(ch, optarg);
			break;
		GETOPT_OPTARG("-s"):
			/* Keep a copy of the path for pidfile generation. */
			if ((opt_s_1 == NULL) &&
			    ((opt_s_1 = strdup(optarg)) == NULL))
				OPT_EPARSE(ch, optarg);

			/* Attempt to resolve to a list of addresses. */
			if ((sas = sock_resolve(optarg)) == NULL) {
				warnp("Cannot resolve address: %s", optarg);
				exit(1);
			}
			if (sas[0] == NULL) {
				warn0("No addresses found for %s", optarg);
				exit(1);
			}

			/* Push pointers to addresses onto the list. */
			for (i = 0; sas[i] != NULL; i++) {
				if (addrlist_append(opt_s, &sas[i], 1))
					OPT_EPARSE(ch, optarg);
			}

			/* Free the array (but keep the addresses). */
			free(sas);
			break;
		GETOPT_OPTARG("-t"):
			if (opt_t != NULL)
				usage();
			if ((opt_t = strdup(optarg)) == NULL)
				OPT_EPARSE(ch, optarg);
			break;
		GETOPT_OPT("--version"):
			fprintf(stderr, "kivaloo-mux @VERSION@\n");
			exit(0);
		GETOPT_MISSING_ARG:
			warn0("Missing argument to %s\n", ch);
			usage();
		GETOPT_DEFAULT:
			warn0("illegal option -- %s\n", ch);
			usage();
		}
	}
	argc -= optind;
	argv += optind;

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

	/* Sanity-check options. */
	if ((opt_s_size = addrlist_getsize(opt_s)) == 0)
		usage();
	if (opt_t == NULL)
		usage();

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

	/* Connect to the target. */
	if ((sock_t = sock_connect(sas)) == -1)
		exit(1);

	/* Free the target address(es). */
	sock_addr_freelist(sas);

	/* Create a queue of requests to the target. */
	if ((Q_t = wire_requestqueue_init(sock_t)) == NULL) {
		warnp("Cannot create request queue");
		exit(1);
	}

	/* Allocate array of source sockets. */
	if ((socks_s = malloc(opt_s_size * sizeof(int))) == NULL) {
		warnp("malloc");
		exit(1);
	}

	/* Create listening sockets. */
	for (i = 0; i < opt_s_size; i++) {
		if ((socks_s[i] =
		    sock_listener(*addrlist_get(opt_s, i))) == -1)
			exit(1);
	}

	/* Initialize the dispatcher. */
	if ((dstate = dispatch_init(socks_s, opt_s_size,
	    Q_t, opt_n ? (size_t)opt_n : SIZE_MAX)) == NULL) {
		warnp("Failed to initialize dispatcher");
		exit(1);
	}

	/* Daemonize and write pid. */
	if (opt_p == NULL) {
		if (asprintf(&opt_p, "%s.pid", opt_s_1) == -1) {
			warnp("asprintf");
			exit(1);
		}
	}
	if (daemonize(opt_p)) {
		warnp("Failed to daemonize");
		exit(1);
	}

	/* Loop until the dispatcher is finished. */
	do {
		if (events_run()) {
			warnp("Error running event loop");
			exit(1);
		}
	} while (dispatch_alive(dstate));

	/* Clean up the dispatcher. */
	dispatch_done(dstate);

	/* Shut down the request queue. */
	wire_requestqueue_destroy(Q_t);
	wire_requestqueue_free(Q_t);

	/* Close sockets. */
	for (i = 0; i < opt_s_size; i++)
		close(socks_s[i]);
	free(socks_s);
	close(sock_t);

	/* Free source socket addresses. */
	for (i = 0; i < addrlist_getsize(opt_s); i++)
		sock_addr_free(*addrlist_get(opt_s, i));
	addrlist_free(opt_s);

	/* Shut down the event subsystem. */
	events_shutdown();

	/* Free option strings. */
	free(opt_p);
	free(opt_s_1);
	free(opt_t);

	/* Success! */
	return (0);
}
Ejemplo n.º 3
0
void FindNumericToken(char const *s, Token *t)
{
    int mult = 1, hour, min;
    char const *s_orig = s;

    t->type = T_Illegal;
    t->val = 0;
    if (isdigit(*s)) {
	PARSENUM(t->val, s);

	/* If we hit a '-' or a '/', we may have a date or a datetime */
	if (*s == '-' || *s == '/') {
	    char const *p = s_orig;
	    int jul, tim;
	    if (ParseLiteralDate(&p, &jul, &tim) == OK) {
		if (*p) return;
		if (tim == NO_TIME) {
		    t->type = T_Date;
		    t->val = jul;
		    return;
		}
		t->type = T_DateTime;
		t->val = MINUTES_PER_DAY * jul + tim;
	    }
	    return;
	}

	/* If we hit a comma, swallow it.  This allows stuff
	   like Jan 6, 1998 */
	if (*s == ',') {
	    s++;
	    /* Special hack - convert years between 90 and
	       99 to 1990 and 1999 */
	    if (t->val >= 90 && t->val <= 99) t->val += 1900;

	    /* Classify the number we've got */
	    if (t->val >= BASE && t->val <= BASE+YR_RANGE) t->type = T_Year;
	    else if (t->val >= 1 && t->val <= 31) t->type = T_Day;
	    else t->type = T_Number;
	    return;
	}
	/* If we hit a colon or a period, we've probably got a time hr:min */
	if (*s == ':' || *s == '.' || *s == TimeSep) {
	    s++;
	    hour = t->val;
	    PARSENUM(min, s);
	    if (*s || min > 59) return;  /* Illegal time */
	    t->val = hour*60 + min;  /* Convert to minutes past midnight */
	    if (hour <= 23) {
		t->type = T_Time;
	    } else {
		t->type = T_LongTime;
	    }
	    return;
	}

	/* If we hit a non-digit, error! */
	if (*s) return;

	/* Special hack - convert years between 90 and 99 to 1990 and 1999 */
	if (t->val >= 90 && t->val <= 99) t->val += 1900;

	/* Classify the number we've got */
	if (t->val >= BASE && t->val <= BASE+YR_RANGE) t->type = T_Year;
	else if (t->val >= 1 && t->val <= 31) t->type = T_Day;
	else t->type = T_Number;
	return;
    } else if (*s == '*') {
	s++;
	PARSENUM(t->val, s);
	if (*s) return;  /* Illegal token if followed by non-numeric char */
	t->type = T_Rep;
	return;
    } else if (*s == '+') {
	s++;
	if (*s == '+') { mult = -1; s++; }
	PARSENUM(t->val, s);
	if (*s) return;  /* Illegal token if followed by non-numeric char */
	t->type = T_Delta;
	t->val *= mult;
	return;
    } else if (*s == '-') {
	s++;
	if (*s == '-') { mult = -1; s++; }
	PARSENUM(t->val, s);
	if (*s) return;  /* Illegal token if followed by non-numeric char */
	t->type = T_Back;
	t->val *= mult;
	return;
    }
    return;  /* Unknown token type */
}