void mcp_frame_package_renegotiate(const char* package) { McpVer nullver = { 0, 0 }; McpFrameList* mfrl = mcp_frame_list; McpFrame* mfr; McpMesg cando; char verbuf[32]; McpPkg *p; p = mcp_PackageList; while (p) { if (!strcmp_nocase(p->pkgname, package)) { break; } p = p->next; } if (!p) { mcp_mesg_init(&cando, MCP_NEGOTIATE_PKG, "can"); mcp_mesg_arg_append(&cando, "package", package); mcp_mesg_arg_append(&cando, "min-version", "0.0"); mcp_mesg_arg_append(&cando, "max-version", "0.0"); } else { mcp_mesg_init(&cando, MCP_NEGOTIATE_PKG, "can"); mcp_mesg_arg_append(&cando, "package", p->pkgname); snprintf(verbuf, sizeof(verbuf), "%d.%d", p->minver.vermajor, p->minver.verminor); mcp_mesg_arg_append(&cando, "min-version", verbuf); snprintf(verbuf, sizeof(verbuf), "%d.%d", p->maxver.vermajor, p->maxver.verminor); mcp_mesg_arg_append(&cando, "max-version", verbuf); } while (mfrl) { mfr = mfrl->mfr; if (mfr->enabled) { if (mcp_version_compare(mfr->version, nullver) > 0) { mcp_frame_package_remove(mfr, package); mcp_frame_output_mesg(mfr, &cando); } } mfrl = mfrl->next; } mcp_mesg_clear(&cando); /* mcp_mesg_init(&cando, MCP_NEGOTIATE_PKG, "end"); mcp_frame_output_mesg(mfr, &cando); mcp_mesg_clear(&cando); */ }
int GuiMenuItem(const char *dlogid, const char *id, const char *type, const char *name, const char **args) { McpMesg msg; McpFrame *mfr; int i; int descr = gui_dlog_get_descr(dlogid); mfr = descr_mcpframe(descr); if (!mfr) { return EGUINODLOG; } if (GuiSupported(descr)) { mcp_mesg_init(&msg, GUI_PACKAGE, "menu-item"); mcp_mesg_arg_append(&msg, "dlogid", dlogid); mcp_mesg_arg_append(&msg, "id", id); mcp_mesg_arg_append(&msg, "name", name); mcp_mesg_arg_append(&msg, "type", name); i = 0; while (args && args[i]) { const char *arg = args[i]; const char *val = args[i + 1]; mcp_mesg_arg_append(&msg, arg, val); i += 2; } mcp_frame_output_mesg(mfr, &msg); mcp_mesg_clear(&msg); return 0; } return EGUINOSUPPORT; }
int GuiListDel(const char *dlogid, const char *id, int from, int to) { McpMesg msg; McpFrame *mfr; char numbuf[32]; int descr = gui_dlog_get_descr(dlogid); mfr = descr_mcpframe(descr); if (!mfr) { return EGUINODLOG; } if (GuiSupported(descr)) { mcp_mesg_init(&msg, GUI_PACKAGE, "list-delete"); mcp_mesg_arg_append(&msg, "dlogid", dlogid); mcp_mesg_arg_append(&msg, "id", id); if (from == GUI_LIST_END) { mcp_mesg_arg_append(&msg, "from", "end"); } else { snprintf(numbuf, sizeof(numbuf), "%d", from); mcp_mesg_arg_append(&msg, "from", numbuf); } if (to == GUI_LIST_END) { mcp_mesg_arg_append(&msg, "to", "end"); } else { snprintf(numbuf, sizeof(numbuf), "%d", to); mcp_mesg_arg_append(&msg, "to", numbuf); } mcp_frame_output_mesg(mfr, &msg); mcp_mesg_clear(&msg); return 0; } return EGUINOSUPPORT; }
int GuiListInsert(const char *dlogid, const char *id, int after, int lines, const char **value) { McpMesg msg; McpFrame *mfr; char numbuf[32]; int i; int descr = gui_dlog_get_descr(dlogid); mfr = descr_mcpframe(descr); if (!mfr) { return EGUINODLOG; } if (GuiSupported(descr)) { mcp_mesg_init(&msg, GUI_PACKAGE, "list-insert"); mcp_mesg_arg_append(&msg, "dlogid", dlogid); mcp_mesg_arg_append(&msg, "id", id); if (after > 0) { snprintf(numbuf, sizeof(numbuf), "%d", after); mcp_mesg_arg_append(&msg, "after", numbuf); } for (i = 0; i < lines; i++) { mcp_mesg_arg_append(&msg, "values", value[i]); } mcp_frame_output_mesg(mfr, &msg); mcp_mesg_clear(&msg); return 0; } return EGUINOSUPPORT; }
int GuiSetVal(const char *dlogid, const char *id, int lines, const char **value) { McpMesg msg; McpFrame *mfr; int i; int descr = gui_dlog_get_descr(dlogid); mfr = descr_mcpframe(descr); if (!mfr) { return EGUINODLOG; } if (GuiSupported(descr)) { mcp_mesg_init(&msg, GUI_PACKAGE, "ctrl-value"); mcp_mesg_arg_append(&msg, "dlogid", dlogid); mcp_mesg_arg_append(&msg, "id", id); for (i = 0; i < lines; i++) { mcp_mesg_arg_append(&msg, "value", value[i]); } mcp_frame_output_mesg(mfr, &msg); mcp_mesg_clear(&msg); gui_value_set_local(dlogid, id, lines, value); return 0; } return EGUINOSUPPORT; }
const char * GuiHelper(int descr, const char *title, int pagecount, const char **pagenames, const char **pageids, Gui_CB callback, GuiErr_CB error_cb, void *context) { McpMesg msg; McpFrame *mfr = descr_mcpframe(descr); const char *id; int i; if (!mfr) { return NULL; } if (GuiSupported(descr)) { id = gui_dlog_alloc(descr, callback, error_cb, context); mcp_mesg_init(&msg, GUI_PACKAGE, "dlog-create"); mcp_mesg_arg_append(&msg, "dlogid", id); mcp_mesg_arg_append(&msg, "type", "helper"); mcp_mesg_arg_append(&msg, "title", title); for (i = 0; i < pagecount; i++) { mcp_mesg_arg_append(&msg, "panes", pageids[i]); mcp_mesg_arg_append(&msg, "names", pagenames[i]); } mcp_frame_output_mesg(mfr, &msg); mcp_mesg_clear(&msg); return id; } else { return NULL; } }
int gui_dlog_closeall_descr(int descr) { DlogData *ptr; McpMesg msg; ptr = dialog_list; while (ptr) { while (ptr) { if (ptr->descr == descr) { break; } ptr = ptr->next; } if (!ptr) { return 0; } if (ptr->callback) { mcp_mesg_init(&msg, GUI_PACKAGE, "ctrl-event"); mcp_mesg_arg_append(&msg, "dlogid", ptr->id); mcp_mesg_arg_append(&msg, "id", "_closed"); mcp_mesg_arg_append(&msg, "dismissed", "1"); mcp_mesg_arg_append(&msg, "event", "buttonpress"); ptr->callback(ptr->descr, ptr->id, "_closed", "buttonpress", &msg, 1, ptr->context); mcp_mesg_clear(&msg); } ptr = ptr->next; } return 0; }
void mcpedit_program(int descr, dbref player, dbref prog, const char *name, McpFrame *mfr) { char namestr[BUFFER_LEN]; char refstr[BUFFER_LEN]; struct line *curr; McpMesg msg; McpVer supp; supp = mcp_frame_package_supported(mfr, "dns-org-mud-moo-simpleedit"); if (supp.verminor == 0 && supp.vermajor == 0) { do_prog(descr, player, name); return; } FLAGS(prog) |= INTERNAL; snprintf(refstr, sizeof(refstr), "%d.prog.", prog); snprintf(namestr, sizeof(namestr), "a program named %s(%d)", NAME(prog), prog); mcp_mesg_init(&msg, "dns-org-mud-moo-simpleedit", "content"); mcp_mesg_arg_append(&msg, "reference", refstr); mcp_mesg_arg_append(&msg, "type", "muf-code"); mcp_mesg_arg_append(&msg, "name", namestr); for (curr = DBFETCH(prog)->sp.program.first; curr; curr = curr->next) mcp_mesg_arg_append(&msg, "content", DoNull(curr->this_line)); mcp_frame_output_mesg(mfr, &msg); mcp_mesg_clear(&msg); free_prog_text(DBFETCH(prog)->sp.program.first); DBFETCH(prog)->sp.program.first = NULL; }
int gui_ctrl_make_l(const char *dlogid, const char *type, const char *pane, const char *id, const char *text, const char *value, int layout, ...) { va_list ap; McpMesg msg; McpFrame *mfr; int descr; va_start(ap, layout); descr = gui_dlog_get_descr(dlogid); mfr = descr_mcpframe(descr); if (!mfr) { va_end(ap); return EGUINODLOG; } if (GuiSupported(descr)) { char cmdname[64]; snprintf(cmdname, sizeof(cmdname), "ctrl-%.55s", type); mcp_mesg_init(&msg, GUI_PACKAGE, cmdname); gui_ctrl_process_layout(&msg, layout); mcp_mesg_arg_append(&msg, "dlogid", dlogid); mcp_mesg_arg_append(&msg, "id", id); if (text) mcp_mesg_arg_append(&msg, "text", text); if (value) { mcp_mesg_arg_append(&msg, "value", value); if (id) { gui_value_set_local(dlogid, id, 1, &value); } } if (pane) mcp_mesg_arg_append(&msg, "pane", pane); while (1) { const char *val; const char *arg; arg = va_arg(ap, const char *); if (!arg) break; val = va_arg(ap, const char *); mcp_mesg_arg_append(&msg, arg, val); } mcp_frame_output_mesg(mfr, &msg); mcp_mesg_clear(&msg); va_end(ap); return 0; } va_end(ap); return EGUINOSUPPORT; }
void mcp_negotiation_start(McpFrame * mfr) { McpMesg reply; mfr->enabled = 1; mcp_mesg_init(&reply, MCP_INIT_PKG, ""); mcp_mesg_arg_append(&reply, "version", "2.1"); mcp_mesg_arg_append(&reply, "to", "2.1"); mcp_frame_output_mesg(mfr, &reply); mcp_mesg_clear(&reply); mfr->enabled = 0; }
int gui_ctrl_make_v(const char *dlogid, const char *type, const char *pane, const char *id, const char *text, const char *value, int layout, const char **args) { McpMesg msg; McpFrame *mfr; int descr; int i; descr = gui_dlog_get_descr(dlogid); mfr = descr_mcpframe(descr); if (!mfr) { return EGUINODLOG; } if (GuiSupported(descr)) { char cmdname[64]; snprintf(cmdname, sizeof(cmdname), "ctrl-%.55s", type); mcp_mesg_init(&msg, GUI_PACKAGE, cmdname); gui_ctrl_process_layout(&msg, layout); mcp_mesg_arg_append(&msg, "dlogid", dlogid); mcp_mesg_arg_append(&msg, "id", id); if (text) mcp_mesg_arg_append(&msg, "text", text); if (value) { mcp_mesg_arg_append(&msg, "value", value); if (id) { gui_value_set_local(dlogid, id, 1, &value); } } if (pane) mcp_mesg_arg_append(&msg, "pane", pane); i = 0; while (args && args[i]) { const char *arg = args[i]; const char *val = args[i + 1]; if (id && !string_compare(arg, "value")) { gui_value_set_local(dlogid, id, 1, &val); } mcp_mesg_arg_append(&msg, arg, val); i += 2; } mcp_frame_output_mesg(mfr, &msg); mcp_mesg_clear(&msg); return 0; } return EGUINOSUPPORT; }
int GuiClose(const char *id) { McpMesg msg; McpFrame *mfr; int descr = gui_dlog_get_descr(id); mfr = descr_mcpframe(descr); if (!mfr) { return EGUINODLOG; } if (GuiSupported(descr)) { if (!GuiClosed(id)) { mcp_mesg_init(&msg, GUI_PACKAGE, "dlog-close"); mcp_mesg_arg_append(&msg, "dlogid", id); mcp_frame_output_mesg(mfr, &msg); mcp_mesg_clear(&msg); } return 0; } return EGUINOSUPPORT; }
const char * GuiSimple(int descr, const char *title, Gui_CB callback, GuiErr_CB error_cb, void *context) { McpMesg msg; McpFrame *mfr = descr_mcpframe(descr); const char *id; if (!mfr) { return NULL; } if (GuiSupported(descr)) { id = gui_dlog_alloc(descr, callback, error_cb, context); mcp_mesg_init(&msg, GUI_PACKAGE, "dlog-create"); mcp_mesg_arg_append(&msg, "dlogid", id); mcp_mesg_arg_append(&msg, "type", "simple"); mcp_mesg_arg_append(&msg, "title", title); mcp_frame_output_mesg(mfr, &msg); mcp_mesg_clear(&msg); return id; } else { return NULL; } }
int mcp_intern_is_mesg_start(McpFrame * mfr, const char *in) { char mesgname[128]; char authkey[128]; char *subname = NULL; McpMesg *newmsg = NULL; McpPkg *pkg = NULL; int longlen = 0; if (!mcp_intern_is_ident(&in, mesgname, sizeof(mesgname))) return 0; if (strcmp_nocase(mesgname, MCP_INIT_PKG)) { if (!isspace(*in)) return 0; while (isspace(*in)) in++; if (!mcp_intern_is_unquoted(&in, authkey, sizeof(authkey))) return 0; if (strcmp(authkey, mfr->authkey)) return 0; } if (strncmp_nocase(mesgname, MCP_INIT_PKG, 3)) { for (pkg = mfr->packages; pkg; pkg = pkg->next) { int pkgnamelen = strlen(pkg->pkgname); if (!strncmp_nocase(pkg->pkgname, mesgname, pkgnamelen)) { if (mesgname[pkgnamelen] == '\0' || mesgname[pkgnamelen] == '-') { if (pkgnamelen > longlen) { longlen = pkgnamelen; } } } } } if (!longlen) { int neglen = strlen(MCP_NEGOTIATE_PKG); if (!strncmp_nocase(mesgname, MCP_NEGOTIATE_PKG, neglen)) { longlen = neglen; } else if (!strcmp_nocase(mesgname, MCP_INIT_PKG)) { longlen = strlen(mesgname); } else { return 0; } } subname = mesgname + longlen; if (*subname) { *subname++ = '\0'; } newmsg = (McpMesg *) malloc(sizeof(McpMesg)); mcp_mesg_init(newmsg, mesgname, subname); while (*in) { if (!mcp_intern_is_keyval(newmsg, &in)) { mcp_mesg_clear(newmsg); free(newmsg); return 0; } } /* Okay, we've recieved a valid message. */ if (newmsg->incomplete) { /* It's incomplete. Remember it to finish later. */ const char *msgdt = mcp_mesg_arg_getline(newmsg, MCP_DATATAG, 0); newmsg->datatag = string_dup(msgdt); mcp_mesg_arg_remove(newmsg, MCP_DATATAG); newmsg->next = mfr->messages; mfr->messages = newmsg; } else { /* It's complete. Execute the callback function for this package. */ mcp_frame_package_docallback(mfr, newmsg); mcp_mesg_clear(newmsg); free(newmsg); } return 1; }
void mcp_basic_handler(McpFrame * mfr, McpMesg * mesg, void *dummy) { McpVer myminver = { 2, 1 }; McpVer mymaxver = { 2, 1 }; McpVer minver = { 0, 0 }; McpVer maxver = { 0, 0 }; McpVer nullver = { 0, 0 }; const char *ptr; const char *auth; if (!*mesg->mesgname) { auth = mcp_mesg_arg_getline(mesg, "authentication-key", 0); if (auth) { mfr->authkey = string_dup(auth); } else { McpMesg reply; char authval[128]; mcp_mesg_init(&reply, MCP_INIT_PKG, ""); mcp_mesg_arg_append(&reply, "version", "2.1"); mcp_mesg_arg_append(&reply, "to", "2.1"); snprintf(authval, sizeof(authval), "%.8lX", (unsigned long)(RANDOM() ^ RANDOM())); mcp_mesg_arg_append(&reply, "authentication-key", authval); mfr->authkey = string_dup(authval); mcp_frame_output_mesg(mfr, &reply); mcp_mesg_clear(&reply); } ptr = mcp_mesg_arg_getline(mesg, "version", 0); if (!ptr) return; while (isdigit(*ptr)) minver.vermajor = (minver.vermajor * 10) + (*ptr++ - '0'); if (*ptr++ != '.') return; while (isdigit(*ptr)) minver.verminor = (minver.verminor * 10) + (*ptr++ - '0'); ptr = mcp_mesg_arg_getline(mesg, "to", 0); if (!ptr) { maxver = minver; } else { while (isdigit(*ptr)) maxver.vermajor = (maxver.vermajor * 10) + (*ptr++ - '0'); if (*ptr++ != '.') return; while (isdigit(*ptr)) maxver.verminor = (maxver.verminor * 10) + (*ptr++ - '0'); } mfr->version = mcp_version_select(myminver, mymaxver, minver, maxver); if (mcp_version_compare(mfr->version, nullver)) { McpMesg cando; char verbuf[32]; McpPkg *p = mcp_PackageList; mfr->enabled = 1; while (p) { if (strcmp_nocase(p->pkgname, MCP_INIT_PKG)) { mcp_mesg_init(&cando, MCP_NEGOTIATE_PKG, "can"); mcp_mesg_arg_append(&cando, "package", p->pkgname); snprintf(verbuf, sizeof(verbuf), "%d.%d", p->minver.vermajor, p->minver.verminor); mcp_mesg_arg_append(&cando, "min-version", verbuf); snprintf(verbuf, sizeof(verbuf), "%d.%d", p->maxver.vermajor, p->maxver.verminor); mcp_mesg_arg_append(&cando, "max-version", verbuf); mcp_frame_output_mesg(mfr, &cando); mcp_mesg_clear(&cando); } p = p->next; } mcp_mesg_init(&cando, MCP_NEGOTIATE_PKG, "end"); mcp_frame_output_mesg(mfr, &cando); mcp_mesg_clear(&cando); } } }
void mcppkg_help_request(McpFrame * mfr, McpMesg * msg, McpVer ver, void *context) { FILE *f; const char* file; char buf[BUFFER_LEN]; char topic[BUFFER_LEN]; char *p; int arglen, found; McpVer supp = mcp_frame_package_supported(mfr, "org-fuzzball-help"); McpMesg omsg; if (supp.verminor == 0 && supp.vermajor == 0) { notify(mcpframe_to_user(mfr), "MCP: org-fuzzball-help not supported."); return; } if (!string_compare(msg->mesgname, "request")) { char *onwhat; char *valtype; onwhat = mcp_mesg_arg_getline(msg, "topic", 0); valtype = mcp_mesg_arg_getline(msg, "type", 0); *topic = '\0'; strcpyn(topic, sizeof(topic), onwhat); if (*onwhat) { strcatn(topic, sizeof(topic), "|"); } if (!string_compare(valtype, "man")) { file = MAN_FILE; } else if (!string_compare(valtype, "mpi")) { file = MPI_FILE; } else if (!string_compare(valtype, "help")) { file = HELP_FILE; } else if (!string_compare(valtype, "news")) { file = NEWS_FILE; } else { snprintf(buf, sizeof(buf), "Sorry, %s is not a valid help type.", valtype); mcp_mesg_init(&omsg, "org-fuzzball-help", "error"); mcp_mesg_arg_append(&omsg, "text", buf); mcp_mesg_arg_append(&omsg, "topic", onwhat); mcp_frame_output_mesg(mfr, &omsg); mcp_mesg_clear(&omsg); return; } if ((f = fopen(file, "rb")) == NULL) { snprintf(buf, sizeof(buf), "Sorry, %s is missing. Management has been notified.", file); fprintf(stderr, "help: No file %s!\n", file); mcp_mesg_init(&omsg, "org-fuzzball-help", "error"); mcp_mesg_arg_append(&omsg, "text", buf); mcp_mesg_arg_append(&omsg, "topic", onwhat); mcp_frame_output_mesg(mfr, &omsg); mcp_mesg_clear(&omsg); } else { if (*topic) { arglen = strlen(topic); do { do { if (!(fgets(buf, sizeof buf, f))) { snprintf(buf, sizeof(buf), "Sorry, no help available on topic \"%s\"", onwhat); fclose(f); mcp_mesg_init(&omsg, "org-fuzzball-help", "error"); mcp_mesg_arg_append(&omsg, "text", buf); mcp_mesg_arg_append(&omsg, "topic", onwhat); mcp_frame_output_mesg(mfr, &omsg); mcp_mesg_clear(&omsg); return; } } while (*buf != '~'); do { if (!(fgets(buf, sizeof buf, f))) { snprintf(buf, sizeof(buf), "Sorry, no help available on topic \"%s\"", onwhat); fclose(f); mcp_mesg_init(&omsg, "org-fuzzball-help", "error"); mcp_mesg_arg_append(&omsg, "text", buf); mcp_mesg_arg_append(&omsg, "topic", onwhat); mcp_frame_output_mesg(mfr, &omsg); mcp_mesg_clear(&omsg); return; } } while (*buf == '~'); p = buf; found = 0; buf[strlen(buf) - 1] = '|'; while (*p && !found) { if (strncasecmp(p, topic, arglen)) { while (*p && (*p != '|')) p++; if (*p) p++; } else { found = 1; } } } while (!found); } mcp_mesg_init(&omsg, "org-fuzzball-help", "entry"); mcp_mesg_arg_append(&omsg, "topic", onwhat); while (fgets(buf, sizeof buf, f)) { if (*buf == '~') break; for (p = buf; *p; p++) { if (*p == '\n' || *p == '\r') { *p = '\0'; break; } } if (!*buf) { strcpyn(buf, sizeof(buf), " "); } mcp_mesg_arg_append(&omsg, "text", buf); } fclose(f); mcp_frame_output_mesg(mfr, &omsg); mcp_mesg_clear(&omsg); } } }