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_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_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); }
int db_object_allows(Objid oid, Objid progr, db_object_flag f) { return (progr == db_object_owner(oid) || is_wizard(progr) || db_object_has_flag(oid, f)); }
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_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); }
int immune_asp(object p) { //check if the person is immune to asphyxiation if( p->test_prop(WaterBreatheP) || p->test_prop(NoBreatheP) || !interactive(p) || p->query_ghost() || !present(p, THISO) || is_wizard(p) ) {return 1;} //they are immune drowning! } //end immune_asp
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_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_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_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_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 enum error set_prop_info(Objid oid, const char *pname, Var info, Objid progr) { Objid new_owner; unsigned new_flags; const char *new_name; enum error e; db_prop_handle h; if (!valid(oid)) e = E_INVARG; else e = validate_prop_info(info, &new_owner, &new_flags, &new_name); if (e != E_NONE) return e; h = db_find_property(oid, pname, 0); if (!h.ptr || h.built_in) return E_PROPNF; else if (!db_property_allows(h, progr, PF_WRITE) || (!is_wizard(progr) && db_property_owner(h) != new_owner)) return E_PERM; if (new_name) { if (!db_rename_propdef(oid, pname, new_name)) return E_INVARG; h = db_find_property(oid, new_name, 0); } db_set_property_owner(h, new_owner); db_set_property_flags(h, new_flags); return E_NONE; }
static package bf_mysql_connections(Var arglist, Byte next, void *vdata, Objid progr) { Var r; free_var(arglist); if (!is_wizard(progr)) return make_error_pack(E_PERM); int count=0; int lcv=0; for (lcv=0;lcv<MOOSQL_MAX_CON;lcv++) if (SQL_CONNECTIONS[lcv].active == 1) count++; r = new_list(count); /* needed to know how many to allocate the list firstly */ count = 0; for (lcv=0;lcv<MOOSQL_MAX_CON;lcv++) { if (SQL_CONNECTIONS[lcv].active == 1) { count++; r.v.list[count].type = TYPE_OBJ; r.v.list[count].v.obj = SQL_CONNECTIONS[lcv].id; } } return make_var_pack(r); }
/* Permissions should all be IN-DB!! * Except can_program, because without that someone could take control * of their objects out of the hands of wizards. * Robin Powell, May 14, 1998 * */ int can_program(Objid player, Objid what) { return (owns(player, what) || is_wizard(player)); }
static package bf_mysql_query( Var arglist, Byte next, void *vdata, Objid progr) { Var r; char error_string[MOOSQL_ERROR_LEN]; MYSQL_CONN *wrapper; MYSQL_RES *res_set; #ifdef MOOSQL_MULTIPLE_STATEMENTS Var tmp; Var end; int len = 0; int continu = 1; #endif 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 *query = arglist.v.list[2].v.str; free_var(arglist); /* we do the query now. */ if (mysql_query (wrapper->conn, query) != 0) /* failed */ { /* there is an error, so we will return that string. similar to below which * returns a string for a successful query with no result set which is handled in * process_mysql_query */ snprintf(error_string,MOOSQL_ERROR_LEN,"ERR: %s",mysql_error(wrapper->conn)); r.type = TYPE_STR; r.v.str = str_dup(error_string); return make_var_pack(r); } wrapper->last_query_time = time(0); #ifdef MOOSQL_MULTIPLE_STATEMENTS r = new_list(1); r.v.list[1].type = TYPE_INT; r.v.list[1].v.num = 0; end = new_list(0); while (continu) { len++; res_set = process_mysql_query(wrapper,error_string); if (res_set == NULL) /* there was no result on this query */ { tmp.type = TYPE_STR; tmp.v.str = str_dup(error_string); end = listappend(end,var_dup(tmp)); } else { tmp = process_result_set(wrapper,res_set); end = listappend(end,var_dup(tmp)); } if (mysql_more_results(wrapper->conn)) { mysql_next_result(wrapper->conn); continu = 1; } else continu = 0; } if (len <= 1) /* if there is only one result return it like in previous versions, a list of rows */ return make_var_pack(end.v.list[1]); r.v.list[1].v.num = len; /* if there are more return it in this format {X, Y} where X is the number of results and Y is a list of results */ r = listappend(r,end); return make_var_pack(r); #else res_set = process_mysql_query(wrapper,error_string); if (res_set == NULL) /* there was either an error / no result on this query */ { r.type = TYPE_STR; r.v.str = str_dup(error_string); return make_var_pack(r); } r = process_result_set(wrapper,res_set); return make_var_pack(r); #endif }
static package bf_http_request( Var arglist, Byte next, void *vdata, Objid progr) { CURL *curl_handle; CURLcode ok; package result; if (!is_wizard(progr)) { free_var(arglist); return make_error_pack(E_PERM); } int nargs = arglist.v.list[0].v.num; const char *address = arglist.v.list[1].v.str; const char *agent="",*postfields="",*cookies=""; int headers = 0; switch(nargs) { case 5: cookies = arglist.v.list[5].v.str; case 4: postfields = arglist.v.list[4].v.str; case 3: agent = arglist.v.list[3].v.str; case 2: headers = arglist.v.list[2].v.num; } if(!strlen(agent)) agent = "MOO-http/1.0"; const char delimiters[] = "\n"; free_var(arglist); struct MemoryStruct chunk; chunk.memory = malloc(1); chunk.size = 0; curl_global_init(CURL_GLOBAL_ALL); curl_handle = curl_easy_init(); curl_easy_setopt(curl_handle, CURLOPT_URL, address); curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, agent); curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 5); curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, 3); curl_easy_setopt(curl_handle, CURLOPT_FTP_RESPONSE_TIMEOUT, 3); curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 5); curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl_handle, CURLOPT_MAXFILESIZE, 1048576); if(strlen(postfields)) curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, postfields); if(strlen(cookies)) curl_easy_setopt(curl_handle, CURLOPT_COOKIE, cookies); if(headers) curl_easy_setopt(curl_handle, CURLOPT_HEADER, 1); ok = curl_easy_perform(curl_handle); curl_easy_cleanup(curl_handle); if(ok == CURLE_OK && strlen(chunk.memory) != chunk.size) ok = CURLE_BAD_CONTENT_ENCODING; // binary !!! if(ok == CURLE_OK) { char *token,*p=chunk.memory; Var r; r.type = TYPE_LIST; r = new_list(0); token = strsep(&p, delimiters); while( token != NULL ) { Var line; line.type = TYPE_STR; if(token[strlen(token)-1] == '\r') token[strlen(token)-1] = '\0'; //run it through utf8_substr to get rid of invalid utf8 line.v.str = (char *)utf8_substr(token,1,utf8_strlen(token)); r = listappend(r, var_dup(line)); token = strsep(&p, delimiters); free_var(line); } result = make_var_pack(r); } else { Var r; r.type = TYPE_INT; r.v.num = ok; result = make_raise_pack(E_INVARG, curl_easy_strerror(ok), r); } if(chunk.memory) free(chunk.memory); curl_global_cleanup(); return result; }