1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999-2021 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include "mail.h"
18
19 /* Scroll directions */
20 #define D_BWD -1 /* z- */
21 #define D_NONE 0 /* z. */
22 #define D_FWD 1 /* z+ */
23
24 /*
25 * z [+|-|. [count]]
26 * Optional [count] specifies number of pages to skip before
27 * displaying from lines. Default is 1.
28 * . modifier causes command to redisplay the current page, i.e.
29 * starting from the current message.
30 */
31
32 static int
z_parse_args(int argc,char ** argv,off_t * return_count,int * return_dir)33 z_parse_args(int argc, char **argv,
34 off_t *return_count, int *return_dir)
35 {
36 int count = 1;
37 int mul = 1;
38 int dir = D_FWD;
39 int an = 0;
40 char *argp = NULL;
41
42 argp = &argv[an][1];
43 if (*argp == 0)
44 {
45 an++;
46 if (an < argc)
47 argp = argv[an];
48 }
49
50 if (*argp)
51 {
52 switch (*argp++)
53 {
54 case '+':
55 break;
56 case '-':
57 dir = D_BWD;
58 break;
59 case '.':
60 dir = D_NONE;
61 break;
62 default:
63 mu_error (_("Bad arguments for the scrolling command"));
64 return 1;
65 }
66
67 if (*argp == 0)
68 {
69 an++;
70 if (an < argc)
71 argp = argv[an];
72 }
73
74 argc -= an;
75
76 if (argc > 1)
77 {
78 mu_error (_("Too many arguments for the scrolling command"));
79 return 1;
80 }
81
82 if (argp && *argp)
83 {
84 if (dir == D_NONE)
85 {
86 mu_error (_("Argument not applicable for z"));
87 return 1;
88 }
89
90 if ((mul = strtoul (argp, NULL, 10)) == 0)
91 {
92 mu_error (_("Bad number of pages"));
93 return 1;
94 }
95 }
96
97 }
98
99 *return_count = mul * count;
100 *return_dir = dir;
101
102 return 0;
103 }
104
105 int
mail_z(int argc,char ** argv)106 mail_z (int argc, char **argv)
107 {
108 off_t count;
109 int dir;
110 unsigned int pagelines = util_screen_lines ();
111
112 if (z_parse_args(argc, argv, &count, &dir))
113 return 1;
114
115 count *= pagelines;
116
117 switch (dir)
118 {
119 case D_BWD:
120 if (page_move (-count) == 0)
121 {
122 mu_printf (_("On first screenful of messages\n"));
123 return 0;
124 }
125 break;
126
127 case D_FWD:
128 if (page_move (count) == 0)
129 {
130 mu_printf (_("On last screenful of messages\n"));
131 return 0;
132 }
133 break;
134
135 case D_NONE:
136 {
137 /* z. is a GNU extension, so it will be more useful
138 when we reach the last message to show a full screen
139 of the last message. This behaviour is used on startup
140 when displaying the summary and the headers, new messages
141 are last but we want to display a screenful with the
142 real crs set by summary() to the new message.
143 FIXME: Basically it's the same as headers now. Do we need
144 it still? */
145 break;
146 }
147 }
148
149 page_do (mail_from0, NULL);
150 return 0;
151 }
152