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); }
/* 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); }
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; }
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)); }
static void finish_insn(Stream * s, Stream * insn) { while (bytes_width--) stream_add_string(s, " "); stream_add_string(s, reset_stream(insn)); output(s); }
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); }
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; }
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); }
/****************************************************************************** * @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); } } }
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; }
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; }
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; }
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)); } }
static void output(Stream * str) { (*receiver) (receiver_data, reset_stream(str)); }
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; }
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; }
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; }
static void output(Stream * s) { (*print) (reset_stream(s), print_data); }
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; }
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; }
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; }
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; }