#include "config.h" #include <math.h> #include <ctype.h> #include "params.h" #include "db.h" #include "tune.h" #include "mpi.h" #include "mcp.h" #include "externs.h" #include "props.h" #include "match.h" #include "interp.h" #include "interface.h" #include "msgparse.h" struct line *get_new_line(void); void show_mcp_error(McpFrame * mfr, char *topic, char *text) { McpMesg msg; McpVer supp = mcp_frame_package_supported(mfr, "org-fuzzball-notify"); if (supp.verminor != 0 || supp.vermajor != 0) { mcp_mesg_init(&msg, "org-fuzzball-notify", "error"); mcp_mesg_arg_append(&msg, "text", text); mcp_mesg_arg_append(&msg, "topic", topic); mcp_frame_output_mesg(mfr, &msg); mcp_mesg_clear(&msg); } else { notify(mcpframe_to_user(mfr), text); } } /* * reference is in the format objnum.category.misc where objnum is the * object reference, and category can be one of the following: * prop to set a property named by misc. * proplist to store a string proplist named by misc. * prog to set the program text of the given object. Ignores misc. * sysparm to set an @tune value. Ignores objnum. * user to return data to a muf program. * * If the category is prop, then it accepts the following types: * string to set the property to a string value. * string-list to set the property to a multi-line string value. * integer to set the property to an integer value. * * Any other values are ignored. */ void mcppkg_simpleedit(McpFrame * mfr, McpMesg * msg, McpVer ver, void *context) { if (!string_compare(msg->mesgname, "set")) { dbref obj = NOTHING; char *reference; char *valtype; char category[BUFFER_LEN]; char *ptr; int lines; dbref player; char buf[BUFFER_LEN]; char *content; int line; int descr; reference = mcp_mesg_arg_getline(msg, "reference", 0); valtype = mcp_mesg_arg_getline(msg, "type", 0); lines = mcp_mesg_arg_linecount(msg, "content"); player = mcpframe_to_user(mfr); descr = mcpframe_to_descr(mfr); /* extract object number. -1 for none. */ if (isdigit(*reference)) { obj = 0; while (isdigit(*reference)) { obj = (10 * obj) + (*reference++ - '0'); if (obj >= 100000000) { show_mcp_error(mfr, "simpleedit-set", "Bad reference object."); return; } } } if (*reference != '.') { show_mcp_error(mfr, "simpleedit-set", "Bad reference value."); return; } reference++; /* extract category string */ ptr = category; while (*reference && *reference != '.') { *ptr++ = *reference++; } *ptr = '\0'; if (*reference != '.') { show_mcp_error(mfr, "simpleedit-set", "Bad reference value."); return; } reference++; /* the rest is category specific data. */ if (!string_compare(category, "prop")) { if (obj < 0 || obj >= db_top || Typeof(obj) == TYPE_GARBAGE) { show_mcp_error(mfr, "simpleedit-set", "Bad reference object."); return; } if (!controls(player, obj)) { show_mcp_error(mfr, "simpleedit-set", "Permission denied."); return; } for (ptr = reference; *ptr; ptr++) { if (*ptr == ':') { show_mcp_error(mfr, "simpleedit-set", "Bad property name."); return; } } if (Prop_System(reference) || (!Wizard(player) && (Prop_SeeOnly(reference) || Prop_Hidden(reference)))) { show_mcp_error(mfr, "simpleedit-set", "Permission denied."); return; } if (!string_compare(valtype, "string-list") || !string_compare(valtype, "string")) { int left = BUFFER_LEN - 1; int len; buf[0] = '\0'; for (line = 0; line < lines; line++) { content = mcp_mesg_arg_getline(msg, "content", line); if (line > 0) { if (left >= 1) { strcatn(buf, sizeof(buf), "\r"); left--; } else { break; } } len = strlen(content); if (len >= left - 1) { strncat(buf, content, left); left = 0; break; } else { strcatn(buf, sizeof(buf), content); left -= len; } } buf[BUFFER_LEN - 1] = '\0'; add_property(obj, reference, buf, 0); } else if (!string_compare(valtype, "integer")) { if (lines != 1) { show_mcp_error(mfr, "simpleedit-set", "Bad integer value."); return; } content = mcp_mesg_arg_getline(msg, "content", 0); add_property(obj, reference, NULL, atoi(content)); } } else if (!string_compare(category, "proplist")) { if (obj < 0 || obj >= db_top || Typeof(obj) == TYPE_GARBAGE) { show_mcp_error(mfr, "simpleedit-set", "Bad reference object."); return; } if (!controls(player, obj)) { show_mcp_error(mfr, "simpleedit-set", "Permission denied."); return; } for (ptr = reference; *ptr; ptr++) { if (*ptr == ':') { show_mcp_error(mfr, "simpleedit-set", "Bad property name."); return; } } if (Prop_System(reference) || (!Wizard(player) && (Prop_SeeOnly(reference) || Prop_Hidden(reference)))) { show_mcp_error(mfr, "simpleedit-set", "Permission denied."); return; } if (!string_compare(valtype, "string-list")) { if (lines == 0) { snprintf(buf, sizeof(buf), "%s#", reference); remove_property(obj, buf); } else { snprintf(buf, sizeof(buf), "%s#", reference); remove_property(obj, buf); add_property(obj, buf, "", lines); for (line = 0; line < lines; line++) { content = mcp_mesg_arg_getline(msg, "content", line); if (!content || !*content) { content = " "; } snprintf(buf, sizeof(buf), "%s#/%d", reference, line + 1); add_property(obj, buf, content, 0); } } } else if (!string_compare(valtype, "string") || !string_compare(valtype, "integer")) { show_mcp_error(mfr, "simpleedit-set", "Bad value type for proplist."); return; } } else if (!string_compare(category, "prog")) { struct line *tmpline; struct line *curr = NULL; struct line *new_line; if (obj < 0 || obj >= db_top || Typeof(obj) == TYPE_GARBAGE) { show_mcp_error(mfr, "simpleedit-set", "Bad reference object."); return; } if (Typeof(obj) != TYPE_PROGRAM || !controls(player, obj)) { show_mcp_error(mfr, "simpleedit-set", "Permission denied."); return; } if (!Mucker(player)) { show_mcp_error(mfr, "simpleedit-set", "Permission denied."); return; } if (FLAGS(obj) & INTERNAL) { show_mcp_error(mfr, "simpleedit-set", "Sorry, this program is currently being edited. Try again later."); return; } tmpline = PROGRAM_FIRST(obj); PROGRAM_SET_FIRST(obj, NULL); for (line = 0; line < lines; line++) { new_line = get_new_line(); content = mcp_mesg_arg_getline(msg, "content", line); if (!content || !*content) { new_line->this_line = alloc_string(" "); } else { new_line->this_line = alloc_string(content); } new_line->next = NULL; if (line == 0) { PROGRAM_SET_FIRST(obj, new_line); } else { curr->next = new_line; } curr = new_line; } log_status("PROGRAM SAVED: %s by %s(%d)\n", unparse_object(player, obj), NAME(player), player); write_program(PROGRAM_FIRST(obj), obj); if (tp_log_programs) log_program_text(PROGRAM_FIRST(obj), player, obj); do_compile(descr, player, obj, 1); free_prog_text(PROGRAM_FIRST(obj)); PROGRAM_SET_FIRST(obj, tmpline); DBDIRTY(player); DBDIRTY(obj); } else if (!string_compare(category, "sysparm")) { if (!Wizard(player)) { show_mcp_error(mfr, "simpleedit-set", "Permission denied."); return; } if (lines != 1) { show_mcp_error(mfr, "simpleedit-set", "Bad @tune value."); return; } content = mcp_mesg_arg_getline(msg, "content", 0); tune_setparm(reference, content); } else if (!string_compare(category, "user")) { } else { show_mcp_error(mfr, "simpleedit-set", "Unknown reference category."); return; } } }