Commit 63d1c196 63d1c19652942be6b600a5855880667f16fdb8a3 by Sergey Poznyakoff

Implement pager in mu shell.

* mu/mu.h (mutool_shell_interactive): New extern.
(mutool_open_pager): New proto.
* mu/pop.c (com_list, com_top, com_retr): Use pager.
* mu/shell.c (mutool_shell_interactive, mustrout): New
variables.
(print_comtab, print_help): Print to stream.
(shell_help): Use pager if necessary.
(mutool_open_pager): New function.
(mutool_shell): Create mutool_stream_out and destroy it before
returning.
(all functions): Use mu_stream_printf instead of printf.
1 parent c5cc666d
......@@ -37,5 +37,7 @@ int mutool_acl (int argc, char **argv);
extern char *mutool_shell_prompt;
extern mu_vartab_t mutool_prompt_vartab;
extern int mutool_shell_interactive;
extern mu_stream_t mustrout;
int mutool_shell (const char *name, struct mutool_command *cmd);
mu_stream_t mutool_open_pager (void);
......
......@@ -244,24 +244,24 @@ com_verbose (int argc, char **argv)
{
if (QRY_VERBOSE ())
{
printf ("verbose is on");
mu_stream_printf (mustrout, "verbose is on");
if (HAS_VERBOSE_MASK ())
{
char *delim = " (";
if (QRY_VERBOSE_MASK (MU_XSCRIPT_SECURE))
{
printf("%ssecure", delim);
mu_stream_printf (mustrout, "%ssecure", delim);
delim = ", ";
}
if (QRY_VERBOSE_MASK (MU_XSCRIPT_PAYLOAD))
printf("%spayload", delim);
printf (")");
mu_stream_printf (mustrout, "%spayload", delim);
mu_stream_printf (mustrout, ")");
}
printf ("\n");
mu_stream_printf (mustrout, "\n");
}
else
printf ("verbose is off\n");
mu_stream_printf (mustrout, "verbose is off\n");
}
else
{
......@@ -346,13 +346,13 @@ com_capa (int argc, char **argv)
{
case 0:
if (*elt)
printf ("%s: %s\n", argv[i], elt);
mu_stream_printf (mustrout, "%s: %s\n", argv[i], elt);
else
printf ("%s is set\n", argv[i]);
mu_stream_printf (mustrout, "%s is set\n", argv[i]);
break;
case MU_ERR_NOENT:
printf ("%s is not set\n", argv[i]);
mu_stream_printf (mustrout, "%s is not set\n", argv[i]);
break;
default:
......@@ -371,7 +371,7 @@ com_capa (int argc, char **argv)
{
char *capa = NULL;
mu_iterator_current (iterator, (void **) &capa);
printf ("CAPA: %s\n", capa ? capa : "");
mu_stream_printf (mustrout, "CAPA: %s\n", capa ? capa : "");
}
mu_iterator_destroy (&iterator);
}
......@@ -385,6 +385,7 @@ com_uidl (int argc, char **argv)
int status = 0;
if (argc == 1)
{
mu_stream_t out = mutool_open_pager ();
mu_iterator_t uidl_iterator = NULL;
status = mu_pop3_uidl_all (pop3, &uidl_iterator);
if (status == 0)
......@@ -395,10 +396,11 @@ com_uidl (int argc, char **argv)
{
char *uidl = NULL;
mu_iterator_current (uidl_iterator, (void **) &uidl);
printf ("UIDL: %s\n", uidl ? uidl : "");
mu_stream_printf (out, "UIDL: %s\n", uidl ? uidl : "");
}
mu_iterator_destroy (&uidl_iterator);
}
mu_stream_destroy (&out);
}
else
{
......@@ -406,7 +408,7 @@ com_uidl (int argc, char **argv)
unsigned int msgno = strtoul (argv[1], NULL, 10);
status = mu_pop3_uidl (pop3, msgno, &uidl);
if (status == 0)
printf ("Msg: %d UIDL: %s\n", msgno, uidl ? uidl : "");
mu_stream_printf (mustrout, "Msg: %d UIDL: %s\n", msgno, uidl ? uidl : "");
free (uidl);
}
return status;
......@@ -418,6 +420,7 @@ com_list (int argc, char **argv)
int status = 0;
if (argc == 1)
{
mu_stream_t out = mutool_open_pager ();
mu_iterator_t list_iterator;
status = mu_pop3_list_all (pop3, &list_iterator);
if (status == 0)
......@@ -428,9 +431,10 @@ com_list (int argc, char **argv)
{
char *list = NULL;
mu_iterator_current (list_iterator, (void **) &list);
printf ("LIST: %s\n", (list) ? list : "");
mu_stream_printf (out, "LIST: %s\n", (list) ? list : "");
}
mu_iterator_destroy (&list_iterator);
mu_stream_destroy (&out);
}
}
else
......@@ -439,7 +443,7 @@ com_list (int argc, char **argv)
unsigned int msgno = strtoul (argv[1], NULL, 10);
status = mu_pop3_list (pop3, msgno, &size);
if (status == 0)
printf ("Msg: %u Size: %lu\n", msgno, (unsigned long) size);
mu_stream_printf (mustrout, "Msg: %u Size: %lu\n", msgno, (unsigned long) size);
}
return status;
}
......@@ -506,7 +510,7 @@ com_stat (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
int status = 0;
status = mu_pop3_stat (pop3, &count, &size);
printf ("Mesgs: %lu Size %lu\n",
mu_stream_printf (mustrout, "Mesgs: %lu Size %lu\n",
(unsigned long) count, (unsigned long) size);
return status;
}
......@@ -549,10 +553,9 @@ com_top (int argc, char **argv)
if (status == 0)
{
size_t n = 0;
char buf[128];
while ((mu_stream_readline (stream, buf, sizeof buf, &n) == 0) && n)
printf ("%s", buf);
mu_stream_t out = mutool_open_pager ();
mu_stream_copy (out, stream, 0, NULL);
mu_stream_destroy (&out);
mu_stream_destroy (&stream);
}
return status;
......@@ -570,10 +573,9 @@ com_retr (int argc, char **argv)
if (status == 0)
{
size_t n = 0;
char buf[128];
while ((mu_stream_readline (stream, buf, sizeof buf, &n) == 0) && n)
printf ("%s", buf);
mu_stream_t out = mutool_open_pager ();
mu_stream_copy (out, stream, 0, NULL);
mu_stream_destroy (&out);
mu_stream_destroy (&stream);
}
return status;
......@@ -706,11 +708,11 @@ com_quit (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
}
else
{
printf ("Try 'exit' to leave %s\n", mu_program_name);
mu_stream_printf (mustrout, "Try 'exit' to leave %s\n", mu_program_name);
}
}
else
printf ("Try 'exit' to leave %s\n", mu_program_name);
mu_stream_printf (mustrout, "Try 'exit' to leave %s\n", mu_program_name);
return status;
}
......
......@@ -32,6 +32,8 @@
char *mutool_shell_prompt;
mu_vartab_t mutool_prompt_vartab;
int mutool_shell_interactive;
mu_stream_t mustrout;
static char *
expand_prompt ()
......@@ -65,25 +67,25 @@ struct mutool_command default_comtab[] = {
/* Print a single comtab entry */
static void
print_comtab (struct mutool_command *tab)
print_comtab (mu_stream_t stream, struct mutool_command *tab)
{
printf ("%s\t\t%s\n", tab->name, tab->doc);
mu_stream_printf (stream, "%s\t\t%s\n", tab->name, tab->doc);
}
/* Print a single comtab entry.
FIXME: Way too primitive. Rewrite. */
int
print_help (struct mutool_command *tab, size_t n)
print_help (mu_stream_t stream, struct mutool_command *tab, size_t n)
{
if (n)
{
for (; n > 0 && tab->name; tab++, n--)
print_comtab (tab);
print_comtab (stream, tab);
}
else
{
for (; tab->name; tab++)
print_comtab (tab);
print_comtab (stream, tab);
}
return 0;
}
......@@ -102,16 +104,16 @@ list_commands (struct mutool_command *tab, const char *name)
if (printed == 6)
{
printed = 0;
printf ("\n");
mu_stream_printf (mustrout, "\n");
}
if (mu_c_strncasecmp (tab->name, name, namelen) == 0)
{
printf ("%s\t", tab->name);
mu_stream_printf (mustrout, "%s\t", tab->name);
printed++;
}
}
if (printed && printed < 6)
printf ("\n");
mu_stream_printf (mustrout, "\n");
}
static struct mutool_command *
......@@ -139,23 +141,28 @@ int
shell_help (int argc, char **argv)
{
char *name = argv[1];
if (name)
{
struct mutool_command *com = find_command (argv[1]);
if (com)
print_comtab (com);
print_comtab (mustrout, com);
else
{
printf ("No commands match `%s'. Possibilties are:\n", name);
mu_stream_printf (mustrout,
"No commands match `%s'. Possibilties are:\n",
name);
list_commands (shell_comtab, name);
}
}
else
{
print_help (shell_comtab, user_command_count);
printf ("\n");
print_help (shell_comtab + user_command_count, 0);
mu_stream_t str = mutool_open_pager ();
print_help (str, shell_comtab, user_command_count);
mu_stream_printf (str, "\n");
print_help (str, shell_comtab + user_command_count, 0);
mu_stream_destroy (&str);
}
return 0;
}
......@@ -173,6 +180,21 @@ shell_prompt (int argc, char **argv)
return 0;
}
mu_stream_t
mutool_open_pager ()
{
char *pager;
if (mutool_shell_interactive && (pager = getenv ("PAGER")) != NULL)
{
mu_stream_t stream;
int rc = mu_prog_stream_create (&stream, pager, MU_STREAM_WRITE);
if (rc == 0)
return stream;
mu_error (_("cannot start pager: %s"), mu_strerror (rc));
}
mu_stream_ref (mustrout);
return mustrout;
}
#ifdef WITH_READLINE
......@@ -313,7 +335,7 @@ retrieve_history (char *str)
return 1;
case 2:
printf ("%s\n", out);
mu_stream_printf (mustrout, "%s\n", out);
free (out);
return 1;
}
......@@ -328,7 +350,7 @@ shell_history (int argc, char **argv)
hlist = history_list ();
for (i = 0; i < history_length; i++)
printf ("%4d) %s\n", i + 1, hlist[i]->line);
mu_stream_printf (mustrout, "%4d) %s\n", i + 1, hlist[i]->line);
return 0;
}
......@@ -345,7 +367,7 @@ readline (char *prompt)
if (prompt)
{
printf ("%s", prompt);
mu_stream_printf (mustrout, "%s", prompt);
fflush (stdout);
}
if (getline (&buf, &size, stdin) <= 0)
......@@ -440,9 +462,20 @@ shell_exit (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
int
mutool_shell (const char *name, struct mutool_command *cmd)
{
int rc;
size_t n;
int interactive = isatty (0);
char *(*input_line) () = interactive ?
char *(*input_line) ();
rc = mu_stdio_stream_create (&mustrout, MU_STDOUT_FD,
MU_STREAM_WRITE);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_stdio_stream_create", "1", rc);
return 1;
}
mutool_shell_interactive = isatty (0);
input_line = mutool_shell_interactive ?
input_line_interactive : input_line_script;
for (n = 0; cmd[n].name; n++)
......@@ -471,7 +504,7 @@ mutool_shell (const char *name, struct mutool_command *cmd)
int status;
#ifdef WITH_READLINE
if (interactive)
if (mutool_shell_interactive)
{
if (retrieve_history (s))
continue;
......@@ -486,7 +519,8 @@ mutool_shell (const char *name, struct mutool_command *cmd)
free (line);
}
if (interactive)
if (mutool_shell_interactive)
finish_readline ();
mu_stream_destroy (&mustrout);
return 0;
}
......