static int _mh_prop_write_stream (mu_header_t header, struct mu_mh_prop *mhprop, mu_stream_t stream) { int rc; mu_stream_t instream; mu_off_t size; mu_header_get_streamref (header, &instream); rc = mu_stream_copy (stream, instream, 0, &size); if (rc) { mu_error (_("error writing to context file %s: %s"), mhprop->filename, mu_strerror (rc)); return rc; } else rc = mu_stream_truncate (stream, size); mu_stream_destroy (&instream); return rc; }
int mu_progmailer_send (struct _mu_progmailer *pm, mu_message_t msg) { int status; mu_stream_t stream = NULL; char buffer[512]; size_t len = 0; int rc; mu_header_t hdr; mu_body_t body; int found_nl = 0; int exit_status; if (!pm || !msg) return EINVAL; mu_message_get_header (msg, &hdr); status = mu_header_get_streamref (hdr, &stream); if (status) { mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR, ("cannot get header stream: %s", mu_strerror (status))); return status; } mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE, ("Sending headers...")); mu_stream_seek (stream, 0, MU_SEEK_SET, NULL); while ((status = mu_stream_readline (stream, buffer, sizeof (buffer), &len)) == 0 && len != 0) { if (mu_c_strncasecmp (buffer, MU_HEADER_FCC, sizeof (MU_HEADER_FCC) - 1)) { mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_PROT, ("Header: %s", buffer)); if (write (pm->fd, buffer, len) == -1) { status = errno; mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR, ("write failed: %s", strerror (status))); break; } } found_nl = (len == 1 && buffer[0] == '\n'); } if (!found_nl) { if (write (pm->fd, "\n", 1) == -1) { status = errno; mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR, ("write failed: %s", strerror (status))); } } mu_stream_destroy (&stream); mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE, ("Sending body...")); mu_message_get_body (msg, &body); status = mu_body_get_streamref (body, &stream); if (status) { mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR, ("cannot get body stream: %s\n", mu_strerror (status))); return status; } mu_stream_seek (stream, 0, MU_SEEK_SET, NULL); while ((status = mu_stream_read (stream, buffer, sizeof (buffer), &len)) == 0 && len != 0) { if (write (pm->fd, buffer, len) == -1) { status = errno; mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR, ("write failed: %s\n", strerror (status))); break; } } mu_body_get_streamref (body, &stream); close (pm->fd); rc = waitpid (pm->pid, &exit_status, 0); if (status == 0) { if (rc < 0) { if (errno == ECHILD) status = 0; else { status = errno; mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR, ("waitpid(%lu) failed: %s\n", (unsigned long) pm->pid, strerror (status))); } } else if (WIFEXITED (exit_status)) { exit_status = WEXITSTATUS (exit_status); mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE, ("%s exited with: %d\n", pm->command, exit_status)); status = (exit_status == 0) ? 0 : MU_ERR_PROCESS_EXITED; } else if (WIFSIGNALED (exit_status)) status = MU_ERR_PROCESS_SIGNALED; else status = MU_ERR_PROCESS_UNKNOWN_FAILURE; } pm->pid = -1; return status; }