/* * 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); }
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); }
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); }
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); }
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); }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }