static int pop_header_fill (void *data, char **pbuf, size_t *plen) { struct _pop3_message *mpm = data; struct _pop3_mailbox *mpd = mpm->mpd; mu_stream_t stream; int status; if (mpm->flags & _POP3_MSG_SCANNED) { status = _pop_message_get_stream (mpm, &stream); if (status == 0) { status = pop_header_blurb (stream, mpm->header_lines, pbuf, plen); mu_stream_destroy (&stream); } } else { status = mu_pop3_top (mpd->pop3, mpm->num, 0, &stream); if (status) status = _pop_message_get_stream (mpm, &stream); if (status == 0) { status = pop_header_blurb (stream, 0, pbuf, plen); if (!mu_stream_eof (stream)) pop_stream_drain (stream); mu_stream_destroy (&stream); } return status; } return status; }
int mu_message_save_attachment (mu_message_t msg, const char *filename, mu_mime_io_buffer_t info) { mu_stream_t istream; int ret; mu_header_t hdr; const char *fname = NULL; char *partname = NULL; if (msg == NULL) return EINVAL; if ((ret = _attachment_setup (&info, msg, &istream)) != 0) return ret; if (ret == 0 && (ret = mu_message_get_header (msg, &hdr)) == 0) { if (filename == NULL) { ret = mu_message_aget_decoded_attachment_name (msg, info->charset, &partname, NULL); if (partname) fname = partname; } else fname = filename; if (fname && (ret = mu_file_stream_create (&info->fstream, fname, MU_STREAM_WRITE | MU_STREAM_CREAT)) == 0) { const char *content_encoding; if (mu_header_sget_value (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING, &content_encoding)) content_encoding = "7bit"; ret = mu_filter_create (&info->stream, istream, content_encoding, MU_FILTER_DECODE, MU_STREAM_READ); } } if (info->stream && istream) ret = mu_stream_copy (info->fstream, info->stream, 0, NULL); if (ret != EAGAIN && info) { mu_stream_close (info->fstream); mu_stream_destroy (&info->stream); mu_stream_destroy (&info->fstream); } mu_stream_destroy (&istream); _attachment_free (info, ret); /* FIXME: or 0? */ /* Free fname if we allocated it. */ if (partname) free (partname); return ret; }
int main (int argc, char * argv []) { int c; mu_stream_t in, out; int reread_option = 0; mu_off_t reread_off; int skip_option = 0; mu_off_t skip_off; while ((c = getopt (argc, argv, "hs:r:")) != EOF) switch (c) { case 'r': reread_option = 1; reread_off = strtoul (optarg, NULL, 10); break; case 's': skip_option = 1; skip_off = strtoul (optarg, NULL, 10); break; case 'h': printf ("usage: cat [-s off]\n"); exit (0); default: exit (1); } MU_ASSERT (mu_stdio_stream_create (&in, MU_STDIN_FD, MU_STREAM_SEEK)); MU_ASSERT (mu_stdio_stream_create (&out, MU_STDOUT_FD, 0)); if (skip_option) { mu_stream_printf (out, "skipping to %lu:\n", (unsigned long) skip_off); MU_ASSERT (mu_stream_seek (in, skip_off, MU_SEEK_SET, NULL)); } MU_ASSERT (mu_stream_copy (out, in, 0, NULL)); if (reread_option) { mu_stream_printf (out, "rereading from %lu:\n", (unsigned long) reread_off); MU_ASSERT (mu_stream_seek (in, reread_off, MU_SEEK_SET, NULL)); MU_ASSERT (mu_stream_copy (out, in, 0, NULL)); } mu_stream_close (in); mu_stream_destroy (&in); mu_stream_close (out); mu_stream_destroy (&out); return 0; }
static int _mh_prop_read_stream (mu_header_t *phdr, mu_stream_t stream) { int rc; mu_stream_t flt; const char *argv[4]; mu_off_t size; size_t total; char *blurb; rc = mu_stream_size (stream, &size); if (rc) return rc; argv[0] = "INLINE-COMMENT"; argv[1] = "#"; argv[2] = "-r"; argv[3] = NULL; rc = mu_filter_create_args (&flt, stream, argv[0], 3, argv, MU_FILTER_DECODE, MU_STREAM_READ); if (rc) { mu_error (_("cannot open filter stream: %s"), mu_strerror (rc)); return rc; } blurb = malloc (size + 1); if (!blurb) { mu_stream_destroy (&flt); return ENOMEM; } total = 0; while (1) { size_t n; rc = mu_stream_read (flt, blurb + total, size - total, &n); if (rc) break; if (n == 0) break; total += n; } mu_stream_destroy (&flt); if (rc) { free (blurb); return rc; } rc = mu_header_create (phdr, blurb, total); free (blurb); return rc; }
int mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, mu_mime_io_buffer_t info) { mu_stream_t istream, ostream; int ret = 0; mu_message_t tmsg = NULL; if (newmsg == NULL) return MU_ERR_OUT_PTR_NULL; if (msg == NULL) { mu_header_t hdr; ret = mu_message_create (&tmsg, NULL); if (ret) return ret; msg = tmsg; #define MSG822_HEADER "Content-Type: message/rfc822\n" \ "Content-Transfer-Encoding: 7bit\n\n" if ((ret = mu_header_create (&hdr, MSG822_HEADER, sizeof (MSG822_HEADER) - 1)) == 0) ret = mu_message_set_header (msg, hdr, NULL); #undef MSG822_HEADER if (ret) { mu_message_destroy (&msg, NULL); return ret; } } if ((ret = _attachment_setup (&info, msg, &ostream)) != 0) { mu_message_destroy (&tmsg, NULL); return ret; } info->msg = msg; if (ret == 0 && (ret = mu_message_get_streamref (msg, &istream)) == 0) { mu_stream_seek (istream, 0, MU_SEEK_SET, NULL); ret = mu_stream_copy (ostream, istream, 0, NULL); mu_stream_destroy (&istream); } if (ret == 0) *newmsg = info->msg; mu_stream_destroy (&ostream); _attachment_free (info, ret && ret != EAGAIN); return ret; }
int mail_tmp_finish (struct mail_tmp *mtmp, mu_mailbox_t *mbox) { int status; static char *newline = "\n"; size_t n; if (!mtmp->had_nl) status = mu_stream_sequential_write (mtmp->stream, newline, 1); status = mu_stream_sequential_write (mtmp->stream, newline, 1); unlink (mtmp->tempfile); free (mtmp->tempfile); mtmp->tempfile = NULL; if (status) { errno = status; maidag_error (_("error writing temporary file: %s"), mu_strerror (status)); mu_stream_destroy (&mtmp->stream, mu_stream_get_owner (mtmp->stream)); return status; } mu_stream_flush (mtmp->stream); if ((status = mu_mailbox_create (mbox, "mbox:/dev/null")) || (status = mu_mailbox_open (*mbox, MU_STREAM_READ)) || (status = mu_mailbox_set_stream (*mbox, mtmp->stream))) { maidag_error (_("error opening temporary file: %s"), mu_strerror (status)); mu_stream_destroy (&mtmp->stream, mu_stream_get_owner (mtmp->stream)); return status; } status = mu_mailbox_messages_count (*mbox, &n); if (status) { errno = status; maidag_error (_("error creating temporary message: %s"), mu_strerror (status)); mu_stream_destroy (&mtmp->stream, mu_stream_get_owner (mtmp->stream)); return status; } mtmp->stream = NULL; mtmp->line = 0; return status; }
int mu_tcp_stream_create_from_sa (mu_stream_t *pstream, struct mu_sockaddr *remote_addr, struct mu_sockaddr *source_addr, int flags) { int rc; mu_stream_t stream; struct _tcp_instance *tcp; tcp = _create_tcp_stream (flags | MU_STREAM_RDWR); if (!tcp) return ENOMEM; tcp->remote_addr = remote_addr; tcp->source_addr = source_addr; stream = (mu_stream_t) tcp; rc = mu_stream_open (stream); if (rc == 0 || rc == EAGAIN || rc == EINPROGRESS) *pstream = stream; else { /* Make sure sockaddrs are not freed on error */ tcp->remote_addr = tcp->source_addr = NULL; mu_stream_destroy (&stream); } return rc; }
char * dispatch_docstring (const char *text) { mu_stream_t str; struct mutool_action_tab *p; mu_off_t size; size_t n; char *ret; mu_memory_stream_create (&str, MU_STREAM_RDWR); mu_stream_printf (str, "%s\n%s\n\n", text, _("Commands are:")); for (p = mutool_action_tab; p->name; p++) mu_stream_printf (str, " %s %-16s - %s\n", mu_program_name, p->name, gettext (p->docstring)); mu_stream_printf (str, _("\nTry `%s COMMAND --help' to get help on a particular " "COMMAND.\n\n"), mu_program_name); mu_stream_printf (str, "%s\n", _("Options are:")); mu_stream_flush (str); mu_stream_size (str, &size); ret = mu_alloc (size + 1); mu_stream_seek (str, 0, MU_SEEK_SET, NULL); mu_stream_read (str, ret, size, &n); ret[n] = 0; mu_stream_destroy (&str); return ret; }
static int pop_close (mu_mailbox_t mbox) { struct _pop3_mailbox *mpd = mbox->data; int status; status = mu_pop3_quit (mpd->pop3); if (status) mu_error ("mu_pop3_quit failed: %s", mu_strerror (status)); status = mu_pop3_disconnect (mpd->pop3); if (status) mu_error ("mu_pop3_disconnect failed: %s", mu_strerror (status)); if (mpd->msg) { size_t i; mu_monitor_wrlock (mbox->monitor); /* Destroy the pop messages and resources associated to them. */ for (i = 0; i < mpd->msg_count; i++) { if (mpd->msg[i]) { mu_message_destroy (&mpd->msg[i]->message, mpd->msg[i]); if (mpd->msg[i]->uidl) free (mpd->msg[i]->uidl); free (mpd->msg[i]); } } mu_monitor_unlock (mbox->monitor); } mu_stream_destroy (&mpd->cache); return 0; }
/* Open the file. For MU_STREAM_READ, the code tries mmap() first and fall back to normal file. */ static int mbox_open (mu_mailbox_t mailbox, int flags) { mbox_data_t mud = mailbox->data; int status = 0; if (mud == NULL) return EINVAL; mailbox->flags = flags; /* Get a stream. */ if (mailbox->stream == NULL) { /* We do not try to mmap for CREAT or APPEND, it is not supported. */ status = (flags & MU_STREAM_CREAT) || (mailbox->flags & MU_STREAM_APPEND); /* Try to mmap () the file first. */ if (status == 0) { status = mu_mapfile_stream_create (&mailbox->stream, mud->name, mailbox->flags); if (status == 0) { status = mu_stream_open (mailbox->stream); } } /* Fall back to normal file if mmap() failed. */ if (status != 0) { status = mu_file_stream_create (&mailbox->stream, mud->name, mailbox->flags); if (status != 0) return status; status = mu_stream_open (mailbox->stream); } /* All failed, bail out. */ if (status != 0) { mu_stream_destroy (&mailbox->stream, NULL); return status; } /* Even on top of normal FILE *, lets agressively cache. But this may not be suitable for system tight on memory. */ mu_stream_setbufsiz (mailbox->stream, BUFSIZ); } else { status = mu_stream_open (mailbox->stream); if (status != 0) return status; } MU_DEBUG2 (mailbox->debug, MU_DEBUG_TRACE1, "mbox_open (%s, 0x%x)\n", mud->name, mailbox->flags); if (mailbox->locker == NULL) status = mu_locker_create (&(mailbox->locker), mud->name, 0); return status; }
static int top0 (msgset_t *mspec, mu_message_t msg, void *data) { mu_stream_t stream; char *buf = NULL; size_t size = 0, n; int lines; if (mailvar_get (&lines, "toplines", mailvar_type_number, 1) || lines < 0) return 1; mu_message_get_streamref (msg, &stream); for (; lines > 0; lines--) { int status = mu_stream_getline (stream, &buf, &size, &n); if (status != 0 || n == 0) break; mu_printf ("%s", buf); } free (buf); mu_stream_destroy (&stream); set_cursor (mspec->msg_part[0]); util_mark_read (msg); return 0; }
int mail_tmp_add_line (struct mail_tmp *mtmp, char *buf, size_t buflen) { int status = 0; mtmp->line++; if (mtmp->line == 1) { const char *from = mtmp->from; if (buflen >= 5 && memcmp (buf, "From ", 5)) { struct mu_auth_data *auth = NULL; if (!from) { auth = mu_get_auth_by_uid (getuid ()); if (auth) from = auth->name; } if (from) { time_t t; char *envs; time (&t); asprintf (&envs, "From %s %s", from, ctime (&t)); status = mu_stream_sequential_write (mtmp->stream, envs, strlen (envs)); free (envs); } else { maidag_error (_("cannot determine sender address")); return EINVAL; } if (auth) mu_auth_data_free (auth); } } else if (buflen >= 5 && !memcmp (buf, "From ", 5)) { static char *escape = ">"; status = mu_stream_sequential_write (mtmp->stream, escape, 1); } if (!status) status = mu_stream_sequential_write (mtmp->stream, buf, buflen); if (status) { maidag_error (_("error writing temporary file: %s"), mu_strerror (status)); mu_stream_destroy (&mtmp->stream, mu_stream_get_owner (mtmp->stream)); } mtmp->had_nl = buf[buflen-1] == '\n'; return status; }
int mu_pop3_read_list (mu_pop3_t pop3, mu_list_t list) { mu_stream_t stream; int status = mu_pop3_stream_create (pop3, &stream); if (status) return status; status = mu_pop3_stream_to_list (pop3, stream, list); mu_stream_destroy (&stream); return status; }
static PyObject * api_stream_destroy (PyObject *self, PyObject *args) { PyStream *py_stm; if (!PyArg_ParseTuple (args, "O!", &PyStreamType, &py_stm)) return NULL; mu_stream_destroy (&py_stm->stm); return _ro (Py_None); }
static int chk_ssha (const char *db_pass, const char *pass) { int rc; unsigned char sha1digest[20]; unsigned char *d1; struct mu_sha1_ctx sha1context; mu_stream_t str = NULL, flt = NULL; size_t size; size = strlen (db_pass); mu_static_memory_stream_create (&str, db_pass, size); mu_filter_create (&flt, str, "base64", MU_FILTER_DECODE, MU_STREAM_READ); mu_stream_unref (str); d1 = malloc (size); if (!d1) { mu_stream_destroy (&flt); return ENOMEM; } mu_stream_read (flt, (char*) d1, size, &size); mu_stream_destroy (&flt); if (size <= 16) { mu_error ("malformed SSHA1 password: %s", db_pass); return MU_ERR_FAILURE; } mu_sha1_init_ctx (&sha1context); mu_sha1_process_bytes (pass, strlen (pass), &sha1context); mu_sha1_process_bytes (d1 + 20, size - 20, &sha1context); mu_sha1_finish_ctx (&sha1context, sha1digest); rc = memcmp (sha1digest, d1, sizeof sha1digest) == 0 ? 0 : MU_ERR_AUTH_FAILURE; free (d1); return rc; }
int moderator_message_get_part (mu_sieve_machine_t mach, mu_message_t msg, size_t index, mu_message_t *pmsg) { int rc; mu_message_t tmp; mu_header_t hdr = NULL; const char *value; if ((rc = mu_message_get_part (msg, index, &tmp))) { mu_sieve_error (mach, _("cannot get message part #%lu: %s"), (unsigned long) index, mu_strerror (rc)); return 1; } mu_message_get_header (tmp, &hdr); if (mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, &value) == 0 && memcmp (value, "message/rfc822", 14) == 0) { mu_stream_t str; mu_body_t body; mu_message_get_body (tmp, &body); mu_body_get_streamref (body, &str); rc = mu_stream_to_message (str, pmsg); mu_stream_destroy (&str); if (rc) { mu_sieve_error (mach, _("cannot convert MIME part stream to message: %s"), mu_strerror (rc)); return 1; } } else if (value) { mu_sieve_error (mach, _("expected message type message/rfc822, but found %s"), value); return 1; } else { mu_sieve_error (mach, _("no Content-Type header found")); return 1; } return 0; }
int mu_nntp_set_carrier (mu_nntp_t nntp, mu_stream_t carrier) { /* Sanity checks. */ if (nntp == NULL) return EINVAL; if (nntp->carrier) { /* Close any old carrier. */ mu_nntp_disconnect (nntp); mu_stream_destroy (&nntp->carrier); } nntp->carrier = carrier; return 0; }
void mail_tmp_destroy (struct mail_tmp **pmtmp) { struct mail_tmp *mtmp = *pmtmp; if (mtmp) { if (mtmp->tempfile) { unlink (mtmp->tempfile); free (mtmp->tempfile); } mu_stream_destroy (&mtmp->stream, mu_stream_get_owner (mtmp->stream)); free (*pmtmp); *pmtmp = NULL; } }
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; }
void mh_comp_draft (const char *formfile, const char *draftfile) { char *s; if (mh_find_file (formfile, &s) == 0) { if (mh_file_copy (s, draftfile)) exit (1); free (s); } else { /* I doubt if we need that: */ int rc; mu_stream_t stream; if ((rc = mu_file_stream_create (&stream, draftfile, MU_STREAM_WRITE|MU_STREAM_CREAT))) { mu_error (_("cannot open output file \"%s\": %s"), draftfile, mu_strerror (rc)); exit (1); } rc = mu_stream_write (stream, default_format_str, strlen (default_format_str), NULL); mu_stream_close (stream); mu_stream_destroy (&stream); if (rc) { mu_error (_("error writing to \"%s\": %s"), draftfile, mu_strerror (rc)); exit (1); } } }
static int chk_sha (const char *db_pass, const char *pass) { unsigned char sha1digest[20]; unsigned char d1[20]; mu_stream_t str = NULL, flt = NULL; struct mu_sha1_ctx sha1context; mu_sha1_init_ctx (&sha1context); mu_sha1_process_bytes (pass, strlen (pass), &sha1context); mu_sha1_finish_ctx (&sha1context, sha1digest); mu_static_memory_stream_create (&str, db_pass, strlen (db_pass)); mu_filter_create (&flt, str, "base64", MU_FILTER_DECODE, MU_STREAM_READ); mu_stream_unref (str); mu_stream_read (flt, (char*) d1, sizeof d1, NULL); mu_stream_destroy (&flt); return memcmp (sha1digest, d1, sizeof sha1digest) == 0 ? 0 : MU_ERR_AUTH_FAILURE; }
int mu_smtp_send_stream (mu_smtp_t smtp, mu_stream_t stream) { int status; mu_stream_t input; if (!smtp) return EINVAL; if (MU_SMTP_FISSET (smtp, _MU_SMTP_ERR)) return MU_ERR_FAILURE; if (smtp->state != MU_SMTP_MORE) return MU_ERR_SEQ; status = mu_filter_create (&input, stream, "CRLFDOT", MU_FILTER_ENCODE, MU_STREAM_READ); if (status) return status; status = _smtp_data_send (smtp, input); mu_stream_destroy (&input); return status; }
/* Display the contents of the given file on the terminal */ static void display_file (const char *name) { const char *pager = mh_global_profile_get ("moreproc", getenv ("PAGER")); if (pager) mh_spawnp (pager, name); else { mu_stream_t stream; int rc; size_t off = 0; size_t n; char buffer[512]; rc = mu_file_stream_create (&stream, name, MU_STREAM_READ); if (rc) { mu_error ("mu_file_stream_create: %s", mu_strerror (rc)); return; } rc = mu_stream_open (stream); if (rc) { mu_error ("mu_stream_open: %s", mu_strerror (rc)); return; } while (mu_stream_read (stream, buffer, sizeof buffer - 1, off, &n) == 0 && n != 0) { buffer[n] = '\0'; printf ("%s", buffer); off += n; } mu_stream_destroy (&stream, NULL); } }
/* Message read overload */ static int nntp_body_read (mu_stream_t stream, char *buffer, size_t buflen, mu_off_t offset, size_t *plen) { mu_body_t body = mu_stream_get_owner (stream); mu_message_t msg = mu_body_get_owner (body); msg_nntp_t msg_nntp = mu_message_get_owner (msg); m_nntp_t m_nntp = msg_nntp->m_nntp; f_nntp_t f_nntp = m_nntp->f_nntp; int status; size_t len = 0; /* Start over. */ if (plen == NULL) plen = &len; /* Select first. */ status = nntp_mailbox_messages_count (m_nntp->mailbox, NULL); if (status != 0) return status; if (msg_nntp->bstream == NULL) { status = mu_nntp_body (f_nntp->nntp, msg_nntp->msgno, NULL, &msg_nntp->mid, &msg_nntp->bstream); if (status != 0) return status; } status = mu_stream_read (msg_nntp->bstream, buffer, buflen, offset, plen); if (status == 0) { /* Destroy the stream. */ if (*plen == 0) { mu_stream_destroy (&msg_nntp->bstream, NULL); } } return status; }
void _mu_onexit_run (void) { mu_iterator_t itr; int rc, status = 0; if (!onexit_list) return; rc = mu_list_get_iterator (onexit_list, &itr); if (rc) { mu_error (_("cannot create iterator, onexit aborted: %s"), mu_strerror (rc)); mu_stream_destroy (&mu_strerr); _exit (127); } for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr)) { struct onexit_closure *cp; int rc = mu_iterator_current (itr, (void**)&cp); if (rc) { status = 127; mu_error (_("cannot obtain current item while traversing the" " onexit action list: %s"), mu_strerror (rc)); } else cp->function (cp->data); mu_iterator_ctl (itr, mu_itrctl_delete, NULL); } mu_iterator_destroy (&itr); mu_list_destroy (&onexit_list); if (status) _exit (status); }
int main (int argc, char * argv []) { mu_stream_t in, out, sock; pid_t pid; int status, c; while ((c = getopt (argc, argv, "v")) != EOF) switch (c) { case 'v': verbose++; break; case 'h': printf ("usage: musocio file\n"); return 0; default: return 1; } argc -= optind; argv += optind; if (argc != 2) { mu_error ("usage: musocio file"); return 1; } MU_ASSERT (mu_stdio_stream_create (&in, MU_STDIN_FD, 0)); mu_stream_set_buffer (in, mu_buffer_line, 0); MU_ASSERT (mu_stdio_stream_create (&out, MU_STDOUT_FD, 0)); mu_stream_set_buffer (out, mu_buffer_line, 0); MU_ASSERT (mu_socket_stream_create (&sock, argv[1], MU_STREAM_RDWR)); mu_stream_set_buffer (sock, mu_buffer_line, 0); pid = fork (); if (pid == -1) { mu_error ("fork failed: %s", mu_strerror (errno)); return 1; } if (pid == 0) { mu_stream_close (in); mu_stream_destroy (&in); ioloop ("reader", sock, out); exit (0); } ioloop ("writer", in, sock); mu_stream_close (in); mu_stream_destroy (&in); mu_stream_shutdown (sock, MU_STREAM_WRITE); waitpid (pid, &status, 0); mu_stream_close (sock); mu_stream_destroy (&sock); mu_stream_close (out); mu_stream_destroy (&out); return 0; }
/* Build a mime response message from original message MSG. TEXT is the message text. */ static int build_mime (mu_sieve_machine_t mach, mu_list_t tags, mu_mime_t *pmime, mu_message_t msg, const char *text) { mu_mime_t mime = NULL; mu_message_t newmsg; mu_stream_t stream, input; mu_header_t hdr; mu_body_t body; const char *header = "Content-Type: text/plain;charset=" MU_SIEVE_CHARSET "\n" "Content-Transfer-Encoding: 8bit\n\n"; int rc; mu_mime_create (&mime, NULL, 0); mu_message_create (&newmsg, NULL); mu_message_get_body (newmsg, &body); if ((rc = mu_static_memory_stream_create (&input, text, strlen (text)))) { mu_sieve_error (mach, _("cannot create temporary stream: %s"), mu_strerror (rc)); mu_mime_destroy (&mime); mu_message_destroy (&newmsg, NULL); return 1; } if (mu_sieve_tag_lookup (tags, "mime", NULL)) { mu_stream_t fstr; rc = mu_filter_create (&fstr, input, "base64", MU_FILTER_ENCODE, MU_STREAM_READ); mu_stream_unref (input); if (rc == 0) { header = "Content-Type: text/plain;charset=" MU_SIEVE_CHARSET "\n" "Content-Transfer-Encoding: base64\n\n"; input = fstr; } } rc = mu_body_get_streamref (body, &stream); if (rc) { mu_sieve_error (mach, _("cannot get input body stream: %s"), mu_strerror (rc)); mu_mime_destroy (&mime); mu_message_destroy (&newmsg, NULL); mu_stream_destroy (&input); return 1; } rc = mu_stream_copy (stream, input, 0, NULL); if (rc) { mu_sieve_error (mach, _("stream copy failed: %s"), mu_strerror (rc)); mu_mime_destroy (&mime); mu_message_destroy (&newmsg, NULL); mu_stream_destroy (&input); mu_stream_destroy (&stream); return 1; } mu_stream_destroy (&input); mu_header_create (&hdr, header, strlen (header)); mu_message_set_header (newmsg, hdr, NULL); mu_mime_add_part (mime, newmsg); mu_message_unref (newmsg); *pmime = mime; return 0; }
static int _pop_message_get_stream (struct _pop3_message *mpm, mu_stream_t *pstr) { int status; struct _pop3_mailbox *mpd = mpm->mpd; if (!(mpm->flags & _POP3_MSG_CACHED)) { mu_stream_t stream; mu_off_t size; status = mu_pop3_retr (mpd->pop3, mpm->num, &stream); if (status) return status; do { mu_stream_t flt; if (!mpd->cache) { status = mu_temp_file_stream_create (&mpd->cache, NULL, 0); if (status) /* FIXME: Try to recover first */ break; mu_stream_set_buffer (mpd->cache, mu_buffer_full, 8192); } status = mu_stream_size (mpd->cache, &mpm->offset); if (status) break; status = mu_filter_create (&flt, stream, "CRLF", MU_FILTER_DECODE, MU_STREAM_READ); if (status) break; status = mu_stream_copy (mpd->cache, flt, 0, &size); mu_stream_destroy (&flt); } while (0); if (status) { pop_stream_drain (stream); mu_stream_unref (stream); return status; } mu_stream_unref (stream); mpm->message_size = size; /* FIXME: Possible overflow. */ mpm->flags |= _POP3_MSG_CACHED | _POP3_MSG_SIZE; } return mu_streamref_create_abridged (pstr, mpd->cache, mpm->offset, mpm->offset + mpm->message_size - 1); }
static int pop_open (mu_mailbox_t mbox, int flags) { struct _pop3_mailbox *mpd = mbox->data; int status; mu_stream_t stream; struct mu_sockaddr *sa; struct mu_sockaddr_hints hints; /* Sanity checks. */ if (mpd == NULL) return EINVAL; mbox->flags = flags; memset (&hints, 0, sizeof (hints)); hints.flags = MU_AH_DETECT_FAMILY; hints.port = mpd->pops ? MU_POPS_PORT : MU_POP_PORT; hints.protocol = IPPROTO_TCP; hints.socktype = SOCK_STREAM; status = mu_sockaddr_from_url (&sa, mbox->url, &hints); if (status) return status; status = mu_tcp_stream_create_from_sa (&stream, sa, NULL, mbox->flags); if (status) { mu_sockaddr_free (sa); return status; } #ifdef WITH_TLS if (mpd->pops) { mu_stream_t newstr; status = mu_tls_client_stream_create (&newstr, stream, stream, 0); mu_stream_unref (stream); if (status) { mu_error ("pop_open: mu_tls_client_stream_create: %s", mu_strerror (status)); return status; } stream = newstr; } #endif /* WITH_TLS */ /* FIXME: How to configure buffer size? */ mu_stream_set_buffer (stream, mu_buffer_line, 0); status = mu_pop3_create (&mpd->pop3); if (status) { mu_stream_destroy (&stream); return status; } mu_pop3_set_carrier (mpd->pop3, stream); if (mu_debug_level_p (MU_DEBCAT_MAILBOX, MU_DEBUG_PROT)) mu_pop3_trace (mpd->pop3, MU_POP3_TRACE_SET); if (mu_debug_level_p (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE6)) mu_pop3_trace_mask (mpd->pop3, MU_POP3_TRACE_SET, MU_XSCRIPT_SECURE); if (mu_debug_level_p (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE7)) mu_pop3_trace_mask (mpd->pop3, MU_POP3_TRACE_SET, MU_XSCRIPT_PAYLOAD); do { status = mu_pop3_connect (mpd->pop3); if (status) break; status = mu_pop3_capa (mpd->pop3, 1, NULL); if (status == MU_ERR_REPLY) { mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR, ("server rejected the CAPA command: %s", mu_pop3_strresp (mpd->pop3))); /* try to continue anyway */ } else if (status) return status; #ifdef WITH_TLS if (!mpd->pops && mu_url_sget_param (mbox->url, "notls", NULL) == MU_ERR_NOENT && mu_pop3_capa_test (mpd->pop3, "STLS", NULL) == 0) { status = mu_pop3_stls (mpd->pop3); if (status) break; } #endif status = mu_authority_authenticate (mbox->folder->authority); } while (0); if (status) mu_pop3_destroy (&mpd->pop3); return status; }
int main (int argc, char **argv) { int i; char *host = NULL; char *infile = NULL; char *port = NULL; int tls = 0; int raw = 1; int flags = 0; mu_stream_t stream; mu_smtp_t smtp; mu_stream_t instr; char *from = NULL; mu_list_t rcpt_list = NULL; mu_list_t meth_list = NULL; mu_list_t skiphdr_list = NULL; struct mu_sockaddr *sa; struct mu_sockaddr_hints hints; mu_set_program_name (argv[0]); mu_stdstream_setup (MU_STDSTREAM_RESET_NONE); if (argc < 2) usage (); memset (&hints, 0, sizeof (hints)); hints.flags = MU_AH_DETECT_FAMILY; hints.port = 25; hints.protocol = IPPROTO_TCP; hints.socktype = SOCK_STREAM; MU_ASSERT (mu_smtp_create (&smtp)); for (i = 1; i < argc; i++) { if (strncmp (argv[i], "port=", 5) == 0) port = argv[i] + 5; else if (strncmp (argv[i], "family=", 7) == 0) { hints.flags &= ~MU_AH_DETECT_FAMILY; switch (argv[i][7]) { case '4': hints.family = AF_INET; break; case '6': hints.family = AF_INET6; break; default: mu_error ("invalid family name: %s", argv[i]+7); exit (1); } } else if (strncmp (argv[i], "trace=", 6) == 0) { char *arg = argv[i] + 6; if (mu_isdigit (arg[0])) mu_smtp_trace (smtp, atoi (argv[i] + 6) ? MU_SMTP_TRACE_SET : MU_SMTP_TRACE_CLR); else { mu_smtp_trace (smtp, MU_SMTP_TRACE_SET); if (strcmp (arg, "secure") == 0) mu_smtp_trace_mask (smtp, MU_SMTP_TRACE_SET, MU_XSCRIPT_SECURE); else if (strcmp (arg, "payload") == 0) mu_smtp_trace_mask (smtp, MU_SMTP_TRACE_SET, MU_XSCRIPT_PAYLOAD); } } else if (strncmp (argv[i], "tls=", 4) == 0) tls = atoi (argv[i] + 4); else if (strncmp (argv[i], "domain=", 7) == 0) MU_ASSERT (mu_smtp_set_param (smtp, MU_SMTP_PARAM_DOMAIN, argv[i] + 7)); else if (strncmp (argv[i], "user="******"pass="******"service=", 8) == 0) MU_ASSERT (mu_smtp_set_param (smtp, MU_SMTP_PARAM_SERVICE, argv[i] + 8)); else if (strncmp (argv[i], "realm=", 6) == 0) MU_ASSERT (mu_smtp_set_param (smtp, MU_SMTP_PARAM_REALM, argv[i] + 6)); else if (strncmp (argv[i], "host=", 5) == 0) MU_ASSERT (mu_smtp_set_param (smtp, MU_SMTP_PARAM_HOST, argv[i] + 5)); else if (strncmp (argv[i], "url=", 4) == 0) MU_ASSERT (mu_smtp_set_param (smtp, MU_SMTP_PARAM_URL, argv[i] + 4)); else if (strncmp (argv[i], "input=", 6) == 0) infile = argv[i] + 6; else if (strncmp (argv[i], "raw=", 4) == 0) raw = atoi (argv[i] + 4); else if (strncmp (argv[i], "rcpt=", 5) == 0) { if (!rcpt_list) MU_ASSERT (mu_list_create (&rcpt_list)); MU_ASSERT (mu_list_append (rcpt_list, argv[i] + 5)); } else if (strncmp (argv[i], "from=", 5) == 0) from = argv[i] + 5; else if (strncmp (argv[i], "auth=", 5) == 0) update_list (&meth_list, argv[i] + 5); else if (strncmp (argv[i], "skiphdr=", 8) == 0) { update_list (&skiphdr_list, argv[i] + 8); raw = 0; } else if (host) { mu_error ("server name already given: %s, new name %s?", host, argv[i]); exit (1); } else host = argv[i]; } if (!host) usage (); if (!raw) flags = MU_STREAM_SEEK; if (infile) MU_ASSERT (mu_file_stream_create (&instr, infile, MU_STREAM_READ|flags)); else MU_ASSERT (mu_stdio_stream_create (&instr, MU_STDIN_FD, flags)); host = argv[1]; MU_ASSERT (mu_sockaddr_from_node (&sa, host, port, &hints)); MU_ASSERT (mu_tcp_stream_create_from_sa (&stream, sa, NULL, MU_STREAM_RDWR)); mu_smtp_set_carrier (smtp, stream); mu_stream_unref (stream); if (!from) { from = getenv ("USER"); if (!from) { mu_error ("cannot determine sender name"); exit (1); } } if (raw && !rcpt_list) { mu_error ("no recipients"); exit (1); } MU_ASSERT (mu_smtp_open (smtp)); MU_ASSERT (mu_smtp_ehlo (smtp)); if (tls && mu_smtp_capa_test (smtp, "STARTTLS", NULL) == 0) { MU_ASSERT (mu_smtp_starttls (smtp)); MU_ASSERT (mu_smtp_ehlo (smtp)); } if (meth_list) { int status; MU_ASSERT (mu_smtp_add_auth_mech_list (smtp, meth_list)); status = mu_smtp_auth (smtp); switch (status) { case 0: MU_ASSERT (mu_smtp_ehlo (smtp)); break; case ENOSYS: case MU_ERR_NOENT: /* Ok, skip it */ break; default: mu_error ("authentication failed: %s", mu_strerror (status)); exit (1); } } MU_ASSERT (mu_smtp_mail_basic (smtp, from, NULL)); mu_list_foreach (rcpt_list, send_rcpt_command, smtp); if (raw) { /* Raw sending mode: send from the stream directly */ MU_ASSERT (mu_smtp_send_stream (smtp, instr)); } else { /* Message (standard) sending mode: send a MU message. */ mu_message_t msg; mu_stream_t ostr, bstr; mu_header_t hdr; mu_iterator_t itr; mu_body_t body; if (skiphdr_list) mu_list_set_comparator (skiphdr_list, headercmp); MU_ASSERT (mu_stream_to_message (instr, &msg)); mu_stream_unref (instr); MU_ASSERT (mu_smtp_data (smtp, &ostr)); MU_ASSERT (mu_message_get_header (msg, &hdr)); MU_ASSERT (mu_header_get_iterator (hdr, &itr)); for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr)) { const char *name; void *value; mu_iterator_current_kv (itr, (void*) &name, &value); if (mu_list_locate (skiphdr_list, (void*) name, NULL) == 0) continue; mu_stream_printf (ostr, "%s: %s\n", name, (char*)value); } mu_iterator_destroy (&itr); MU_ASSERT (mu_stream_write (ostr, "\n", 1, NULL)); MU_ASSERT (mu_message_get_body (msg, &body)); MU_ASSERT (mu_body_get_streamref (body, &bstr)); MU_ASSERT (mu_stream_copy (ostr, bstr, 0, NULL)); mu_stream_destroy (&bstr); mu_stream_close (ostr); mu_stream_destroy (&ostr); } MU_ASSERT (mu_smtp_dot (smtp)); MU_ASSERT (mu_smtp_quit (smtp)); mu_smtp_destroy (&smtp); mu_stream_close (instr); mu_stream_destroy (&instr); return 0; }