// Initializes a state and loads the source of the Lua script. // // source - The script source code. // L - A reference to where the new Lua state should be returned. // // Returns 0 if successful, otherwise returns -1. int sky_lua_initscript(bstring source, lua_State **L) { int rc; assert(source != NULL); assert(L != NULL); // Load Lua with standard library. *L = luaL_newstate(); check_mem(L); luaL_openlibs(*L); // Load Lua msgpack library. rc = luaopen_cmsgpack(*L); check(rc == 1, "Unable to load lua-cmsgpack"); //debug("--SOURCE--\n%s", bdata(source)); // Compile lua script. rc = luaL_loadstring(*L, bdata(source)); check(rc == 0, "Unable to compile Lua script: %s", lua_tostring(*L, -1)); // Call once to make the functions available. lua_call(*L, 0, 0); return 0; error: lua_close(*L); *L = NULL; return -1; }
/** * This function creates a bstring of a partition file name. * The caller is responsible for freeing the bstring. The infile can be NULL. * When partition files are created, the infile partition names need to be * created. This is usually the case the whole procedure is done by count * command. If infile is not NULL, the list of partition files is considered * a list of partition files. * * @param o counter * @param i_np partition index * * @return partition file name or NULL */ static bstring filename_partition(alder_kmer_thread7_t *o, uint64_t i_np) { /* File name setup */ bstring bfpar = NULL; if (o->infile == NULL) { bfpar = bformat("%s/%s-%llu-%llu.par", bdata(o->boutdir), bdata(o->boutfile), o->i_ni, i_np); if (bfpar == NULL) return NULL; } else { bfpar = bstrcpy(o->infile->entry[i_np]); if (bfpar == NULL) return NULL; } return bfpar; }
char *test_parser_thrashing() { glob_t test_files; int i = 0; int nparsed = 0; int delta = 0; int tests_run = 0; int execs_run = 0; int unfinished = 0; int errors = 0; int rc = glob("tests/and_suite/*", 0, NULL, &test_files); mu_assert(rc == 0, "Failed to glob file sin tests/and_suite/*"); for(i = 0; i < test_files.gl_pathc; i++) { FILE *infile = fopen(test_files.gl_pathv[i], "r"); mu_assert(infile != NULL, "Failed to open test file."); bstring data = bread((bNread)fread, infile); fclose(infile); mu_assert(data != NULL, "Failed to read test file."); tests_run++; http_parser p = setup_parser(); nparsed = 0; delta = 0; while(nparsed < blength(data)) { debug("json PARSING: %d of %d at %s", nparsed, blength(data), bdataofs(data, nparsed)); delta = http_parser_execute(&p, bdata(data), blength(data), nparsed); execs_run++; if(delta == 0) { break; } if(!http_parser_finish(&p)) { unfinished++; } nparsed += delta; if(http_parser_has_error(&p)) { errors++; } debug("TEST %s results: delta %d, has_error: %d, is_finished: %d", test_files.gl_pathv[i], nparsed, http_parser_has_error(&p), http_parser_is_finished(&p)); http_parser_init(&p); // reset for the next try } } debug("HTTP PARSING: tests_run: %d, execs_run: %d, unfinished: %d, errors: %d", tests_run, execs_run, unfinished, errors); return NULL; }
static int traverse_good_cb(BSTreeNode *node) { debug("KEY: %s", bdata((bstring)node->key)); traverse_called++; return 0; }
/** * Take the request header and adds it to a magic GUID. * Which is returned in a SHA1-hash * @param req - Mongrel2 request data * @return 0 on success */ static int mongrel2_ws_08_calculate_accept(mongrel2_request *req, bstring *ptr){ int retval; bstring key = mongrel2_request_get_header(req,WEBSOCKET_08_KEY); if(key == NULL){ return -1; } retval = bcatcstr(key,WEBSOCKET_08_GUID); if(retval != 0){ return -1; } void* buf = calloc(sizeof(char),SHA1_LEN); if(buf == NULL){ return -1; } sha1((const unsigned char*)bdata(key),blength(key),buf); bstring accept = blk2bstr(buf,SHA1_LEN); bstring accept_encoded = bBase64Encode(accept); bdestroy(accept); free(buf); bdestroy(key); *ptr = accept_encoded; return 0; }
void render_png(Scene *scene, bstring output_file) { int width = scene->canvas->width; int height = scene->canvas->height; Colour **data = scene->canvas->data; Colour colour; unsigned err; unsigned char* image = malloc(width * height * 4); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { // Fix image being upside down // We trace from bottom left to top right // Logepng goes topleft to bottom right int yc = (height - 1) - y; colour = data[x][y]; image[4 * width * yc + 4 * x + 0] = (uint8_t)colour.red; image[4 * width * yc + 4 * x + 1] = (uint8_t)colour.green; image[4 * width * yc + 4 * x + 2] = (uint8_t)colour.blue; image[4 * width * yc + 4 * x + 3] = (uint8_t)colour.alpha; } } err = lodepng_encode32_file(bdata(output_file), image, width, height); if (err) { printf("error %u: %s\n", err, lodepng_error_text(err)); } }
// Retrieves a reference to a standardized bstring that represents the name // of the data type. // // type_name - The name of the type. // ret - A pointer to where the standardized type name should be returned. // // Returns 0 if successful, otherwise returns -1. int sky_property_get_standard_data_type_name(bstring type_name, bstring *ret) { check(type_name != NULL, "Type name required"); check(ret != NULL, "Return pointer required"); // Check against standard types. if(biseq(&SKY_DATA_TYPE_INT, type_name)) { *ret = &SKY_DATA_TYPE_INT; } else if(biseq(&SKY_DATA_TYPE_FLOAT, type_name)) { *ret = &SKY_DATA_TYPE_FLOAT; } else if(biseq(&SKY_DATA_TYPE_BOOLEAN, type_name)) { *ret = &SKY_DATA_TYPE_BOOLEAN; } else if(biseq(&SKY_DATA_TYPE_STRING, type_name)) { *ret = &SKY_DATA_TYPE_STRING; } // If this is not a standard type then return the name that came in. else { sentinel("Type is not a standard type: %s", bdata(type_name)); } return 0; error: return -1; }
// Closes a table and detaches it from the server. // // server - The server. // table - The table to close. // // Returns 0 if successful, otherwise returns -1. int sky_server_close_table(sky_server *server, sky_table *table) { int rc; assert(server != NULL); assert(table != NULL); // Send shutdown message for servlets associated with this table. rc = sky_server_stop_servlets(server, table); check(rc == 0, "Unable to shutdown servlets related to table: %s", bdata(table->path)); // Remove the server association. uint32_t i, j; for(i=0; i<server->table_count; i++) { if(server->tables[i] == table) { sky_table_free(table); table = NULL; for(j=i+1; j<server->table_count; j++) { server->tables[j-1] = server->tables[j]; } server->tables[server->table_count-1] = NULL; server->table_count--; i--; } } return 0; error: return -1; }
void taskmain(int argc, char *argv[]) { dbg_set_log(stderr); int i = 0; bstring arguments = bfromcstr(argv[0]); for(i = 1; i < argc; i++) { bstring a = bfromcstr(argv[i]); // compensate for quotes getting taken off by the shell // TODO: also need to escape " to bring back that if(bstrchr(a, ' ') != -1) { bcatcstr(arguments, " \""); bconcat(arguments, a); bcatcstr(arguments, "\""); } else { bcatcstr(arguments, " "); bconcat(arguments, a); } bdestroy(a); } debug("RUNNING: %s", bdata(arguments)); taskexitall(Command_run(arguments)); }
TSTree *add_route_data(TSTree *routes,bstring line) { struct bstrList *data = bsplit(line,' '); check(data->qty == 2, "Line %s does not have 2 columns", bdata(line)); routes = TSTree_insert(routes, bdata(data->entry[0]),blength(data->entry[0]), bstrcpy(data->entry[1])); bstrListDestroy(data); return routes; error: return NULL; }
const char *AST_str(tst_t *settings, tst_t *fr, const char *name, TokenType type) { bstring key = bfromcstr(name); bstring val = AST_get_bstr(settings, fr, key, type); bdestroy(key); return bdata(val); }
bstring get_token_from_config_file() { bstring config_file = locate_config_file(); dictionary *config; struct stat statbuf; int rc = stat((char *) config_file->data, &statbuf); if (rc < 0 || statbuf.st_size == 0) { bdestroy(config_file); return 0; } else { config = iniparser_load(bdata(config_file)); } char *token = iniparser_getstring(config, "authentication:token", 0); bdestroy(config_file); bstring ret = 0; if (token) { ret = bfromcstr(token); } iniparser_freedict(config); return ret; }
void alder_wordtable_bigbitarray_print(alder_wordtable_bigbitarray_t *o) { bool isExit = false; bstring bs = bfromcstralloc((int)o->maxsize * 10, " "); alder_dwordtable_t x1 = 1; for (size_t i = 0; i < o->blockarraysize; i++) { for (size_t j = 0; j < o->subarraybits; j++) { size_t pos = j + i * o->subarraybits; if (j + i * o->subarraybits == o->maxsize) { isExit = true; break; } size_t k = j / o->blocksize; size_t kbit = j % o->blocksize; alder_dwordtable_t x = o->blockarray[i][k]; bformata(bs, "[%zu] ", pos); if (x & (x1 << kbit)) { bconchar(bs, '1'); } else { bconchar(bs, '0'); } bconchar(bs, ' '); } if (isExit == true) { break; } } alder_log5("bit: %s", bdata(bs)); bdestroy(bs); }
void Handler_notify_leave(Handler *handler, int id) { void *socket = handler->send_socket; assert(socket && "Socket can't be NULL"); bstring payload = bformat("%s %d @* %d:%s,%d:%s,", bdata(handler->send_ident), id, blength(&LEAVE_HEADER), bdata(&LEAVE_HEADER), blength(&LEAVE_MSG), bdata(&LEAVE_MSG)); if(Handler_deliver(socket, bdata(payload), blength(payload)) == -1) { log_err("Can't tell handler %d died.", id); } bdestroy(payload); }
int Handler_deliver(void *handler_socket, char *buffer, size_t len) { int rc = 0; zmq_msg_t *msg = calloc(sizeof(zmq_msg_t), 1); bstring msg_buf = NULL; rc = zmq_msg_init(msg); check(rc == 0, "Failed to initialize 0mq message to send."); msg_buf = blk2bstr(buffer, len); check_mem(msg_buf); rc = zmq_msg_init_data(msg, bdata(msg_buf), blength(msg_buf), bstring_free, msg_buf); check(rc == 0, "Failed to init 0mq message data."); rc = mqsend(handler_socket, msg, 0); check(rc == 0, "Failed to deliver 0mq message to handler."); if(msg) free(msg); return 0; error: // TODO: confirm what if this is the right shutdown if(msg) free(msg); return -1; }
int Host_load(tst_t *settings, Value *val) { CONFIRM_TYPE("Host"); Class *cls = val->as.cls; char *sql = NULL; struct tagbstring ROUTES_VAR = bsStatic("routes"); const char *name = AST_str(settings, cls->params, "name", VAL_QSTRING); check(name, "No name set for Host."); sql = sqlite3_mprintf(bdata(&HOST_SQL), SERVER_ID, name, name); int rc = DB_exec(sql, NULL, NULL); check(rc == 0, "Failed to store Host: %s", name); cls->id = HOST_ID = DB_lastid(); Value *routes = AST_get(settings, cls->params, &ROUTES_VAR, VAL_HASH); check(routes, "Didn't find any routes for %s", name); AST_walk_hash(settings, routes, Route_load); sqlite3_free(sql); return 0; error: if(sql) sqlite3_free(sql); return -1; }
// Parses a JSON document into an array of tokens. // // importer - The importer. // source - The import file contents. // tokens - A pointer to where the tokens should be returned. // // Returns 0 if successful, otherwise returns -1. int sky_importer_tokenize(sky_importer *importer, bstring source, jsmntok_t **tokens) { check(importer != NULL, "Importer required"); check(source != NULL, "File source required"); check(tokens != NULL, "Tokens return pointer required"); // Initialize return values. *tokens = NULL; // Create JSON parser. jsmn_parser parser; jsmn_init(&parser); // Parse tokens until we're done. uint32_t token_count = 1024; jsmnerr_t ret; do { *tokens = realloc(*tokens, token_count * sizeof(jsmntok_t)); ret = jsmn_parse(&parser, bdata(source), *tokens, token_count); check(ret != JSMN_ERROR_INVAL, "Invalid json token"); check(ret != JSMN_ERROR_PART, "Unexpected end in json data"); // If we didn't have enough tokens then reallocate and try again. if(ret == JSMN_ERROR_NOMEM) token_count *= 2; } while(ret != JSMN_SUCCESS); return 0; error: free(*tokens); *tokens = NULL; return -1; }
static void socks_accept_cb(struct evconnlistener *lis, evutil_socket_t fd, struct sockaddr *addr, int len, void *ptr) { obfsproxyssh_client_t *client = ptr; obfsproxyssh_t *state = client->state; obfsproxyssh_client_session_t *session; struct sockaddr_in *sa; char addr_buf[INET_ADDRSTRLEN]; uint32_t tmp; assert(lis == client->listener); /* * It is possible to defer allocating the session object till after the * SOCKS protocol handling is done, but there isn't much point in doing * so. */ session = calloc(1, sizeof(obfsproxyssh_client_session_t)); if (NULL == session) { log_f(state, "SOCKS: Error: Failed to allocate session"); goto out_close; } session->socks_ev = bufferevent_socket_new(state->base, fd, BEV_OPT_CLOSE_ON_FREE); if (NULL == session->socks_ev) { log_f(state, "SOCKS: Error: Failed to allocate bev"); free(session); goto out_close; } bufferevent_setcb(session->socks_ev, socks_read_cb, NULL, socks_event_cb, session); bufferevent_enable(session->socks_ev, EV_READ | EV_WRITE); sa = (struct sockaddr_in *) addr; if (0 == state->unsafe_logging) { tmp = ntohl(sa->sin_addr.s_addr); tmp &= 0x000000ff; session->socks_addr = bformat("xxx.xxx.xxx.%d:%d", tmp, ntohs(sa->sin_port)); } else { evutil_inet_ntop(AF_INET, &sa->sin_addr, addr_buf, INET_ADDRSTRLEN); session->socks_addr = bformat("%s:%d", addr_buf, ntohs(sa->sin_port)); } /* TODO: Set the timeout */ LIST_INSERT_HEAD(&client->sessions, session, entries); session->client = client; log_f(state, "SOCKS: %s Connect", bdata(session->socks_addr)); return; out_close: evutil_closesocket(fd); }
int connection_proxy_req_parse(Connection *conn) { int rc = 0; Host *target_host = conn->req->target_host; Backend *req_action = conn->req->action; check_debug(!IOBuf_closed(conn->iob), "Client closed, goodbye."); rc = Connection_read_header(conn, conn->req); check_debug(rc > 0, "Failed to read another header."); error_unless(Request_is_http(conn->req), conn, 400, "Someone tried to change the protocol on us from HTTP."); Backend *found = Host_match_backend(target_host, Request_path(conn->req), NULL); error_unless(found, conn, 404, "Handler not found: %s", bdata(Request_path(conn->req))); // break out of PROXY if the actions don't match if(found != req_action) { Request_set_action(conn->req, found); return Connection_backend_event(found, conn); } else { return HTTP_REQ; } error_response(conn, 500, "Invalid code branch, tell Zed."); error: return REMOTE_CLOSE; }
/* * ino_dirty() * Purge a directory entry back to the fs * * Whenever we have completed a series of modifications to some inode * data we need to write them back to the disk in the directory. */ void ino_dirty(struct inode *i) { struct dirent *d; void *handle; /* * First off grab the directory info off the disk */ handle = bget(i->i_dirblk); if (handle == NULL ) { perror("bfs ino_dirty"); exit(1); } d = (struct dirent *)((char *)bdata(handle) + i->i_diroff); /* * Then write the new information into the buffer */ memcpy(d->d_name, i->i_name, BFSNAMELEN); d->d_inum = i->i_num; d->d_start = i->i_start; d->d_len = i->i_fsize; /* * Then mark the buffer dirty and free the space */ bdirty(handle); bfree(handle); }
static inline void StringScanner_set_needle(StringScanner *scan, bstring tofind) { scan->needle = (const unsigned char *)bdata(tofind); scan->nlen = blength(tofind); String_setup_skip_chars(scan->skip_chars, scan->needle, scan->nlen); }
int sky_importer_process_event(sky_importer *importer, bstring source, jsmntok_t *tokens, uint32_t *index) { int rc; check(importer != NULL, "Importer required"); check(source != NULL, "Source required"); check(tokens != NULL, "Tokens required"); check(index != NULL, "Token index required"); jsmntok_t *event_token = &tokens[*index]; (*index)++; // Open table if it hasn't been already. if(!importer->table->opened) { check(sky_table_open(importer->table) == 0, "Unable to open table"); } // Create the event object. sky_event *event = sky_event_create(0, 0, 0); check_mem(event); // Process over child tokens. int32_t i; for(i=0; i<(event_token->size/2); i++) { jsmntok_t *token = &tokens[*index]; (*index)++; if(sky_importer_tokstr_equal(source, token, "timestamp")) { bstring timestamp = sky_importer_token_parse_bstring(source, &tokens[(*index)++]); rc = sky_timestamp_parse(timestamp, &event->timestamp); check(rc == 0, "Unable to parse timestamp"); bdestroy(timestamp); } else if(sky_importer_tokstr_equal(source, token, "objectId")) { event->object_id = (sky_object_id_t)sky_importer_token_parse_int(source, &tokens[(*index)++]); } else if(sky_importer_tokstr_equal(source, token, "action")) { sky_action *action = NULL; bstring action_name = sky_importer_token_parse_bstring(source, &tokens[(*index)++]); rc = sky_action_file_find_action_by_name(importer->table->action_file, action_name, &action); check(rc == 0, "Unable to find action: %s", bdata(action_name)); event->action_id = action->id; } else if(sky_importer_tokstr_equal(source, token, "data")) { rc = sky_importer_process_event_data(importer, event, source, tokens, index); check(rc == 0, "Unable to import event data"); } else { sentinel("Invalid token at char %d", tokens[*index].start); } } // Add event. rc = sky_table_add_event(importer->table, event); check(rc == 0, "Unable to add event"); return 0; error: return -1; }
int String_find(bstring in, bstring what) { const unsigned char *found = NULL; const unsigned char *haystack = (const unsigned char *)bdata(in); ssize_t hlen = blength(in); const unsigned char *needle = (const unsigned char *)bdata(what); ssize_t nlen = blength(what); size_t skip_chars[UCHAR_MAX + 1] = {0}; String_setup_skip_chars(skip_chars, needle, nlen); found = String_base_search(haystack, hlen, needle, nlen, skip_chars); return found != NULL ? found - haystack : -1; }
char *test_insert() { node = TSTree_insert(node, bdata(&test1), blength(&test1), valueA); mu_assert(node != NULL, "Failed to insert into tst."); node = TSTree_insert(node, bdata(&test2), blength(&test2), value2); mu_assert(node != NULL, "Failed to insert into tst with second name"); node = TSTree_insert(node, bdata(&test3), blength(&test3), reverse); mu_assert(node != NULL, "Failed to insert into tst with reverse name"); node = TSTree_insert(node, bdata(&test4), blength(&test4), value4); mu_assert(node != NULL, "Failed to insert into tst with second name"); return NULL; }
int Response_send_socket_policy(Connection *conn) { // must have +1 to include the \0 that xml sockets expect return IOBuf_send(conn->iob, bdata(&FLASH_RESPONSE), blength(&FLASH_RESPONSE) + 1); }
inline bstring Dir_calculate_response(Request *req, FileRecord *file) { int if_unmodified_since = 0; int if_modified_since = 0; bstring if_match = NULL; bstring if_none_match = NULL; if(file) { if(file->is_dir) return bformat(DIR_REDIRECT_FORMAT, bdata(req->host), bdata(req->uri)); if_match = Request_get(req, &HTTP_IF_MATCH); if(!if_match || biseqcstr(if_match, "*") || bstring_match(if_match, &ETAG_PATTERN)) { if_none_match = Request_get(req, &HTTP_IF_NONE_MATCH); if_unmodified_since = Request_get_date(req, &HTTP_IF_UNMODIFIED_SINCE, RFC_822_TIME); if_modified_since = Request_get_date(req, &HTTP_IF_MODIFIED_SINCE, RFC_822_TIME); debug("TESTING WITH: if_match: %s, if_none_match: %s, if_unmodified_since: %d, if_modified_since: %d", bdata(if_match), bdata(if_none_match), if_unmodified_since, if_modified_since); if(if_unmodified_since) { if(file->sb.st_mtime > if_unmodified_since) { return &HTTP_412; } else if(if_none_match) { return Dir_none_match(req, file, if_modified_since, if_none_match); } else if(if_modified_since) { return Dir_if_modified_since(req, file, if_modified_since); } } else if(if_none_match) { return Dir_none_match(req, file, if_modified_since, if_none_match); } else if(if_modified_since) { return Dir_if_modified_since(req, file, if_modified_since); } else { // they've got nothing, 200 return NULL; } } else { return &HTTP_412; } } else { return &HTTP_404; } return &HTTP_500; }
int connection_msg_to_handler(Connection *conn) { Handler *handler = Request_get_action(conn->req, handler); int rc = 0; int header_len = Request_header_length(conn->req); // body_len will include \0 int body_len = Request_content_length(conn->req); check(handler, "JSON request doesn't match any handler: %s", bdata(Request_path(conn->req))); if(pattern_match(IOBuf_start(conn->iob), header_len + body_len, bdata(&PING_PATTERN))) { Register_ping(IOBuf_fd(conn->iob)); } else { check(body_len >= 0, "Parsing error, body length ended up being: %d", body_len); bstring payload = NULL; if(handler->protocol == HANDLER_PROTO_TNET) { payload = Request_to_tnetstring(conn->req, handler->send_ident, IOBuf_fd(conn->iob), IOBuf_start(conn->iob) + header_len, body_len - 1); // drop \0 on payloads } else if(handler->protocol == HANDLER_PROTO_JSON) { payload = Request_to_payload(conn->req, handler->send_ident, IOBuf_fd(conn->iob), IOBuf_start(conn->iob) + header_len, body_len - 1); // drop \0 on payloads } else { sentinel("Invalid protocol type: %d", handler->protocol); } debug("SENT: %s", bdata(payload)); check(payload != NULL, "Failed to generate payload."); check(handler->send_socket != NULL, "Handler socket is NULL, tell Zed."); rc = Handler_deliver(handler->send_socket, bdata(payload), blength(payload)); free(payload); check(rc == 0, "Failed to deliver to handler: %s", bdata(Request_path(conn->req))); } // consumes \0 from body_len check(IOBuf_read_commit(conn->iob, header_len + body_len) != -1, "Final commit failed."); return REQ_SENT; error: return CLOSE; }
int Command_access_logs(Command *cmd) { bstring log_filename = option(cmd, "log", "logs/access.log"); check(log_filename, "Invalid log file given."); FILE *log_file = fopen(bdata(log_filename), "r"); check(log_file != NULL, "Failed to open log file: %s", bdata(log_filename)); int line_number = 0; bstring line; while ((line = bgets((bNgetc) fgetc, log_file, '\n')) != NULL) { line_number++; tns_value_t *log_item = tns_parse(bdata(line), blength(line), NULL); if (log_item == NULL || tns_get_type(log_item) != tns_tag_list || darray_end(log_item->value.list) < 9 ) { log_warn("Malformed log line: %d.", line_number); continue; } darray_t *entries = log_item->value.list; bstring hostname = darray_get_as(entries, 0, string); bstring remote_addr = darray_get_as(entries, 1, string); long remote_port = darray_get_as(entries, 2, number); long timestamp = darray_get_as(entries, 3, number); bstring request_method = darray_get_as(entries, 4, string); bstring request_path = darray_get_as(entries, 5, string); bstring version = darray_get_as(entries, 6, string); long status = darray_get_as(entries, 7, number); long size = darray_get_as(entries, 8, number); printf("[%ld] %s:%ld %s \"%s %s %s\" %ld %ld\n", timestamp, bdata(remote_addr), remote_port, bdata(hostname), bdata(request_method), bdata(request_path), bdata(version), status, size); tns_value_destroy(log_item); } return 0; error: return -1; }
int clear_pid_file(Server *srv) { bstring pid_file; if(srv->chroot != NULL) { pid_file = bformat("%s%s", bdata(srv->chroot), bdata(srv->pid_file)); } else { pid_file = bstrcpy(srv->pid_file); } int rc = Unixy_remove_dead_pidfile(pid_file); check(rc == 0, "Failed to remove the dead PID file: %s", bdata(pid_file)); bdestroy(pid_file); return 0; error: return -1; }
int Server_load(tst_t *settings, Value *val) { CONFIRM_TYPE("Server"); Class *cls = val->as.cls; int rc = 0; char *sql = NULL; struct tagbstring HOSTS_VAR = bsStatic("hosts"); const char *bind_addr = NULL; if(tst_search(cls->params, bdata(&BIND_ADDR), blength(&BIND_ADDR))) { bind_addr = AST_str(settings, cls->params, "bind_addr", VAL_QSTRING); } else { bind_addr = "0.0.0.0"; } sql = sqlite3_mprintf(bdata(&SERVER_SQL), AST_str(settings, cls->params, "uuid", VAL_QSTRING), AST_str(settings, cls->params, "access_log", VAL_QSTRING), AST_str(settings, cls->params, "error_log", VAL_QSTRING), AST_str(settings, cls->params, "pid_file", VAL_QSTRING), AST_str(settings, cls->params, "chroot", VAL_QSTRING), AST_str(settings, cls->params, "default_host", VAL_QSTRING), AST_str(settings, cls->params, "name", VAL_QSTRING), bind_addr, AST_str(settings, cls->params, "port", VAL_NUMBER)); rc = DB_exec(sql, NULL, NULL); check(rc == 0, "Failed to exec SQL: %s", sql); cls->id = SERVER_ID = DB_lastid(); Value *hosts = AST_get(settings, cls->params, &HOSTS_VAR, VAL_LIST); check(hosts != NULL, "Could not find Server.hosts setting in host %s:%s", AST_str(settings, cls->params, "uuid", VAL_QSTRING), AST_str(settings, cls->params, "name", VAL_QSTRING)); AST_walk_list(settings, hosts->as.list, Host_load); sqlite3_free(sql); return 0; error: if(sql) sqlite3_free(sql); return -1; }