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.
Showing
3 changed files
with
84 additions
and
46 deletions
... | @@ -37,5 +37,7 @@ int mutool_acl (int argc, char **argv); | ... | @@ -37,5 +37,7 @@ int mutool_acl (int argc, char **argv); |
37 | 37 | ||
38 | extern char *mutool_shell_prompt; | 38 | extern char *mutool_shell_prompt; |
39 | extern mu_vartab_t mutool_prompt_vartab; | 39 | extern mu_vartab_t mutool_prompt_vartab; |
40 | 40 | extern int mutool_shell_interactive; | |
41 | extern mu_stream_t mustrout; | ||
41 | int mutool_shell (const char *name, struct mutool_command *cmd); | 42 | int mutool_shell (const char *name, struct mutool_command *cmd); |
43 | mu_stream_t mutool_open_pager (void); | ... | ... |
... | @@ -244,24 +244,24 @@ com_verbose (int argc, char **argv) | ... | @@ -244,24 +244,24 @@ com_verbose (int argc, char **argv) |
244 | { | 244 | { |
245 | if (QRY_VERBOSE ()) | 245 | if (QRY_VERBOSE ()) |
246 | { | 246 | { |
247 | printf ("verbose is on"); | 247 | mu_stream_printf (mustrout, "verbose is on"); |
248 | if (HAS_VERBOSE_MASK ()) | 248 | if (HAS_VERBOSE_MASK ()) |
249 | { | 249 | { |
250 | char *delim = " ("; | 250 | char *delim = " ("; |
251 | 251 | ||
252 | if (QRY_VERBOSE_MASK (MU_XSCRIPT_SECURE)) | 252 | if (QRY_VERBOSE_MASK (MU_XSCRIPT_SECURE)) |
253 | { | 253 | { |
254 | printf("%ssecure", delim); | 254 | mu_stream_printf (mustrout, "%ssecure", delim); |
255 | delim = ", "; | 255 | delim = ", "; |
256 | } | 256 | } |
257 | if (QRY_VERBOSE_MASK (MU_XSCRIPT_PAYLOAD)) | 257 | if (QRY_VERBOSE_MASK (MU_XSCRIPT_PAYLOAD)) |
258 | printf("%spayload", delim); | 258 | mu_stream_printf (mustrout, "%spayload", delim); |
259 | printf (")"); | 259 | mu_stream_printf (mustrout, ")"); |
260 | } | 260 | } |
261 | printf ("\n"); | 261 | mu_stream_printf (mustrout, "\n"); |
262 | } | 262 | } |
263 | else | 263 | else |
264 | printf ("verbose is off\n"); | 264 | mu_stream_printf (mustrout, "verbose is off\n"); |
265 | } | 265 | } |
266 | else | 266 | else |
267 | { | 267 | { |
... | @@ -346,13 +346,13 @@ com_capa (int argc, char **argv) | ... | @@ -346,13 +346,13 @@ com_capa (int argc, char **argv) |
346 | { | 346 | { |
347 | case 0: | 347 | case 0: |
348 | if (*elt) | 348 | if (*elt) |
349 | printf ("%s: %s\n", argv[i], elt); | 349 | mu_stream_printf (mustrout, "%s: %s\n", argv[i], elt); |
350 | else | 350 | else |
351 | printf ("%s is set\n", argv[i]); | 351 | mu_stream_printf (mustrout, "%s is set\n", argv[i]); |
352 | break; | 352 | break; |
353 | 353 | ||
354 | case MU_ERR_NOENT: | 354 | case MU_ERR_NOENT: |
355 | printf ("%s is not set\n", argv[i]); | 355 | mu_stream_printf (mustrout, "%s is not set\n", argv[i]); |
356 | break; | 356 | break; |
357 | 357 | ||
358 | default: | 358 | default: |
... | @@ -371,7 +371,7 @@ com_capa (int argc, char **argv) | ... | @@ -371,7 +371,7 @@ com_capa (int argc, char **argv) |
371 | { | 371 | { |
372 | char *capa = NULL; | 372 | char *capa = NULL; |
373 | mu_iterator_current (iterator, (void **) &capa); | 373 | mu_iterator_current (iterator, (void **) &capa); |
374 | printf ("CAPA: %s\n", capa ? capa : ""); | 374 | mu_stream_printf (mustrout, "CAPA: %s\n", capa ? capa : ""); |
375 | } | 375 | } |
376 | mu_iterator_destroy (&iterator); | 376 | mu_iterator_destroy (&iterator); |
377 | } | 377 | } |
... | @@ -385,6 +385,7 @@ com_uidl (int argc, char **argv) | ... | @@ -385,6 +385,7 @@ com_uidl (int argc, char **argv) |
385 | int status = 0; | 385 | int status = 0; |
386 | if (argc == 1) | 386 | if (argc == 1) |
387 | { | 387 | { |
388 | mu_stream_t out = mutool_open_pager (); | ||
388 | mu_iterator_t uidl_iterator = NULL; | 389 | mu_iterator_t uidl_iterator = NULL; |
389 | status = mu_pop3_uidl_all (pop3, &uidl_iterator); | 390 | status = mu_pop3_uidl_all (pop3, &uidl_iterator); |
390 | if (status == 0) | 391 | if (status == 0) |
... | @@ -395,10 +396,11 @@ com_uidl (int argc, char **argv) | ... | @@ -395,10 +396,11 @@ com_uidl (int argc, char **argv) |
395 | { | 396 | { |
396 | char *uidl = NULL; | 397 | char *uidl = NULL; |
397 | mu_iterator_current (uidl_iterator, (void **) &uidl); | 398 | mu_iterator_current (uidl_iterator, (void **) &uidl); |
398 | printf ("UIDL: %s\n", uidl ? uidl : ""); | 399 | mu_stream_printf (out, "UIDL: %s\n", uidl ? uidl : ""); |
399 | } | 400 | } |
400 | mu_iterator_destroy (&uidl_iterator); | 401 | mu_iterator_destroy (&uidl_iterator); |
401 | } | 402 | } |
403 | mu_stream_destroy (&out); | ||
402 | } | 404 | } |
403 | else | 405 | else |
404 | { | 406 | { |
... | @@ -406,7 +408,7 @@ com_uidl (int argc, char **argv) | ... | @@ -406,7 +408,7 @@ com_uidl (int argc, char **argv) |
406 | unsigned int msgno = strtoul (argv[1], NULL, 10); | 408 | unsigned int msgno = strtoul (argv[1], NULL, 10); |
407 | status = mu_pop3_uidl (pop3, msgno, &uidl); | 409 | status = mu_pop3_uidl (pop3, msgno, &uidl); |
408 | if (status == 0) | 410 | if (status == 0) |
409 | printf ("Msg: %d UIDL: %s\n", msgno, uidl ? uidl : ""); | 411 | mu_stream_printf (mustrout, "Msg: %d UIDL: %s\n", msgno, uidl ? uidl : ""); |
410 | free (uidl); | 412 | free (uidl); |
411 | } | 413 | } |
412 | return status; | 414 | return status; |
... | @@ -418,6 +420,7 @@ com_list (int argc, char **argv) | ... | @@ -418,6 +420,7 @@ com_list (int argc, char **argv) |
418 | int status = 0; | 420 | int status = 0; |
419 | if (argc == 1) | 421 | if (argc == 1) |
420 | { | 422 | { |
423 | mu_stream_t out = mutool_open_pager (); | ||
421 | mu_iterator_t list_iterator; | 424 | mu_iterator_t list_iterator; |
422 | status = mu_pop3_list_all (pop3, &list_iterator); | 425 | status = mu_pop3_list_all (pop3, &list_iterator); |
423 | if (status == 0) | 426 | if (status == 0) |
... | @@ -428,9 +431,10 @@ com_list (int argc, char **argv) | ... | @@ -428,9 +431,10 @@ com_list (int argc, char **argv) |
428 | { | 431 | { |
429 | char *list = NULL; | 432 | char *list = NULL; |
430 | mu_iterator_current (list_iterator, (void **) &list); | 433 | mu_iterator_current (list_iterator, (void **) &list); |
431 | printf ("LIST: %s\n", (list) ? list : ""); | 434 | mu_stream_printf (out, "LIST: %s\n", (list) ? list : ""); |
432 | } | 435 | } |
433 | mu_iterator_destroy (&list_iterator); | 436 | mu_iterator_destroy (&list_iterator); |
437 | mu_stream_destroy (&out); | ||
434 | } | 438 | } |
435 | } | 439 | } |
436 | else | 440 | else |
... | @@ -439,7 +443,7 @@ com_list (int argc, char **argv) | ... | @@ -439,7 +443,7 @@ com_list (int argc, char **argv) |
439 | unsigned int msgno = strtoul (argv[1], NULL, 10); | 443 | unsigned int msgno = strtoul (argv[1], NULL, 10); |
440 | status = mu_pop3_list (pop3, msgno, &size); | 444 | status = mu_pop3_list (pop3, msgno, &size); |
441 | if (status == 0) | 445 | if (status == 0) |
442 | printf ("Msg: %u Size: %lu\n", msgno, (unsigned long) size); | 446 | mu_stream_printf (mustrout, "Msg: %u Size: %lu\n", msgno, (unsigned long) size); |
443 | } | 447 | } |
444 | return status; | 448 | return status; |
445 | } | 449 | } |
... | @@ -506,7 +510,7 @@ com_stat (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) | ... | @@ -506,7 +510,7 @@ com_stat (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) |
506 | int status = 0; | 510 | int status = 0; |
507 | 511 | ||
508 | status = mu_pop3_stat (pop3, &count, &size); | 512 | status = mu_pop3_stat (pop3, &count, &size); |
509 | printf ("Mesgs: %lu Size %lu\n", | 513 | mu_stream_printf (mustrout, "Mesgs: %lu Size %lu\n", |
510 | (unsigned long) count, (unsigned long) size); | 514 | (unsigned long) count, (unsigned long) size); |
511 | return status; | 515 | return status; |
512 | } | 516 | } |
... | @@ -549,10 +553,9 @@ com_top (int argc, char **argv) | ... | @@ -549,10 +553,9 @@ com_top (int argc, char **argv) |
549 | 553 | ||
550 | if (status == 0) | 554 | if (status == 0) |
551 | { | 555 | { |
552 | size_t n = 0; | 556 | mu_stream_t out = mutool_open_pager (); |
553 | char buf[128]; | 557 | mu_stream_copy (out, stream, 0, NULL); |
554 | while ((mu_stream_readline (stream, buf, sizeof buf, &n) == 0) && n) | 558 | mu_stream_destroy (&out); |
555 | printf ("%s", buf); | ||
556 | mu_stream_destroy (&stream); | 559 | mu_stream_destroy (&stream); |
557 | } | 560 | } |
558 | return status; | 561 | return status; |
... | @@ -570,10 +573,9 @@ com_retr (int argc, char **argv) | ... | @@ -570,10 +573,9 @@ com_retr (int argc, char **argv) |
570 | 573 | ||
571 | if (status == 0) | 574 | if (status == 0) |
572 | { | 575 | { |
573 | size_t n = 0; | 576 | mu_stream_t out = mutool_open_pager (); |
574 | char buf[128]; | 577 | mu_stream_copy (out, stream, 0, NULL); |
575 | while ((mu_stream_readline (stream, buf, sizeof buf, &n) == 0) && n) | 578 | mu_stream_destroy (&out); |
576 | printf ("%s", buf); | ||
577 | mu_stream_destroy (&stream); | 579 | mu_stream_destroy (&stream); |
578 | } | 580 | } |
579 | return status; | 581 | return status; |
... | @@ -706,11 +708,11 @@ com_quit (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) | ... | @@ -706,11 +708,11 @@ com_quit (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) |
706 | } | 708 | } |
707 | else | 709 | else |
708 | { | 710 | { |
709 | printf ("Try 'exit' to leave %s\n", mu_program_name); | 711 | mu_stream_printf (mustrout, "Try 'exit' to leave %s\n", mu_program_name); |
710 | } | 712 | } |
711 | } | 713 | } |
712 | else | 714 | else |
713 | printf ("Try 'exit' to leave %s\n", mu_program_name); | 715 | mu_stream_printf (mustrout, "Try 'exit' to leave %s\n", mu_program_name); |
714 | return status; | 716 | return status; |
715 | } | 717 | } |
716 | 718 | ... | ... |
... | @@ -32,6 +32,8 @@ | ... | @@ -32,6 +32,8 @@ |
32 | 32 | ||
33 | char *mutool_shell_prompt; | 33 | char *mutool_shell_prompt; |
34 | mu_vartab_t mutool_prompt_vartab; | 34 | mu_vartab_t mutool_prompt_vartab; |
35 | int mutool_shell_interactive; | ||
36 | mu_stream_t mustrout; | ||
35 | 37 | ||
36 | static char * | 38 | static char * |
37 | expand_prompt () | 39 | expand_prompt () |
... | @@ -65,25 +67,25 @@ struct mutool_command default_comtab[] = { | ... | @@ -65,25 +67,25 @@ struct mutool_command default_comtab[] = { |
65 | 67 | ||
66 | /* Print a single comtab entry */ | 68 | /* Print a single comtab entry */ |
67 | static void | 69 | static void |
68 | print_comtab (struct mutool_command *tab) | 70 | print_comtab (mu_stream_t stream, struct mutool_command *tab) |
69 | { | 71 | { |
70 | printf ("%s\t\t%s\n", tab->name, tab->doc); | 72 | mu_stream_printf (stream, "%s\t\t%s\n", tab->name, tab->doc); |
71 | } | 73 | } |
72 | 74 | ||
73 | /* Print a single comtab entry. | 75 | /* Print a single comtab entry. |
74 | FIXME: Way too primitive. Rewrite. */ | 76 | FIXME: Way too primitive. Rewrite. */ |
75 | int | 77 | int |
76 | print_help (struct mutool_command *tab, size_t n) | 78 | print_help (mu_stream_t stream, struct mutool_command *tab, size_t n) |
77 | { | 79 | { |
78 | if (n) | 80 | if (n) |
79 | { | 81 | { |
80 | for (; n > 0 && tab->name; tab++, n--) | 82 | for (; n > 0 && tab->name; tab++, n--) |
81 | print_comtab (tab); | 83 | print_comtab (stream, tab); |
82 | } | 84 | } |
83 | else | 85 | else |
84 | { | 86 | { |
85 | for (; tab->name; tab++) | 87 | for (; tab->name; tab++) |
86 | print_comtab (tab); | 88 | print_comtab (stream, tab); |
87 | } | 89 | } |
88 | return 0; | 90 | return 0; |
89 | } | 91 | } |
... | @@ -102,16 +104,16 @@ list_commands (struct mutool_command *tab, const char *name) | ... | @@ -102,16 +104,16 @@ list_commands (struct mutool_command *tab, const char *name) |
102 | if (printed == 6) | 104 | if (printed == 6) |
103 | { | 105 | { |
104 | printed = 0; | 106 | printed = 0; |
105 | printf ("\n"); | 107 | mu_stream_printf (mustrout, "\n"); |
106 | } | 108 | } |
107 | if (mu_c_strncasecmp (tab->name, name, namelen) == 0) | 109 | if (mu_c_strncasecmp (tab->name, name, namelen) == 0) |
108 | { | 110 | { |
109 | printf ("%s\t", tab->name); | 111 | mu_stream_printf (mustrout, "%s\t", tab->name); |
110 | printed++; | 112 | printed++; |
111 | } | 113 | } |
112 | } | 114 | } |
113 | if (printed && printed < 6) | 115 | if (printed && printed < 6) |
114 | printf ("\n"); | 116 | mu_stream_printf (mustrout, "\n"); |
115 | } | 117 | } |
116 | 118 | ||
117 | static struct mutool_command * | 119 | static struct mutool_command * |
... | @@ -139,23 +141,28 @@ int | ... | @@ -139,23 +141,28 @@ int |
139 | shell_help (int argc, char **argv) | 141 | shell_help (int argc, char **argv) |
140 | { | 142 | { |
141 | char *name = argv[1]; | 143 | char *name = argv[1]; |
144 | |||
142 | if (name) | 145 | if (name) |
143 | { | 146 | { |
144 | struct mutool_command *com = find_command (argv[1]); | 147 | struct mutool_command *com = find_command (argv[1]); |
145 | 148 | ||
146 | if (com) | 149 | if (com) |
147 | print_comtab (com); | 150 | print_comtab (mustrout, com); |
148 | else | 151 | else |
149 | { | 152 | { |
150 | printf ("No commands match `%s'. Possibilties are:\n", name); | 153 | mu_stream_printf (mustrout, |
154 | "No commands match `%s'. Possibilties are:\n", | ||
155 | name); | ||
151 | list_commands (shell_comtab, name); | 156 | list_commands (shell_comtab, name); |
152 | } | 157 | } |
153 | } | 158 | } |
154 | else | 159 | else |
155 | { | 160 | { |
156 | print_help (shell_comtab, user_command_count); | 161 | mu_stream_t str = mutool_open_pager (); |
157 | printf ("\n"); | 162 | print_help (str, shell_comtab, user_command_count); |
158 | print_help (shell_comtab + user_command_count, 0); | 163 | mu_stream_printf (str, "\n"); |
164 | print_help (str, shell_comtab + user_command_count, 0); | ||
165 | mu_stream_destroy (&str); | ||
159 | } | 166 | } |
160 | return 0; | 167 | return 0; |
161 | } | 168 | } |
... | @@ -173,6 +180,21 @@ shell_prompt (int argc, char **argv) | ... | @@ -173,6 +180,21 @@ shell_prompt (int argc, char **argv) |
173 | return 0; | 180 | return 0; |
174 | } | 181 | } |
175 | 182 | ||
183 | mu_stream_t | ||
184 | mutool_open_pager () | ||
185 | { | ||
186 | char *pager; | ||
187 | if (mutool_shell_interactive && (pager = getenv ("PAGER")) != NULL) | ||
188 | { | ||
189 | mu_stream_t stream; | ||
190 | int rc = mu_prog_stream_create (&stream, pager, MU_STREAM_WRITE); | ||
191 | if (rc == 0) | ||
192 | return stream; | ||
193 | mu_error (_("cannot start pager: %s"), mu_strerror (rc)); | ||
194 | } | ||
195 | mu_stream_ref (mustrout); | ||
196 | return mustrout; | ||
197 | } | ||
176 | 198 | ||
177 | 199 | ||
178 | #ifdef WITH_READLINE | 200 | #ifdef WITH_READLINE |
... | @@ -313,7 +335,7 @@ retrieve_history (char *str) | ... | @@ -313,7 +335,7 @@ retrieve_history (char *str) |
313 | return 1; | 335 | return 1; |
314 | 336 | ||
315 | case 2: | 337 | case 2: |
316 | printf ("%s\n", out); | 338 | mu_stream_printf (mustrout, "%s\n", out); |
317 | free (out); | 339 | free (out); |
318 | return 1; | 340 | return 1; |
319 | } | 341 | } |
... | @@ -328,7 +350,7 @@ shell_history (int argc, char **argv) | ... | @@ -328,7 +350,7 @@ shell_history (int argc, char **argv) |
328 | 350 | ||
329 | hlist = history_list (); | 351 | hlist = history_list (); |
330 | for (i = 0; i < history_length; i++) | 352 | for (i = 0; i < history_length; i++) |
331 | printf ("%4d) %s\n", i + 1, hlist[i]->line); | 353 | mu_stream_printf (mustrout, "%4d) %s\n", i + 1, hlist[i]->line); |
332 | 354 | ||
333 | return 0; | 355 | return 0; |
334 | } | 356 | } |
... | @@ -345,7 +367,7 @@ readline (char *prompt) | ... | @@ -345,7 +367,7 @@ readline (char *prompt) |
345 | 367 | ||
346 | if (prompt) | 368 | if (prompt) |
347 | { | 369 | { |
348 | printf ("%s", prompt); | 370 | mu_stream_printf (mustrout, "%s", prompt); |
349 | fflush (stdout); | 371 | fflush (stdout); |
350 | } | 372 | } |
351 | if (getline (&buf, &size, stdin) <= 0) | 373 | if (getline (&buf, &size, stdin) <= 0) |
... | @@ -440,9 +462,20 @@ shell_exit (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) | ... | @@ -440,9 +462,20 @@ shell_exit (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) |
440 | int | 462 | int |
441 | mutool_shell (const char *name, struct mutool_command *cmd) | 463 | mutool_shell (const char *name, struct mutool_command *cmd) |
442 | { | 464 | { |
465 | int rc; | ||
443 | size_t n; | 466 | size_t n; |
444 | int interactive = isatty (0); | 467 | char *(*input_line) (); |
445 | char *(*input_line) () = interactive ? | 468 | |
469 | rc = mu_stdio_stream_create (&mustrout, MU_STDOUT_FD, | ||
470 | MU_STREAM_WRITE); | ||
471 | if (rc) | ||
472 | { | ||
473 | mu_diag_funcall (MU_DIAG_ERROR, "mu_stdio_stream_create", "1", rc); | ||
474 | return 1; | ||
475 | } | ||
476 | |||
477 | mutool_shell_interactive = isatty (0); | ||
478 | input_line = mutool_shell_interactive ? | ||
446 | input_line_interactive : input_line_script; | 479 | input_line_interactive : input_line_script; |
447 | 480 | ||
448 | for (n = 0; cmd[n].name; n++) | 481 | for (n = 0; cmd[n].name; n++) |
... | @@ -471,7 +504,7 @@ mutool_shell (const char *name, struct mutool_command *cmd) | ... | @@ -471,7 +504,7 @@ mutool_shell (const char *name, struct mutool_command *cmd) |
471 | int status; | 504 | int status; |
472 | 505 | ||
473 | #ifdef WITH_READLINE | 506 | #ifdef WITH_READLINE |
474 | if (interactive) | 507 | if (mutool_shell_interactive) |
475 | { | 508 | { |
476 | if (retrieve_history (s)) | 509 | if (retrieve_history (s)) |
477 | continue; | 510 | continue; |
... | @@ -486,7 +519,8 @@ mutool_shell (const char *name, struct mutool_command *cmd) | ... | @@ -486,7 +519,8 @@ mutool_shell (const char *name, struct mutool_command *cmd) |
486 | 519 | ||
487 | free (line); | 520 | free (line); |
488 | } | 521 | } |
489 | if (interactive) | 522 | if (mutool_shell_interactive) |
490 | finish_readline (); | 523 | finish_readline (); |
524 | mu_stream_destroy (&mustrout); | ||
491 | return 0; | 525 | return 0; |
492 | } | 526 | } | ... | ... |
-
Please register or sign in to post a comment