int main(int argc, char *argv[]) { int sockfd; struct sockaddr_in serv_addr; char *local_ip; if (argc < 2) local_ip = "127.0.0.1"; else local_ip = argv[1]; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) exit_failure(); memset(&serv_addr, '0', sizeof(struct sockaddr_in)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(5000); if (inet_pton(AF_INET, local_ip, &serv_addr.sin_addr) != 1) exit_failure(); printf("Local sockaddr\n"); info_sockaddr((struct sockaddr* ) &serv_addr); p("Connnect"); if (connect(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) != 0) exit_failure(); test_getpeername(sockfd); p("Read data"); read_data(sockfd); return 0; }
void test_getpeername(int sockfd) { socklen_t len; struct sockaddr_storage addr; char ipstr[INET6_ADDRSTRLEN]; int port; len = sizeof(addr); // printf("0000\n"); if (getpeername(sockfd, (struct sockaddr*) &addr, &len) != 0) exit_failure(); // printf("1111\n"); if (addr.ss_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in*) &addr; port = ntohs(s->sin_port); // printf("1111\n") if (inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof(ipstr)) == NULL) exit_failure(); // printf("2222\n"); } else if (addr.ss_family == AF_INET6) { struct sockaddr_in6 *s = (struct sockaddr_in6*) &addr; port = ntohs(s->sin6_port); if (inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof(ipstr)) == NULL) exit_failure(); } else { printf("Unsupported address family: %d", addr.ss_family); exit(EXIT_FAILURE); } printf("Peer IP address: %s\n", ipstr); printf("Peer port : %d\n", port); }
void rsh_relay(int s_src, int s_dst) { ssize_t n; fd_set readfds; int error; struct timeval tv; FD_ZERO(&readfds); FD_SET(s_src, &readfds); tv.tv_sec = FAITH_TIMEOUT; tv.tv_usec = 0; error = select(s_src + 1, &readfds, NULL, NULL, &tv); if (error == -1) exit_failure("select %d: %s", s_src, strerror(errno)); else if (error == 0) exit_failure("connection timeout"); n = read(s_src, rshbuf, sizeof(rshbuf)); if (rshbuf[0] != 0) { rsh_dual_relay(s_src, s_dst); /* NOTREACHED */ } write(s_dst, rshbuf, n); tcp_relay(s_src, s_dst, "rsh"); /* NOTREACHED */ }
void tcp_relay(int s_src, int s_dst, const char *service) { syslog(LOG_INFO, "starting %s relay", service); child_lastactive = parent_lastactive = time(NULL); cpid = fork(); switch (cpid) { case -1: exit_failure("tcp_relay: can't fork grand child: %s", strerror(errno)); /* NOTREACHED */ case 0: /* child process: relay going traffic */ ppid = getppid(); /* this is child so reopen log */ closelog(); openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); relay(s_src, s_dst, service, 1); /* NOTREACHED */ default: /* parent process: relay coming traffic */ ppid = (pid_t)0; signal(SIGUSR1, sig_ctimeout); signal(SIGCHLD, sig_child); relay(s_dst, s_src, service, 0); /* NOTREACHED */ } }
static sexp check_exception (sexp ctx, sexp res) { sexp_gc_var4(err, advise, sym, tmp); if (res && sexp_exceptionp(res)) { sexp_gc_preserve4(ctx, err, advise, sym, tmp); tmp = res; err = sexp_current_error_port(ctx); if (! sexp_oportp(err)) err = sexp_make_output_port(ctx, stderr, SEXP_FALSE); sexp_print_exception(ctx, res, err); sexp_stack_trace(ctx, err); #if SEXP_USE_MAIN_ERROR_ADVISE if (sexp_envp(sexp_global(ctx, SEXP_G_META_ENV))) { advise = sexp_eval_string(ctx, sexp_advice_environment, -1, sexp_global(ctx, SEXP_G_META_ENV)); if (sexp_vectorp(advise)) { advise = sexp_vector_ref(advise, SEXP_ONE); if (sexp_envp(advise)) { sym = sexp_intern(ctx, "repl-advise-exception", -1); advise = sexp_env_ref(ctx, advise, sym, SEXP_FALSE); if (sexp_procedurep(advise)) sexp_apply(ctx, advise, tmp=sexp_list2(ctx, res, err)); } } } #endif sexp_gc_release4(ctx); exit_failure(); } return res; }
void sexp_usage(int err) { printf("usage: chibi-scheme [<options> ...] [<file> <args> ...]\n" #if SEXP_USE_FOLD_CASE_SYMS " -f - case-fold symbols\n" #endif " -q - \"quick\" load, use the core -xchibi language\n" " -Q - extra \"quick\" load, -xchibi.primitive\n" " -V - print version information\n" " -D <feature> - add <feature> to the list of features\n" #if ! SEXP_USE_BOEHM " -h <size> - specify the initial heap size\n" #endif #if SEXP_USE_MODULES " -A <dir> - append a module search directory\n" " -I <dir> - prepend a module search directory\n" " -m <module> - import a module\n" " -x <module> - import only a module\n" #endif " -e <expr> - evaluate an expression\n" " -p <expr> - evaluate and print an expression\n" " -r[<main>] - run a SRFI-22 main\n" " -R[<module>] - run main from a module\n" " -t <module.proc> - trace a procedure\n" " -T - disable TCO (dangerous)\n" #if SEXP_USE_IMAGE_LOADING " -d <file> - dump an image file and exit\n" " -i <file> - load an image file\n" #endif ); if (err == 0) exit_success(); else exit_failure(); }
static void parse_option (char*** keys, char*** values, const char* option) { char* key; char* value; size_t length = 0; key = strdup (option); value = strchr (key, '='); if (value == NULL) { fprintf (stderr, "Invalid option (\"%s\").", option); exit (exit_failure ()); } *value = '\0'; value++; if (*keys != NULL) { while ( (*keys)[length] != NULL ) { if ( strcmp ((*keys)[length], key) == 0 ) { free ((*values)[length]); (*values)[length] = strdup (value); free (key); return; } length++; } } *keys = (char**) realloc (*keys, sizeof (char*) * (length + 2)); *values = (char**) realloc (*values, sizeof (char*) * (length + 2)); (*keys)[length] = key; (*values)[length] = strdup (value); (*keys)[length + 1] = NULL; (*values)[length + 1] = NULL; }
static void notify_inactive() { time_t t; /* only on parent side... */ if (ppid) return; /* parent side should check for timeout. */ t = time(NULL); if (dflag) { syslog(LOG_DEBUG, "parent side %sactive, child side %sactive", (FAITH_TIMEOUT < t - parent_lastactive) ? "in" : "", (FAITH_TIMEOUT < t - child_lastactive) ? "in" : ""); } if (FAITH_TIMEOUT < t - child_lastactive && FAITH_TIMEOUT < t - parent_lastactive) { /* both side timeouted */ signal(SIGCHLD, SIG_DFL); kill(cpid, SIGTERM); wait(NULL); exit_failure("connection timeout"); /* NOTREACHED */ } }
static void send_data(int s_rcv, int s_snd, const char *service, int direction) { int cc; if (oob_exists) { cc = send(s_snd, atmark_buf, 1, MSG_OOB); if (cc == -1) goto retry_or_err; oob_exists = 0; if (s_rcv >= FD_SETSIZE) exit_failure("descriptor too big"); FD_SET(s_rcv, &exceptfds); } for (; tboff < tblen; tboff += cc) { cc = write(s_snd, tcpbuf + tboff, tblen - tboff); if (cc < 0) goto retry_or_err; } #ifdef DEBUG if (tblen) { if (tblen >= sizeof(tcpbuf)) tblen = sizeof(tcpbuf) - 1; tcpbuf[tblen] = '\0'; syslog(LOG_DEBUG, "from %s (%dbytes): %s", direction == 1 ? "client" : "server", tblen, tcpbuf); } #endif /* DEBUG */ tblen = 0; tboff = 0; if (s_snd >= FD_SETSIZE) exit_failure("descriptor too big"); FD_CLR(s_snd, &writefds); if (s_rcv >= FD_SETSIZE) exit_failure("descriptor too big"); FD_SET(s_rcv, &readfds); return; retry_or_err: if (errno != EAGAIN) exit_failure("writing relay data failed: %s", strerror(errno)); if (s_snd >= FD_SETSIZE) exit_failure("descriptor too big"); FD_SET(s_snd, &writefds); }
void read_data(int sockfd) { int i; char buf[1024]; while ((i = read(sockfd, buf, sizeof(buf) - 1)) > 0) { buf[i] = 0; printf("%s", buf); } if (i < 0) exit_failure(); }
static void do_init_context (sexp* ctx, sexp* env, sexp_uint_t heap_size, sexp_uint_t heap_max_size, sexp_sint_t fold_case) { *ctx = sexp_make_eval_context(NULL, NULL, NULL, heap_size, heap_max_size); if (! *ctx) { fprintf(stderr, "chibi-scheme: out of memory\n"); exit_failure(); } #if SEXP_USE_FOLD_CASE_SYMS sexp_global(*ctx, SEXP_G_FOLD_CASE_P) = sexp_make_boolean(fold_case); #endif *env = sexp_context_env(*ctx); }
int main (int argc, char **argv) { #if SEXP_USE_PRINT_BACKTRACE_ON_SEGFAULT signal(SIGSEGV, sexp_segfault_handler); #endif sexp_scheme_init(); if (run_main(argc, argv) == SEXP_FALSE) { exit_failure(); } else { exit_success(); } return 0; }
static sexp check_exception (sexp ctx, sexp res) { sexp err; if (res && sexp_exceptionp(res)) { err = sexp_current_error_port(ctx); if (! sexp_oportp(err)) err = sexp_make_output_port(ctx, stderr, SEXP_FALSE); sexp_print_exception(ctx, res, err); sexp_stack_trace(ctx, err); exit_failure(); } return res; }
// ------------------------Core Functions--------------------------- extern "C" void barista_core_init (int argc, char *argv[]) { int ret; if (argc < MIN_ARGS) { exit_failure (USAGE_ERROR); } io_manager.init (argv[METADATA]); persistent_metadata->init (argv[METADATA]); ret = set_stripe_size (atoi(argv[STRIPE_SIZE])); if (ret < 0) { exit_failure (get_size_error_message ("stripe", argv[STRIPE_SIZE])); } ret = set_chunk_size (atoi(argv[CHUNK_SIZE])); if (ret < 0) { exit_failure (get_size_error_message ("chunk", argv[CHUNK_SIZE])); } set_num_espressos (atoi(argv[NUM_ESPRESSOS])); strategy_startup(); }
static void repl (sexp ctx, sexp env) { sexp_gc_var6(obj, tmp, res, in, out, err); sexp_gc_preserve6(ctx, obj, tmp, res, in, out, err); sexp_context_tracep(ctx) = 1; in = sexp_param_ref(ctx, env, sexp_global(ctx, SEXP_G_CUR_IN_SYMBOL)); out = sexp_param_ref(ctx, env, sexp_global(ctx, SEXP_G_CUR_OUT_SYMBOL)); err = sexp_param_ref(ctx, env, sexp_global(ctx, SEXP_G_CUR_ERR_SYMBOL)); if (in == NULL || out == NULL) { fprintf(stderr, "Standard I/O ports not found, aborting. Maybe a bad -x language?\n"); exit_failure(); } if (err == NULL) err = out; sexp_port_sourcep(in) = 1; while (1) { sexp_write_string(ctx, "> ", out); sexp_flush(ctx, out); sexp_maybe_block_port(ctx, in, 1); obj = sexp_read(ctx, in); sexp_maybe_unblock_port(ctx, in); if (obj == SEXP_EOF) break; if (sexp_exceptionp(obj)) { sexp_print_exception(ctx, obj, err); } else { sexp_context_top(ctx) = 0; if (!(sexp_idp(obj)||sexp_pairp(obj)||sexp_nullp(obj))) obj = sexp_make_lit(ctx, obj); tmp = sexp_env_bindings(env); res = sexp_eval(ctx, obj, env); #if SEXP_USE_WARN_UNDEFS sexp_warn_undefs(ctx, sexp_env_bindings(env), tmp, res); #endif if (res && sexp_exceptionp(res)) { sexp_print_exception(ctx, res, err); if (res != sexp_global(ctx, SEXP_G_OOS_ERROR)) sexp_stack_trace(ctx, err); } else if (res != SEXP_VOID) { sexp_write(ctx, res, out); sexp_write_char(ctx, '\n', out); } } } sexp_gc_release6(ctx); }
static void notify_active() { if (ppid) { /* child side: notify parent of active traffic */ time_t t; t = time(NULL); if (FAITH_TIMEOUT / 4 < t - child_lastactive) { if (kill(ppid, SIGUSR1) < 0) { exit_failure("terminate connection due to parent termination"); /* NOTREACHED */ } child_lastactive = t; } } else { /* parent side */ parent_lastactive = time(NULL); } }
static void relay(int src, int dst) { int error; ssize_t n; int atmark; error = ioctl(s_rcv, SIOCATMARK, &atmark); if (error != -1 && atmark == 1) { n = read(s_rcv, rshbuf, 1); if (n == 1) send(s_snd, rshbuf, 1, MSG_OOB); return; } n = read(s_rcv, rshbuf, sizeof(rshbuf)); switch (n) { case -1: exit_failure("%s", strerror(errno)); case 0: if (s_rcv == src) { /* half close */ shutdown(dst, 1); half = YES; break; } close(src); close(dst); close(s_ctl); close(s_ctl6); exit_success("terminating rsh/contorol connections"); break; default: write(s_snd, rshbuf, n); } }
static int ftp_copy(int src, int dst) { int error, atmark, n; /* OOB data handling */ error = ioctl(src, SIOCATMARK, &atmark); if (error != -1 && atmark == 1) { n = read(src, rbuf, 1); if (n == -1) goto bad; send(dst, rbuf, n, MSG_OOB); #if 0 n = read(src, rbuf, sizeof(rbuf)); if (n == -1) goto bad; write(dst, rbuf, n); return n; #endif } n = read(src, rbuf, sizeof(rbuf)); switch (n) { case -1: case 0: return n; default: write(dst, rbuf, n); return n; } bad: exit_failure("%s", strerror(errno)); /*NOTREACHED*/ return 0; /* to make gcc happy */ }
static int ftp_copyresult(int src, int dst, enum state state) { int error, atmark, n; socklen_t len; char *param; int code; char *a, *p; int i; /* OOB data handling */ error = ioctl(src, SIOCATMARK, &atmark); if (error != -1 && atmark == 1) { n = read(src, rbuf, 1); if (n == -1) goto bad; send(dst, rbuf, n, MSG_OOB); #if 0 n = read(src, rbuf, sizeof(rbuf)); if (n == -1) goto bad; write(dst, rbuf, n); return n; #endif } n = read(src, rbuf, sizeof(rbuf)); if (n <= 0) return n; rbuf[n] = '\0'; /* * parse argument */ p = rbuf; for (i = 0; i < 3; i++) { if (!isdigit(*p)) { /* invalid reply */ write(dst, rbuf, n); return n; } p++; } if (!isspace(*p)) { /* invalid reply */ write(dst, rbuf, n); return n; } code = atoi(rbuf); param = p; /* param points to first non-command token, if any */ while (*param && isspace(*param)) param++; if (!*param) param = NULL; switch (state) { case NONE: if (!passivemode && rbuf[0] == '1') { if (ftp_activeconn() < 0) { n = snprintf(rbuf, sizeof(rbuf), "425 Cannot open data connetion\r\n"); if (n < 0 || n >= sizeof(rbuf)) n = 0; } } if (n) write(dst, rbuf, n); return n; case LPRT: case EPRT: /* expecting "200 PORT command successful." */ if (code == 200) { p = strstr(rbuf, "PORT"); if (p) { p[0] = (state == LPRT) ? 'L' : 'E'; p[1] = 'P'; } } else { close(wport4); wport4 = -1; } write(dst, rbuf, n); return n; case LPSV: case EPSV: /* * expecting "227 Entering Passive Mode (x,x,x,x,x,x,x)" * (in some cases result comes without paren) */ if (code != 227) { passivefail0: close(wport6); wport6 = -1; write(dst, rbuf, n); return n; } { unsigned int ho[4], po[2]; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; u_short port; /* * PASV result -> LPSV/EPSV result */ p = param; while (*p && *p != '(' && !isdigit(*p)) /*)*/ p++; if (!*p) goto passivefail0; /*XXX*/ if (*p == '(') /*)*/ p++; n = sscanf(p, "%u,%u,%u,%u,%u,%u", &ho[0], &ho[1], &ho[2], &ho[3], &po[0], &po[1]); if (n != 6) goto passivefail0; /*XXX*/ /* keep PORT parameter */ memset(&data4, 0, sizeof(data4)); sin = (struct sockaddr_in *)&data4; sin->sin_len = sizeof(*sin); sin->sin_family = AF_INET; sin->sin_addr.s_addr = 0; for (n = 0; n < 4; n++) { sin->sin_addr.s_addr |= htonl((ho[n] & 0xff) << ((3 - n) * 8)); } sin->sin_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff)); /* get ready for passive data connection */ memset(&data6, 0, sizeof(data6)); sin6 = (struct sockaddr_in6 *)&data6; sin6->sin6_len = sizeof(*sin6); sin6->sin6_family = AF_INET6; wport6 = socket(sin6->sin6_family, SOCK_STREAM, 0); if (wport6 == -1) { passivefail: n = snprintf(sbuf, sizeof(sbuf), "500 could not translate from PASV\r\n"); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(src, sbuf, n); return n; } #ifdef IPV6_FAITH { int on = 1; error = setsockopt(wport6, IPPROTO_IPV6, IPV6_FAITH, &on, sizeof(on)); if (error == -1) exit_failure("setsockopt(IPV6_FAITH): %s", strerror(errno)); } #endif error = bind(wport6, (struct sockaddr *)sin6, sin6->sin6_len); if (error == -1) { close(wport6); wport6 = -1; goto passivefail; } error = listen(wport6, 1); if (error == -1) { close(wport6); wport6 = -1; goto passivefail; } /* transmit LPSV or EPSV */ /* * addr from dst, port from wport6 */ len = sizeof(data6); error = getsockname(wport6, (struct sockaddr *)&data6, &len); if (error == -1) { close(wport6); wport6 = -1; goto passivefail; } sin6 = (struct sockaddr_in6 *)&data6; port = sin6->sin6_port; len = sizeof(data6); error = getsockname(dst, (struct sockaddr *)&data6, &len); if (error == -1) { close(wport6); wport6 = -1; goto passivefail; } sin6 = (struct sockaddr_in6 *)&data6; sin6->sin6_port = port; if (state == LPSV) { a = (char *)&sin6->sin6_addr; p = (char *)&sin6->sin6_port; n = snprintf(sbuf, sizeof(sbuf), "228 Entering Long Passive Mode (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\r\n", 6, 16, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(a[4]), UC(a[5]), UC(a[6]), UC(a[7]), UC(a[8]), UC(a[9]), UC(a[10]), UC(a[11]), UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]), 2, UC(p[0]), UC(p[1])); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(dst, sbuf, n); passivemode = 1; return n; } else { n = snprintf(sbuf, sizeof(sbuf), "229 Entering Extended Passive Mode (|||%d|)\r\n", ntohs(sin6->sin6_port)); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(dst, sbuf, n); passivemode = 1; return n; } } } bad: exit_failure("%s", strerror(errno)); /*NOTREACHED*/ return 0; /* to make gcc happy */ }
static int ftp_passiveconn() { socklen_t len; int error; #ifdef HAVE_POLL_H struct pollfd pfd[1]; #else fd_set set; #endif struct timeval timeout; struct sockaddr *sa; /* get passive connection from client */ #ifdef HAVE_POLL_H pfd[0].fd = wport6; pfd[0].events = POLLIN; #else FD_ZERO(&set); if (wport6 >= FD_SETSIZE) exit_failure("descriptor too big"); FD_SET(wport6, &set); #endif timeout.tv_sec = 120; timeout.tv_usec = 0; len = sizeof(data6); #ifdef HAVE_POLL_H if (poll(pfd, sizeof(pfd)/sizeof(pfd[0]), timeout.tv_sec * 1000) == 0 || (port6 = accept(wport6, (struct sockaddr *)&data6, &len)) < 0) #else if (select(wport6 + 1, &set, NULL, NULL, &timeout) == 0 || (port6 = accept(wport6, (struct sockaddr *)&data6, &len)) < 0) #endif { close(wport6); wport6 = -1; syslog(LOG_INFO, "passive mode data connection failed"); return -1; } /* ask passive connection to server */ sa = (struct sockaddr *)&data4; port4 = socket(sa->sa_family, SOCK_STREAM, 0); if (port4 == -1) { close(wport6); close(port6); wport6 = port6 = -1; syslog(LOG_INFO, "passive mode data connection failed"); return -1; } error = connect(port4, sa, sa->sa_len); if (error < 0) { close(wport6); close(port4); close(port6); wport6 = port4 = port6 = -1; syslog(LOG_INFO, "passive mode data connection failed"); return -1; } syslog(LOG_INFO, "passive mode data connection established"); return 0; }
int main (int argc, char** argv) { SquashStatus res; SquashCodec* codec = NULL; SquashOptions* options = NULL; SquashStreamType direction = SQUASH_STREAM_COMPRESS; FILE* input = NULL; FILE* output = NULL; char* input_name = NULL; char* output_name = NULL; bool list_codecs = false; bool list_plugins = false; char** option_keys = NULL; char** option_values = NULL; bool keep = false; bool force = false; int opt; int optc = 0; char* tmp_string; int retval = EXIT_SUCCESS; struct parg_state ps; int optend; const struct parg_option squash_options[] = { {"keep", PARG_NOARG, NULL, 'k'}, {"option", PARG_REQARG, NULL, 'o'}, {"codec", PARG_REQARG, NULL, 'c'}, {"list-codecs", PARG_NOARG, NULL, 'L'}, {"list-plugins", PARG_NOARG, NULL, 'P'}, {"force", PARG_NOARG, NULL, 'f'}, {"decompress", PARG_NOARG, NULL, 'd'}, {"version", PARG_NOARG, NULL, 'V'}, {"help", PARG_NOARG, NULL, 'h'}, {NULL, 0, NULL, 0} }; option_keys = (char**) malloc (sizeof (char*)); option_values = (char**) malloc (sizeof (char*)); *option_keys = NULL; *option_values = NULL; optend = parg_reorder (argc, argv, "c:ko:123456789LPfdhb:V", squash_options); parg_init(&ps); while ( (opt = parg_getopt_long (&ps, optend, argv, "c:ko:123456789LPfdhb:V", squash_options, NULL)) != -1 ) { switch ( opt ) { case 'c': codec = squash_get_codec (ps.optarg); if ( codec == NULL ) { fprintf (stderr, "Unable to find codec '%s'\n", ps.optarg); retval = exit_failure (); goto cleanup; } break; case 'k': keep = true; break; case 'o': parse_option (&option_keys, &option_values, ps.optarg); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': tmp_string = malloc (8); snprintf (tmp_string, 8, "level=%c", (char) opt); parse_option (&option_keys, &option_values, tmp_string); free (tmp_string); break; case 'L': list_codecs = true; break; case 'P': list_plugins = true; break; case 'f': force = true; break; case 'h': print_help_and_exit (argc, argv, EXIT_SUCCESS); break; case 'd': direction = SQUASH_STREAM_DECOMPRESS; break; case 'V': print_version_and_exit (argc, argv, EXIT_SUCCESS); break; } optc++; } if (list_plugins) { if (list_codecs) squash_foreach_plugin (list_plugins_and_codecs_foreach_cb, NULL); else squash_foreach_plugin (list_plugins_foreach_cb, NULL); goto cleanup; } else if (list_codecs) { squash_foreach_codec (list_codecs_foreach_cb, NULL); goto cleanup; } if ( ps.optind < argc ) { input_name = argv[ps.optind++]; if ( (direction == SQUASH_STREAM_DECOMPRESS) && codec == NULL ) { char* extension; extension = strrchr (input_name, '.'); if (extension != NULL) extension++; if (extension != NULL) codec = squash_get_codec_from_extension (extension); } } else { fprintf (stderr, "You must provide an input file name.\n"); retval = exit_failure (); goto cleanup; } if ( ps.optind < argc ) { output_name = strdup (argv[ps.optind++]); if ( codec == NULL && direction == SQUASH_STREAM_COMPRESS ) { const char* extension = strrchr (output_name, '.'); if (extension != NULL) extension++; if (extension != NULL) codec = squash_get_codec_from_extension (extension); } } else { if ( codec != NULL ) { const char* extension = squash_codec_get_extension (codec); if (extension != NULL) { if (strcmp (input_name, "-") == 0) { output_name = strdup ("-"); } else { size_t extension_length = strlen (extension); size_t input_name_length = strlen (input_name); if ( (extension_length + 1) < input_name_length && input_name[input_name_length - (1 + extension_length)] == '.' && strcasecmp (extension, input_name + (input_name_length - (extension_length))) == 0 ) { output_name = squash_strndup (input_name, input_name_length - (1 + extension_length)); } } } } } if ( ps.optind < argc ) { fprintf (stderr, "Too many arguments.\n"); } if ( codec == NULL ) { fprintf (stderr, "Unable to determine codec. Please pass -c \"codec\", or -L to see a list of available codecs.\n"); retval = exit_failure (); goto cleanup; } if ( output_name == NULL ) { fprintf (stderr, "Unable to determine output file.\n"); retval = exit_failure (); goto cleanup; } if ( strcmp (input_name, "-") == 0 ) { input = stdin; } else { input = fopen (input_name, "rb"); if ( input == NULL ) { perror ("Unable to open input file"); retval = exit_failure (); goto cleanup; } } if ( strcmp (output_name, "-") == 0 ) { output = stdout; } else { int output_fd = open (output_name, #if !defined(_WIN32) O_RDWR | O_CREAT | (force ? O_TRUNC : O_EXCL), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH #else O_RDWR | O_CREAT | (force ? O_TRUNC : O_EXCL) | O_BINARY, S_IREAD | S_IWRITE #endif ); if ( output_fd < 0 ) { perror ("Unable to open output file"); retval = exit_failure (); goto cleanup; } output = fdopen (output_fd, "wb"); if ( output == NULL ) { perror ("Unable to open output"); retval = exit_failure (); goto cleanup; } } options = squash_options_newa (codec, (const char * const*) option_keys, (const char * const*) option_values); res = squash_splice_with_options (codec, direction, output, input, 0, options); if ( res != SQUASH_OK ) { fprintf (stderr, "Failed to %s: %s\n", (direction == SQUASH_STREAM_COMPRESS) ? "compress" : "decompress", squash_status_to_string (res)); retval = exit_failure (); goto cleanup; } if ( !keep && input != stdin ) { fclose (input); if ( unlink (input_name) != 0 ) { perror ("Unable to remove input file"); } input = NULL; } cleanup: if (input != stdin && input != NULL) fclose (stdin); if (output != stdout) fclose (stdout); if (option_keys != NULL) { for (opt = 0 ; option_keys[opt] != NULL ; opt++) { free(option_keys[opt]); } free (option_keys); } if (option_values != NULL) { for (opt = 0 ; option_values[opt] != NULL ; opt++) { free(option_values[opt]); } free (option_values); } free (output_name); return retval; }
void rsh_dual_relay(int s_src, int s_dst) { fd_set readfds; int len, s_wld, error; struct sockaddr_storage ctladdr6; struct sockaddr_storage ctladdr; int port6 = 0, lport, lport6; char *p; struct timeval tv; struct sockaddr *sa; half = NO; s_rcv = s_src; s_snd = s_dst; syslog(LOG_INFO, "starting rsh connection"); for (p = rshbuf; *p; p++) port6 = port6 * 10 + *p - '0'; len = sizeof(ctladdr6); getpeername(s_src, (struct sockaddr *)&ctladdr6, &len); if (((struct sockaddr *)&ctladdr6)->sa_family == AF_INET6) ((struct sockaddr_in6 *)&ctladdr6)->sin6_port = htons(port6); else ((struct sockaddr_in *)&ctladdr6)->sin_port = htons(port6); s_wld = rresvport(&lport); if (s_wld == -1) goto bad; error = listen(s_wld, 1); if (error == -1) goto bad; snprintf(rshbuf, sizeof(rshbuf), "%d", lport); write(s_dst, rshbuf, strlen(rshbuf)+1); len = sizeof(ctladdr); s_ctl = accept(s_wld, (struct sockaddr *)&ctladdr, &len); if (s_ctl == -1) goto bad; close(s_wld); sa = (struct sockaddr *)&ctladdr6; s_ctl6 = rresvport_af(&lport6, sa->sa_family); if (s_ctl6 == -1) goto bad; error = connect(s_ctl6, sa, sa->sa_len); if (error == -1) goto bad; syslog(LOG_INFO, "starting rsh control connection"); for (;;) { int maxfd = 0; FD_ZERO(&readfds); if (half == NO) FD_SET(s_src, &readfds); FD_SET(s_dst, &readfds); if (s_dst > maxfd) maxfd = s_dst; FD_SET(s_ctl, &readfds); if (s_ctl > maxfd) maxfd = s_ctl; FD_SET(s_ctl6, &readfds); if (s_ctl6 > maxfd) maxfd = s_ctl6; tv.tv_sec = FAITH_TIMEOUT; tv.tv_usec = 0; error = select(maxfd + 1, &readfds, NULL, NULL, &tv); if (error == -1) exit_failure("select 4 sockets: %s", strerror(errno)); else if (error == 0) exit_failure("connection timeout"); if (half == NO && FD_ISSET(s_src, &readfds)) { s_rcv = s_src; s_snd = s_dst; relay(s_src, s_dst); } if (FD_ISSET(s_dst, &readfds)) { s_rcv = s_dst; s_snd = s_src; relay(s_src, s_dst); } if (FD_ISSET(s_ctl, &readfds)) { s_rcv = s_ctl; s_snd = s_ctl6; relay(s_src, s_dst); } if (FD_ISSET(s_ctl6, &readfds)) { s_rcv = s_ctl6; s_snd = s_ctl; relay(s_src, s_dst); } } /* NOTREACHED */ bad: exit_failure("%s", strerror(errno)); }
sexp run_main (int argc, char **argv) { #if SEXP_USE_MODULES char *impmod; #endif char *arg; const char *prefix=NULL, *suffix=NULL, *main_symbol=NULL, *main_module=NULL; sexp_sint_t i, j, c, quit=0, print=0, init_loaded=0, mods_loaded=0, fold_case=SEXP_DEFAULT_FOLD_CASE_SYMS, nonblocking=0; sexp_uint_t heap_size=0, heap_max_size=SEXP_MAXIMUM_HEAP_SIZE; sexp out=SEXP_FALSE, ctx=NULL, ls; sexp_gc_var4(tmp, sym, args, env); args = SEXP_NULL; env = NULL; /* SRFI 22: invoke `main` procedure by default if the interpreter is */ /* invoked as `scheme-r7rs`. */ arg = strrchr(argv[0], '/'); if (strncmp((arg == NULL ? argv[0] : arg + 1), "scheme-r7rs", strlen("scheme-r7rs")) == 0) { main_symbol = "main"; /* skip option parsing since we can't pass `--` before the name of script */ /* to avoid misinterpret the name as options when the interpreter is */ /* executed via `#!/usr/env/bin scheme-r7rs` shebang. */ i = 1; goto done_options; } /* parse options */ for (i=1; i < argc && argv[i][0] == '-'; i++) { switch ((c=argv[i][1])) { case 'D': init_context(); arg = (argv[i][2] == '\0') ? argv[++i] : argv[i]+2; sym = sexp_intern(ctx, arg, -1); ls = sexp_global(ctx, SEXP_G_FEATURES); if (sexp_pairp(ls)) { for (; sexp_pairp(sexp_cdr(ls)); ls=sexp_cdr(ls)) ; sexp_cdr(ls) = sexp_cons(ctx, sym, SEXP_NULL); } break; case 'e': case 'p': mods_loaded = 1; load_init(0); print = (argv[i][1] == 'p'); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('e', arg); tmp = check_exception(ctx, sexp_eval_string(ctx, arg, -1, env)); if (print) { if (! sexp_oportp(out)) out = sexp_eval_string(ctx, "(current-output-port)", -1, env); sexp_write(ctx, tmp, out); sexp_write_char(ctx, '\n', out); } quit = 1; break; case 'l': mods_loaded = 1; load_init(0); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('l', arg); check_exception(ctx, sexp_load_module_file(ctx, arg, env)); break; case 'x': prefix = sexp_environment_prefix; suffix = sexp_environment_suffix; case 'm': arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); if (c == 'x') { if (strcmp(arg, "chibi.primitive") == 0) { goto load_primitive; } else if (strcmp(arg, "scheme.small") == 0) { load_init(0); break; } } else { prefix = sexp_import_prefix; suffix = sexp_import_suffix; } mods_loaded = 1; load_init(c == 'x'); #if SEXP_USE_MODULES check_nonull_arg(c, arg); impmod = make_import(prefix, arg, suffix); tmp = check_exception(ctx, sexp_eval_string(ctx, impmod, -1, (c=='x' ? sexp_global(ctx, SEXP_G_META_ENV) : env))); free(impmod); if (c == 'x') { sexp_set_parameter(ctx, sexp_global(ctx, SEXP_G_META_ENV), sexp_global(ctx, SEXP_G_INTERACTION_ENV_SYMBOL), tmp); sexp_context_env(ctx) = env = tmp; sexp_add_import_binding(ctx, env); tmp = sexp_param_ref(ctx, env, sexp_global(ctx, SEXP_G_CUR_OUT_SYMBOL)); if (tmp != NULL && !sexp_oportp(tmp)) { sexp_load_standard_ports(ctx, env, stdin, stdout, stderr, 0); } } #endif break; load_primitive: case 'Q': init_context(); mods_loaded = 1; if (! init_loaded++) sexp_load_standard_ports(ctx, env, stdin, stdout, stderr, 0); handle_noarg(); break; case 'q': argv[i--] = (char*)"-xchibi"; break; case 'A': init_context(); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('A', arg); sexp_add_module_directory(ctx, tmp=sexp_c_string(ctx,arg,-1), SEXP_TRUE); break; case 'I': init_context(); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('I', arg); sexp_add_module_directory(ctx, tmp=sexp_c_string(ctx,arg,-1), SEXP_FALSE); break; #if SEXP_USE_GREEN_THREADS case 'b': nonblocking = 1; break; #endif case '-': if (argv[i][2] == '\0') { i++; goto done_options; } sexp_usage(1); case 'h': arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('h', arg); #if ! SEXP_USE_BOEHM heap_size = strtoul(arg, &arg, 0); if (sexp_isalpha((unsigned char)*arg)) heap_size *= multiplier(*arg++); if (*arg == '/') { heap_max_size = strtoul(arg+1, &arg, 0); if (sexp_isalpha((unsigned char)*arg)) heap_max_size *= multiplier(*arg++); } #endif break; #if SEXP_USE_IMAGE_LOADING case 'i': arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); if (ctx) { fprintf(stderr, "-:i <file>: image files must be loaded first\n"); exit_failure(); } ctx = sexp_load_image(arg, 0, heap_size, heap_max_size); if (!ctx || !sexp_contextp(ctx)) { fprintf(stderr, "-:i <file>: couldn't open image file for reading: %s\n", arg); fprintf(stderr, " %s\n", sexp_load_image_err()); ctx = NULL; } else { env = sexp_load_standard_params(ctx, sexp_context_env(ctx), nonblocking); init_loaded++; } break; case 'd': if (! init_loaded++) { init_context(); env = sexp_load_standard_env(ctx, env, SEXP_SEVEN); } arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); if (sexp_save_image(ctx, arg) != SEXP_TRUE) { fprintf(stderr, "-d <file>: couldn't save image to file: %s\n", arg); fprintf(stderr, " %s\n", sexp_load_image_err()); exit_failure(); } quit = 1; break; #endif case 'V': load_init(1); if (! sexp_oportp(out)) out = sexp_eval_string(ctx, "(current-output-port)", -1, env); sexp_write_string(ctx, sexp_version_string, out); tmp = sexp_env_ref(ctx, env, sym=sexp_intern(ctx, "*features*", -1), SEXP_NULL); sexp_write(ctx, tmp, out); sexp_newline(ctx, out); return SEXP_TRUE; #if SEXP_USE_FOLD_CASE_SYMS case 'f': fold_case = 1; init_context(); sexp_global(ctx, SEXP_G_FOLD_CASE_P) = SEXP_TRUE; handle_noarg(); break; #endif case 'R': main_module = argv[i][2] != '\0' ? argv[i]+2 : (i+1 < argc && argv[i+1][0] != '-') ? argv[++i] : "chibi.repl"; if (main_symbol == NULL) main_symbol = "main"; break; case 'r': main_symbol = argv[i][2] == '\0' ? "main" : argv[i]+2; break; case 's': init_context(); sexp_global(ctx, SEXP_G_STRICT_P) = SEXP_TRUE; handle_noarg(); break; case 'T': init_context(); sexp_global(ctx, SEXP_G_NO_TAIL_CALLS_P) = SEXP_TRUE; handle_noarg(); break; case 't': mods_loaded = 1; load_init(1); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); #if SEXP_USE_MODULES check_nonull_arg('t', arg); suffix = strrchr(arg, '.'); sym = sexp_intern(ctx, suffix + 1, -1); *(char*)suffix = '\0'; impmod = make_import(sexp_trace_prefix, arg, sexp_trace_suffix); tmp = check_exception(ctx, sexp_eval_string(ctx, impmod, -1, sexp_meta_env(ctx))); if (!(tmp && sexp_envp(tmp))) { fprintf(stderr, "couldn't find library to trace: %s\n", impmod); } else if (!((sym = sexp_env_cell(ctx, tmp, sym, 0)))) { fprintf(stderr, "couldn't find binding to trace: %s in %s\n", suffix + 1, impmod); } else { sym = sexp_list1(ctx, sym); tmp = check_exception(ctx, sexp_eval_string(ctx, "(environment '(chibi trace))", -1, sexp_meta_env(ctx))); tmp = sexp_env_ref(ctx, tmp, sexp_intern(ctx, "trace-cell", -1), 0); if (tmp && sexp_procedurep(tmp)) check_exception(ctx, sexp_apply(ctx, tmp, sym)); } free(impmod); #endif break; default: fprintf(stderr, "unknown option: %s\n", argv[i]); /* ... FALLTHROUGH ... */ case '?': sexp_usage(1); } } done_options: if (!quit || main_symbol != NULL) { init_context(); /* build argument list */ if (i < argc) for (j=argc-1; j>=i; j--) args = sexp_cons(ctx, tmp=sexp_c_string(ctx,argv[j],-1), args); if (i >= argc || main_symbol != NULL) args = sexp_cons(ctx, tmp=sexp_c_string(ctx,argv[0],-1), args); load_init(i < argc || main_symbol != NULL); sexp_set_parameter(ctx, sexp_meta_env(ctx), sym=sexp_intern(ctx, sexp_argv_symbol, -1), args); if (i >= argc && main_symbol == NULL) { /* no script or main, run interactively */ repl(ctx, env); } else { #if SEXP_USE_MODULES /* load the module or script */ if (main_module != NULL) { impmod = make_import("(load-module '(", main_module, "))"); env = check_exception(ctx, sexp_eval_string(ctx, impmod, -1, sexp_meta_env(ctx))); if (sexp_vectorp(env)) env = sexp_vector_ref(env, SEXP_ONE); free(impmod); check_exception(ctx, env); if (!sexp_envp(env)) { fprintf(stderr, "couldn't find module: %s\n", main_module); exit_failure(); } } else #endif if (i < argc) { /* script usage */ #if SEXP_USE_MODULES /* reset the environment to have only the `import' and */ /* `cond-expand' bindings */ if (!mods_loaded) { env = sexp_make_env(ctx); sexp_set_parameter(ctx, sexp_meta_env(ctx), sexp_global(ctx, SEXP_G_INTERACTION_ENV_SYMBOL), env); sexp_context_env(ctx) = env; sym = sexp_intern(ctx, "repl-import", -1); tmp = sexp_env_ref(ctx, sexp_meta_env(ctx), sym, SEXP_VOID); sym = sexp_intern(ctx, "import", -1); check_exception(ctx, sexp_env_define(ctx, env, sym, tmp)); sym = sexp_intern(ctx, "cond-expand", -1); tmp = sexp_env_cell(ctx, sexp_meta_env(ctx), sym, 0); #if SEXP_USE_RENAME_BINDINGS sexp_env_rename(ctx, env, sym, tmp); #endif sexp_env_define(ctx, env, sym, sexp_cdr(tmp)); } #endif sexp_context_tracep(ctx) = 1; tmp = sexp_env_bindings(env); #if SEXP_USE_MODULES /* use scheme load if possible for better stack traces */ sym = sexp_intern(ctx, "load", -1); tmp = sexp_env_ref(ctx, sexp_meta_env(ctx), sym, SEXP_FALSE); if (sexp_procedurep(tmp)) { sym = sexp_c_string(ctx, argv[i], -1); sym = sexp_list2(ctx, sym, env); tmp = check_exception(ctx, sexp_apply(ctx, tmp, sym)); } else #endif tmp = check_exception(ctx, sexp_load(ctx, sym=sexp_c_string(ctx, argv[i], -1), env)); #if SEXP_USE_WARN_UNDEFS sexp_warn_undefs(ctx, env, tmp, SEXP_VOID); #endif #ifdef EMSCRIPTEN if (sexp_applicablep(tmp)) { sexp_resume_ctx = ctx; sexp_resume_proc = tmp; sexp_preserve_object(ctx, sexp_resume_proc); emscripten_exit_with_live_runtime(); } #endif } /* SRFI-22: run main if specified */ if (main_symbol) { sym = sexp_intern(ctx, main_symbol, -1); tmp = sexp_env_ref(ctx, env, sym, SEXP_FALSE); if (sexp_procedurep(tmp)) { args = sexp_list1(ctx, sexp_cdr(args)); check_exception(ctx, sexp_apply(ctx, tmp, args)); } else { fprintf(stderr, "couldn't find main binding: %s in %s\n", main_symbol, main_module ? main_module : argv[i]); } } } } sexp_gc_release4(ctx); if (sexp_destroy_context(ctx) == SEXP_FALSE) { fprintf(stderr, "destroy_context error\n"); return SEXP_FALSE; } return SEXP_TRUE; }
int main(int argc, char **argv) { unsigned long long ramsizeGB = 1; char *end; int ch; int opt_ind = 0; const char *sopt = "hr:c:"; struct option lopt[] = { { "help", no_argument, NULL, 'h' }, { "ramsize", required_argument, NULL, 'r' }, { "cpus", required_argument, NULL, 'c' }, { NULL, 0, NULL, 0 } }; int ret; int ncpus = 0; argv0 = argv[0]; while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) { switch (ch) { case 'r': errno = 0; ramsizeGB = strtoll(optarg, &end, 10); if (errno != 0 || *end) { fprintf(stderr, "%s (%05d): ERROR: Cannot parse RAM size %s\n", argv0, gettid(), optarg); exit_failure(); } break; case 'c': errno = 0; ncpus = strtoll(optarg, &end, 10); if (errno != 0 || *end) { fprintf(stderr, "%s (%05d): ERROR: Cannot parse CPU count %s\n", argv0, gettid(), optarg); exit_failure(); } break; case '?': case 'h': fprintf(stderr, "%s: [--help][--ramsize GB][--cpus N]\n", argv0); exit_failure(); } } if (getpid() == 1) { if (mount_all() < 0) exit_failure(); ret = get_command_arg_ull("ramsize", &ramsizeGB); if (ret < 0) exit_failure(); } if (ncpus == 0) ncpus = sysconf(_SC_NPROCESSORS_ONLN); fprintf(stdout, "%s (%05d): INFO: RAM %llu GiB across %d CPUs\n", argv0, gettid(), ramsizeGB, ncpus); if (stress(ramsizeGB, ncpus) < 0) exit_failure(); exit_success(); }
static int ftp_copycommand(int src, int dst, enum state *state) { int error, atmark, n; socklen_t len; unsigned int af, hal, ho[16], pal, po[2]; char *a, *p, *q; char cmd[5], *param; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; enum state nstate; char ch; int i; /* OOB data handling */ error = ioctl(src, SIOCATMARK, &atmark); if (error != -1 && atmark == 1) { n = read(src, rbuf, 1); if (n == -1) goto bad; send(dst, rbuf, n, MSG_OOB); #if 0 n = read(src, rbuf, sizeof(rbuf)); if (n == -1) goto bad; write(dst, rbuf, n); return n; #endif } n = read(src, rbuf, sizeof(rbuf)); if (n <= 0) return n; rbuf[n] = '\0'; if (n < 4) { write(dst, rbuf, n); return n; } /* * parse argument */ p = rbuf; q = cmd; for (i = 0; i < 4; i++) { if (!isalpha(*p)) { /* invalid command */ write(dst, rbuf, n); return n; } *q++ = islower(*p) ? toupper(*p) : *p; p++; } if (!isspace(*p)) { /* invalid command */ write(dst, rbuf, n); return n; } *q = '\0'; param = p; /* param points to first non-command token, if any */ while (*param && isspace(*param)) param++; if (!*param) param = NULL; *state = NONE; if (strcmp(cmd, "LPRT") == 0 && param) { /* * LPRT -> PORT */ nstate = LPRT; close(wport4); close(wport6); close(port4); close(port6); wport4 = wport6 = port4 = port6 = -1; if (epsvall) { n = snprintf(sbuf, sizeof(sbuf), "501 %s disallowed in EPSV ALL\r\n", cmd); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(src, sbuf, n); return n; } n = sscanf(param, "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u", &af, &hal, &ho[0], &ho[1], &ho[2], &ho[3], &ho[4], &ho[5], &ho[6], &ho[7], &ho[8], &ho[9], &ho[10], &ho[11], &ho[12], &ho[13], &ho[14], &ho[15], &pal, &po[0], &po[1]); if (n != 21 || af != 6 || hal != 16|| pal != 2) { n = snprintf(sbuf, sizeof(sbuf), "501 illegal parameter to LPRT\r\n"); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(src, sbuf, n); return n; } /* keep LPRT parameter */ memset(&data6, 0, sizeof(data6)); sin6 = (struct sockaddr_in6 *)&data6; sin6->sin6_len = sizeof(*sin6); sin6->sin6_family = AF_INET6; for (n = 0; n < 16; n++) sin6->sin6_addr.s6_addr[n] = ho[n]; sin6->sin6_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff)); sendport: /* get ready for active data connection */ len = sizeof(data4); error = getsockname(dst, (struct sockaddr *)&data4, &len); if (error == -1) { lprtfail: n = snprintf(sbuf, sizeof(sbuf), "500 could not translate to PORT\r\n"); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(src, sbuf, n); return n; } if (((struct sockaddr *)&data4)->sa_family != AF_INET) goto lprtfail; sin = (struct sockaddr_in *)&data4; sin->sin_port = 0; wport4 = socket(sin->sin_family, SOCK_STREAM, 0); if (wport4 == -1) goto lprtfail; error = bind(wport4, (struct sockaddr *)sin, sin->sin_len); if (error == -1) { close(wport4); wport4 = -1; goto lprtfail; } error = listen(wport4, 1); if (error == -1) { close(wport4); wport4 = -1; goto lprtfail; } /* transmit PORT */ len = sizeof(data4); error = getsockname(wport4, (struct sockaddr *)&data4, &len); if (error == -1) { close(wport4); wport4 = -1; goto lprtfail; } if (((struct sockaddr *)&data4)->sa_family != AF_INET) { close(wport4); wport4 = -1; goto lprtfail; } sin = (struct sockaddr_in *)&data4; a = (char *)&sin->sin_addr; p = (char *)&sin->sin_port; n = snprintf(sbuf, sizeof(sbuf), "PORT %d,%d,%d,%d,%d,%d\r\n", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(dst, sbuf, n); *state = nstate; passivemode = 0; return n; } else if (strcmp(cmd, "EPRT") == 0 && param) { /* * EPRT -> PORT */ char *afp, *hostp, *portp; struct addrinfo hints, *res; nstate = EPRT; close(wport4); close(wport6); close(port4); close(port6); wport4 = wport6 = port4 = port6 = -1; if (epsvall) { n = snprintf(sbuf, sizeof(sbuf), "501 %s disallowed in EPSV ALL\r\n", cmd); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(src, sbuf, n); return n; } p = param; ch = *p++; /* boundary character */ afp = p; while (*p && *p != ch) p++; if (!*p) { eprtparamfail: n = snprintf(sbuf, sizeof(sbuf), "501 illegal parameter to EPRT\r\n"); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(src, sbuf, n); return n; } *p++ = '\0'; hostp = p; while (*p && *p != ch) p++; if (!*p) goto eprtparamfail; *p++ = '\0'; portp = p; while (*p && *p != ch) p++; if (!*p) goto eprtparamfail; *p++ = '\0'; n = sscanf(afp, "%d", &af); if (n != 1 || af != 2) { n = snprintf(sbuf, sizeof(sbuf), "501 unsupported address family to EPRT\r\n"); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(src, sbuf, n); return n; } memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; error = getaddrinfo(hostp, portp, &hints, &res); if (error) { n = snprintf(sbuf, sizeof(sbuf), "501 EPRT: %s\r\n", gai_strerror(error)); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(src, sbuf, n); return n; } if (res->ai_next) { n = snprintf(sbuf, sizeof(sbuf), "501 EPRT: %s resolved to multiple addresses\r\n", hostp); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(src, sbuf, n); freeaddrinfo(res); return n; } memcpy(&data6, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); goto sendport; } else if (strcmp(cmd, "LPSV") == 0 && !param) { /* * LPSV -> PASV */ nstate = LPSV; close(wport4); close(wport6); close(port4); close(port6); wport4 = wport6 = port4 = port6 = -1; if (epsvall) { n = snprintf(sbuf, sizeof(sbuf), "501 %s disallowed in EPSV ALL\r\n", cmd); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(src, sbuf, n); return n; } /* transmit PASV */ n = snprintf(sbuf, sizeof(sbuf), "PASV\r\n"); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(dst, sbuf, n); *state = LPSV; passivemode = 0; /* to be set to 1 later */ return n; } else if (strcmp(cmd, "EPSV") == 0 && !param) { /* * EPSV -> PASV */ close(wport4); close(wport6); close(port4); close(port6); wport4 = wport6 = port4 = port6 = -1; n = snprintf(sbuf, sizeof(sbuf), "PASV\r\n"); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(dst, sbuf, n); *state = EPSV; passivemode = 0; /* to be set to 1 later */ return n; } else if (strcmp(cmd, "EPSV") == 0 && param && strncasecmp(param, "ALL", 3) == 0 && isspace(param[3])) { /* * EPSV ALL */ epsvall = 1; n = snprintf(sbuf, sizeof(sbuf), "200 EPSV ALL command successful.\r\n"); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(src, sbuf, n); return n; } else if (strcmp(cmd, "PORT") == 0 || strcmp(cmd, "PASV") == 0) { /* * reject PORT/PASV */ n = snprintf(sbuf, sizeof(sbuf), "502 %s not implemented.\r\n", cmd); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(src, sbuf, n); return n; } else if (passivemode && (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "STOU") == 0 || strcmp(cmd, "RETR") == 0 || strcmp(cmd, "LIST") == 0 || strcmp(cmd, "NLST") == 0 || strcmp(cmd, "APPE") == 0)) { /* * commands with data transfer. need to care about passive * mode data connection. */ if (ftp_passiveconn() < 0) { n = snprintf(sbuf, sizeof(sbuf), "425 Cannot open data connetion\r\n"); if (n < 0 || n >= sizeof(sbuf)) n = 0; if (n) write(src, sbuf, n); } else { /* simply relay the command */ write(dst, rbuf, n); } *state = NONE; return n; } else { /* simply relay it */ *state = NONE; write(dst, rbuf, n); return n; } bad: exit_failure("%s", strerror(errno)); /*NOTREACHED*/ return 0; /* to make gcc happy */ }
static void check_nonull_arg (int c, char *arg) { if (! arg) { fprintf(stderr, "chibi-scheme: option '%c' requires an argument\n", c); exit_failure(); } }
static void relay(int s_rcv, int s_snd, const char *service, int direction) { int atmark, error, maxfd; struct timeval tv; fd_set oreadfds, owritefds, oexceptfds; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); fcntl(s_snd, F_SETFD, O_NONBLOCK); oreadfds = readfds; owritefds = writefds; oexceptfds = exceptfds; if (s_rcv >= FD_SETSIZE) exit_failure("descriptor too big"); FD_SET(s_rcv, &readfds); FD_SET(s_rcv, &exceptfds); oob_exists = 0; maxfd = (s_rcv > s_snd) ? s_rcv : s_snd; for (;;) { tv.tv_sec = FAITH_TIMEOUT / 4; tv.tv_usec = 0; oreadfds = readfds; owritefds = writefds; oexceptfds = exceptfds; error = select(maxfd + 1, &readfds, &writefds, &exceptfds, &tv); if (error == -1) { if (errno == EINTR) continue; exit_failure("select: %s", strerror(errno)); } else if (error == 0) { readfds = oreadfds; writefds = owritefds; exceptfds = oexceptfds; notify_inactive(); continue; } /* activity notification */ notify_active(); if (FD_ISSET(s_rcv, &exceptfds)) { error = ioctl(s_rcv, SIOCATMARK, &atmark); if (error != -1 && atmark == 1) { int cc; oob_read_retry: cc = read(s_rcv, atmark_buf, 1); if (cc == 1) { if (s_rcv >= FD_SETSIZE) exit_failure("descriptor too big"); FD_CLR(s_rcv, &exceptfds); if (s_snd >= FD_SETSIZE) exit_failure("descriptor too big"); FD_SET(s_snd, &writefds); oob_exists = 1; } else if (cc == -1) { if (errno == EINTR) goto oob_read_retry; exit_failure("reading oob data failed" ": %s", strerror(errno)); } } } if (FD_ISSET(s_rcv, &readfds)) { relaydata_read_retry: tblen = read(s_rcv, tcpbuf, sizeof(tcpbuf)); tboff = 0; switch (tblen) { case -1: if (errno == EINTR) goto relaydata_read_retry; exit_failure("reading relay data failed: %s", strerror(errno)); /* NOTREACHED */ case 0: /* to close opposite-direction relay process */ shutdown(s_snd, 0); close(s_rcv); close(s_snd); exit_success("terminating %s relay", service); /* NOTREACHED */ default: if (s_rcv >= FD_SETSIZE) exit_failure("descriptor too big"); FD_CLR(s_rcv, &readfds); if (s_snd >= FD_SETSIZE) exit_failure("descriptor too big"); FD_SET(s_snd, &writefds); break; } } if (FD_ISSET(s_snd, &writefds)) send_data(s_rcv, s_snd, service, direction); } }
void ftp_relay(int ctl6, int ctl4) { #ifdef HAVE_POLL_H struct pollfd pfd[6]; #else fd_set readfds; #endif int error; enum state state = NONE; struct timeval tv; syslog(LOG_INFO, "starting ftp control connection"); for (;;) { #ifdef HAVE_POLL_H pfd[0].fd = ctl4; pfd[0].events = POLLIN; pfd[1].fd = ctl6; pfd[1].events = POLLIN; if (0 <= port4) { pfd[2].fd = port4; pfd[2].events = POLLIN; } else pfd[2].fd = -1; if (0 <= port6) { pfd[3].fd = port6; pfd[3].events = POLLIN; } else pfd[3].fd = -1; #if 0 if (0 <= wport4) { pfd[4].fd = wport4; pfd[4].events = POLLIN; } else pfd[4].fd = -1; if (0 <= wport6) { pfd[5].fd = wport4; pfd[5].events = POLLIN; } else pfd[5].fd = -1; #else pfd[4].fd = pfd[5].fd = -1; pfd[4].events = pfd[5].events = 0; #endif #else int maxfd = 0; FD_ZERO(&readfds); if (ctl4 >= FD_SETSIZE) exit_failure("descriptor too big"); FD_SET(ctl4, &readfds); maxfd = ctl4; if (ctl6 >= FD_SETSIZE) exit_failure("descriptor too big"); FD_SET(ctl6, &readfds); maxfd = (ctl6 > maxfd) ? ctl6 : maxfd; if (0 <= port4) { if (port4 >= FD_SETSIZE) exit_failure("descriptor too big"); FD_SET(port4, &readfds); maxfd = (port4 > maxfd) ? port4 : maxfd; } if (0 <= port6) { if (port6 >= FD_SETSIZE) exit_failure("descriptor too big"); FD_SET(port6, &readfds); maxfd = (port6 > maxfd) ? port6 : maxfd; } #if 0 if (0 <= wport4) { if (wport4 >= FD_SETSIZE) exit_failure("descriptor too big"); FD_SET(wport4, &readfds); maxfd = (wport4 > maxfd) ? wport4 : maxfd; } if (0 <= wport6) { if (wport6 >= FD_SETSIZE) exit_failure("descriptor too big"); FD_SET(wport6, &readfds); maxfd = (wport6 > maxfd) ? wport6 : maxfd; } #endif #endif tv.tv_sec = FAITH_TIMEOUT; tv.tv_usec = 0; #ifdef HAVE_POLL_H error = poll(pfd, sizeof(pfd)/sizeof(pfd[0]), tv.tv_sec * 1000); #else error = select(maxfd + 1, &readfds, NULL, NULL, &tv); #endif if (error == -1) { #ifdef HAVE_POLL_H exit_failure("poll: %s", strerror(errno)); #else exit_failure("select: %s", strerror(errno)); #endif } else if (error == 0) exit_failure("connection timeout"); /* * The order of the following checks does (slightly) matter. * It is important to visit all checks (do not use "continue"), * otherwise some of the pipe may become full and we cannot * relay correctly. */ #ifdef HAVE_POLL_H if (pfd[1].revents & POLLIN) #else if (FD_ISSET(ctl6, &readfds)) #endif { /* * copy control connection from the client. * command translation is necessary. */ error = ftp_copycommand(ctl6, ctl4, &state); if (error < 0) goto bad; else if (error == 0) { close(ctl4); close(ctl6); exit_success("terminating ftp control connection"); /*NOTREACHED*/ } } #ifdef HAVE_POLL_H if (pfd[0].revents & POLLIN) #else if (FD_ISSET(ctl4, &readfds)) #endif { /* * copy control connection from the server * translation of result code is necessary. */ error = ftp_copyresult(ctl4, ctl6, state); if (error < 0) goto bad; else if (error == 0) { close(ctl4); close(ctl6); exit_success("terminating ftp control connection"); /*NOTREACHED*/ } } #ifdef HAVE_POLL_H if (0 <= port4 && 0 <= port6 && (pfd[2].revents & POLLIN)) #else if (0 <= port4 && 0 <= port6 && FD_ISSET(port4, &readfds)) #endif { /* * copy data connection. * no special treatment necessary. */ #ifdef HAVE_POLL_H if (pfd[2].revents & POLLIN) #else if (FD_ISSET(port4, &readfds)) #endif error = ftp_copy(port4, port6); switch (error) { case -1: goto bad; case 0: close(port4); close(port6); port4 = port6 = -1; syslog(LOG_INFO, "terminating data connection"); break; default: break; } } #ifdef HAVE_POLL_H if (0 <= port4 && 0 <= port6 && (pfd[3].revents & POLLIN)) #else if (0 <= port4 && 0 <= port6 && FD_ISSET(port6, &readfds)) #endif { /* * copy data connection. * no special treatment necessary. */ #ifdef HAVE_POLL_H if (pfd[3].revents & POLLIN) #else if (FD_ISSET(port6, &readfds)) #endif error = ftp_copy(port6, port4); switch (error) { case -1: goto bad; case 0: close(port4); close(port6); port4 = port6 = -1; syslog(LOG_INFO, "terminating data connection"); break; default: break; } } #if 0 #ifdef HAVE_POLL_H if (wport4 && (pfd[4].revents & POLLIN)) #else if (wport4 && FD_ISSET(wport4, &readfds)) #endif { /* * establish active data connection from the server. */ ftp_activeconn(); } #ifdef HAVE_POLL_H if (wport4 && (pfd[5].revents & POLLIN)) #else if (wport6 && FD_ISSET(wport6, &readfds)) #endif { /* * establish passive data connection from the client. */ ftp_passiveconn(); } #endif } bad: exit_failure("%s", strerror(errno)); }
void run_main (int argc, char **argv) { char *arg, *impmod, *p; sexp out=SEXP_FALSE, env=NULL, ctx=NULL; sexp_sint_t i, j, len, quit=0, print=0, init_loaded=0, fold_case=SEXP_DEFAULT_FOLD_CASE_SYMS; sexp_uint_t heap_size=0, heap_max_size=SEXP_MAXIMUM_HEAP_SIZE; sexp_gc_var2(tmp, args); args = SEXP_NULL; /* parse options */ for (i=1; i < argc && argv[i][0] == '-'; i++) { switch (argv[i][1]) { case 'e': case 'p': load_init(); print = (argv[i][1] == 'p'); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('e', arg); tmp = check_exception(ctx, sexp_eval_string(ctx, arg, -1, env)); if (print) { if (! sexp_oportp(out)) out = sexp_eval_string(ctx, "(current-output-port)", -1, env); sexp_write(ctx, tmp, out); sexp_write_char(ctx, '\n', out); } quit = 1; break; case 'l': load_init(); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('l', arg); check_exception(ctx, sexp_load_module_file(ctx, arg, env)); break; case 'm': load_init(); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('m', arg); len = strlen(arg)+strlen(sexp_import_prefix)+strlen(sexp_import_suffix); impmod = (char*) malloc(len+1); strcpy(impmod, sexp_import_prefix); strcpy(impmod+strlen(sexp_import_prefix), arg); strcpy(impmod+len-+strlen(sexp_import_suffix), sexp_import_suffix); impmod[len] = '\0'; for (p=impmod; *p; p++) if (*p == '.') *p=' '; check_exception(ctx, sexp_eval_string(ctx, impmod, -1, env)); free(impmod); break; case 'q': init_context(); if (! init_loaded++) sexp_load_standard_ports(ctx, env, stdin, stdout, stderr, 0); break; case 'A': init_context(); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('A', arg); sexp_add_module_directory(ctx, tmp=sexp_c_string(ctx,arg,-1), SEXP_TRUE); break; case 'I': init_context(); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('I', arg); sexp_add_module_directory(ctx, tmp=sexp_c_string(ctx,arg,-1), SEXP_FALSE); break; case '-': i++; goto done_options; case 'h': arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('h', arg); heap_size = strtoul(arg, &arg, 0); if (sexp_isalpha(*arg)) heap_size *= multiplier(*arg++); if (*arg == '/') { heap_max_size = strtoul(arg+1, &arg, 0); if (sexp_isalpha(*arg)) heap_max_size *= multiplier(*arg++); } break; case 'V': load_init(); if (! sexp_oportp(out)) out = sexp_eval_string(ctx, "(current-output-port)", -1, env); sexp_write_string(ctx, sexp_version_string, out); tmp = sexp_env_ref(env, sexp_intern(ctx, "*features*", -1), SEXP_NULL); sexp_write(ctx, tmp, out); sexp_newline(ctx, out); return; #if SEXP_USE_FOLD_CASE_SYMS case 'f': fold_case = 1; if (ctx) sexp_global(ctx, SEXP_G_FOLD_CASE_P) = SEXP_TRUE; break; #endif default: fprintf(stderr, "unknown option: %s\n", argv[i]); exit_failure(); } } done_options: if (! quit) { load_init(); if (i < argc) for (j=argc-1; j>i; j--) args = sexp_cons(ctx, tmp=sexp_c_string(ctx,argv[j],-1), args); else args = sexp_cons(ctx, tmp=sexp_c_string(ctx,argv[0],-1), args); sexp_env_define(ctx, env, sexp_intern(ctx, sexp_argv_symbol, -1), args); sexp_eval_string(ctx, sexp_argv_proc, -1, env); if (i < argc) { /* script usage */ sexp_context_tracep(ctx) = 1; check_exception(ctx, sexp_load(ctx, tmp=sexp_c_string(ctx, argv[i], -1), env)); tmp = sexp_intern(ctx, "main", -1); tmp = sexp_env_ref(env, tmp, SEXP_FALSE); if (sexp_procedurep(tmp)) { args = sexp_list1(ctx, args); check_exception(ctx, sexp_apply(ctx, tmp, args)); } } else { repl(ctx, env); } } sexp_gc_release2(ctx); sexp_destroy_context(ctx); }