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); }
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); }
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 */ }