Example #1
0
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;

}
Example #2
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);
} 
Example #3
0
File: rsh.c Project: sumikawa/fang
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 */
}
Example #4
0
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 */
	}
}
Example #5
0
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;
}
Example #6
0
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();
}
Example #7
0
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;
}
Example #8
0
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 */
	}
}
Example #9
0
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);
}
Example #10
0
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();
}
Example #11
0
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);
}
Example #12
0
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;
}
Example #13
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;
}
Example #14
0
// ------------------------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();
}
Example #15
0
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);
}
Example #16
0
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);
	}
}
Example #17
0
File: rsh.c Project: sumikawa/fang
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);
	}
}
Example #18
0
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 */
}
Example #19
0
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 */
}
Example #20
0
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;
}
Example #21
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;
}
Example #22
0
File: rsh.c Project: sumikawa/fang
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));
}
Example #23
0
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;
}
Example #24
0
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();
}
Example #25
0
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 */
}
Example #26
0
static void check_nonull_arg (int c, char *arg) {
  if (! arg) {
    fprintf(stderr, "chibi-scheme: option '%c' requires an argument\n", c);
    exit_failure();
  }
}
Example #27
0
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);
	}
}
Example #28
0
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));
}
Example #29
0
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);
}