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