121c1c48aSSascha Wildner /*
221c1c48aSSascha Wildner * Copyright (c)2004 Cat's Eye Technologies. All rights reserved.
321c1c48aSSascha Wildner *
421c1c48aSSascha Wildner * Redistribution and use in source and binary forms, with or without
521c1c48aSSascha Wildner * modification, are permitted provided that the following conditions
621c1c48aSSascha Wildner * are met:
721c1c48aSSascha Wildner *
821c1c48aSSascha Wildner * Redistributions of source code must retain the above copyright
921c1c48aSSascha Wildner * notice, this list of conditions and the following disclaimer.
1021c1c48aSSascha Wildner *
1121c1c48aSSascha Wildner * Redistributions in binary form must reproduce the above copyright
1221c1c48aSSascha Wildner * notice, this list of conditions and the following disclaimer in
1321c1c48aSSascha Wildner * the documentation and/or other materials provided with the
1421c1c48aSSascha Wildner * distribution.
1521c1c48aSSascha Wildner *
1621c1c48aSSascha Wildner * Neither the name of Cat's Eye Technologies nor the names of its
1721c1c48aSSascha Wildner * contributors may be used to endorse or promote products derived
1821c1c48aSSascha Wildner * from this software without specific prior written permission.
1921c1c48aSSascha Wildner *
2021c1c48aSSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2121c1c48aSSascha Wildner * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2221c1c48aSSascha Wildner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
2321c1c48aSSascha Wildner * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
2421c1c48aSSascha Wildner * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2521c1c48aSSascha Wildner * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2621c1c48aSSascha Wildner * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2721c1c48aSSascha Wildner * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2821c1c48aSSascha Wildner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2921c1c48aSSascha Wildner * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3021c1c48aSSascha Wildner * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
3121c1c48aSSascha Wildner * OF THE POSSIBILITY OF SUCH DAMAGE.
3221c1c48aSSascha Wildner */
3321c1c48aSSascha Wildner
3421c1c48aSSascha Wildner /*
3521c1c48aSSascha Wildner * conn_npipe.c
3621c1c48aSSascha Wildner * $Id: conn_npipe.c,v 1.13 2005/02/06 19:53:19 cpressey Exp $
3721c1c48aSSascha Wildner */
3821c1c48aSSascha Wildner
3921c1c48aSSascha Wildner #include "system.h"
4021c1c48aSSascha Wildner #ifdef HAS_NPIPE
4121c1c48aSSascha Wildner
4221c1c48aSSascha Wildner #include <sys/types.h>
4321c1c48aSSascha Wildner #include <sys/stat.h>
4421c1c48aSSascha Wildner #include <sys/time.h>
4521c1c48aSSascha Wildner #include <sys/errno.h>
4621c1c48aSSascha Wildner
4721c1c48aSSascha Wildner #include <err.h>
4821c1c48aSSascha Wildner #include <stdarg.h>
4921c1c48aSSascha Wildner #include <stdio.h>
5021c1c48aSSascha Wildner #include <stdlib.h>
5121c1c48aSSascha Wildner #include <string.h>
5221c1c48aSSascha Wildner #include <unistd.h>
5321c1c48aSSascha Wildner
5421c1c48aSSascha Wildner #include <libaura/buffer.h>
5521c1c48aSSascha Wildner #include <libaura/fspred.h>
5621c1c48aSSascha Wildner
5721c1c48aSSascha Wildner #define NEEDS_DFUI_STRUCTURE_DEFINITIONS
5821c1c48aSSascha Wildner #include "dfui.h"
5921c1c48aSSascha Wildner #undef NEEDS_DFUI_STRUCTURE_DEFINITIONS
6021c1c48aSSascha Wildner #include "encoding.h"
6121c1c48aSSascha Wildner #include "dump.h"
6221c1c48aSSascha Wildner #include "conn_npipe.h"
6321c1c48aSSascha Wildner
6421c1c48aSSascha Wildner /***** BACKEND ******/
6521c1c48aSSascha Wildner
6621c1c48aSSascha Wildner /** High Level **/
6721c1c48aSSascha Wildner
6821c1c48aSSascha Wildner /*
6921c1c48aSSascha Wildner * Connect to the frontend.
7021c1c48aSSascha Wildner */
7121c1c48aSSascha Wildner dfui_err_t
dfui_npipe_be_start(struct dfui_connection * c)7221c1c48aSSascha Wildner dfui_npipe_be_start(struct dfui_connection *c)
7321c1c48aSSascha Wildner {
7421c1c48aSSascha Wildner asprintf(&T_NPIPE(c)->out_pipename, "/tmp/dfui.%s.to_fe", c->rendezvous);
7521c1c48aSSascha Wildner asprintf(&T_NPIPE(c)->in_pipename, "/tmp/dfui.%s.from_fe", c->rendezvous);
7621c1c48aSSascha Wildner
7721c1c48aSSascha Wildner /*
7821c1c48aSSascha Wildner * Create the named pipes.
7921c1c48aSSascha Wildner */
8021c1c48aSSascha Wildner errno = 0;
8121c1c48aSSascha Wildner if (mkfifo(T_NPIPE(c)->in_pipename, 0600) < 0) {
8221c1c48aSSascha Wildner if (errno != EEXIST) {
8321c1c48aSSascha Wildner warn("mkfifo (to_be)");
8421c1c48aSSascha Wildner return(DFUI_FAILURE);
8521c1c48aSSascha Wildner }
8621c1c48aSSascha Wildner }
8721c1c48aSSascha Wildner errno = 0;
8821c1c48aSSascha Wildner if (mkfifo(T_NPIPE(c)->out_pipename, 0600) < 0) {
8921c1c48aSSascha Wildner if (errno != EEXIST) {
9021c1c48aSSascha Wildner warn("mkfifo (to_fe)");
9121c1c48aSSascha Wildner return(DFUI_FAILURE);
9221c1c48aSSascha Wildner }
9321c1c48aSSascha Wildner }
9421c1c48aSSascha Wildner dfui_debug("opening pipes...\n");
9521c1c48aSSascha Wildner if ((T_NPIPE(c)->out = fopen(T_NPIPE(c)->out_pipename, "w")) == NULL) {
9621c1c48aSSascha Wildner return(DFUI_FAILURE);
9721c1c48aSSascha Wildner }
9821c1c48aSSascha Wildner dfui_debug("opened to_fe pipe\n");
9921c1c48aSSascha Wildner setvbuf(T_NPIPE(c)->out, NULL, _IONBF, 0);
10021c1c48aSSascha Wildner if ((T_NPIPE(c)->in = fopen(T_NPIPE(c)->in_pipename, "r")) == NULL) {
10121c1c48aSSascha Wildner fclose(T_NPIPE(c)->out);
10221c1c48aSSascha Wildner return(DFUI_FAILURE);
10321c1c48aSSascha Wildner }
10421c1c48aSSascha Wildner dfui_debug("opened to_be pipe\n");
10521c1c48aSSascha Wildner return(DFUI_SUCCESS);
10621c1c48aSSascha Wildner }
10721c1c48aSSascha Wildner
10821c1c48aSSascha Wildner /*
10921c1c48aSSascha Wildner * Tell the frontend that we're done and disconnect from it.
11021c1c48aSSascha Wildner */
11121c1c48aSSascha Wildner dfui_err_t
dfui_npipe_be_stop(struct dfui_connection * c)11221c1c48aSSascha Wildner dfui_npipe_be_stop(struct dfui_connection *c)
11321c1c48aSSascha Wildner {
11421c1c48aSSascha Wildner if (dfui_npipe_be_ll_exchange(c, DFUI_BE_MSG_STOP, "")) {
11521c1c48aSSascha Wildner fclose(T_NPIPE(c)->in);
11621c1c48aSSascha Wildner fclose(T_NPIPE(c)->out);
11721c1c48aSSascha Wildner return(DFUI_SUCCESS);
11821c1c48aSSascha Wildner } else
11921c1c48aSSascha Wildner return(DFUI_FAILURE);
12021c1c48aSSascha Wildner }
12121c1c48aSSascha Wildner
12221c1c48aSSascha Wildner /** Low Level **/
12321c1c48aSSascha Wildner
12421c1c48aSSascha Wildner /*
12521c1c48aSSascha Wildner * Exchange a message with the frontend. This involves two receive()/reply()
12621c1c48aSSascha Wildner * cycles: one to provide our message, one to get a reply from the frontend.
12721c1c48aSSascha Wildner *
12821c1c48aSSascha Wildner * Note that this does not immediately send the message to the frontend -
12921c1c48aSSascha Wildner * it can't, because we're a service and it's a client. What it does is
13021c1c48aSSascha Wildner * keep the message handy and wait for a frontend request to come in. It
13121c1c48aSSascha Wildner * then replies to that request with our message.
13221c1c48aSSascha Wildner *
13321c1c48aSSascha Wildner * The protocol looks something like the following, using the PRESENT and
13421c1c48aSSascha Wildner * SUBMIT exchange as an example:
13521c1c48aSSascha Wildner *
13621c1c48aSSascha Wildner * frontend (client) | backend (service)
13721c1c48aSSascha Wildner * ------------------+------------------
13821c1c48aSSascha Wildner *
13921c1c48aSSascha Wildner * [stage 1]
14021c1c48aSSascha Wildner * READY --> ll_receive()
14121c1c48aSSascha Wildner * <-- PRESENT(form) ll_reply()
14221c1c48aSSascha Wildner *
14321c1c48aSSascha Wildner * [stage 2]
14421c1c48aSSascha Wildner * SUBMIT(form) --> ll_receive()
14521c1c48aSSascha Wildner * <-- READY ll_reply()
14621c1c48aSSascha Wildner *
14721c1c48aSSascha Wildner * Each of those exchanges is a pair of calls, on our end, to
14821c1c48aSSascha Wildner * dfui_npipe_be_ll_receive() and dfui_npipe_be_ll_reply().
14921c1c48aSSascha Wildner *
15021c1c48aSSascha Wildner * The set of messages that the client can pass us is determined by
15121c1c48aSSascha Wildner * the conversation state:
15221c1c48aSSascha Wildner *
15321c1c48aSSascha Wildner * o In stage 1, only READY and ABORT are meaningful.
15421c1c48aSSascha Wildner * o After a PRESENT, the messages SUBMIT and ABORT are meaningul
15521c1c48aSSascha Wildner * in stage 2.
15621c1c48aSSascha Wildner * o During a PROG_*, the messages CONTINUE, CANCEL, and ABORT
15721c1c48aSSascha Wildner * are meaningful in stage 2.
15821c1c48aSSascha Wildner *
15921c1c48aSSascha Wildner * If the frontend sends us with READY in stage 2, we assume it has
16021c1c48aSSascha Wildner * fallen out of sync, so we send the same initial reply again, going
16121c1c48aSSascha Wildner * back to stage 1 as it were.
16221c1c48aSSascha Wildner *
16321c1c48aSSascha Wildner * After this call, the message is available in c->ebuf.
16421c1c48aSSascha Wildner */
16521c1c48aSSascha Wildner dfui_err_t
dfui_npipe_be_ll_exchange(struct dfui_connection * c,char msgtype,const char * msg)16621c1c48aSSascha Wildner dfui_npipe_be_ll_exchange(struct dfui_connection *c, char msgtype, const char *msg)
16721c1c48aSSascha Wildner {
16821c1c48aSSascha Wildner char *fmsg;
16921c1c48aSSascha Wildner
17021c1c48aSSascha Wildner /*
17121c1c48aSSascha Wildner * Construct our message to send.
17221c1c48aSSascha Wildner */
17321c1c48aSSascha Wildner
17421c1c48aSSascha Wildner fmsg = malloc(strlen(msg) + 2);
17521c1c48aSSascha Wildner fmsg[0] = msgtype;
17621c1c48aSSascha Wildner strcpy(fmsg + 1, msg);
17721c1c48aSSascha Wildner
17821c1c48aSSascha Wildner /*
17921c1c48aSSascha Wildner * Get the frontend's message.
18021c1c48aSSascha Wildner */
18121c1c48aSSascha Wildner
18221c1c48aSSascha Wildner dfui_npipe_be_ll_receive(c);
18321c1c48aSSascha Wildner
18421c1c48aSSascha Wildner /*
18521c1c48aSSascha Wildner * Frontend message should have been either READY or ABORT.
18621c1c48aSSascha Wildner * If ABORT, we get out of here pronto.
18721c1c48aSSascha Wildner */
18821c1c48aSSascha Wildner
18921c1c48aSSascha Wildner if (aura_buffer_buf(c->ebuf)[0] == DFUI_FE_MSG_ABORT) {
19021c1c48aSSascha Wildner free(fmsg);
19121c1c48aSSascha Wildner return(DFUI_FAILURE);
19221c1c48aSSascha Wildner }
19321c1c48aSSascha Wildner
19421c1c48aSSascha Wildner /* XXX if (!READY) ??? */
19521c1c48aSSascha Wildner
19621c1c48aSSascha Wildner do {
19721c1c48aSSascha Wildner dfui_npipe_be_ll_reply(c, fmsg);
19821c1c48aSSascha Wildner
19921c1c48aSSascha Wildner /*
20021c1c48aSSascha Wildner * Here, the frontend has picked up our request and is
20121c1c48aSSascha Wildner * processing it. We have to wait for the response.
20221c1c48aSSascha Wildner */
20321c1c48aSSascha Wildner
20421c1c48aSSascha Wildner dfui_npipe_be_ll_receive(c);
20521c1c48aSSascha Wildner
20621c1c48aSSascha Wildner /*
20721c1c48aSSascha Wildner * Did we get READY from this?
20821c1c48aSSascha Wildner * If so, loop!
20921c1c48aSSascha Wildner */
21021c1c48aSSascha Wildner
21121c1c48aSSascha Wildner } while (aura_buffer_buf(c->ebuf)[0] == DFUI_FE_MSG_READY);
21221c1c48aSSascha Wildner
21321c1c48aSSascha Wildner fmsg[0] = DFUI_BE_MSG_READY;
21421c1c48aSSascha Wildner fmsg[1] = '\0';
21521c1c48aSSascha Wildner dfui_npipe_be_ll_reply(c, fmsg);
21621c1c48aSSascha Wildner
21721c1c48aSSascha Wildner free(fmsg);
21821c1c48aSSascha Wildner return(DFUI_SUCCESS);
21921c1c48aSSascha Wildner }
22021c1c48aSSascha Wildner
22121c1c48aSSascha Wildner /*
22221c1c48aSSascha Wildner * Receive a message from the frontend.
22321c1c48aSSascha Wildner * This call is synchronous.
22421c1c48aSSascha Wildner * After this call, the NUL-terminated message is available in
22521c1c48aSSascha Wildner * c->ebuf.
22621c1c48aSSascha Wildner */
22721c1c48aSSascha Wildner dfui_err_t
dfui_npipe_be_ll_receive(struct dfui_connection * c)22821c1c48aSSascha Wildner dfui_npipe_be_ll_receive(struct dfui_connection *c)
22921c1c48aSSascha Wildner {
23021c1c48aSSascha Wildner int length;
23121c1c48aSSascha Wildner char *buf;
23221c1c48aSSascha Wildner
23321c1c48aSSascha Wildner dfui_debug("WAITING<<>>\n");
23421c1c48aSSascha Wildner
23521c1c48aSSascha Wildner fread(&length, 4, 1, T_NPIPE(c)->in);
23621c1c48aSSascha Wildner
23721c1c48aSSascha Wildner dfui_debug("LENGTH<<%d>>\n", length);
23821c1c48aSSascha Wildner
23921c1c48aSSascha Wildner buf = malloc(length + 1);
24021c1c48aSSascha Wildner fread(buf, length, 1, T_NPIPE(c)->in);
24121c1c48aSSascha Wildner aura_buffer_set(c->ebuf, buf, length);
24221c1c48aSSascha Wildner free(buf);
24321c1c48aSSascha Wildner
24421c1c48aSSascha Wildner dfui_debug("RECEIVED<<%s>>\n", aura_buffer_buf(c->ebuf));
24521c1c48aSSascha Wildner
24621c1c48aSSascha Wildner return(DFUI_SUCCESS);
24721c1c48aSSascha Wildner }
24821c1c48aSSascha Wildner
24921c1c48aSSascha Wildner /*
25021c1c48aSSascha Wildner * Send a NUL-terminated reply to the frontend.
25121c1c48aSSascha Wildner */
25221c1c48aSSascha Wildner dfui_err_t
dfui_npipe_be_ll_reply(struct dfui_connection * c,const char * fmsg)25321c1c48aSSascha Wildner dfui_npipe_be_ll_reply(struct dfui_connection *c, const char *fmsg)
25421c1c48aSSascha Wildner {
25521c1c48aSSascha Wildner int length;
25621c1c48aSSascha Wildner
25721c1c48aSSascha Wildner dfui_debug("SEND<<%s>>\n", fmsg);
25821c1c48aSSascha Wildner
25921c1c48aSSascha Wildner length = strlen(fmsg);
26021c1c48aSSascha Wildner
26121c1c48aSSascha Wildner fwrite(&length, 4, 1, T_NPIPE(c)->out);
26221c1c48aSSascha Wildner fwrite(fmsg, length, 1, T_NPIPE(c)->out);
26321c1c48aSSascha Wildner
26421c1c48aSSascha Wildner return(DFUI_SUCCESS);
26521c1c48aSSascha Wildner }
26621c1c48aSSascha Wildner
26721c1c48aSSascha Wildner /******** FRONTEND ********/
26821c1c48aSSascha Wildner
26921c1c48aSSascha Wildner /** High Level **/
27021c1c48aSSascha Wildner
27121c1c48aSSascha Wildner dfui_err_t
dfui_npipe_fe_connect(struct dfui_connection * c)27221c1c48aSSascha Wildner dfui_npipe_fe_connect(struct dfui_connection *c)
27321c1c48aSSascha Wildner {
27421c1c48aSSascha Wildner asprintf(&T_NPIPE(c)->in_pipename, "/tmp/dfui.%s.to_fe", c->rendezvous);
27521c1c48aSSascha Wildner asprintf(&T_NPIPE(c)->out_pipename, "/tmp/dfui.%s.from_fe", c->rendezvous);
27621c1c48aSSascha Wildner
27721c1c48aSSascha Wildner dfui_debug("waiting for named pipes...\n");
27821c1c48aSSascha Wildner
27921c1c48aSSascha Wildner /*
28021c1c48aSSascha Wildner * Wait for named pipes to be created.
28121c1c48aSSascha Wildner */
282*9462167aSSascha Wildner if (!is_named_pipe("%s", T_NPIPE(c)->in_pipename)) {
283*9462167aSSascha Wildner while (!is_named_pipe("%s", T_NPIPE(c)->in_pipename)) {
28421c1c48aSSascha Wildner sleep(1);
28521c1c48aSSascha Wildner }
28621c1c48aSSascha Wildner sleep(1);
28721c1c48aSSascha Wildner }
28821c1c48aSSascha Wildner
28921c1c48aSSascha Wildner dfui_debug("opening inflow pipe...\n");
29021c1c48aSSascha Wildner
29121c1c48aSSascha Wildner if ((T_NPIPE(c)->in = fopen(T_NPIPE(c)->in_pipename, "r")) == NULL) {
29221c1c48aSSascha Wildner return(DFUI_FAILURE);
29321c1c48aSSascha Wildner }
29421c1c48aSSascha Wildner
29521c1c48aSSascha Wildner dfui_debug("opening outflow pipe...\n");
29621c1c48aSSascha Wildner
29721c1c48aSSascha Wildner if ((T_NPIPE(c)->out = fopen(T_NPIPE(c)->out_pipename, "w")) == NULL) {
29821c1c48aSSascha Wildner fclose(T_NPIPE(c)->in);
29921c1c48aSSascha Wildner return(DFUI_FAILURE);
30021c1c48aSSascha Wildner }
30121c1c48aSSascha Wildner
30221c1c48aSSascha Wildner dfui_debug("making outflow pipe raw...\n");
30321c1c48aSSascha Wildner
30421c1c48aSSascha Wildner setvbuf(T_NPIPE(c)->out, NULL, _IONBF, 0);
30521c1c48aSSascha Wildner return(DFUI_SUCCESS);
30621c1c48aSSascha Wildner }
30721c1c48aSSascha Wildner
30821c1c48aSSascha Wildner dfui_err_t
dfui_npipe_fe_disconnect(struct dfui_connection * c)30921c1c48aSSascha Wildner dfui_npipe_fe_disconnect(struct dfui_connection *c)
31021c1c48aSSascha Wildner {
31121c1c48aSSascha Wildner fclose(T_NPIPE(c)->in);
31221c1c48aSSascha Wildner fclose(T_NPIPE(c)->out);
31321c1c48aSSascha Wildner return(DFUI_SUCCESS);
31421c1c48aSSascha Wildner }
31521c1c48aSSascha Wildner
31621c1c48aSSascha Wildner /** Low Level **/
31721c1c48aSSascha Wildner
31821c1c48aSSascha Wildner /*
31921c1c48aSSascha Wildner * Ask for, and subsequently receieve, a message from the backend.
32021c1c48aSSascha Wildner * msgtype should be one of the DFUI_FE_MSG_* constants.
32121c1c48aSSascha Wildner * This call is synchronous.
32221c1c48aSSascha Wildner * After this call, the null-terminated, encoded message is
32321c1c48aSSascha Wildner * available in T_NPIPE(c)->buf.
32421c1c48aSSascha Wildner */
32521c1c48aSSascha Wildner dfui_err_t
dfui_npipe_fe_ll_request(struct dfui_connection * c,char msgtype,const char * msg)32621c1c48aSSascha Wildner dfui_npipe_fe_ll_request(struct dfui_connection *c, char msgtype, const char *msg)
32721c1c48aSSascha Wildner {
32821c1c48aSSascha Wildner char *fmsg, *buf;
32921c1c48aSSascha Wildner int length;
33021c1c48aSSascha Wildner
33121c1c48aSSascha Wildner /*
33221c1c48aSSascha Wildner * First, assert that the connection is open.
33321c1c48aSSascha Wildner */
33421c1c48aSSascha Wildner
33521c1c48aSSascha Wildner if (c == NULL || T_NPIPE(c)->in == NULL || T_NPIPE(c)->out == NULL)
33621c1c48aSSascha Wildner return(DFUI_FAILURE);
33721c1c48aSSascha Wildner
33821c1c48aSSascha Wildner /*
33921c1c48aSSascha Wildner * Construct a message.
34021c1c48aSSascha Wildner */
34121c1c48aSSascha Wildner
34221c1c48aSSascha Wildner fmsg = malloc(strlen(msg) + 2);
34321c1c48aSSascha Wildner fmsg[0] = msgtype;
34421c1c48aSSascha Wildner strcpy(fmsg + 1, msg);
34521c1c48aSSascha Wildner
34621c1c48aSSascha Wildner dfui_debug("SEND<<%s>>\n", fmsg);
34721c1c48aSSascha Wildner
34821c1c48aSSascha Wildner /*
34921c1c48aSSascha Wildner * Send a NUL-terminated message to the backend.
35021c1c48aSSascha Wildner */
35121c1c48aSSascha Wildner
35221c1c48aSSascha Wildner length = strlen(fmsg);
35321c1c48aSSascha Wildner fwrite(&length, 4, 1, T_NPIPE(c)->out);
35421c1c48aSSascha Wildner fwrite(fmsg, length, 1, T_NPIPE(c)->out);
35521c1c48aSSascha Wildner
35621c1c48aSSascha Wildner /*
35721c1c48aSSascha Wildner * Receive a reply from the backend.
35821c1c48aSSascha Wildner * If our message was a READY, this should be a message like PRESENT.
35921c1c48aSSascha Wildner * Otherwise it should simply be a READY.
36021c1c48aSSascha Wildner */
36121c1c48aSSascha Wildner
36221c1c48aSSascha Wildner dfui_debug("WAITING<<>>\n");
36321c1c48aSSascha Wildner
36421c1c48aSSascha Wildner fread(&length, 4, 1, T_NPIPE(c)->in);
36521c1c48aSSascha Wildner buf = malloc(length + 1);
36621c1c48aSSascha Wildner fread(buf, length, 1, T_NPIPE(c)->in);
36721c1c48aSSascha Wildner aura_buffer_set(c->ebuf, buf, length);
36821c1c48aSSascha Wildner free(buf);
36921c1c48aSSascha Wildner
37021c1c48aSSascha Wildner dfui_debug("RECV<<%s>>\n", aura_buffer_buf(c->ebuf));
37121c1c48aSSascha Wildner
37221c1c48aSSascha Wildner free(fmsg);
37321c1c48aSSascha Wildner
37421c1c48aSSascha Wildner return(DFUI_SUCCESS);
37521c1c48aSSascha Wildner }
37621c1c48aSSascha Wildner
37721c1c48aSSascha Wildner #endif /* HAS_NPIPE */
378