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