Exemple #1
0
/*
 * Exchange a message with the frontend.  This involves two receive()/reply()
 * cycles: one to provide our message, one to get a reply from the frontend.
 *
 * Note that this does not immediately send the message to the frontend -
 * it can't, because we're a service and it's a client.  What it does is
 * keep the message handy and wait for a frontend request to come in.  It
 * then replies to that request with our message.
 *
 * The protocol looks something like the following, using the PRESENT and
 * SUBMIT exchange as an example:
 *
 * frontend (client) | backend (service)
 * ------------------+------------------
 *
 *                                     [stage 1]
 * READY            -->                ll_receive()
 *                 <--  PRESENT(form)  ll_reply()
 *
 *                                     [stage 2]
 * SUBMIT(form)     -->                ll_receive()
 *                 <--  READY          ll_reply()
 *
 * Each of those exchanges is a pair of calls, on our end, to
 * dfui_tcp_be_ll_receive() and dfui_npipe_be_ll_reply().
 *
 * The set of messages that the client can pass us is determined by
 * the conversation state:
 *
 *   o  In stage 1, only READY and ABORT are meaningful.
 *   o  After a PRESENT, the messages SUBMIT and ABORT are meaningul
 *      in stage 2.
 *   o  During a PROG_*, the messages CONTINUE, CANCEL, and ABORT
 *      are meaningful in stage 2.
 *
 * If the frontend sends us with READY in stage 2, we assume it has
 * fallen out of sync, so we send the same initial reply again, going
 * back to stage 1 as it were.
 *
 * After this call, the message is available in c->ebuf.
 */
dfui_err_t
dfui_tcp_be_ll_exchange(struct dfui_connection *c, char msgtype, const char *msg)
{
	char *fmsg;

	/*
	 * Construct our message to send.
	 */

	fmsg = malloc(strlen(msg) + 2);
	fmsg[0] = msgtype;
	strcpy(fmsg + 1, msg);

	/*
	 * Get the frontend's message.
	 */

	dfui_tcp_be_ll_receive(c);

	/*
	 * Frontend message should have been either READY or ABORT.
	 * If ABORT, we get out of here pronto.
	 */

	if (aura_buffer_buf(c->ebuf)[0] == DFUI_FE_MSG_ABORT) {
		free(fmsg);
		return(DFUI_FAILURE);
	}

	/* XXX if (!READY) ??? */

	do {
		dfui_tcp_be_ll_reply(c, fmsg);

		/*
		 * Here, the frontend has picked up our request and is
		 * processing it.  We have to wait for the response.
		 */

		dfui_tcp_be_ll_receive(c);
	
		/*
		 * Did we get READY from this?
		 * If so, loop!
		 */

	} while (aura_buffer_buf(c->ebuf)[0] == DFUI_FE_MSG_READY);

	fmsg[0] = DFUI_BE_MSG_READY;
	fmsg[1] = '\0';
	dfui_tcp_be_ll_reply(c, fmsg);

	free(fmsg);
	return(DFUI_SUCCESS);
}
Exemple #2
0
void
fn_show_atacontrol(struct i_fn_args *a)
{
	struct aura_buffer *e;
	struct dfui_form *f;
	struct dfui_response *r;

	e = aura_buffer_new(1024);
	aura_buffer_cat_pipe(e, "atacontrol list");

	f = dfui_form_create(
	    "atacontrol",
	    _("ATA Devices"),
	    aura_buffer_buf(e),
	    "",

	    "p", "role", "informative",
	    "p", "minimum_width", "72",
	    "p", "monospaced", "true",

	    "a", "ok", _("OK"), "", "",
	    "p", "accelerator", "ESC",

	    NULL
	);

	if (!dfui_be_present(a->c, f, &r))
		abort_backend();

	dfui_form_free(f);
	dfui_response_free(r);

	aura_buffer_free(e);
}
Exemple #3
0
void 
fn_show_dmesg(struct i_fn_args *a)
{
	struct aura_buffer *e;
	struct dfui_form *f;
	struct dfui_response *r;

	e = aura_buffer_new(1024);
	aura_buffer_cat_file(e, "%s%s", a->os_root, cmd_name(a, "DMESG_BOOT"));

	f = dfui_form_create(
	    "dmesg",
	    _("System Startup Messages (dmesg)"),
	    aura_buffer_buf(e),
	    "",

	    "p", "role", "informative",
	    "p", "minimum_width", "72",
	    "p", "monospaced", "true",

	    "a", "ok", _("OK"), "", "",
	    "p", "accelerator", "ESC",

	    NULL
	);

	if (!dfui_be_present(a->c, f, &r))
		abort_backend();

	dfui_form_free(f);
	dfui_response_free(r);

	aura_buffer_free(e);
}
Exemple #4
0
void
view_memtest_log(struct i_fn_args *a)
{
	struct aura_buffer *error_log;
	struct dfui_form *f;
	struct dfui_response *r;

	error_log = aura_buffer_new(1024);
	aura_buffer_cat_file(error_log, "%smemtest.log", a->tmp);

	f = dfui_form_create(
	    "error_log",
	    _("Error Log"),
	    aura_buffer_buf(error_log),
	    "",

	    "p", "role", "informative",
	    "p", "minimum_width", "72",
	    "p", "monospaced", "true",

	    "a", "ok", _("OK"), "", "",
	    "p", "accelerator", "ESC",

	    NULL
	);

	if (!dfui_be_present(a->c, f, &r))
		abort_backend();

	dfui_form_free(f);
	dfui_response_free(r);

	aura_buffer_free(error_log);
}
Exemple #5
0
void
show_ifconfig(struct dfui_connection *c, char *ifname)
{
	struct aura_buffer *e;

	e = aura_buffer_new(1024);
	aura_buffer_cat_pipe(e, "/sbin/ifconfig %s", ifname);
	inform(c, aura_buffer_buf(e));
	aura_buffer_free(e);
}
Exemple #6
0
/*
 * Ask for, and subsequently receieve, a message from the backend.
 * msgtype should be one of the DFUI_FE_MSG_* constants.
 * This call is synchronous.
 * After this call, the null-terminated, encoded message is
 * available in T_TCP(c)->buf.
 */
dfui_err_t
dfui_tcp_fe_ll_request(struct dfui_connection *c, char msgtype, const char *msg)
{
	char *fmsg, *buf;
	int length, result;

	/*
	 * First, assert that the connection is open.
	 */
	
	if (c == NULL || T_TCP(c)->connected_sd == -1)
		return(DFUI_FAILURE);

	/*
	 * Construct a message.
	 */

	fmsg = malloc(strlen(msg) + 2);
	fmsg[0] = msgtype;
	strcpy(fmsg + 1, msg);
	dfui_debug("SEND<<%s>>\n", fmsg);

	/*
	 * Send a NUL-terminated message to the backend.
	 */

        length = strlen(fmsg);
        result = write_data(T_TCP(c)->stream, (char *)&length, sizeof(length));
	dfui_debug("result<<%d>>\n", result);
	result = write_data(T_TCP(c)->stream, (char *)fmsg, length);
	dfui_debug("result<<%d>>\n", result);

	/*
	 * Receive a reply from the backend.
	 * If our message was a READY, this should be a message like PRESENT.
	 * Otherwise it should simply be a READY.
	 */

	dfui_debug("WAITING<<>>\n");
        result = read_data(T_TCP(c)->stream, (char *)&length, sizeof(length));
	dfui_debug("result<<%d>>\n", result);
        buf = malloc(length + 1);
        result = read_data(T_TCP(c)->stream, buf, length);
	dfui_debug("result<<%d>>\n", result);
        aura_buffer_set(c->ebuf, buf, length);
        free(buf);

	dfui_debug("RECV<<%s>>\n", aura_buffer_buf(c->ebuf));

	free(fmsg);

	return(DFUI_SUCCESS);
}
Exemple #7
0
/*
 * Ask for, and subsequently receieve, a message from the backend.
 * msgtype should be one of the DFUI_FE_MSG_* constants.
 * This call is synchronous.
 * After this call, the null-terminated, encoded message is
 * available in T_NPIPE(c)->buf.
 */
dfui_err_t
dfui_npipe_fe_ll_request(struct dfui_connection *c, char msgtype, const char *msg)
{
	char *fmsg, *buf;
	int length;

	/*
	 * First, assert that the connection is open.
	 */
	
	if (c == NULL || T_NPIPE(c)->in == NULL || T_NPIPE(c)->out == NULL)
		return(DFUI_FAILURE);

	/*
	 * Construct a message.
	 */

	fmsg = malloc(strlen(msg) + 1);
	fmsg[0] = msgtype;
	strcpy(fmsg + 1, msg);

	dfui_debug("SEND<<%s>>\n", fmsg);

	/*
	 * Send a NUL-terminated message to the backend.
	 */

	length = strlen(fmsg);
	fwrite(&length, 4, 1, T_NPIPE(c)->out);
	fwrite(fmsg, length, 1, T_NPIPE(c)->out);

	/*
	 * Receive a reply from the backend.
	 * If our message was a READY, this should be a message like PRESENT.
	 * Otherwise it should simply be a READY.
	 */

	dfui_debug("WAITING<<>>\n");

	fread(&length, 4, 1, T_NPIPE(c)->in);
	buf = malloc(length + 1);
	fread(buf, length, 1, T_NPIPE(c)->in);
	aura_buffer_set(c->ebuf, buf, length);
	free(buf);

	dfui_debug("RECV<<%s>>\n", aura_buffer_buf(c->ebuf));

	free(fmsg);

	return(DFUI_SUCCESS);
}
Exemple #8
0
/*
 * Preview a set of commands.
 */
void
commands_preview(struct dfui_connection *c, const struct commands *cmds)
{
	struct command *cmd;
	struct aura_buffer *preview;

	preview = aura_buffer_new(1024);

	for (cmd = cmds->head; cmd != NULL; cmd = cmd->next) {
		aura_buffer_cat(preview, cmd->cmdline);
		aura_buffer_cat(preview, "\n");
	}

	inform(c, "%s", aura_buffer_buf(preview));

	aura_buffer_free(preview);
}
Exemple #9
0
/*
 * Receive a message from the frontend.
 * This call is synchronous.
 * After this call, the NUL-terminated message is available in
 * c->ebuf.
 */
dfui_err_t
dfui_tcp_be_ll_receive(struct dfui_connection *c)
{
	int length;
	char *buf;

	top:

	if (!T_TCP(c)->is_connected) {
		dfui_debug("NOT_CONNECTED,ACCEPTING_ON<<%d>>\n", T_TCP(c)->listen_sd);
		T_TCP(c)->connected_sd = accept(T_TCP(c)->listen_sd, NULL, NULL);
		dfui_debug("ACCEPTED<<%d>>\n", T_TCP(c)->connected_sd);
		T_TCP(c)->stream = fdopen(T_TCP(c)->connected_sd, "r+");
		T_TCP(c)->is_connected = 1;
	} else {
		dfui_debug("ALREADY_CONNECTED<<>>\n");
	}

	dfui_debug("WAITING<<>>\n");

	if (read_data(T_TCP(c)->stream, (char *)&length, sizeof(length)) == -1) {
		dfui_debug("LOST_THEM<<>>\n");
		fclose(T_TCP(c)->stream);
		T_TCP(c)->is_connected = 0;
		goto top;
	}

	buf = malloc(length + 1);
	if (read_data(T_TCP(c)->stream, buf, length) == -1) {
		dfui_debug("LOST_THEM<<>>\n");
		fclose(T_TCP(c)->stream);
		T_TCP(c)->is_connected = 0;
		goto top;
	}

	aura_buffer_set(c->ebuf, buf, length);
	free(buf);

	dfui_debug("RECEIVED<<%s>>\n", aura_buffer_buf(c->ebuf));

	return(DFUI_SUCCESS);
}
Exemple #10
0
/*
 * Receive a message from the frontend.
 * This call is synchronous.
 * After this call, the NUL-terminated message is available in
 * c->ebuf.
 */
dfui_err_t
dfui_npipe_be_ll_receive(struct dfui_connection *c)
{
	int length;
	char *buf;

	dfui_debug("WAITING<<>>\n");

	fread(&length, 4, 1, T_NPIPE(c)->in);

	dfui_debug("LENGTH<<%d>>\n", length);

	buf = malloc(length + 1);
	fread(buf, length, 1, T_NPIPE(c)->in);
	aura_buffer_set(c->ebuf, buf, length);
	free(buf);

	dfui_debug("RECEIVED<<%s>>\n", aura_buffer_buf(c->ebuf));

	return(DFUI_SUCCESS);
}