/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999-2021 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see . */
/* MH scan command */
#include
#ifdef HAVE_TERMCAP_H
# include
#endif
#include
#include
#include
#include
static char prog_doc[] = N_("Produce a one line per message scan listing");
static char args_doc[] = N_("[MSGLIST]");
static int clear;
static int width;
static int reverse;
static int header;
static mh_format_t format;
static mh_fvm_t fvm;
static mu_msgset_t msgset;
static struct mu_option options[] = {
{ "clear", 0, NULL, MU_OPTION_DEFAULT,
N_("clear screen after displaying the list"),
mu_c_bool, &clear },
{ "form", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("read format from given file"),
mu_c_string, &format, mh_opt_parse_formfile },
{ "format", 0, N_("FORMAT"), MU_OPTION_DEFAULT,
N_("use this format string"),
mu_c_string, &format, mh_opt_parse_format },
{ "header", 0, NULL, MU_OPTION_DEFAULT,
N_("display header"),
mu_c_bool, &header },
{ "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
N_("set output width"),
mu_c_int, &width },
{ "reverse", 0, NULL, MU_OPTION_DEFAULT,
N_("list messages in reverse order"),
mu_c_bool, &reverse },
{ "file", 0, N_("FILE"), MU_OPTION_HIDDEN,
N_("[not yet implemented]"),
mu_c_string, NULL, mh_opt_notimpl },
MU_OPTION_END
};
static void print_header (mu_mailbox_t mbox);
static void clear_screen (void);
static int
list_message (size_t num MU_ARG_UNUSED, mu_message_t msg,
void *data MU_ARG_UNUSED)
{
mh_fvm_run (fvm, msg);
return 0;
}
/* Observable Action this is called at every message discover. */
static int
action (mu_observer_t o, size_t type, void *data, void *action_data)
{
static int counter;
mu_mailbox_t mbox;
mu_message_t msg = NULL;
if (type == MU_EVT_MESSAGE_ADD)
{
mbox = mu_observer_get_owner (o);
counter++;
mu_mailbox_get_message (mbox, counter, &msg);
mh_fvm_run (fvm, msg);
}
return 0;
}
int
main (int argc, char **argv)
{
mu_mailbox_t mbox;
int status;
size_t total = 0;
mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
args_doc, prog_doc, NULL);
if (!format)
format = mh_scan_format ();
mh_fvm_create (&fvm, MH_FMT_FORCENL);
mh_fvm_set_format (fvm, format);
mh_fvm_set_width (fvm, width ? width : mh_width ());
mh_format_destroy (&format);
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
if ((argc == 0 || strcmp (argv[0], "all") == 0) && !reverse)
{
/* Fast approach */
mu_observer_t observer;
mu_observable_t observable;
print_header (mbox);
mu_observer_create (&observer, mbox);
mu_observer_set_action (observer, action, mbox);
mu_mailbox_get_observable (mbox, &observable);
mu_observable_attach (observable, MU_EVT_MESSAGE_ADD, observer);
status = mu_mailbox_scan (mbox, 1, &total);
}
else
{
mu_mailbox_messages_count (mbox, &total);
mh_msgset_parse (&msgset, mbox, argc, argv, "all");
print_header (mbox);
status = mu_msgset_foreach_dir_message (msgset, reverse,
list_message, NULL);
}
if (total == 0)
{
mu_url_t url = NULL;
mu_mailbox_get_url (mbox, &url);
mu_error (_("no messages in %s"), mu_url_to_string (url));
}
clear_screen ();
mh_fvm_destroy (&fvm);
mh_global_save_state ();
mu_mailbox_close (mbox);
mu_mailbox_destroy (&mbox);
return status;
}
static void
print_header (mu_mailbox_t mbox)
{
if (header)
{
mu_url_t url = NULL;
char datestr[64];
time_t t;
mu_mailbox_get_url (mbox, &url);
time (&t);
strftime (datestr, sizeof datestr, "%c", localtime (&t));
printf (_("Folder %s %s\n"), mu_url_to_string (url), datestr);
}
}
#ifdef HAVE_TERMCAP_H
/* A subroutine for tputs */
int
putstdout(char c)
{
return putc(c, stdout);
}
#endif
static void
clear_screen (void)
{
if (clear)
{
#ifdef HAVE_TERMCAP_H
if (isatty (1))
{
char termcap_buf[1024];
char *buffer = termcap_buf;
char *termname;
if ((termname = getenv("TERM")) == NULL)
/* No terminal; Try ansi */
termname = "ansi";
if (tgetent(termcap_buf, termname) == 1)
{
char *clr = tgetstr ("cl", &buffer);
if (clr)
{
tputs(clr, 1, (int (*)())putstdout);
return;
}
}
}
#endif
/* Fall back to formfeed */
fprintf (stdout, "\f");
}
}