diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-12-22 13:31:33 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-12-22 13:31:33 +0200 |
commit | 8571d58b012a8c920073d9b9d139547dd44bd42a (patch) | |
tree | 10f8fe5100e66ece614e8d80402c307216804476 /mu | |
parent | 48bfe14edfa7612b2aea89f408ffa7952e88940a (diff) | |
download | mailutils-8571d58b012a8c920073d9b9d139547dd44bd42a.tar.gz mailutils-8571d58b012a8c920073d9b9d139547dd44bd42a.tar.bz2 |
New command: mailutils stat
* include/mailutils/util.h (mu_c_storage_t): New data type.
* mu/stat.c: New file.
* mu/Makefile.am: Add stat
* doc/texinfo/programs.texi: Document mailutils stat
Diffstat (limited to 'mu')
-rw-r--r-- | mu/Makefile.am | 1 | ||||
-rw-r--r-- | mu/stat.c | 382 |
2 files changed, 383 insertions, 0 deletions
diff --git a/mu/Makefile.am b/mu/Makefile.am index d9355dff6..146c4c4c0 100644 --- a/mu/Makefile.am +++ b/mu/Makefile.am @@ -59,6 +59,7 @@ MODULES = \ $(POP_C)\ query.c\ send.c\ + stat.c\ $(SMTP_C)\ wicket.c diff --git a/mu/stat.c b/mu/stat.c new file mode 100644 index 000000000..170f6d7d0 --- /dev/null +++ b/mu/stat.c @@ -0,0 +1,382 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2010-2012, 2014-2016 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 <http://www.gnu.org/licenses/>. */ + +#include "mu.h" + +char stat_docstring[] = N_("display mailbox status"); +char stat_args_doc[] = N_("[MAILBOX]"); + +char *format_string = "%:t\n\ +%:p\n\ +%:U\n\ +%:s\n\ +%:c\n\ +%:r\n\ +%:u\n\ +%:v\n\ +%:n\n\ +%:A\n"; + +static struct mu_option stat_options[] = { + { "format", 'c', N_("STRING"), MU_OPTION_DEFAULT, + N_("defines output format"), + mu_c_string, &format_string }, + MU_OPTION_END +}; + +#define prcat2(a, b) a ## b +#define PR_C(field, fmt) \ + static void \ + prcat2(pr_,field) (mu_c_storage_t *stor) \ + { \ + mu_printf (fmt, stor->field); \ + } \ + +PR_C(c_string, "%s") +PR_C(c_short, "%hd") +PR_C(c_ushort, "%hu") +PR_C(c_int, "%d") +PR_C(c_uint, "%u") +PR_C(c_long, "%ld") +PR_C(c_ulong, "%lu") +PR_C(c_size, "%zu") +PR_C(c_off, "%" MU_PRI_OFF_T) + +static void +pr_c_time (mu_c_storage_t *stor) +{ + mu_printf ("%lu", (unsigned long)stor->c_time); +} + +static void +pr_c_time_h (mu_c_storage_t *stor) +{ + struct tm *tm = localtime (&stor->c_time); + mu_c_streamftime (mu_strout, "%Y-%m-%d %H:%M:%S %Z", tm, NULL); +} + +static void (*c_fmt[]) (mu_c_storage_t *stor) = { +#define D(t) [prcat2(mu_,t)] = prcat2(pr_,t) + D(c_string), + D(c_short), + D(c_ushort), + D(c_int), + D(c_uint), + D(c_long), + D(c_ulong), + D(c_size), + D(c_off), + D(c_time) +#undef D +}; + +static void +mu_c_output (mu_c_type_t type, mu_c_storage_t *cstor) +{ + if (c_fmt[type]) + c_fmt[type] (cstor); + else + abort (); +} + +struct mbox_property +{ + char fmt; + char *title; + mu_c_type_t type; + int (*fun) (mu_mailbox_t, char const *, mu_c_storage_t *); + void (*prt) (mu_c_storage_t *stor); +}; + +static int get_type (mu_mailbox_t, char const *, mu_c_storage_t *); +static int get_path (mu_mailbox_t, char const *, mu_c_storage_t *); +static int get_url (mu_mailbox_t, char const *, mu_c_storage_t *); +static int get_size (mu_mailbox_t, char const *, mu_c_storage_t *); +static int get_count (mu_mailbox_t, char const *, mu_c_storage_t *); +static int get_recent (mu_mailbox_t, char const *, mu_c_storage_t *); +static int get_unseen (mu_mailbox_t, char const *, mu_c_storage_t *); +static int get_uidvalidity (mu_mailbox_t, char const *, mu_c_storage_t *); +static int get_uidnext (mu_mailbox_t, char const *, mu_c_storage_t *); +static int get_atime (mu_mailbox_t, char const *, mu_c_storage_t *); +static int get_name (mu_mailbox_t, char const *, mu_c_storage_t *); + +static struct mbox_property proptab[] = { + { 't', N_("type"), mu_c_string, get_type }, + { 'p', N_("path"), mu_c_string, get_path }, + { 'U', N_("URL"), mu_c_string, get_url }, + { 's', N_("size"), mu_c_off, get_size }, + { 'c', N_("messages"), mu_c_size, get_count }, + { 'r', N_("recent messages"), mu_c_size, get_recent }, + { 'u', N_("first unseen"), mu_c_size, get_unseen }, + { 'v', N_("uidvalidity"), mu_c_ulong, get_uidvalidity }, + { 'n', N_("next uid"), mu_c_size, get_uidnext }, + { 'a', N_("access"), mu_c_time, get_atime }, + { 'A', N_("access"), mu_c_time, get_atime, pr_c_time_h }, + { 'f', N_("name"), mu_c_string, get_name }, + { 0 } +}; + +static struct mbox_property * +propfmt (int fmt) +{ + struct mbox_property *p; + for (p = proptab; p->fmt; p++) + if (p->fmt == fmt) + return p; + return NULL; +} + +static char const * +fmtspec (char const *fmt, mu_mailbox_t mbx, const char *name) +{ + int c; + int title = 0; + struct mbox_property *prop; + + if (!*++fmt) + { + mu_stream_write (mu_strout, fmt - 1, 1, NULL); + return fmt; + } + + c = *fmt++; + + if (c == '%') + { + mu_stream_write (mu_strout, fmt - 1, 1, NULL); + return fmt; + } + + if (c == ':') + { + if (*fmt == 0) + { + mu_stream_write (mu_strout, fmt - 2, 2, NULL); + return fmt; + } + c = *fmt++; + title = 1; + } + prop = propfmt (c); + if (prop) + { + int rc; + mu_c_storage_t cstor; + if (title) + mu_printf ("%s: ", gettext (prop->title)); + rc = prop->fun (mbx, name, &cstor); + switch (rc) + { + case 0: + if (prop->prt) + prop->prt (&cstor); + else + mu_c_output (prop->type, &cstor); + if (prop->type == mu_c_string) + free (cstor.c_string); + break; + + case MU_ERR_EMPTY_VFN: + case ENOSYS: + mu_printf (_("N/A")); + break; + + default: + mu_printf ("[%s]", mu_strerror (rc)); + } + } + else + mu_stream_write (mu_strout, "?", 1, NULL); + return fmt; +} + +void +format_stat (char const *fmt, mu_mailbox_t mbx, const char *name) +{ + int c; + + while (*fmt) + { + switch (*fmt) + { + case '%': + fmt = fmtspec (fmt, mbx, name); + break; + + case '\\': + if (fmt[1] && (c = mu_wordsplit_c_unquote_char (fmt[1]))) + { + mu_printf ("%c", c); + fmt += 2; + break; + } + /* fall through */ + default: + mu_stream_write (mu_strout, fmt, 1, NULL); + if (*fmt == '\n' && fmt[1] == 0) + return; + fmt++; + } + } + mu_printf ("\n"); +} + +int +mutool_stat (int argc, char **argv) +{ + int rc; + mu_mailbox_t mbox; + const char *name; + + mu_register_all_mbox_formats (); + + mu_action_getopt (&argc, &argv, stat_options, stat_docstring, stat_args_doc); + if (argc > 1) + { + mu_error (_("too many arguments")); + return EX_USAGE; + } + name = argv[0]; + + rc = mu_mailbox_create_default (&mbox, name); + if (rc) + { + mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_create_default", name, rc); + return EX_UNAVAILABLE; + } + + rc = mu_mailbox_open (mbox, MU_STREAM_READ); + if (rc) + { + mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_open", name, rc); + return EX_UNAVAILABLE; + } + + if (!name) + { + mu_url_t url; + mu_mailbox_get_url (mbox, &url); + name = mu_url_to_string (url); + } + + format_stat (format_string, mbox, name); + + mu_mailbox_close (mbox); + mu_mailbox_destroy (&mbox); + return 0; +} + +static int +get_type (mu_mailbox_t mbox, char const *mbname, mu_c_storage_t *cstor) +{ + mu_url_t url; + int rc; + + rc = mu_mailbox_get_url (mbox, &url); + if (rc == 0) + rc = mu_url_aget_scheme (url, &cstor->c_string); + return rc; +} + +static int +get_path (mu_mailbox_t mbox, char const *mbname, mu_c_storage_t *cstor) +{ + int rc; + mu_url_t url; + + rc = mu_mailbox_get_url (mbox, &url); + if (rc == 0) + rc = mu_url_aget_path (url, &cstor->c_string); + return rc; +} + +static int +get_url (mu_mailbox_t mbox, char const *mbname, mu_c_storage_t *cstor) +{ + mu_url_t url; + int rc; + + rc = mu_mailbox_get_url (mbox, &url); + if (rc == 0) + cstor->c_string = mu_strdup (mu_url_to_string (url)); + return rc; +} + +static int +get_size (mu_mailbox_t mbox, char const *mbname, mu_c_storage_t *cstor) +{ + return mu_mailbox_get_size (mbox, &cstor->c_off); +} + +static int +get_count (mu_mailbox_t mbox, char const *mbname, mu_c_storage_t *cstor) +{ + return mu_mailbox_messages_count (mbox, &cstor->c_size); +} + +static int +get_recent (mu_mailbox_t mbox, char const *mbname, mu_c_storage_t *cstor) +{ + return mu_mailbox_messages_recent (mbox, &cstor->c_size); +} + +static int +get_unseen (mu_mailbox_t mbox, char const *mbname, mu_c_storage_t *cstor) +{ + return mu_mailbox_message_unseen (mbox, &cstor->c_size); +} + +static int +get_uidvalidity (mu_mailbox_t mbox, char const *mbname, mu_c_storage_t *cstor) +{ + return mu_mailbox_uidvalidity (mbox, &cstor->c_ulong); +} + +static int +get_uidnext (mu_mailbox_t mbox, char const *mbname, mu_c_storage_t *cstor) +{ + return mu_mailbox_uidnext (mbox, &cstor->c_size); +} + +static int +get_atime (mu_mailbox_t mbox, char const *mbname, mu_c_storage_t *cstor) +{ + return mu_mailbox_access_time (mbox, &cstor->c_time); +} + +static int +get_name (mu_mailbox_t mbox, char const *mbname, mu_c_storage_t *cstor) +{ + cstor->c_string = mu_strdup (mbname); + return 0; +} + +/* + MU Setup: stat + mu-handler: mutool_stat + mu-docstring: stat_docstring + End MU Setup: +*/ + + + + + + + + + + |