size_t mh_get_message (mu_mailbox_t mbox, size_t seqno, mu_message_t *mesg) { size_t num, count; mu_message_t msg; if (mu_mailbox_get_message (mbox, 1, &msg) || mh_message_number (msg, &num)) return 0; if (seqno < num) return 0; else if (seqno == num) { if (mesg) *mesg = msg; return 1; } if (mu_mailbox_messages_count (mbox, &count) || mu_mailbox_get_message (mbox, count, &msg) || mh_message_number (msg, &num)) return 0; if (seqno > num) return 0; else if (seqno == num) { if (mesg) *mesg = msg; return count; } return mh_search_message (mbox, 1, count, seqno, mesg); }
void sort () { size_t *oldlist, i; oldlist = xmalloc (msgset.count * sizeof (*oldlist)); memcpy (oldlist, msgset.list, msgset.count * sizeof (*oldlist)); switch (algorithm) { case ARG_QUICKSORT: qsort(msgset.list, msgset.count, sizeof(msgset.list[0]), comp); break; case ARG_SHELL: shell_sort(); break; } switch (action) { case ACTION_LIST: for (i = 0; i < msgset.count; i++) list_message (msgset.list[i]); break; default: /* Install signal handlers */ signal (SIGINT, sighandler); signal (SIGQUIT, sighandler); signal (SIGTERM, sighandler); if (verbose) fprintf (stderr, _("Transpositions:\n")); for (i = 0, got_signal = 0; !got_signal && i < msgset.count; i++) { if (msgset.list[i] != oldlist[i]) { size_t old_num, new_num; mu_message_t msg; mu_mailbox_get_message (mbox, oldlist[i], &msg); mh_message_number (msg, &old_num); mu_mailbox_get_message (mbox, msgset.list[i], &msg); mh_message_number (msg, &new_num); transpose (i, oldlist[i]); if (verbose) fprintf (stderr, "{%s, %s}\n", mu_umaxtostr (0, old_num), mu_umaxtostr (1, new_num)); if (action == ACTION_REORDER) swap_message (old_num, new_num); } } } }
static int comp0 (size_t na, size_t nb) { mu_message_t a, b; if (mu_mailbox_get_message (mbox, na, &a) || mu_mailbox_get_message (mbox, nb, &b)) return 0; if (verbose > 1) fprintf (stderr, _("comparing messages %s and %s: "), mu_umaxtostr (0, na), mu_umaxtostr (1, nb)); return compare_messages (a, b, na, nb); }
mu_message_t mu_sieve_get_message (mu_sieve_machine_t mach) { if (!mach->msg) mu_mailbox_get_message (mach->mailbox, mach->msgno, &mach->msg); return mach->msg; }
/* Auxiliary function. Performs binary search for a message with the given sequence number */ static size_t mh_search_message (mu_mailbox_t mbox, size_t start, size_t stop, size_t seqno, mu_message_t *mesg) { mu_message_t mid_msg = NULL; size_t num = 0, middle; middle = (start + stop) / 2; if (mu_mailbox_get_message (mbox, middle, &mid_msg) || mh_message_number (mid_msg, &num)) return 0; if (num == seqno) { if (mesg) *mesg = mid_msg; return middle; } if (start >= stop) return 0; if (num > seqno) return mh_search_message (mbox, start, middle-1, seqno, mesg); else /*if (num < seqno)*/ return mh_search_message (mbox, middle+1, stop, seqno, mesg); }
static int msgset_cur (mu_mailbox_t mbox, size_t *pnum) { size_t i, count = 0; static int cached_n = 0; if (cached_n) { *pnum = cached_n; return 0; } mu_mailbox_messages_count (mbox, &count); for (i = 1; i <= count; i++) { mu_message_t msg = NULL; size_t uid = 0; mu_mailbox_get_message (mbox, i, &msg); mh_message_number (msg, &uid); if (uid == current_message) { *pnum = cached_n = i; return 0; } } mu_error (_("no cur message")); exit (1); }
/* Set the current message to that contained at position `index' in the given message set */ int mh_msgset_current (mu_mailbox_t mbox, mh_msgset_t *msgset, int index) { mu_message_t msg = NULL; if (mu_mailbox_get_message (mbox, msgset->list[index], &msg)) return 1; return mh_message_number (msg, ¤t_message); }
int pop3d_uidl (char *arg, struct pop3d_session *sess) { size_t mesgno; char uidl[128]; mu_message_t msg; mu_attribute_t attr; if (state != TRANSACTION) return ERR_WRONG_STATE; if (strchr (arg, ' ') != NULL) return ERR_BAD_ARGS; if (strlen (arg) == 0) { size_t total = 0; pop3d_outf ("+OK\n"); mu_mailbox_messages_count (mbox, &total); for (mesgno = 1; mesgno <= total; mesgno++) { mu_mailbox_get_message (mbox, mesgno, &msg); mu_message_get_attribute (msg, &attr); if (!pop3d_is_deleted (attr)) { mu_message_get_uidl (msg, uidl, sizeof (uidl), NULL); pop3d_outf ("%s %s\n", mu_umaxtostr (0, mesgno), uidl); } } pop3d_outf (".\n"); } else { mesgno = strtoul (arg, NULL, 10); if (mu_mailbox_get_message (mbox, mesgno, &msg) != 0) return ERR_NO_MESG; mu_message_get_attribute (msg, &attr); if (pop3d_is_deleted (attr)) return ERR_MESG_DELE; mu_message_get_uidl (msg, uidl, sizeof (uidl), NULL); pop3d_outf ("+OK %s %s\n", mu_umaxtostr (0, mesgno), uidl); } return OK; }
void list_message (size_t num) { mu_message_t msg = NULL; char *buffer; mu_mailbox_get_message (mbox, num, &msg); mh_format (&format, msg, num, 76, &buffer); printf ("%s\n", buffer); free (buffer); }
void mh_msgset_uids (mu_mailbox_t mbox, mh_msgset_t *msgset) { size_t i; for (i = 0; i < msgset->count; i++) { mu_message_t msg; mu_mailbox_get_message (mbox, msgset->list[i], &msg); mh_message_number (msg, &msgset->list[i]); } }
int mta_stdin (int argc, char **argv) { int c; char *tempfile; mu_mailbox_t mbox; mu_message_t msg = NULL; for (c = 0; c < argc; c++) { if (add_recipient (argv[c])) { mu_error ("%s: bad address %s", progname, argv[c]); return 1; } } make_tmp (stdin, from_person, &tempfile); if ((c = mu_mailbox_create_default (&mbox, tempfile)) != 0) { mu_error ("%s: can't create mailbox %s: %s", progname, tempfile, mu_strerror (c)); unlink (tempfile); return 1; } if ((c = mu_mailbox_open (mbox, MU_STREAM_RDWR)) != 0) { mu_error ("%s: can't open mailbox %s: %s", progname, tempfile, mu_strerror (c)); unlink (tempfile); return 1; } mu_mailbox_get_message (mbox, 1, &msg); if (message_finalize (msg, 1)) return 1; if (!recipients) { mu_error ("%s: Recipient names must be specified", progname); return 1; } mta_send (msg); unlink (tempfile); free (tempfile); return 0; }
static int _sieve_action (mu_observer_t obs, size_t type, void *data, void *action_data) { mu_sieve_machine_t mach; if (type != MU_EVT_MESSAGE_ADD) return 0; mach = mu_observer_get_owner (obs); mach->msgno++; mu_mailbox_get_message (mach->mailbox, mach->msgno, &mach->msg); sieve_run (mach); return 0; }
static int mbx_getitem (void *owner, void **pret, const void **pkey) { struct mailbox_iterator *itr = owner; size_t count; int rc; rc = mu_mailbox_messages_count (itr->mbx, &count); if (rc) return rc; if (itr->idx > count) return MU_ERR_NOENT; rc = mu_mailbox_get_message (itr->mbx, itr->idx, (mu_message_t*)pret); if (rc == 0 && pkey) *pkey = NULL; /* FIXME: Perhaps return UIDL or other unique id? */ return rc; }
static int show_struct (msgset_t *msgset, mu_message_t msg, void *data) { struct mime_descend_closure mclos; mclos.hints = 0; mclos.msgset = msgset; mclos.message = msg; mclos.type = NULL; mclos.encoding = NULL; mclos.parent = NULL; mime_descend (&mclos, show_part, NULL); /* Mark enclosing message as read */ if (mu_mailbox_get_message (mbox, msgset->msg_part[0], &msg) == 0) util_mark_read (msg); return 0; }
/* Preprocess a part of a complex message designation. Returns a pointer to the allocated memory containing expanded part of the designation. Pointer to the beginning of the not expanded part (in arg) is placed into *rest */ static char * msgset_preproc_part (mu_mailbox_t mbox, char *arg, char **rest) { struct msgset_keyword *p; char *cp; for (p = keywords; p->name; p++) if (strncmp (arg, p->name, strlen (p->name)) == 0) { int rc; size_t uid, num; mu_message_t msg; if (p->handler (mbox, &num)) msgset_abort (arg); rc = mu_mailbox_get_message (mbox, num, &msg); if (rc) { mu_error (_("cannot get message %lu: %s"), (unsigned long) num, mu_strerror (rc)); exit (1); } *rest = arg + strlen (p->name); mu_message_get_uid (msg, &uid); return xstrdup (mu_umaxtostr (0, uid)); } cp = strchr (arg, '-'); if (cp) { char *ret; *rest = cp; ret = xmalloc (cp - arg + 1); memcpy (ret, arg, cp - arg); ret[cp - arg] = 0; return ret; } *rest = arg + strlen (arg); return strdup (arg); }
int pop3d_stat (char *arg) { size_t mesgno; size_t size = 0; size_t lines = 0; size_t total = 0; size_t num = 0; size_t tsize = 0; mu_message_t msg = NULL; mu_attribute_t attr = NULL; if (strlen (arg) != 0) return ERR_BAD_ARGS; if (state != TRANSACTION) return ERR_WRONG_STATE; /* rfc1939: if the POP3 server host internally represents end-of-line as a single character, then the POP3 server simply counts each occurrence of this character in a message as two octets. */ mu_mailbox_messages_count (mbox, &total); for (mesgno = 1; mesgno <= total; mesgno++) { mu_mailbox_get_message (mbox, mesgno, &msg); mu_message_get_attribute (msg, &attr); /* rfc1939: Note that messages marked as deleted are not counted in either total. */ if (!pop3d_is_deleted (attr)) { mu_message_size (msg, &size); mu_message_lines (msg, &lines); tsize += size + lines; num++; } } pop3d_outf ("+OK %s %s\r\n", mu_umaxtostr (0, num), mu_umaxtostr (1, tsize)); return OK; }
int main (int argc, const char **argv) { char *from; char *subject; mu_mailbox_t mbox; size_t msgno, total = 0; int status; /* Register the formats. */ mu_register_all_mbox_formats (); status = mu_mailbox_create_default (&mbox, argv[1]); if (status != 0) { mu_error ("mu_mailbox_create: %s", mu_strerror (status)); exit (EXIT_FAILURE); } status = mu_mailbox_open (mbox, MU_STREAM_READ); if (status != 0) { mu_error ("mu_mailbox_open: %s", mu_strerror (status)); exit (EXIT_FAILURE); } mu_mailbox_messages_count (mbox, &total); for (msgno = 1; msgno <= total; msgno++) { mu_message_t msg; mu_header_t hdr; if ((status = mu_mailbox_get_message (mbox, msgno, &msg)) != 0 || (status = mu_message_get_header (msg, &hdr)) != 0) { mu_error ("Error message: %s", mu_strerror (status)); exit (EXIT_FAILURE); } if (mu_header_aget_value (hdr, MU_HEADER_FROM, &from)) from = strdup ("(NO FROM)"); if (mu_header_aget_value (hdr, MU_HEADER_SUBJECT, &subject)) subject = strdup ("(NO SUBJECT)"); printf ("%s\t%s\n", from, subject); free (from); free (subject); } status = mu_mailbox_close (mbox); if (status != 0) { mu_error ("mu_mailbox_close: %s", mu_strerror (status)); exit (EXIT_FAILURE); } mu_mailbox_destroy (&mbox); return 0; }
void smtp (int fd) { int state, c; char *buf = NULL; size_t size = 0; mu_mailbox_t mbox; mu_message_t msg; char *tempfile; char *rcpt_addr; in = fdopen (fd, "r"); out = fdopen (fd, "w"); SETVBUF (in, NULL, _IOLBF, 0); SETVBUF (out, NULL, _IOLBF, 0); smtp_reply (220, "Ready"); for (state = STATE_INIT; state != STATE_QUIT; ) { int argc; char **argv; int kw, len; if (getline (&buf, &size, in) == -1) exit (1); len = strlen (buf); while (len > 0 && (buf[len-1] == '\n' || buf[len-1] == '\r')) len --; buf[len] = 0; if (mu_argcv_get (buf, "", NULL, &argc, &argv)) exit (1); kw = smtp_kw (argv[0]); if (kw == KW_QUIT) { smtp_reply (221, "Done"); state = STATE_QUIT; mu_argcv_free (argc, argv); continue; } switch (state) { case STATE_INIT: switch (kw) { case KW_EHLO: case KW_HELO: if (argc == 2) { smtp_reply (250, "pleased to meet you"); state = STATE_EHLO; } else smtp_reply (501, "%s requires domain address", argv[0]); break; default: smtp_reply (503, "Polite people say HELO first"); break; } break; case STATE_EHLO: switch (kw) { case KW_MAIL: if (argc == 2) from_person = check_prefix (argv[1], "from:"); else if (argc == 3 && mu_c_strcasecmp (argv[1], "from:") == 0) from_person = argv[2]; else from_person = NULL; if (from_person) { from_person = strdup (from_person); smtp_reply (250, "Sender OK"); state = STATE_MAIL; } else smtp_reply (501, "Syntax error"); break; default: smtp_reply (503, "Need MAIL command"); } break; case STATE_MAIL: switch (kw) { case KW_RCPT: if (argc == 2) rcpt_addr = check_prefix (argv[1], "to:"); else if (argc == 3 && mu_c_strcasecmp (argv[1], "to:") == 0) rcpt_addr = argv[2]; else rcpt_addr = NULL; if (rcpt_addr) { if (add_recipient (rcpt_addr)) smtp_reply (451, "Recipient not accepted"); else { smtp_reply (250, "Recipient OK"); state = STATE_RCPT; } } else smtp_reply (501, "Syntax error"); break; default: smtp_reply (503, "Need RCPT command"); } break; case STATE_RCPT: switch (kw) { case KW_RCPT: if (argc == 2) rcpt_addr = check_prefix (argv[1], "to:"); else if (argc == 3 && mu_c_strcasecmp (argv[1], "to:") == 0) rcpt_addr = argv[2]; else rcpt_addr = NULL; if (rcpt_addr) { if (add_recipient (rcpt_addr)) smtp_reply (451, "Recipient not accepted"); else { smtp_reply (250, "Recipient OK"); state = STATE_RCPT; } } else smtp_reply (501, "Syntax error"); break; case KW_DATA: smtp_reply (354, "Enter mail, end with \".\" on a line by itself"); make_tmp (in, from_person, &tempfile); if ((c = mu_mailbox_create_default (&mbox, tempfile)) != 0) { mu_error ("%s: can't create mailbox %s: %s", progname, tempfile, mu_strerror (c)); unlink (tempfile); exit (1); } if ((c = mu_mailbox_open (mbox, MU_STREAM_RDWR)) != 0) { mu_error ("%s: can't open mailbox %s: %s", progname, tempfile, mu_strerror (c)); unlink (tempfile); exit (1); } mu_mailbox_get_message (mbox, 1, &msg); if (message_finalize (msg, 0) == 0) mta_send (msg); else smtp_reply (501, "can't send message"); /*FIXME: code?*/ unlink (tempfile); mu_address_destroy (&recipients); from_person = NULL; smtp_reply (250, "Message accepted for delivery"); state = STATE_EHLO; break; default: smtp_reply (503, "Invalid command"); break; } break; } mu_argcv_free (argc, argv); } close (fd); }
int main (int argc, char **argv) { mu_mailbox_t mbox = NULL; size_t i; size_t count = 0; char *mailbox_name; int debug = 0; for (i = 1; i < argc; i++) { if (strcmp (argv[i], "-d") == 0) debug = 1; else if (strcmp (argv[i], "-p") == 0) print_attachments = 1; else if (strcmp (argv[i], "-i") == 0) { if (++i == argc) { mu_error ("-i requires argument"); exit (1); } indent_level = strtoul (argv[i], NULL, 0); } else if (strcmp (argv[i], "-c") == 0) { if (++i == argc) { mu_error ("-c requires argument"); exit (1); } charset = argv[i]; } else break; } mailbox_name = argv[i]; /* Registration. */ mu_registrar_record (mu_imap_record); mu_registrar_record (mu_pop_record); mu_registrar_record (mu_mbox_record); mu_registrar_set_default_record (mu_mbox_record); MU_ASSERT (mu_mailbox_create_default (&mbox, mailbox_name)); /* Debugging trace. */ if (debug) { mu_debug_set_category_level (MU_DEBCAT_MAILBOX, MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT)); } /* Open the mailbox for reading only. */ MU_ASSERT (mu_mailbox_open (mbox, MU_STREAM_READ)); /* Iterate through the entire message set. */ MU_ASSERT (mu_mailbox_messages_count (mbox, &count)); for (i = 1; i <= count; ++i) { mu_message_t msg; mu_header_t hdr; size_t nparts; size_t msize, nlines; MU_ASSERT (mu_mailbox_get_message (mbox, i, &msg)); MU_ASSERT (mu_message_size (msg, &msize)); MU_ASSERT (mu_message_lines (msg, &nlines)); MU_ASSERT (mu_message_get_header (msg, &hdr)); if (mu_header_sget_value (hdr, MU_HEADER_FROM, &from)) from = ""; if (mu_header_sget_value (hdr, MU_HEADER_SUBJECT, &subject)) subject = ""; printf ("Message: %lu\n", (unsigned long) i); printf ("From: %s\n", from); printf ("Subject: %s\n", subject); MU_ASSERT (mu_message_get_num_parts (msg, &nparts)); printf ("Number of parts in message - %lu\n", (unsigned long) nparts); printf ("Total message size - %lu/%lu\n", (unsigned long) msize, (unsigned long) nlines); message_display_parts (msg, 0); } mu_mailbox_close (mbox); mu_mailbox_destroy (&mbox); return 0; }