static int set_timer(duk_context *duk, int repeat) { es_context_t *ec = es_get(duk); es_timer_t *et = es_resource_create(ec, &es_resource_timer, 1); int val = duk_require_int(duk, 1); es_root_register(duk, 0, et); et->et_interval = val * repeat; int64_t now = arch_get_ts(); et->et_expire = now + val * 1000LL; hts_mutex_lock(&timer_mutex); if(thread_running == 0) { thread_running = 1; hts_thread_create_detached("estimer", timer_thread, NULL, THREAD_PRIO_MODEL); } else { hts_cond_signal(&timer_cond); } LIST_INSERT_SORTED(&timers, et, et_link, estimercmp, es_timer_t); hts_mutex_unlock(&timer_mutex); es_resource_push(duk, &et->super); return 1; }
static int es_faprovider_register(duk_context *ctx) { es_context_t *ec = es_get(ctx); const char *name = duk_require_string(ctx, 0); es_fap_t *ef = es_resource_alloc(&es_resource_fap); ef->fap.fap_opaque = ef; if(es_prop_is_true(ctx, 1, "cachable")) ef->fap.fap_flags |= FAP_ALLOW_CACHE, ef->fap.fap_fini = es_fap_fini; ef->fap.fap_open = es_fap_open; ef->fap.fap_seek = es_fap_seek; ef->fap.fap_read = es_fap_read; ef->fap.fap_close = es_fap_close; ef->fap.fap_fsize = es_fap_fsize; ef->fap.fap_stat = es_fap_stat; ef->name = strdup(name); ef->fap.fap_name = ef->name; es_resource_retain(&ef->super); // Refcount owned by FAP fileaccess_register_dynamic(&ef->fap); es_resource_link(&ef->super, ec, 1); es_root_register(ctx, 1, ef); es_resource_push(ctx, &ef->super); return 1; }
static int es_file_copy(duk_context *ctx) { char *cleanup; char path[URL_MAX]; char errbuf[256]; es_context_t *ec = es_get(ctx); const char *from = duk_to_string(ctx, 0); const char *to = duk_to_string(ctx, 1); cleanup = mystrdupa(to); fa_sanitize_filename(cleanup); snprintf(path, sizeof(path), "%s/copy/%s", ec->ec_storage, cleanup); TRACE(TRACE_DEBUG, "JS", "Copying file from '%s' to '%s'", from, path); if(fa_copy(path, from, errbuf, sizeof(errbuf))) duk_error(ctx, DUK_ERR_ERROR, "Copy failed: %s", errbuf); duk_push_string(ctx, path); return 1; }
static int es_sqlite_create(duk_context *ctx) { char path[PATH_MAX]; char errbuf[512]; es_context_t *ec = es_get(ctx); const char *name = duk_safe_to_string(ctx, 0); // Create the db-dir for this plugin snprintf(path, sizeof(path), "%s/databases", ec->ec_storage); if(fa_makedirs(path, errbuf, sizeof(errbuf))) duk_error(ctx, DUK_ERR_ERROR, "Unable to create directory %s -- %s", path, errbuf); snprintf(path, sizeof(path), "%s/databases/%s", ec->ec_storage, name); sqlite3 *db = db_open(path, 0); if(db == NULL) duk_error(ctx, DUK_ERR_ERROR, "Unable to open database -- check logs"); es_sqlite_t *es = es_resource_create(ec, &es_resource_sqlite, 0); es->es_db = db; es->es_name = strdup(name); es_resource_push(ctx, &es->super); return 1; }
static int es_file_basename(duk_context *ctx) { es_context_t *ec = es_get(ctx); char tmp[URL_MAX]; fa_url_get_last_component(tmp, sizeof(tmp), get_filename(ctx, 0, ec, 0)); duk_push_string(ctx, tmp); return 1; }
static int es_file_dirname(duk_context *ctx) { es_context_t *ec = es_get(ctx); const char *filename = mystrdupa(get_filename(ctx, 0, ec, 0)); char *x = strrchr(filename, '/'); if(x) { *x = 0; duk_push_string(ctx, filename); } return 1; }
/** * oldname, newname */ static int es_file_mkdirs(duk_context *ctx) { es_context_t *ec = es_get(ctx); const char *filename = get_filename(ctx, 0, ec, 1); char errbuf[512]; if(fa_makedirs(filename, errbuf, sizeof(errbuf))) duk_error(ctx, DUK_ERR_ERROR, "Unable to mkdir '%s' -- %s", filename, errbuf); return 0; }
static int es_route_create(duk_context *ctx) { const char *str = duk_safe_to_string(ctx, 0); if(str[0] != '^') { int l = strlen(str); char *s = alloca(l + 2); s[0] = '^'; memcpy(s+1, str, l+1); str = s; } es_context_t *ec = es_get(ctx); hts_mutex_lock(&route_mutex); es_route_t *er; LIST_FOREACH(er, &routes, er_link) if(!strcmp(er->er_pattern, str)) break; if(er != NULL) { hts_mutex_unlock(&route_mutex); duk_error(ctx, DUK_ERR_ERROR, "Route %s already exist", str); } er = es_resource_alloc(&es_resource_route); if(hts_regcomp(&er->er_regex, str)) { hts_mutex_unlock(&route_mutex); free(er); duk_error(ctx, DUK_ERR_ERROR, "Invalid regular expression for route %s", str); } er->er_pattern = strdup(str); er->er_prio = strcspn(str, "()[].*?+$") ?: INT32_MAX; LIST_INSERT_SORTED(&routes, er, er_link, er_cmp, es_route_t); es_resource_link(&er->super, ec, 1); hts_mutex_unlock(&route_mutex); es_root_register(ctx, 1, er); es_resource_push(ctx, &er->super); return 1; }
/** * oldname, newname */ static int es_file_rename(duk_context *ctx) { es_context_t *ec = es_get(ctx); const char *oldname = get_filename(ctx, 0, ec, 0); const char *newname = get_filename(ctx, 1, ec, 1); char errbuf[512]; if(fa_rename(oldname, newname, errbuf, sizeof(errbuf))) duk_error(ctx, DUK_ERR_ERROR, "Unable to rename '%s' to '%s' -- %s", oldname, newname, errbuf); return 0; }
static int es_file_open(duk_context *ctx) { char errbuf[512]; es_context_t *ec = es_get(ctx); const char *flagsstr = duk_to_string(ctx, 1); // int mode = duk_to_int(ctx, 2); int flags; if(!strcmp(flagsstr, "r")) { flags = 0; } else if(!strcmp(flagsstr, "w")) { flags = FA_WRITE; } else if(!strcmp(flagsstr, "a")) { flags = FA_WRITE | FA_APPEND; } else { duk_error(ctx, DUK_ERR_ERROR, "Invalid flags '%s' to open", flagsstr); } const char *filename = get_filename(ctx, 0, ec, !!flags); fa_handle_t *fh = fa_open_ex(filename, errbuf, sizeof(errbuf), flags, NULL); if(fh == NULL) duk_error(ctx, DUK_ERR_ERROR, "Unable to open file '%s' -- %s", filename, errbuf); es_fd_t *efd = es_resource_create(ec, &es_resource_fd, 0); efd->efd_path = strdup(filename); efd->efd_fh = fh; es_resource_push(ctx, &efd->super); return 1; }
void ZmqServer::start() { // init estate if(this->peers.size() < 1) es_init(this->estate_node_address.c_str(), this->estate_node_port); else es_init_with_peers(this->estate_node_address.c_str(), this->estate_node_port, this->peers.c_str()); cout << "ZMQ API server listening to port: " << this->local_api_port << endl; while (true) { // prepare messages zmqpp::message response_msg; zmqpp::message request_msg; // receive requests this->recv_socket->receive(request_msg); // work on request if(request_msg.parts() > 1) { //cout << "received: " << request_msg.get(0) << " " << request_msg.get(1) << endl; if(request_msg.get(0) == "SET") { //--- SET command es_set(request_msg.get(1).c_str(), request_msg.get(2).c_str()); response_msg.push_back("OK"); } else if(request_msg.get(0) == "GET") { //--- GET command const char* data = es_get(request_msg.get(1).c_str()); response_msg.push_back("OK"); response_msg.push_back(data); } else if(request_msg.get(0) == "DEL") { //--- DEL command es_del(request_msg.get(1).c_str()); response_msg.push_back("OK"); } else if(request_msg.get(0) == "GET_GLOBAL") { //--- GET_GLOBAL command if(request_msg.get(2) == "LATEST") { const char* data = es_get_global(request_msg.get(1).c_str(), reduce_latest); response_msg.push_back("OK"); response_msg.push_back(data); } else if(request_msg.get(2) == "SUM") { const char* data = es_get_global(request_msg.get(1).c_str(), reduce_sum); response_msg.push_back("OK"); response_msg.push_back(data); } else if(request_msg.get(2) == "AVG") { const char* data = es_get_global(request_msg.get(1).c_str(), reduce_avg); response_msg.push_back("OK"); response_msg.push_back(data); } else { response_msg.push_back("ERROR"); response_msg.push_back("reduce function not implemented"); } } else { response_msg.push_back("ERROR"); response_msg.push_back("unknown command"); } } else { response_msg.push_back("ERROR"); response_msg.push_back("missing message parts"); } // send reply //cout << "sending: " << response_msg.get(0) << endl; this->recv_socket->send(response_msg); } }