]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - usr.sbin/sysinstall/ttys.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / usr.sbin / sysinstall / ttys.c
1 /*
2  * The new sysinstall program.
3  *
4  * This is probably the last program in the `sysinstall' line - the next
5  * generation being essentially a complete rewrite.
6  *
7  * $FreeBSD$
8  *
9  * Copyright (c) 2001
10  *      Andrey A. Chernov.  All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer,
17  *    verbatim and that no modifications are made prior to this
18  *    point in the file.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  *
23  * THIS SOFTWARE IS PROVIDED BY ANDREY A. CHERNOV ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL ANDREY A. CHERNOV OR HIS PETS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  */
36
37 #include "sysinstall.h"
38 #include <sys/stat.h>
39 #include <ctype.h>
40 #include <ttyent.h>
41
42 #define _X_EXTENSION ".XXXXXX"
43
44 void
45 configTtys(void)
46 {
47     size_t len;
48     int t, tlen, changed;
49     FILE *fp, *np;
50     char sq, *line, *p, *q, *cp, *tptr;
51     char templ[sizeof(_PATH_TTYS) + sizeof(_X_EXTENSION) - 1];
52     struct ttyent *tnam;
53     
54     if ((cp = variable_get(VAR_CONSTERM)) == NULL ||
55         strcmp(cp, "NO") == 0)
56         return;
57     if (!file_readable(_PATH_TTYS)) {
58         msgConfirm("%s not exist or not readable", _PATH_TTYS);
59         return;
60     }
61     if ((fp = fopen(_PATH_TTYS, "r")) == NULL) {
62         msgConfirm("Can't open %s for read: %s", _PATH_TTYS,
63                    strerror(errno));
64         return;
65     }
66     strcpy(templ, _PATH_TTYS _X_EXTENSION);
67     if ((t = mkstemp(templ)) < 0) {
68         msgConfirm("Can't create %s: %s", templ, strerror(errno));
69         (void)fclose(fp);
70         return;
71     }
72     if (fchmod(t, 0644)) {
73         msgConfirm("Can't fchmod %s: %s", templ, strerror(errno));
74         (void)fclose(fp);
75         return;
76     }
77     if ((np = fdopen(t, "w")) == NULL) {
78         msgConfirm("Can't fdopen %s: %s", templ, strerror(errno));
79         (void)close(t);
80         (void)fclose(fp);
81         (void)unlink(templ);
82         return;
83     }
84     changed = 0;
85     while ((line = fgetln(fp, &len)) != NULL) {
86         p = line;
87         while (p < (line + len) && isspace((unsigned char)*p))
88             ++p;
89         if (strncmp(p, "ttyv", 4) != 0) {
90     dump:
91             if (fwrite(line, len, 1, np) != 1) {
92     wrerr:
93                 msgConfirm("%s: write error: %s", templ, strerror(errno));
94                 (void)fclose(fp);
95                 (void)fclose(np);
96                 (void)unlink(templ);
97                 return;
98             }
99         } else {
100             q = p;
101             while(q < (line + len) && !isspace((unsigned char)*q))
102                 ++q;
103             if (!isspace((unsigned char)*q))
104                 goto dump;
105             sq = *q;
106             *q = '\0';
107             tnam = getttynam(p);
108             *q = sq;
109             if (tnam == NULL || tnam->ty_type == NULL ||
110                 strcmp(tnam->ty_type, cp) == 0 ||
111                 strncmp(tnam->ty_type, "cons", 4) != 0 ||
112                 !isdigit((unsigned char)tnam->ty_type[4])
113                )
114                 goto dump;
115             tlen = strlen(tnam->ty_type);
116             tptr = NULL;
117             p = ++q;
118             while(p < (line + len)) {
119                 if (strncmp(p, tnam->ty_type, tlen) == 0) {
120                     tptr = p;
121                     break;
122                 }
123                 ++p;
124             }
125             if (tptr == NULL)
126                 goto dump;
127             changed = 1;
128             if (fwrite(line, tptr - line, 1, np) != 1 ||
129                 fputs(cp, np) ||
130                 fwrite(tptr + tlen,
131                        len - (tptr + tlen - line), 1, np) != 1)
132                 goto wrerr;
133         }
134     }
135     if (!feof(fp)) {
136         msgConfirm("%s: read error: %s", _PATH_TTYS, strerror(errno));
137         (void)fclose(fp);
138         (void)fclose(np);
139         (void)unlink(templ);
140         return;
141     }
142     (void)fclose(fp);
143     if (fclose(np)) {
144         if (changed)
145                 msgConfirm("%s: close error: %s", templ, strerror(errno));
146         else
147                 variable_set2(VAR_CONSTERM, "NO", 0);
148         (void)unlink(templ);
149         return;
150     }
151     if (!changed) {
152         (void)unlink(templ);
153         variable_set2(VAR_CONSTERM, "NO", 0);
154         return;
155     }
156     if (rename(templ, _PATH_TTYS)) {
157         msgConfirm("Can't rename %s to %s: %s", templ, _PATH_TTYS,
158                    strerror(errno));
159         return;
160     }
161     variable_set2(VAR_CONSTERM, "NO", 0);
162 }