179813Sache/*
279813Sache * The new sysinstall program.
379813Sache *
479813Sache * This is probably the last program in the `sysinstall' line - the next
579813Sache * generation being essentially a complete rewrite.
679813Sache *
779813Sache * $FreeBSD$
879813Sache *
979813Sache * Copyright (c) 2001
1079813Sache *      Andrey A. Chernov.  All rights reserved.
1179813Sache *
1279813Sache * Redistribution and use in source and binary forms, with or without
1379813Sache * modification, are permitted provided that the following conditions
1479813Sache * are met:
1579813Sache * 1. Redistributions of source code must retain the above copyright
1679813Sache *    notice, this list of conditions and the following disclaimer,
1779813Sache *    verbatim and that no modifications are made prior to this
1879813Sache *    point in the file.
1979813Sache * 2. Redistributions in binary form must reproduce the above copyright
2079813Sache *    notice, this list of conditions and the following disclaimer in the
2179813Sache *    documentation and/or other materials provided with the distribution.
2279813Sache *
2379813Sache * THIS SOFTWARE IS PROVIDED BY ANDREY A. CHERNOV ``AS IS'' AND
2479813Sache * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2579813Sache * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2679820Sache * ARE DISCLAIMED.  IN NO EVENT SHALL ANDREY A. CHERNOV OR HIS PETS BE LIABLE
2779813Sache * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2879813Sache * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2979813Sache * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
3079813Sache * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3179813Sache * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3279813Sache * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3379813Sache * SUCH DAMAGE.
3479813Sache *
3579813Sache */
3679813Sache
3779813Sache#include "sysinstall.h"
3879813Sache#include <sys/stat.h>
3979813Sache#include <ctype.h>
4079813Sache#include <ttyent.h>
4179813Sache
4279813Sache#define _X_EXTENSION ".XXXXXX"
4379813Sache
4479813Sachevoid
4579813SacheconfigTtys(void)
4679813Sache{
4783845Smurray    size_t len;
4883845Smurray    int t, tlen, changed;
4979813Sache    FILE *fp, *np;
5079813Sache    char sq, *line, *p, *q, *cp, *tptr;
5179813Sache    char templ[sizeof(_PATH_TTYS) + sizeof(_X_EXTENSION) - 1];
5279813Sache    struct ttyent *tnam;
5379813Sache
5479813Sache    if ((cp = variable_get(VAR_CONSTERM)) == NULL ||
5579813Sache	strcmp(cp, "NO") == 0)
5679813Sache	return;
5779813Sache    if (!file_readable(_PATH_TTYS)) {
5879813Sache	msgConfirm("%s not exist or not readable", _PATH_TTYS);
5979813Sache	return;
6079813Sache    }
6179813Sache    if ((fp = fopen(_PATH_TTYS, "r")) == NULL) {
6279813Sache	msgConfirm("Can't open %s for read: %s", _PATH_TTYS,
6379813Sache		   strerror(errno));
6479813Sache	return;
6579813Sache    }
6679813Sache    strcpy(templ, _PATH_TTYS _X_EXTENSION);
6779813Sache    if ((t = mkstemp(templ)) < 0) {
6879813Sache	msgConfirm("Can't create %s: %s", templ, strerror(errno));
6979813Sache	(void)fclose(fp);
7079813Sache	return;
7179813Sache    }
7279813Sache    if (fchmod(t, 0644)) {
7379813Sache	msgConfirm("Can't fchmod %s: %s", templ, strerror(errno));
7479813Sache	(void)fclose(fp);
7579813Sache	return;
7679813Sache    }
7779813Sache    if ((np = fdopen(t, "w")) == NULL) {
7879813Sache	msgConfirm("Can't fdopen %s: %s", templ, strerror(errno));
7979813Sache	(void)close(t);
8079813Sache	(void)fclose(fp);
8179813Sache	(void)unlink(templ);
8279813Sache	return;
8379813Sache    }
8479813Sache    changed = 0;
8579813Sache    while ((line = fgetln(fp, &len)) != NULL) {
8679813Sache	p = line;
8779813Sache	while (p < (line + len) && isspace((unsigned char)*p))
8879813Sache	    ++p;
8979813Sache	if (strncmp(p, "ttyv", 4) != 0) {
9079813Sache    dump:
9179813Sache	    if (fwrite(line, len, 1, np) != 1) {
9279813Sache    wrerr:
9379813Sache		msgConfirm("%s: write error: %s", templ, strerror(errno));
9479813Sache		(void)fclose(fp);
9579813Sache		(void)fclose(np);
9679813Sache		(void)unlink(templ);
9779813Sache		return;
9879813Sache	    }
9979813Sache	} else {
10079813Sache	    q = p;
10179813Sache	    while(q < (line + len) && !isspace((unsigned char)*q))
10279813Sache		++q;
10379813Sache	    if (!isspace((unsigned char)*q))
10479813Sache		goto dump;
10579813Sache	    sq = *q;
10679813Sache	    *q = '\0';
10779813Sache	    tnam = getttynam(p);
10879813Sache	    *q = sq;
10979813Sache	    if (tnam == NULL || tnam->ty_type == NULL ||
11079813Sache		strcmp(tnam->ty_type, cp) == 0 ||
11179813Sache		strncmp(tnam->ty_type, "cons", 4) != 0 ||
11279813Sache		!isdigit((unsigned char)tnam->ty_type[4])
11379813Sache	       )
11479813Sache		goto dump;
11579813Sache	    tlen = strlen(tnam->ty_type);
11679813Sache	    tptr = NULL;
11779813Sache	    p = ++q;
11879813Sache	    while(p < (line + len)) {
11979813Sache		if (strncmp(p, tnam->ty_type, tlen) == 0) {
12079813Sache		    tptr = p;
12179813Sache		    break;
12279813Sache		}
12379813Sache		++p;
12479813Sache	    }
12579813Sache	    if (tptr == NULL)
12679813Sache		goto dump;
12779813Sache	    changed = 1;
12879813Sache	    if (fwrite(line, tptr - line, 1, np) != 1 ||
12979813Sache		fputs(cp, np) ||
13079813Sache		fwrite(tptr + tlen,
13179813Sache		       len - (tptr + tlen - line), 1, np) != 1)
13279813Sache		goto wrerr;
13379813Sache	}
13479813Sache    }
13579813Sache    if (!feof(fp)) {
13679813Sache	msgConfirm("%s: read error: %s", _PATH_TTYS, strerror(errno));
13779813Sache	(void)fclose(fp);
13879813Sache	(void)fclose(np);
13979813Sache	(void)unlink(templ);
14079813Sache	return;
14179813Sache    }
14279813Sache    (void)fclose(fp);
14379813Sache    if (fclose(np)) {
14479813Sache	if (changed)
14579813Sache		msgConfirm("%s: close error: %s", templ, strerror(errno));
14681056Sache	else
14781056Sache		variable_set2(VAR_CONSTERM, "NO", 0);
14879813Sache	(void)unlink(templ);
14979813Sache	return;
15079813Sache    }
15179813Sache    if (!changed) {
15279813Sache	(void)unlink(templ);
15381056Sache	variable_set2(VAR_CONSTERM, "NO", 0);
15479813Sache	return;
15579813Sache    }
15679813Sache    if (rename(templ, _PATH_TTYS)) {
15779813Sache	msgConfirm("Can't rename %s to %s: %s", templ, _PATH_TTYS,
15879813Sache		   strerror(errno));
15979813Sache	return;
16079813Sache    }
16181056Sache    variable_set2(VAR_CONSTERM, "NO", 0);
16279813Sache}
163