+ msg_fd_in = fd;
+}
+
+/* Setup the fd used to send our MSG_* messages. Only needed when
+ * we're the receiver (to send our messages to the generator). */
+void set_msg_fd_out(int fd)
+{
+ msg_fd_out = fd;
+ set_nonblocking(msg_fd_out);
+}
+
+/* Add a message to the pending MSG_* list. */
+static void msg_list_add(int code, char *buf, int len)
+{
+ struct msg_list *ml;
+
+ if (!(ml = new(struct msg_list)))
+ exit_cleanup(RERR_MALLOC);
+ ml->next = NULL;
+ if (!(ml->buf = new_array(char, len+4)))
+ exit_cleanup(RERR_MALLOC);
+ SIVAL(ml->buf, 0, ((code+MPLEX_BASE)<<24) | len);
+ memcpy(ml->buf+4, buf, len);
+ ml->len = len+4;
+ if (msg_list_tail)
+ msg_list_tail->next = ml;
+ else
+ msg_list_head = ml;
+ msg_list_tail = ml;
+}
+
+void send_msg(enum msgcode code, char *buf, int len)
+{
+ msg_list_add(code, buf, len);
+ msg_list_push(NORMAL_FLUSH);
+}
+
+/* Read a message from the MSG_* fd and handle it. This is called either
+ * during the early stages of being a local sender (up through the sending
+ * of the file list) or when we're the generator (to fetch the messages
+ * from the receiver). */
+static void read_msg_fd(void)
+{
+ char buf[2048];