コード例 #1
0
ファイル: mcp.c プロジェクト: hyena/fuzzball
void
mcp_negotiate_handler(McpFrame * mfr, McpMesg * mesg, McpVer version, void *dummy)
{
	McpVer minver = { 0, 0 };
	McpVer maxver = { 0, 0 };
	const char *ptr;
	const char *pkg;

	if (!strcmp(mesg->mesgname, "can")) {
		pkg = mcp_mesg_arg_getline(mesg, "package", 0);
		if (!pkg)
			return;
		ptr = mcp_mesg_arg_getline(mesg, "min-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, "max-version", 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');
		}

		mcp_frame_package_add(mfr, pkg, minver, maxver);
	} else if (!strcmp(mesg->mesgname, "end")) {
		/* nothing to do for end of package negotiations. */
	}
}
コード例 #2
0
ファイル: mcpgui.c プロジェクト: PyroMuddypaw/fuzzball
void
gui_pkg_callback(McpFrame * mfr, McpMesg * msg, McpVer ver, void *context)
{
	DlogData *dat;
	const char *dlogid = mcp_mesg_arg_getline(msg, "dlogid", 0);
	const char *id = mcp_mesg_arg_getline(msg, "id", 0);

	if (!dlogid || !*dlogid) {
		show_mcp_error(mfr, msg->mesgname, "Missing dialog ID.");
		return;
	}
	dat = gui_dlog_find(dlogid);
	if (!dat) {
		show_mcp_error(mfr, msg->mesgname, "Invalid dialog ID.");
		return;
	}
	if (!string_compare(msg->mesgname, "ctrl-value")) {
		int valcount = mcp_mesg_arg_linecount(msg, "value");
		int i;
		const char **value = (const char **) malloc(sizeof(const char *) * valcount);

		if (!id || !*id) {
			show_mcp_error(mfr, msg->mesgname, "Missing control ID.");
			return;
		}
		for (i = 0; i < valcount; i++) {
			value[i] = mcp_mesg_arg_getline(msg, "value", i);
		}
		gui_value_set_local(dlogid, id, valcount, value);
		free((char **)value);

	} else if (!string_compare(msg->mesgname, "ctrl-event")) {
		const char *evt = mcp_mesg_arg_getline(msg, "event", 0);
		const char *dismissed = mcp_mesg_arg_getline(msg, "dismissed", 0);
		int did_dismiss = 1;

		if (!id || !*id) {
			show_mcp_error(mfr, msg->mesgname, "Missing control ID.");
			return;
		}
		if (!evt || !*evt) {
			evt = "buttonpress";
		}
		if (NULL != dismissed) {
			if (!string_compare(dismissed, "false")) {
				did_dismiss = 0;
			} else if (!string_compare(dismissed, "0")) {
				did_dismiss = 0;
			}
		}
		if (did_dismiss) {
			dat->dismissed = 1;
		}
		if (dat->callback) {
			dat->callback(dat->descr, dlogid, id, evt, msg, did_dismiss, dat->context);
		}
	} else if (!string_compare(msg->mesgname, "error")) {
		const char *err  = mcp_mesg_arg_getline(msg, "errcode", 0);
		const char *text = mcp_mesg_arg_getline(msg, "errtext", 0);
		const char *id   = mcp_mesg_arg_getline(msg, "id", 0);

		if (!err) {
			err = "";
		}
		if (!text) {
			text = "";
		}
		if (dat->error_cb) {
			dat->error_cb(dat->descr, dlogid, id, err, text, dat->context);
		}
	}
}
コード例 #3
0
ファイル: mcp.c プロジェクト: hyena/fuzzball
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;
}
コード例 #4
0
ファイル: mcp.c プロジェクト: hyena/fuzzball
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);
		}
	}
}
コード例 #5
0
ファイル: help.c プロジェクト: hyena/fuzzball
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);
		}
	}
}