示例#1
0
VmsatCase::VmsatCase(std::istream& is)
{
    // Record start of case description in stream for error feedback
  this->case_pos0 = is.tellg();
    // Read one token at a time skipping to EOL when encountering a
    // comment.  Push the token into a vector buffer for processing of
    // each major "input block"
  bool parsing_block {false};
  std::vector<std::string> input_block;
  CaseKeyWord kw_ndx = CaseKeyWord::NONE;
  std::string token;
  while (this->valid  &&  (is >> token)) {
    if (token.front() == '#') {
      // If this is a comment, read until EOL
      char ch;
      do {
        if (!is.get(ch)) return;
      } while (ch != '\n'  && ch != '\r');
    } else if (/*{*/ token == "}" && parsing_block) {
      // End of a block encountered - process
      try {
        this->parse_keyword_block(kw_ndx, input_block);
      } catch (std::invalid_argument &ia) {
        reset_stream(is);
        this->err_pos = is.tellg();
        this->valid = false;
      }
      input_block.clear();
      parsing_block = false;
    } else if (!parsing_block) {
      // Expecting a keyword followed by an opening bracket
      this->etoken = token;
      try {
        this->err_pos0 = is.tellg();
        kw_ndx = keyword_table.at(token);
        std::string start_bracket;
        is >> start_bracket;
        if (start_bracket == "{" /*}*/) {
          parsing_block = true;
        } else {
          std::cerr << '\n' << "Expecting end bracket, not " << token << '\n';
          reset_stream(is);
          this->err_pos = is.tellg();
          this->valid = false;
        }
      } catch(std::out_of_range &oor) {
        std::cerr << '\n' << "Not a keyword: " << token << '\n';
        reset_stream(is);
        this->err_pos = is.tellg();
        this->valid = false;
      } catch (std::exception &e) {
        reset_stream(is);
        this->err_pos = is.tellg();
        this->valid = false;
      }
    } else if (parsing_block) {
/**
 * Functions of this signature are called whenever we transmitted a
 * query via a stream.
 *
 * @param cls the struct StreamHandle for which we did the write call
 * @param status the status of the stream at the time this function is called;
 *          GNUNET_OK if writing to stream was completed successfully,
 *          GNUNET_STREAM_SHUTDOWN if the stream is shutdown for writing in the
 *          mean time.
 * @param size the number of bytes written
 */
static void
query_write_continuation (void *cls,
			  enum GNUNET_STREAM_Status status,
			  size_t size)
{
  struct StreamHandle *sh = cls;

  sh->wh = NULL;
  if ( (GNUNET_STREAM_OK != status) ||
       (sizeof (struct StreamQueryMessage) != size) )
  {
    reset_stream (sh);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Successfully transmitted %u bytes via stream to %s\n",
	      (unsigned int) size,
	      GNUNET_i2s (&sh->target));
  if (NULL == sh->rh)
    sh->rh = GNUNET_STREAM_read (sh->stream,
				 GNUNET_TIME_UNIT_FOREVER_REL,
				 &handle_stream_reply,
				 sh);
  transmit_pending (sh);
}
示例#3
0
文件: json.c 项目: chrisnorman7/stunt
/* Append type information. */
static const char *
append_type(const char *str, var_type type)
{
    static Stream *stream = NULL;
    if (NULL == stream)
	stream = new_stream(20);
    stream_add_string(stream, str);
    switch (type) {
    case TYPE_OBJ:
	stream_add_string(stream, "|obj");
	break;
    case TYPE_INT:
	stream_add_string(stream, "|int");
	break;
    case TYPE_FLOAT:
	stream_add_string(stream, "|float");
	break;
    case TYPE_ERR:
	stream_add_string(stream, "|err");
	break;
    case TYPE_STR:
	stream_add_string(stream, "|str");
	break;
    default:
	panic("Unsupported type in append_type()");
    }
    return reset_stream(stream);
}
示例#4
0
文件: db_io.c 项目: zelch/LambdaMOO
const char *
dbio_read_string(void)
{
    static Stream *str = 0;
    static char buffer[1024];
    int len, used_stream = 0;

    if (str == 0)
	str = new_stream(1024);

  try_again:
    fgets(buffer, sizeof(buffer), input);
    len = strlen(buffer);
    if (len == sizeof(buffer) - 1 && buffer[len - 1] != '\n') {
	stream_add_string(str, buffer);
	used_stream = 1;
	goto try_again;
    }
    if (buffer[len - 1] == '\n')
	buffer[len - 1] = '\0';

    if (used_stream) {
	stream_add_string(str, buffer);
	return reset_stream(str);
    } else
	return buffer;
}
enum proto_accept_error
proto_accept_connection(int listener_fd, int *read_fd, int *write_fd,
			const char **name)
{
    int timeout = server_int_option("name_lookup_timeout", 5);
    int fd;
    struct sockaddr_in address;
    size_t addr_length = sizeof(address);
    static Stream *s = 0;

    if (!s)
	s = new_stream(100);

    fd = accept(listener_fd, (struct sockaddr *) &address, &addr_length);
    if (fd < 0) {
	if (errno == EMFILE)
	    return PA_FULL;
	else {
	    log_perror("Accepting new network connection");
	    return PA_OTHER;
	}
    }
    *read_fd = *write_fd = fd;
    stream_printf(s, "%s, port %d",
		  lookup_name_from_addr(&address, timeout),
		  (int) ntohs(address.sin_port));
    *name = reset_stream(s);
    return PA_OKAY;
}
示例#6
0
static int
pull_input(nhandle * h)
{
    Stream *s = h->input;
    int count;
    char buffer[1024];
    char *ptr, *end;

    ptr = buffer;
    if (h->excess_utf_count) {
        memcpy(buffer, h->excess_utf, h->excess_utf_count);
        ptr += h->excess_utf_count;
    }

    if ((count = read(h->rfd, ptr, sizeof(buffer) - h->excess_utf_count)) > 0) {
	if (h->binary) {
	    stream_add_string(s, raw_bytes_to_binary(buffer, count));
	    server_receive_line(h->shandle, reset_stream(s));
	    h->last_input_was_CR = 0;
            h->excess_utf_count = 0;
	} else {
	    for (ptr = buffer, end = buffer + count; ptr < end && ptr + clearance_utf(*ptr) <= end;) {
		int c = get_utf((const char **)&ptr);

		if (my_is_printable(c))
		    stream_add_utf(s, c);
#ifdef INPUT_APPLY_BACKSPACE
		else if (c == 0x08 || c == 0x7F)
		    stream_delete_utf(s);
#endif
		else if (c == '\r' || (c == '\n' && !h->last_input_was_CR))
		    server_receive_line(h->shandle, reset_stream(s));

		h->last_input_was_CR = (c == '\r');
	    }
            if (ptr < end)
            {
                h->excess_utf_count = end - ptr;
                memcpy(h->excess_utf, ptr, end - ptr);
            }
            h->excess_utf_count = end - ptr;
	}
	return 1;
    } else
	return (count == 0 && !proto.believe_eof)
	    || (count < 0 && (errno == eagain || errno == ewouldblock));
}
示例#7
0
static void
finish_insn(Stream * s, Stream * insn)
{
    while (bytes_width--)
	stream_add_string(s, "    ");
    stream_add_string(s, reset_stream(insn));
    output(s);
}
示例#8
0
文件: json.c 项目: chrisnorman7/stunt
static const char *
value_to_literal(Var v)
{
    static Stream *s = NULL;
    if (!s)
	s = new_stream(100);
    unparse_value(s, v);
    return reset_stream(s);
}
/**
 * Task called when it is time to reset an stream.
 *
 * @param cls the 'struct StreamHandle' to tear down
 * @param tc scheduler context, unused
 */
static void
reset_stream_task (void *cls,
		   const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct StreamHandle *sh = cls;

  sh->reset_task = GNUNET_SCHEDULER_NO_TASK;
  reset_stream (sh);
}
示例#10
0
enum error
proto_make_listener(Var desc, int *fd, Var * canon, const char **name)
{
    struct sockaddr_in address;
    int s, port, option = 1;
    static Stream *st = 0;

    if (!st)
	st = new_stream(20);

    if (desc.type != TYPE_INT)
	return E_TYPE;

    port = desc.v.num;
    s = socket(AF_INET, SOCK_STREAM, 0);
    if (s < 0) {
	log_perror("Creating listening socket");
	return E_QUOTA;
    }
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
		   (char *) &option, sizeof(option)) < 0) {
	log_perror("Setting listening socket options");
	close(s);
	return E_QUOTA;
    }
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = bind_local_ip;
    address.sin_port = htons(port);
    if (bind(s, (struct sockaddr *) &address, sizeof(address)) < 0) {
	enum error e = E_QUOTA;

	log_perror("Binding listening socket");
	if (errno == EACCES)
	    e = E_PERM;
	close(s);
	return e;
    }
    if (port == 0) {
	size_t length = sizeof(address);

	if (getsockname(s, (struct sockaddr *) &address, &length) < 0) {
	    log_perror("Discovering local port number");
	    close(s);
	    return E_QUOTA;
	}
	canon->type = TYPE_INT;
	canon->v.num = ntohs(address.sin_port);
    } else
	*canon = var_ref(desc);

    stream_printf(st, "port %d", canon->v.num);
    *name = reset_stream(st);

    *fd = s;
    return E_NONE;
}
示例#11
0
static const char *
fmt_verb_name(void *data)
{
    db_verb_handle *h = data;
    static Stream *s = 0;

    if (!s)
	s = new_stream(40);

    stream_printf(s, "#%d:%s", db_verb_definer(*h), db_verb_names(*h));
    return reset_stream(s);
}
示例#12
0
/******************************************************************************
 * @brief    Write output data and convert units if necessary.
 *****************************************************************************/
void
write_output(stream_struct **streams,
             dmy_struct     *dmy)
{
    extern option_struct options;

    size_t               stream_idx;

    // Write data
    for (stream_idx = 0; stream_idx < options.Noutstreams; stream_idx++) {
        if (raise_alarm(&(*streams)[stream_idx].agg_alarm, dmy)) {
            write_data(&((*streams)[stream_idx]), dmy);
            reset_stream((&(*streams)[stream_idx]), dmy);
        }
    }
}
示例#13
0
文件: buffer.c 项目: dmt4/ne
int delete_one_line(buffer * const b, line_desc * const ld, const int64_t line) {
	assert_line_desc(ld, b->encoding);
	assert_buffer(b);

	block_signals();

	if (ld->line_len && (b->last_deleted = reset_stream(b->last_deleted))) add_to_stream(b->last_deleted, ld->line, ld->line_len);

	/* We delete a line by delete_stream()ing its length plus one. However, if
		we are on the last line of text, there is no terminating line feed. */

	const int error = delete_stream(b, ld, line, 0, ld->line_len + (ld->ld_node.next->next ? 1 : 0));
	release_signals();

	return error;
}
示例#14
0
enum proto_accept_error
proto_accept_connection(int listener_fd, int *read_fd, int *write_fd,
			const char **name)
{
    int timeout = server_int_option("name_lookup_timeout", 5);
    int fd;
    struct sockaddr_in *addr = (struct sockaddr_in *) call->addr.buf;
    static Stream *s = 0;

    if (!s)
	s = new_stream(100);

    fd = t_open((void *) "/dev/tcp", O_RDWR, 0);
    if (fd < 0) {
	if (t_errno == TSYSERR && errno == EMFILE)
	    return PA_FULL;
	else {
	    log_ti_error("Opening endpoint for new connection");
	    return PA_OTHER;
	}
    }
    if (t_bind(fd, 0, 0) < 0) {
	log_ti_error("Binding endpoint for new connection");
	t_close(fd);
	return PA_OTHER;
    }
    if (t_listen(listener_fd, call) < 0) {
	log_ti_error("Accepting new network connection");
	t_close(fd);
	return PA_OTHER;
    }
    if (t_accept(listener_fd, fd, call) < 0) {
	log_ti_error("Accepting new network connection");
	t_close(fd);
	return PA_OTHER;
    }
    if (!set_rw_able(fd)) {
	t_close(fd);
	return PA_OTHER;
    }
    *read_fd = *write_fd = fd;
    stream_printf(s, "%s, port %d",
		  lookup_name_from_addr(addr, timeout),
		  (int) ntohs(addr->sin_port));
    *name = reset_stream(s);
    return PA_OKAY;
}
示例#15
0
static nhandle *
new_nhandle(int rfd, int wfd, const char *local_name, const char *remote_name,
	    int outbound)
{
    nhandle *h;
    static Stream *s = 0;

    if (s == 0)
	s = new_stream(100);

    if (!network_set_nonblocking(rfd)
	|| (rfd != wfd && !network_set_nonblocking(wfd)))
	log_perror("Setting connection non-blocking");

    h = (nhandle *)mymalloc(sizeof(nhandle), M_NETWORK);

    if (all_nhandles)
	all_nhandles->prev = &(h->next);
    h->next = all_nhandles;
    h->prev = &all_nhandles;
    all_nhandles = h;

    h->rfd = rfd;
    h->wfd = wfd;
    h->input = new_stream(100);
    h->last_input_was_CR = 0;
    h->input_suspended = 0;
    h->output_head = 0;
    h->output_tail = &(h->output_head);
    h->output_length = 0;
    h->output_lines_flushed = 0;
    h->outbound = outbound;
    h->binary = 0;
    h->excess_utf_count = 0;
#if NETWORK_PROTOCOL == NP_TCP
    h->client_echo = 1;
#endif

    stream_printf(s, "%s %s %s",
		  local_name, outbound ? "to" : "from", remote_name);
    h->name = str_dup(reset_stream(s));

    return h;
}
示例#16
0
static void 
finish_node(XMLdata *data)
{
  XMLdata *parent = data->parent;
  Var element = data->element;
  Var body;
  Stream *s = data->body;
  body.type = TYPE_STR;
  if(s == NULL) {
    body.v.str = str_dup("");
  } else {
    body.v.str = str_dup(reset_stream(s));
  }
  element.v.list[3] = body;
  if(parent != NULL) {
    Var pelement = parent->element;
    pelement.v.list[4] = listappend(pelement.v.list[4], var_ref(element));
  }
}
示例#17
0
static void
output(Stream * str)
{
    (*receiver) (receiver_data, reset_stream(str));
}
示例#18
0
int
network_process_io(int timeout)
{
    network_handle nh;
    static server_handle sh;
    static Stream *s = 0;
    char buffer[1024];
    int count;
    char *ptr, *end;
    int got_some = 0;

    if (s == 0) {
	int flags;

	s = new_stream(1000);

	if ((flags = fcntl(0, F_GETFL)) < 0
	    || fcntl(0, F_SETFL, flags | NONBLOCK_FLAG) < 0) {
	    log_perror("Setting standard input non-blocking");
	    return 0;
	}
    }
    switch (state) {
    case STATE_CLOSED:
	if (listening) {
	    sh = server_new_connection(slistener, nh, 0);
	    state = STATE_OPEN;
	    got_some = 1;
	} else if (timeout != 0)
	    sleep(timeout);
	break;

    case STATE_OPEN:
	for (;;) {
	    while (!input_suspended
		   && (count = read(0, buffer, sizeof(buffer))) > 0) {
		got_some = 1;
		if (binary) {
		    stream_add_string(s, raw_bytes_to_binary(buffer, count));
		    server_receive_line(sh, reset_stream(s));
		} else
		    for (ptr = buffer, end = buffer + count;
			 ptr < end;
			 ptr++) {
			unsigned char c = *ptr;

			if (isgraph(c) || c == ' ' || c == '\t')
			    stream_add_char(s, c);
			else if (c == '\n')
			    server_receive_line(sh, reset_stream(s));
		    }
	    }

	    if (got_some || timeout == 0)
		goto done;

	    sleep(1);
	    timeout--;
	}
    }

  done:
    return got_some;
}
示例#19
0
static int
dump_database(Dump_Reason reason)
{
    Stream *s = new_stream(100);
    char *temp_name;
    FILE *f;
    int success;

  retryDumping:

    stream_printf(s, "%s.#%d#", dump_db_name, dump_generation);
    remove(reset_stream(s));	/* Remove previous checkpoint */

    if (reason == DUMP_PANIC)
	stream_printf(s, "%s.PANIC", dump_db_name);
    else {
	dump_generation++;
	stream_printf(s, "%s.#%d#", dump_db_name, dump_generation);
    }
    temp_name = reset_stream(s);

    oklog("%s on %s ...\n", reason_names[reason], temp_name);

#ifdef UNFORKED_CHECKPOINTS
    reset_command_history();
#else
    if (reason == DUMP_CHECKPOINT) {
	switch (fork_server("checkpointer")) {
	case FORK_PARENT:
	    reset_command_history();
	    free_stream(s);
	    return 1;
	case FORK_ERROR:
	    free_stream(s);
	    return 0;
	case FORK_CHILD:
	    set_server_cmdline("(MOO checkpointer)");
	    break;
	}
    }
#endif

    success = 1;
    if ((f = fopen(temp_name, "w")) != 0) {
	dbpriv_set_dbio_output(f);
	if (!write_db_file(reason_names[reason])) {
	    log_perror("Trying to dump database");
	    fclose(f);
	    remove(temp_name);
	    if (reason == DUMP_CHECKPOINT) {
		errlog("Abandoning checkpoint attempt...\n");
		success = 0;
	    } else {
		int retry_interval = 60;

		errlog("Waiting %d seconds and retrying dump...\n",
		       retry_interval);
		timer_sleep(retry_interval);
		goto retryDumping;
	    }
	} else {
	    fclose(f);
	    oklog("%s on %s finished\n", reason_names[reason], temp_name);
	    if (reason != DUMP_PANIC) {
		remove(dump_db_name);
		if (rename(temp_name, dump_db_name) != 0) {
		    log_perror("Renaming temporary dump file");
		    success = 0;
		}
	    }
	}
    } else {
	log_perror("Opening temporary dump file");
	success = 0;
    }

    free_stream(s);

#ifndef UNFORKED_CHECKPOINTS
    if (reason == DUMP_CHECKPOINT)
	/* We're a child, so we'd better go away. */
	exit(!success);
#endif

    return success;
}
示例#20
0
static const char *
translate_pattern(const char *pattern, int *tpatlen)
{
    /* Translate a MOO pattern into a more standard syntax.  Effectively, this
     * just involves converting from `%' escapes into `\' escapes.
     */

    static Stream *s = 0;
    const char *p = pattern;
    char c;

    if (!s)
	s = new_stream(100);

    while (*p) {
	switch (c = *p++) {
	case '%':
	    c = *p++;
	    if (!c)
		goto fail;
	    else if (strchr(".*+?[^$|()123456789bB<>wW", c))
		stream_add_char(s, '\\');
	    stream_add_char(s, c);
	    break;
	case '\\':
	    stream_add_string(s, "\\\\");
	    break;
	case '[':
	    /* Any '%' or '\' characters inside a charset should be copied
	     * over without translation. */
	    stream_add_char(s, c);
	    c = *p++;
	    if (c == '^') {
		stream_add_char(s, c);
		c = *p++;
	    }
	    /* This is the only place a ']' can appear and not be the end of
	     * the charset. */
	    if (c == ']') {
		stream_add_char(s, c);
		c = *p++;
	    }
	    while (c && c != ']') {
		stream_add_char(s, c);
		c = *p++;
	    }
	    if (!c)
		goto fail;
	    else
		stream_add_char(s, c);
	    break;
	default:
	    stream_add_char(s, c);
	    break;
	}
    }

    *tpatlen = stream_length(s);
    return reset_stream(s);

  fail:
    reset_stream(s);
    return 0;
}
示例#21
0
static void
output(Stream * s)
{
    (*print) (reset_stream(s), print_data);
}
示例#22
0
enum error
proto_open_connection(Var arglist, int *read_fd, int *write_fd,
		      const char **local_name, const char **remote_name)
{
    /* These are `static' rather than `volatile' because I can't cope with
     * getting all those nasty little parameter-passing rules right.  This
     * function isn't recursive anyway, so it doesn't matter.
     */
    struct sockaddr_in rec_addr;
    struct t_bind received;
    static const char *host_name;
    static int port;
    static Timer_ID id;
    int fd, result;
    int timeout = server_int_option("name_lookup_timeout", 5);
    static struct sockaddr_in addr;
    static Stream *st1 = 0, *st2 = 0;

    if (!st1) {
	st1 = new_stream(20);
	st2 = new_stream(50);
    }
    if (arglist.v.list[0].v.num != 2)
	return E_ARGS;
    else if (arglist.v.list[1].type != TYPE_STR ||
	     arglist.v.list[2].type != TYPE_INT)
	return E_TYPE;

    host_name = arglist.v.list[1].v.str;
    port = arglist.v.list[2].v.num;

    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = lookup_addr_from_name(host_name, timeout);
    if (addr.sin_addr.s_addr == 0)
	return E_INVARG;

    /* Cast to (void *) here to workaround const-less decls on some systems. */
    fd = t_open((void *) "/dev/tcp", O_RDWR, 0);
    if (fd < 0) {
	if (t_errno != TSYSERR || errno != EMFILE)
	    log_ti_error("Making endpoint in proto_open_connection");
	return E_QUOTA;
    }
    received.addr.maxlen = sizeof(rec_addr);
    received.addr.len = sizeof(rec_addr);
    received.addr.buf = (void *) &rec_addr;

    if (t_bind(fd, 0, &received) < 0) {
	log_ti_error("Binding outbound endpoint");
	t_close(fd);
	return E_QUOTA;
    }
    call->addr.maxlen = sizeof(addr);
    call->addr.len = sizeof(addr);
    call->addr.buf = (void *) &addr;

    TRY
	id = set_timer(server_int_option("outbound_connect_timeout", 5),
		       timeout_proc, 0);
    result = t_connect(fd, call, 0);
    cancel_timer(id);
    EXCEPT(timeout_exception)
	result = -1;
    errno = ETIMEDOUT;
    t_errno = TSYSERR;
    reenable_timers();
    ENDTRY

	if (result < 0) {
	t_close(fd);
	log_ti_error("Connecting in proto_open_connection");
	return E_QUOTA;
    }
    if (!set_rw_able(fd)) {
	t_close(fd);
	return E_QUOTA;
    }
    *read_fd = *write_fd = fd;

    stream_printf(st1, "port %d", (int) ntohs(rec_addr.sin_port));
    *local_name = reset_stream(st1);

    stream_printf(st2, "%s, port %d", host_name, port);
    *remote_name = reset_stream(st2);

    return E_NONE;
}
示例#23
0
enum error
proto_open_connection(Var arglist, int *read_fd, int *write_fd,
		      const char **local_name, const char **remote_name)
{
    /* These are `static' rather than `volatile' because I can't cope with
     * getting all those nasty little parameter-passing rules right.  This
     * function isn't recursive anyway, so it doesn't matter.
     */
    static const char *host_name;
    static int port;
    static Timer_ID id;
    size_t length;
    int s, result;
    int timeout = server_int_option("name_lookup_timeout", 5);
    static struct sockaddr_in addr;
    static Stream *st1 = 0, *st2 = 0;

    if (!outbound_network_enabled)
	return E_PERM;

    if (!st1) {
	st1 = new_stream(20);
	st2 = new_stream(50);
    }
    if (arglist.v.list[0].v.num != 2)
	return E_ARGS;
    else if (arglist.v.list[1].type != TYPE_STR ||
	     arglist.v.list[2].type != TYPE_INT)
	return E_TYPE;

    host_name = arglist.v.list[1].v.str;
    port = arglist.v.list[2].v.num;

    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = lookup_addr_from_name(host_name, timeout);
    if (addr.sin_addr.s_addr == 0)
	return E_INVARG;

    s = socket(AF_INET, SOCK_STREAM, 0);
    if (s < 0) {
	if (errno != EMFILE)
	    log_perror("Making socket in proto_open_connection");
	return E_QUOTA;
    }
    
    if (bind_local_ip != INADDR_ANY) {
	static struct sockaddr_in local_addr;

	local_addr.sin_family = AF_INET;
	local_addr.sin_addr.s_addr = bind_local_ip;
	local_addr.sin_port = 0;
	/* In theory, if the original listen() succeeded,
	 * then this should too, but who knows, really? */
	if (bind(s, (struct sockaddr *) &local_addr, sizeof(local_addr)) < 0) {
	    enum error e = E_QUOTA;

	    log_perror("Binding local address in proto_open_connection");
	    if (errno == EACCES)
		e = E_PERM;
	    close(s);
	    return e;
	}
    }	 
    TRY {
	id = set_timer(server_int_option("outbound_connect_timeout", 5),
		       timeout_proc, 0);
	result = connect(s, (struct sockaddr *) &addr, sizeof(addr));
	cancel_timer(id);
    }
    EXCEPT(timeout_exception) {
	result = -1;
	errno = ETIMEDOUT;
	reenable_timers();
    }
    ENDTRY;

    if (result < 0) {
	close(s);
	if (errno == EADDRNOTAVAIL ||
	    errno == ECONNREFUSED ||
	    errno == ENETUNREACH ||
	    errno == ETIMEDOUT)
	    return E_INVARG;
	log_perror("Connecting in proto_open_connection");
	return E_QUOTA;
    }
    length = sizeof(addr);
    if (getsockname(s, (struct sockaddr *) &addr, &length) < 0) {
	close(s);
	log_perror("Getting local name in proto_open_connection");
	return E_QUOTA;
    }
    *read_fd = *write_fd = s;

    stream_printf(st1, "port %d", (int) ntohs(addr.sin_port));
    *local_name = reset_stream(st1);

    stream_printf(st2, "%s, port %d", host_name, port);
    *remote_name = reset_stream(st2);

    return E_NONE;
}
示例#24
0
enum error
proto_make_listener(Var desc, int *fd, Var * canon, const char **name)
{
    struct sockaddr_in req_addr, rec_addr;
    struct t_bind requested, received;
    int s, port;
    static Stream *st = 0;

    if (!st)
	st = new_stream(20);

    if (desc.type != TYPE_INT)
	return E_TYPE;

    port = desc.v.num;
    s = t_open((void *) "/dev/tcp", O_RDWR, 0);
    if (s < 0) {
	log_ti_error("Creating listening endpoint");
	return E_QUOTA;
    }
    req_addr.sin_family = AF_INET;
    req_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    req_addr.sin_port = htons(port);

    requested.addr.maxlen = sizeof(req_addr);
    requested.addr.len = sizeof(req_addr);
    requested.addr.buf = (void *) &req_addr;
    requested.qlen = 5;

    received.addr.maxlen = sizeof(rec_addr);
    received.addr.len = sizeof(rec_addr);
    received.addr.buf = (void *) &rec_addr;

    if (t_bind(s, &requested, &received) < 0) {
	enum error e = E_QUOTA;

	log_ti_error("Binding to listening address");
	t_close(s);
	if (t_errno == TACCES || (t_errno == TSYSERR && errno == EACCES))
	    e = E_PERM;
	return e;
    } else if (port != 0 && rec_addr.sin_port != port) {
	errlog("Can't bind to requested port!\n");
	t_close(s);
	return E_QUOTA;
    }
    if (!call)
	call = (struct t_call *) t_alloc(s, T_CALL, T_ADDR);
    if (!call) {
	log_ti_error("Allocating T_CALL structure");
	t_close(s);
	return E_QUOTA;
    }
    canon->type = TYPE_INT;
    canon->v.num = ntohs(rec_addr.sin_port);

    stream_printf(st, "port %d", canon->v.num);
    *name = reset_stream(st);

    *fd = s;
    return E_NONE;
}
示例#25
0
readstat_error_t rdata_parse(rdata_parser_t *parser, const char *filename, void *user_ctx) {
    int is_rdata = 0;
    readstat_error_t retval = READSTAT_OK;
    rdata_v2_header_t v2_header;
    rdata_ctx_t *ctx = init_rdata_ctx(filename);

    if (ctx == NULL) {
        retval = READSTAT_ERROR_OPEN;
        goto cleanup;
    }

    ctx->user_ctx = user_ctx;
    ctx->table_handler = parser->table_handler;
    ctx->column_handler = parser->column_handler;
    ctx->column_name_handler = parser->column_name_handler;
    ctx->text_value_handler = parser->text_value_handler;
    ctx->value_label_handler = parser->value_label_handler;
    ctx->error_handler = parser->error_handler;
    
    if ((retval = init_stream(ctx)) != READSTAT_OK) {
        goto cleanup;
    }

    char header_line[5];
    if (read_st(ctx, &header_line, sizeof(header_line)) != sizeof(header_line)) {
        retval = READSTAT_ERROR_READ;
        goto cleanup;
    }
    if (strncmp("RDX2\n", header_line, sizeof(header_line)) == 0) {
        is_rdata = 1;
    } else {
        reset_stream(ctx);
    }

    if (read_st(ctx, &v2_header, sizeof(v2_header)) != sizeof(v2_header)) {
        retval = READSTAT_ERROR_READ;
        goto cleanup;
    }
    
    if (ctx->machine_needs_byteswap) {
        v2_header.format_version = byteswap4(v2_header.format_version);
        v2_header.writer_version = byteswap4(v2_header.writer_version);
        v2_header.reader_version = byteswap4(v2_header.reader_version);
    }
    
    if (is_rdata) {
        retval = read_environment(NULL, ctx);
    } else {
        retval = read_toplevel_object(NULL, NULL, ctx);
    }
    if (retval != READSTAT_OK)
        goto cleanup;
    
    char test;
    
    if (read_st(ctx, &test, 1) == 1) {
        retval = READSTAT_ERROR_PARSE;
        goto cleanup;
    }
    
cleanup:
    if (ctx) {
        free_rdata_ctx(ctx);
    }
    
    return retval;
}