* The Regents of the University of California. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)options_f.c 8.25 (Berkeley) 12/20/93";
static int opt_putenv
__P((char *));
/* Validate the number. */
if (val
< MINIMUM_SCREEN_COLS
) {
msgq(sp
, M_ERR
, "Screen columns too small, less than %d.",
if (val
< O_VAL(sp
, O_SHIFTWIDTH
)) {
"Screen columns too small, less than shiftwidth.");
if (val
< O_VAL(sp
, O_SIDESCROLL
)) {
"Screen columns too small, less than sidescroll.");
if (val
< O_VAL(sp
, O_TABSTOP
)) {
"Screen columns too small, less than tabstop.");
if (val
< O_VAL(sp
, O_WRAPMARGIN
)) {
"Screen columns too small, less than wrapmargin.");
* This has to be checked by reaching down into the screen code.
if (val
< O_NUMBER_LENGTH
) {
"Screen columns too small, less than number option.");
/* Set the columns value in the environment for curses. */
(void)snprintf(buf
, sizeof(buf
), "COLUMNS=%lu", val
);
/* This is expensive, don't do it unless it's necessary. */
if (O_VAL(sp
, O_COLUMNS
) == val
)
O_VAL(sp
, O_COLUMNS
) = val
;
O_VAL(sp
, O_KEYTIME
) = val
;
F_SET(sp
, S_REFORMAT
| S_REDRAW
);
/* Validate the number. */
if (val
< MINIMUM_SCREEN_ROWS
) {
msgq(sp
, M_ERR
, "Screen lines too small, less than %d.",
/* Set the rows value in the environment for curses. */
(void)snprintf(buf
, sizeof(buf
), "ROWS=%lu", val
);
/* This is expensive, don't do it unless it's necessary. */
if (O_VAL(sp
, O_LINES
) == val
)
O_VAL(sp
, O_LINES
) = val
;
* If no window value set, set a new default window and,
* optionally, a new scroll value.
if (!F_ISSET(&sp
->opts
[O_WINDOW
], OPT_SET
)) {
O_VAL(sp
, O_WINDOW
) = val
- 1;
if (!F_ISSET(&sp
->opts
[O_SCROLL
], OPT_SET
))
O_VAL(sp
, O_SCROLL
) = val
/ 2;
msgq(sp
, M_ERR
, "The lisp option is not implemented.");
F_SET(sp
, S_REFORMAT
| S_REDRAW
);
O_VAL(sp
, O_MATCHTIME
) = val
;
if ((tty
= ttyname(STDERR_FILENO
)) == NULL
) {
msgq(sp
, M_ERR
, "ttyname: %s.", strerror(errno
));
/* Save the tty mode for later; only save it once. */
if (!F_ISSET(sp
->gp
, G_SETMODE
)) {
F_SET(sp
->gp
, G_SETMODE
);
if (stat(tty
, &sb
) < 0) {
msgq(sp
, M_ERR
, "%s: %s.", tty
, strerror(errno
));
sp
->gp
->origmode
= sb
.st_mode
;
if (chmod(tty
, sp
->gp
->origmode
& ~S_IWGRP
) < 0) {
msgq(sp
, M_ERR
, "messages not turned off: %s: %s.",
if (chmod(tty
, sp
->gp
->origmode
| S_IWGRP
) < 0) {
msgq(sp
, M_ERR
, "messages not turned on: %s: %s.",
* This has been documented in historical systems as both "modeline"
* and as "modelines". Regardless of the name, this option represents
* a security problem of mammoth proportions, not to mention a stunning
* example of what your intro CS professor referred to as the perils of
* mixing code and data. Don't add it, or I will kill you.
msgq(sp
, M_ERR
, "The modeline(s) option may never be set.");
F_SET(sp
, S_REFORMAT
| S_REDRAW
);
msgq(sp
, M_ERR
, "The optimize option is not implemented.");
"Paragraph options must be in sets of two characters.");
if (F_ISSET(&sp
->opts
[O_PARAGRAPHS
], OPT_ALLOCATED
))
free(O_STR(sp
, O_PARAGRAPHS
));
if ((O_STR(sp
, O_PARAGRAPHS
) = strdup(str
)) == NULL
) {
msgq(sp
, M_SYSERR
, NULL
);
F_SET(&sp
->opts
[O_PARAGRAPHS
], OPT_ALLOCATED
| OPT_SET
);
F_CLR(sp
->frp
, FR_RDONLY
);
F_SET(sp
->frp
, FR_RDONLY
);
"Section options must be in sets of two characters.");
if (F_ISSET(&sp
->opts
[O_SECTIONS
], OPT_ALLOCATED
))
free(O_STR(sp
, O_SECTIONS
));
if ((O_STR(sp
, O_SECTIONS
) = strdup(str
)) == NULL
) {
msgq(sp
, M_SYSERR
, NULL
);
F_SET(&sp
->opts
[O_SECTIONS
], OPT_ALLOCATED
| OPT_SET
);
msgq(sp
, M_ERR
, "The shiftwidth can't be set to 0.");
if (val
> O_VAL(sp
, O_COLUMNS
)) {
"Shiftwidth can't be larger than screen size.");
O_VAL(sp
, O_SHIFTWIDTH
) = val
;
if (val
> O_VAL(sp
, O_COLUMNS
)) {
"Sidescroll can't be larger than screen size.");
O_VAL(sp
, O_SIDESCROLL
) = val
;
* Historic vi, on startup, source'd $HOME/.exrc and ./.exrc, if they
* were owned by the user. The sourceany option was an undocumented
* feature of historic vi which permitted the startup source'ing of
* .exrc files the user didn't own. This is an obvious security problem,
* and we ignore the option.
msgq(sp
, M_ERR
, "The sourceany option may never be set.");
msgq(sp
, M_ERR
, "Tab stops can't be set to 0.");
"Tab stops can't be larger than %d.", MAXTABSTOP
);
if (val
> O_VAL(sp
, O_COLUMNS
)) {
"Tab stops can't be larger than screen size.",
O_VAL(sp
, O_TABSTOP
) = val
;
F_SET(sp
, S_REFORMAT
| S_REDRAW
);
/* Copy for user display. */
if ((O_STR(sp
, O_TAGS
) = strdup(str
)) == NULL
) {
msgq(sp
, M_SYSERR
, NULL
);
if (F_ISSET(&sp
->opts
[O_TAGS
], OPT_ALLOCATED
))
F_SET(&sp
->opts
[O_TAGS
], OPT_ALLOCATED
| OPT_SET
);
if (F_ISSET(&sp
->opts
[O_TERM
], OPT_ALLOCATED
))
if ((O_STR(sp
, O_TERM
) = strdup(str
)) == NULL
) {
msgq(sp
, M_SYSERR
, NULL
);
F_SET(&sp
->opts
[O_TERM
], OPT_ALLOCATED
| OPT_SET
);
/* Set the terminal value in the environment for curses. */
(void)snprintf(buf
, sizeof(buf
), "TERM=%s", str
);
if (set_window_size(sp
, 0, 0))
/* Historical behavior for w300 was < 1200. */
if (baud_from_bval(sp
) >= 1200)
if (val
> O_VAL(sp
, O_LINES
) - 1)
val
= O_VAL(sp
, O_LINES
) - 1;
/* Historical behavior for w1200 was == 1200. */
if (v
< 1200 || v
> 4800)
if (val
> O_VAL(sp
, O_LINES
) - 1)
val
= O_VAL(sp
, O_LINES
) - 1;
O_VAL(sp
, O_W1200
) = val
;
/* Historical behavior for w9600 was > 1200. */
if (val
> O_VAL(sp
, O_LINES
) - 1)
val
= O_VAL(sp
, O_LINES
) - 1;
O_VAL(sp
, O_W9600
) = val
;
if (val
< MINIMUM_SCREEN_ROWS
) {
msgq(sp
, M_ERR
, "Window too small, less than %d.",
if (val
> O_VAL(sp
, O_LINES
) - 1)
val
= O_VAL(sp
, O_LINES
) - 1;
O_VAL(sp
, O_WINDOW
) = val
;
O_VAL(sp
, O_SCROLL
) = val
/ 2;
if (val
> O_VAL(sp
, O_COLUMNS
)) {
"Wrapmargin value can't be larger than screen size.");
O_VAL(sp
, O_WRAPMARGIN
) = val
;
* Put a value into the environment. We use putenv(3) because it's
* more portable. The following hack is because some moron decided
* to keep a reference to the memory passed to putenv(3), instead of
* having it allocate its own. Someone clearly needs to get promoted
if ((t
= strdup(s
)) == NULL
)