1/*	$OpenBSD: options_f.c,v 1.13 2019/05/21 09:24:58 martijn Exp $	*/
2
3/*-
4 * Copyright (c) 1993, 1994
5 *	The Regents of the University of California.  All rights reserved.
6 * Copyright (c) 1993, 1994, 1995, 1996
7 *	Keith Bostic.  All rights reserved.
8 *
9 * See the LICENSE file for redistribution information.
10 */
11
12#include "config.h"
13
14#include <sys/types.h>
15#include <sys/queue.h>
16#include <sys/stat.h>
17
18#include <bitstring.h>
19#include <ctype.h>
20#include <errno.h>
21#include <limits.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26
27#include "common.h"
28
29/*
30 * PUBLIC: int f_altwerase(SCR *, OPTION *, char *, u_long *);
31 */
32int
33f_altwerase(SCR *sp, OPTION *op, char *str, u_long *valp)
34{
35	if (!*valp)
36		O_CLR(sp, O_TTYWERASE);
37	return (0);
38}
39
40/*
41 * PUBLIC: int f_columns(SCR *, OPTION *, char *, u_long *);
42 */
43int
44f_columns(SCR *sp, OPTION *op, char *str, u_long *valp)
45{
46	/* Validate the number. */
47	if (*valp < MINIMUM_SCREEN_COLS) {
48		msgq(sp, M_ERR, "Screen columns too small, less than %d",
49		    MINIMUM_SCREEN_COLS);
50		return (1);
51	}
52
53	/*
54	 * !!!
55	 * It's not uncommon for allocation of huge chunks of memory to cause
56	 * core dumps on various systems.  So, we prune out numbers that are
57	 * "obviously" wrong.  Vi will not work correctly if it has the wrong
58	 * number of lines/columns for the screen, but at least we don't drop
59	 * core.
60	 */
61#define	MAXIMUM_SCREEN_COLS	768
62	if (*valp > MAXIMUM_SCREEN_COLS) {
63		msgq(sp, M_ERR, "Screen columns too large, greater than %d",
64		    MAXIMUM_SCREEN_COLS);
65		return (1);
66	}
67	return (0);
68}
69
70/*
71 * PUBLIC: int f_lines(SCR *, OPTION *, char *, u_long *);
72 */
73int
74f_lines(SCR *sp, OPTION *op, char *str, u_long *valp)
75{
76	/* Validate the number. */
77	if (*valp < MINIMUM_SCREEN_ROWS) {
78		msgq(sp, M_ERR, "Screen lines too small, less than %d",
79		    MINIMUM_SCREEN_ROWS);
80		return (1);
81	}
82
83	/*
84	 * !!!
85	 * It's not uncommon for allocation of huge chunks of memory to cause
86	 * core dumps on various systems.  So, we prune out numbers that are
87	 * "obviously" wrong.  Vi will not work correctly if it has the wrong
88	 * number of lines/columns for the screen, but at least we don't drop
89	 * core.
90	 */
91#define	MAXIMUM_SCREEN_ROWS	500
92	if (*valp > MAXIMUM_SCREEN_ROWS) {
93		msgq(sp, M_ERR, "Screen lines too large, greater than %d",
94		    MAXIMUM_SCREEN_ROWS);
95		return (1);
96	}
97
98	/*
99	 * Set the value, and the related scroll value.  If no window
100	 * value set, set a new default window.
101	 */
102	o_set(sp, O_LINES, 0, NULL, *valp);
103	if (*valp == 1) {
104		sp->defscroll = 1;
105
106		if (O_VAL(sp, O_WINDOW) == O_D_VAL(sp, O_WINDOW) ||
107		    O_VAL(sp, O_WINDOW) > *valp) {
108			o_set(sp, O_WINDOW, 0, NULL, 1);
109			o_set(sp, O_WINDOW, OS_DEF, NULL, 1);
110		}
111	} else {
112		sp->defscroll = (*valp - 1) / 2;
113
114		if (O_VAL(sp, O_WINDOW) == O_D_VAL(sp, O_WINDOW) ||
115		    O_VAL(sp, O_WINDOW) > *valp) {
116			o_set(sp, O_WINDOW, 0, NULL, *valp - 1);
117			o_set(sp, O_WINDOW, OS_DEF, NULL, *valp - 1);
118		}
119	}
120	return (0);
121}
122
123/*
124 * PUBLIC: int f_paragraph(SCR *, OPTION *, char *, u_long *);
125 */
126int
127f_paragraph(SCR *sp, OPTION *op, char *str, u_long *valp)
128{
129	if (strlen(str) & 1) {
130		msgq(sp, M_ERR,
131		    "The paragraph option must be in two character groups");
132		return (1);
133	}
134	return (0);
135}
136
137/*
138 * PUBLIC: int f_print(SCR *, OPTION *, char *, u_long *);
139 */
140int
141f_print(SCR *sp, OPTION *op, char *str, u_long *valp)
142{
143	/* Reinitialize the key fast lookup table. */
144	v_key_ilookup(sp);
145
146	/* Reformat the screen. */
147	F_SET(sp, SC_SCR_REFORMAT);
148	return (0);
149}
150
151/*
152 * PUBLIC: int f_readonly(SCR *, OPTION *, char *, u_long *);
153 */
154int
155f_readonly(SCR *sp, OPTION *op, char *str, u_long *valp)
156{
157	/*
158	 * !!!
159	 * See the comment in exf.c.
160	 */
161	if (*valp)
162		F_CLR(sp, SC_READONLY);
163	else
164		F_SET(sp, SC_READONLY);
165	return (0);
166}
167
168/*
169 * PUBLIC: int f_recompile(SCR *, OPTION *, char *, u_long *);
170 */
171int
172f_recompile(SCR *sp, OPTION *op, char *str, u_long *valp)
173{
174	if (F_ISSET(sp, SC_RE_SEARCH)) {
175		regfree(&sp->re_c);
176		F_CLR(sp, SC_RE_SEARCH);
177	}
178	if (F_ISSET(sp, SC_RE_SUBST)) {
179		regfree(&sp->subre_c);
180		F_CLR(sp, SC_RE_SUBST);
181	}
182	return (0);
183}
184
185/*
186 * PUBLIC: int f_reformat(SCR *, OPTION *, char *, u_long *);
187 */
188int
189f_reformat(SCR *sp, OPTION *op, char *str, u_long *valp)
190{
191	F_SET(sp, SC_SCR_REFORMAT);
192	return (0);
193}
194
195/*
196 * PUBLIC: int f_section(SCR *, OPTION *, char *, u_long *);
197 */
198int
199f_section(SCR *sp, OPTION *op, char *str, u_long *valp)
200{
201	if (strlen(str) & 1) {
202		msgq(sp, M_ERR,
203		    "The section option must be in two character groups");
204		return (1);
205	}
206	return (0);
207}
208
209/*
210 * PUBLIC: int f_secure(SCR *, OPTION *, char *, u_long *)
211 */
212int
213f_secure(SCR *sp, OPTION *op, char *str, u_long *valp)
214{
215	if (pledge("stdio rpath wpath cpath fattr flock getpw tty", NULL) == -1) {
216		msgq(sp, M_ERR, "pledge failed");
217		return (1);
218	}
219	return (0);
220}
221
222/*
223 * PUBLIC: int f_ttywerase(SCR *, OPTION *, char *, u_long *);
224 */
225int
226f_ttywerase(SCR *sp, OPTION *op, char *str, u_long *valp)
227{
228	if (!*valp)
229		O_CLR(sp, O_ALTWERASE);
230	return (0);
231}
232
233/*
234 * PUBLIC: int f_w300(SCR *, OPTION *, char *, u_long *);
235 */
236int
237f_w300(SCR *sp, OPTION *op, char *str, u_long *valp)
238{
239	u_long v;
240
241	/* Historical behavior for w300 was < 1200. */
242	if (sp->gp->scr_baud(sp, &v))
243		return (1);
244	if (v >= 1200)
245		return (0);
246
247	return (f_window(sp, op, str, valp));
248}
249
250/*
251 * PUBLIC: int f_w1200(SCR *, OPTION *, char *, u_long *);
252 */
253int
254f_w1200(SCR *sp, OPTION *op, char *str, u_long *valp)
255{
256	u_long v;
257
258	/* Historical behavior for w1200 was == 1200. */
259	if (sp->gp->scr_baud(sp, &v))
260		return (1);
261	if (v < 1200 || v > 4800)
262		return (0);
263
264	return (f_window(sp, op, str, valp));
265}
266
267/*
268 * PUBLIC: int f_w9600(SCR *, OPTION *, char *, u_long *);
269 */
270int
271f_w9600(SCR *sp, OPTION *op, char *str, u_long *valp)
272{
273	u_long v;
274
275	/* Historical behavior for w9600 was > 1200. */
276	if (sp->gp->scr_baud(sp, &v))
277		return (1);
278	if (v <= 4800)
279		return (0);
280
281	return (f_window(sp, op, str, valp));
282}
283
284/*
285 * PUBLIC: int f_window(SCR *, OPTION *, char *, u_long *);
286 */
287int
288f_window(SCR *sp, OPTION *op, char *str, u_long *valp)
289{
290	if (*valp >= O_VAL(sp, O_LINES) - 1 &&
291	    (*valp = O_VAL(sp, O_LINES) - 1) == 0)
292		*valp = 1;
293	return (0);
294}
295