static package bf_mysql_status(Var arglist, Byte next, void *vdata, Objid progr) { Var r; Objid oid = arglist.v.list[1].v.obj; free_var(arglist); if (!is_wizard(progr)) return make_error_pack(E_PERM); MYSQL_CONN *wrapper; wrapper = resolve_mysql_connection(oid); if (wrapper == NULL || wrapper->active == 0) return make_error_pack(E_INVARG); r = new_list(7); r.v.list[1].type = TYPE_STR; r.v.list[1].v.str = str_dup(wrapper->server); r.v.list[2].type = TYPE_INT; r.v.list[2].v.num = wrapper->port; r.v.list[3].type = TYPE_STR; r.v.list[3].v.str = str_dup(wrapper->username); r.v.list[4].type = TYPE_STR; r.v.list[4].v.str = str_dup(wrapper->database); r.v.list[5].type = TYPE_INT; r.v.list[5].v.num = wrapper->connect_time; r.v.list[6].type = TYPE_INT; r.v.list[6].v.num = wrapper->last_query_time; r.v.list[7].type = TYPE_INT; r.v.list[7].v.num = mysql_get_server_version(wrapper->conn); return make_var_pack(r); }
static package bf_has_callable_verb(Var arglist, Byte next, void *vdata, Objid progr) { /* (object) */ Objid oid = arglist.v.list[1].v.obj; if (!valid(oid)) { free_var(arglist); return make_error_pack(E_INVARG); } else if (!db_object_allows(oid, progr, FLAG_READ)) { free_var(arglist); return make_error_pack(E_PERM); } else { db_verb_handle vh; Var result; vh = db_find_callable_verb(oid, arglist.v.list[2].v.str); if (vh.ptr) { result = new_list(1); result.v.list[1].type = TYPE_OBJ; result.v.list[1].v.obj = db_verb_definer(vh); } else { result = new_list(0); } free_var(arglist); return make_var_pack(result); } }
static package bf_verb_args(Var arglist, Byte next, void *vdata, Objid progr) { /* (object, verb-desc) */ Objid oid = arglist.v.list[1].v.obj; Var desc = arglist.v.list[2]; db_verb_handle h; db_arg_spec dobj, iobj; db_prep_spec prep; Var r; enum error e; if ((e = validate_verb_descriptor(desc)) != E_NONE || (e = E_INVARG, !valid(oid))) { free_var(arglist); return make_error_pack(e); } h = find_described_verb(oid, desc); free_var(arglist); if (!h.ptr) return make_error_pack(E_VERBNF); else if (!db_verb_allows(h, progr, VF_READ)) return make_error_pack(E_PERM); db_verb_arg_specs(h, &dobj, &prep, &iobj); r = new_list(3); r.v.list[1].type = TYPE_STR; r.v.list[1].v.str = unparse_arg_spec(dobj); r.v.list[2].type = TYPE_STR; r.v.list[2].v.str = str_dup(db_unparse_prep(prep)); r.v.list[3].type = TYPE_STR; r.v.list[3].v.str = unparse_arg_spec(iobj); return make_var_pack(r); }
static package bf_slice(Var arglist, Byte next, void *vdata, Objid progr) { Var ret, list=arglist.v.list[1]; int n=list.v.list[0].v.num, c, i; if(n < 0) { free_var(arglist); make_error_pack(E_INVARG); } ret = new_list(n); InitListToZero(ret); if(arglist.v.list[0].v.num == 2) c = arglist.v.list[2].v.num; else c = 1; for(i = 1; i <= n; i++) if( list.v.list[i].type != TYPE_LIST || list.v.list[i].v.list[0].v.num < c ) { free_var(ret); free_var(arglist); return make_error_pack(E_INVARG); } else { ret.v.list[i] = var_dup(list.v.list[i].v.list[c]); } free_var(arglist); return make_var_pack(ret); }
static package bf_verb_code(Var arglist, Byte next, void *vdata, Objid progr) { /* (object, verb-desc [, fully-paren [, indent]]) */ int nargs = arglist.v.list[0].v.num; Objid oid = arglist.v.list[1].v.obj; Var desc = arglist.v.list[2]; int parens = nargs >= 3 && is_true(arglist.v.list[3]); int indent = nargs < 4 || is_true(arglist.v.list[4]); db_verb_handle h; Var code; enum error e; if ((e = validate_verb_descriptor(desc)) != E_NONE || (e = E_INVARG, !valid(oid))) { free_var(arglist); return make_error_pack(e); } h = find_described_verb(oid, desc); free_var(arglist); if (!h.ptr) return make_error_pack(E_VERBNF); else if (!db_verb_allows(h, progr, VF_READ)) return make_error_pack(E_PERM); code = new_list(0); unparse_program(db_verb_program(h), lister, &code, parens, indent, MAIN_VECTOR); return make_var_pack(code); }
static package bf_set_verb_args(Var arglist, Byte next, void *vdata, Objid progr) { /* (object, verb-desc, {dobj, prep, iobj}) */ Objid oid = arglist.v.list[1].v.obj; Var desc = arglist.v.list[2]; Var args = arglist.v.list[3]; enum error e; db_verb_handle h; db_arg_spec dobj, iobj; db_prep_spec prep; if ((e = validate_verb_descriptor(desc)) != E_NONE); /* Do nothing; e is already set. */ else if (!valid(oid)) e = E_INVARG; else e = validate_verb_args(args, &dobj, &prep, &iobj); if (e != E_NONE) { free_var(arglist); return make_error_pack(e); } h = find_described_verb(oid, desc); free_var(arglist); if (!h.ptr) return make_error_pack(E_VERBNF); else if (!db_verb_allows(h, progr, VF_WRITE)) return make_error_pack(E_PERM); db_set_verb_arg_specs(h, dobj, prep, iobj); return no_var_pack(); }
static package bf_mysql_escape( Var arglist, Byte next, void *vdata, Objid progr) { Var r; MYSQL_CONN *wrapper; if (!is_wizard(progr)) { free_var(arglist); return make_error_pack(E_PERM); } Objid oid = arglist.v.list[1].v.obj; wrapper = resolve_mysql_connection(oid); if (wrapper == NULL || wrapper->conn == NULL || wrapper->active == 0) { free_var(arglist); return make_error_pack(E_INVARG); } const char *string = arglist.v.list[2].v.str; free_var(arglist); ulong bytes = strlen(string); char ostring[(2 * bytes)+1]; mysql_real_escape_string(wrapper->conn,ostring,string,bytes); r.type = TYPE_STR; r.v.str = str_dup(ostring); return make_var_pack(r); }
static package bf_mysql_connect(Var arglist, Byte next, void *vdata, Objid progr) { #ifdef OUTBOUND_NETWORK Var r; char error_string[MOOSQL_ERROR_LEN]; MYSQL_CONN *wrapper; if (!is_wizard(progr)) { free_var(arglist); return make_error_pack(E_PERM); } const char *hostname = arglist.v.list[1].v.str; const int port = arglist.v.list[2].v.num; const char *username = arglist.v.list[3].v.str; const char *password = arglist.v.list[4].v.str; const char *dbname = arglist.v.list[5].v.str; free_var(arglist); /* get rid of that now */ /* try to connect to mysql server */ /* check if we have enough connection slots. */ int index=-1; index = connection_array_index(); if (index == -1) return make_error_pack(E_QUOTA); #ifdef MOOSQL_MULTIPLE_STATEMENTS wrapper = do_mysql_connect(hostname, username, password, dbname, port, NULL, CLIENT_MULTI_STATEMENTS, error_string); #else wrapper = do_mysql_connect(hostname, username, password, dbname, port, NULL, 0, error_string); #endif if (wrapper == NULL || wrapper->conn == NULL) { /* an error happened in the connect, return that as a STR */ r.type = TYPE_STR; r.v.str = str_dup(error_string); return make_var_pack(r); } r.type = TYPE_OBJ; r.v.obj = wrapper->id; return make_var_pack(r); #else /* !OUTBOUND_NETWORK */ /* This function is disabled in this server. */ free_var(arglist); return make_error_pack(E_PERM); #endif }
static package bf_mysql_close(Var arglist, Byte next, void *vdata, Objid progr) { Var r; Objid oid = arglist.v.list[1].v.obj; r.type = TYPE_INT; free_var(arglist); MYSQL_CONN *wrapper; if (!is_wizard(progr)) return make_error_pack(E_PERM); wrapper = resolve_mysql_connection(oid); if (wrapper == NULL) { r.v.num = 0; return make_var_pack(r); } else { wrapper->active = 0; wrapper->id = 0; wrapper->port = 0; wrapper->connect_time = 0; wrapper->last_query_time = 0; r.v.num = 1; } if (mysql_connection_status(wrapper) != 0) { do_mysql_disconnect(wrapper); wrapper->conn = NULL; r.v.num = 1; } return make_var_pack(r); }
static package bf_delete_verb(Var arglist, Byte next, void *vdata, Objid progr) { /* (object, verb-desc) */ Objid oid = arglist.v.list[1].v.obj; Var desc = arglist.v.list[2]; db_verb_handle h; enum error e; if ((e = validate_verb_descriptor(desc)) != E_NONE); /* Do nothing; e is already set. */ else if (!valid(oid)) e = E_INVARG; else if (!db_object_allows(oid, progr, FLAG_WRITE)) e = E_PERM; else { h = find_described_verb(oid, desc); if (h.ptr) db_delete_verb(h); else e = E_VERBNF; } free_var(arglist); if (e == E_NONE) return no_var_pack(); else return make_error_pack(e); }
static package bf_make(Var arglist, Byte next, void *vdata, Objid progr) { Var ret, elt; int n=arglist.v.list[1].v.num, i; if(n < 0) { free_var(arglist); make_error_pack(E_INVARG); } ret = new_list(n); InitListToZero(ret); if(arglist.v.list[0].v.num == 2) { elt = var_dup(arglist.v.list[2]); } else { elt.type = TYPE_INT; elt.v.num = 0; } for(i = 1; i <= n; i++) ret.v.list[i] = var_dup(elt); free_var(elt); free_var(arglist); return make_var_pack(ret); }
static package bf_sort(Var arglist, Byte next, void *vdata, Objid progr) { /* sort(list) => sorts and returns list. sort({1,3,2}) => {1,2,3} */ /* returns E_TYPE is list is not all the same type */ Var sorted = new_list(0), tmp; Var e; int i, l; e.type=TYPE_NONE; for(i = 1; i <= arglist.v.list[1].v.list[0].v.num; i++) { e = var_ref(arglist.v.list[1].v.list[i]); l = find_insert(sorted, e); if(l == -10) { free_var(arglist); free_var(sorted); free_var(e); return make_error_pack(E_TYPE); } tmp = listinsert(var_ref(sorted), var_ref(e), l); free_var(sorted); sorted = var_ref(tmp); free_var(tmp); } free_var(arglist); free_var(e); return make_var_pack(sorted); }
static package bf_is_clear_prop(Var arglist, Byte next, void *vdata, Objid progr) { /* (object, prop-name) */ Objid oid = arglist.v.list[1].v.obj; const char *pname = arglist.v.list[2].v.str; Var r; db_prop_handle h; enum error e; if (!valid(oid)) e = E_INVARG; else { h = db_find_property(oid, pname, 0); if (!h.ptr) e = E_PROPNF; else if (!h.built_in && !db_property_allows(h, progr, PF_READ)) e = E_PERM; else { r.type = TYPE_INT; r.v.num = (!h.built_in && db_property_value(h).type == TYPE_CLEAR); e = E_NONE; } } free_var(arglist); if (e == E_NONE) return make_var_pack(r); else return make_error_pack(e); }
static package bf_clear_prop(Var arglist, Byte next, void *vdata, Objid progr) { /* (object, prop-name) */ Objid oid = arglist.v.list[1].v.obj; const char *pname = arglist.v.list[2].v.str; db_prop_handle h; Var value; enum error e; if (!valid(oid)) e = E_INVARG; else { h = db_find_property(oid, pname, 0); if (!h.ptr) e = E_PROPNF; else if (h.built_in || (progr != db_property_owner(h) && !is_wizard(progr))) e = E_PERM; else if (h.definer == oid) e = E_INVARG; else { value.type = TYPE_CLEAR; db_set_property_value(h, value); e = E_NONE; } } free_var(arglist); if (e == E_NONE) return no_var_pack(); else return make_error_pack(e); }
static package bf_add_prop(Var arglist, Byte next, void *vdata, Objid progr) { /* (object, prop-name, initial-value, initial-info) */ Objid oid = arglist.v.list[1].v.obj; const char *pname = arglist.v.list[2].v.str; Var value = arglist.v.list[3]; Var info = arglist.v.list[4]; Objid owner; unsigned flags; const char *new_name; enum error e; if ((e = validate_prop_info(info, &owner, &flags, &new_name)) != E_NONE); /* Already failed */ else if (new_name) e = E_TYPE; else if (!valid(oid)) e = E_INVARG; else if (!db_object_allows(oid, progr, FLAG_WRITE) || (progr != owner && !is_wizard(progr))) e = E_PERM; else if (!db_add_propdef(oid, pname, value, owner, flags)) e = E_INVARG; free_var(arglist); if (e == E_NONE) return no_var_pack(); else return make_error_pack(e); }
static package bf_add_verb(Var arglist, Byte next, void *vdata, Objid progr) { /* (object, info, args) */ Objid oid = arglist.v.list[1].v.obj; Var info = arglist.v.list[2]; Var args = arglist.v.list[3]; Objid owner; unsigned flags; const char *names; db_arg_spec dobj, iobj; db_prep_spec prep; enum error e; if ((e = validate_verb_info(info, &owner, &flags, &names)) != E_NONE); /* Already failed */ else if ((e = validate_verb_args(args, &dobj, &prep, &iobj)) != E_NONE) free_str(names); else if (!valid(oid)) { free_str(names); e = E_INVARG; } else if (!db_object_allows(oid, progr, FLAG_WRITE) || (progr != owner && !is_wizard(progr))) { free_str(names); e = E_PERM; } else db_add_verb(oid, names, owner, flags, dobj, prep, iobj); free_var(arglist); if (e == E_NONE) return no_var_pack(); else return make_error_pack(e); }
static package bf_urldecode( Var arglist, Byte next, void *vdata, Objid progr) { Var r; CURL *curl_handle; const char *string = arglist.v.list[1].v.str; free_var(arglist); curl_global_init(CURL_GLOBAL_ALL); curl_handle = curl_easy_init(); r.type = TYPE_STR; char *output = curl_easy_unescape(curl_handle,string,0,NULL); if(output == NULL) { curl_free(output); return make_error_pack(E_INVARG); } r.v.str = str_dup(output); curl_free(output); curl_easy_cleanup(curl_handle); curl_global_cleanup(); return make_var_pack(r); }
static package bf_generate_json(Var arglist, Byte next, void *vdata, Objid progr) { yajl_gen g; yajl_gen_config cfg = { 0, "" }; struct generate_context gctx; gctx.mode = MODE_COMMON_SUBSET; const char *buf; unsigned int len; Var json; package pack; if (1 < arglist.v.list[0].v.num) { if (!mystrcasecmp(arglist.v.list[2].v.str, "common-subset")) { gctx.mode = MODE_COMMON_SUBSET; } else if (!mystrcasecmp(arglist.v.list[2].v.str, "embedded-types")) { gctx.mode = MODE_EMBEDDED_TYPES; } else { free_var(arglist); return make_error_pack(E_INVARG); } } g = yajl_gen_alloc(&cfg, NULL); if (yajl_gen_status_ok == generate(g, arglist.v.list[1], &gctx)) { yajl_gen_get_buf(g, (const unsigned char **)&buf, &len); json.type = TYPE_STR; json.v.str = str_dup(buf); pack = make_var_pack(json); } else { pack = make_error_pack(E_INVARG); } yajl_gen_clear(g); yajl_gen_free(g); free_var(arglist); return pack; }
static package bf_verb_info(Var arglist, Byte next, void *vdata, Objid progr) { /* (object, verb-desc) */ Objid oid = arglist.v.list[1].v.obj; Var desc = arglist.v.list[2]; db_verb_handle h; Var r; unsigned flags; char perms[5], *s; enum error e; if ((e = validate_verb_descriptor(desc)) != E_NONE || (e = E_INVARG, !valid(oid))) { free_var(arglist); return make_error_pack(e); } h = find_described_verb(oid, desc); free_var(arglist); if (!h.ptr) return make_error_pack(E_VERBNF); else if (!db_verb_allows(h, progr, VF_READ)) return make_error_pack(E_PERM); r = new_list(3); r.v.list[1].type = TYPE_OBJ; r.v.list[1].v.obj = db_verb_owner(h); r.v.list[2].type = TYPE_STR; s = perms; flags = db_verb_flags(h); if (flags & VF_READ) *s++ = 'r'; if (flags & VF_WRITE) *s++ = 'w'; if (flags & VF_EXEC) *s++ = 'x'; if (flags & VF_DEBUG) *s++ = 'd'; *s = '\0'; r.v.list[2].v.str = str_dup(perms); r.v.list[3].type = TYPE_STR; r.v.list[3].v.str = str_ref(db_verb_names(h)); return make_var_pack(r); }
static package bf_eval(Var arglist, Byte next, void *data, Objid progr) { package p; if (next == 1) { if (!is_programmer(progr)) { free_var(arglist); p = make_error_pack(E_PERM); } else { Var errors; Program *program = parse_list_as_program(arglist, &errors); free_var(arglist); if (program) { free_var(errors); if (setup_activ_for_eval(program)) p = make_call_pack(2, 0); else { free_program(program); p = make_error_pack(E_MAXREC); } } else { Var r; r = new_list(2); r.v.list[1].type = TYPE_INT; r.v.list[1].v.num = 0; r.v.list[2] = errors; p = make_var_pack(r); } } } else { /* next == 2 */ Var r; r = new_list(2); r.v.list[1].type = TYPE_INT; r.v.list[1].v.num = 1; r.v.list[2] = arglist; p = make_var_pack(r); } return p; }
static package bf_log_cache_stats(Var arglist, Byte next, void *vdata, Objid progr) { free_var(arglist); if (!is_wizard(progr)) { return make_error_pack(E_PERM); } db_log_cache_stats(); return no_var_pack(); }
static package bf_verbs(Var arglist, Byte next, void *vdata, Objid progr) { /* (object) */ Objid oid = arglist.v.list[1].v.obj; free_var(arglist); if (!valid(oid)) return make_error_pack(E_INVARG); else if (!db_object_allows(oid, progr, FLAG_READ)) return make_error_pack(E_PERM); else { struct verb_data d; d.r = new_list(db_count_verbs(oid)); d.i = 0; db_for_all_verbs(oid, add_to_list, &d); return make_var_pack(d.r); } }
static package bf_set_verb_code(Var arglist, Byte next, void *vdata, Objid progr) { /* (object, verb-desc, code) */ Objid oid = arglist.v.list[1].v.obj; Var desc = arglist.v.list[2]; Var code = arglist.v.list[3]; int i; Program *program; db_verb_handle h; Var errors; enum error e; for (i = 1; i <= code.v.list[0].v.num; i++) if (code.v.list[i].type != TYPE_STR) { free_var(arglist); return make_error_pack(E_TYPE); } if ((e = validate_verb_descriptor(desc)) != E_NONE || (e = E_INVARG, !valid(oid))) { free_var(arglist); return make_error_pack(e); } h = find_described_verb(oid, desc); if (!h.ptr) { free_var(arglist); return make_error_pack(E_VERBNF); } else if (!is_programmer(progr) || !db_verb_allows(h, progr, VF_WRITE)) { free_var(arglist); return make_error_pack(E_PERM); } program = parse_list_as_program(code, &errors); if (program) { if (task_timed_out) free_program(program); else db_set_verb_program(h, program); } free_var(arglist); return make_var_pack(errors); }
static package bf_prop_info(Var arglist, Byte next, void *vdata, Objid progr) { /* (object, prop-name) */ Objid oid = arglist.v.list[1].v.obj; const char *pname = arglist.v.list[2].v.str; db_prop_handle h; Var r; unsigned flags; char *s; if (!valid(oid)) { free_var(arglist); return make_error_pack(E_INVARG); } h = db_find_property(oid, pname, 0); free_var(arglist); if (!h.ptr || h.built_in) return make_error_pack(E_PROPNF); else if (!db_property_allows(h, progr, PF_READ)) return make_error_pack(E_PERM); r = new_list(2); r.v.list[1].type = TYPE_OBJ; r.v.list[1].v.obj = db_property_owner(h); r.v.list[2].type = TYPE_STR; r.v.list[2].v.str = s = str_dup("xxx"); flags = db_property_flags(h); if (flags & PF_READ) *s++ = 'r'; if (flags & PF_WRITE) *s++ = 'w'; if (flags & PF_CHOWN) *s++ = 'c'; if (flags & PF_PRIVATE) *s++ = 'p'; *s = '\0'; return make_var_pack(r); }
static package bf_set_verb_info(Var arglist, Byte next, void *vdata, Objid progr) { /* (object, verb-desc, {owner, flags, names}) */ Objid oid = arglist.v.list[1].v.obj; Var desc = arglist.v.list[2]; Var info = arglist.v.list[3]; Objid new_owner; unsigned new_flags; const char *new_names; enum error e; db_verb_handle h; if ((e = validate_verb_descriptor(desc)) != E_NONE); /* Do nothing; e is already set. */ else if (!valid(oid)) e = E_INVARG; else e = validate_verb_info(info, &new_owner, &new_flags, &new_names); if (e != E_NONE) { free_var(arglist); return make_error_pack(e); } h = find_described_verb(oid, desc); free_var(arglist); if (!h.ptr) { free_str(new_names); return make_error_pack(E_VERBNF); } else if (!db_verb_allows(h, progr, VF_WRITE) || (!is_wizard(progr) && db_verb_owner(h) != new_owner)) { free_str(new_names); return make_error_pack(E_PERM); } db_set_verb_owner(h, new_owner); db_set_verb_flags(h, new_flags); db_set_verb_names(h, new_names); return no_var_pack(); }
static package bf_set_prop_info(Var arglist, Byte next, void *vdata, Objid progr) { /* (object, prop-name, {owner, perms [, new-name]}) */ Objid oid = arglist.v.list[1].v.obj; const char *pname = arglist.v.list[2].v.str; Var info = arglist.v.list[3]; enum error e = set_prop_info(oid, pname, info, progr); free_var(arglist); if (e == E_NONE) return no_var_pack(); else return make_error_pack(e); }
static package bf_mysql_ping(Var arglist, Byte next, void *vdata, Objid progr) { /* we will return 1 if the connection is active, 0 if it is not */ Var r; Objid oid = arglist.v.list[1].v.obj; free_var(arglist); if (!is_wizard(progr)) return make_error_pack(E_PERM); MYSQL_CONN *wrapper; wrapper = resolve_mysql_connection(oid); r.type = TYPE_INT; r.v.num = mysql_connection_status(wrapper); return make_var_pack(r); }
static package bf_verb_cache_stats(Var arglist, Byte next, void *vdata, Objid progr) { Var r; free_var(arglist); if (!is_wizard(progr)) { return make_error_pack(E_PERM); } r = db_verb_cache_stats(); return make_var_pack(r); }
static package bf_has_property(Var arglist, Byte next, void *vdata, Objid progr) { /* (object) */ Objid oid = arglist.v.list[1].v.obj; if (!valid(oid)) { free_var(arglist); return make_error_pack(E_INVARG); } else if (!db_object_allows(oid, progr, FLAG_READ)) { free_var(arglist); return make_error_pack(E_PERM); } else { Var result; result.type = TYPE_INT; if (db_find_property(oid, arglist.v.list[2].v.str, 0).ptr) { result.v.num = 1; } else { result.v.num = 0; } free_var(arglist); return make_var_pack(result); } }
static package bf_assoc(Var arglist, Byte next, void *vdata, Objid progr) { /* (ANY, LIST[, INT]) */ Var r; int index = 1; if (arglist.v.list[0].v.num == 3) index = arglist.v.list[3].v.num; if (index < 1) { free_var(arglist); return make_error_pack(E_RANGE); } r = list_assoc(arglist.v.list[1], arglist.v.list[2], index); free_var(arglist); return make_var_pack(r); } /* end bf_listassoc() */