]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - usr.sbin/sade/config.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / usr.sbin / sade / config.c
1 /*
2  * $FreeBSD$
3  *
4  * Copyright (c) 1995
5  *      Jordan Hubbard.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer,
12  *    verbatim and that no modifications are made prior to this
13  *    point in the file.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  */
31
32 #include "sade.h"
33 #include <sys/disklabel.h>
34 #include <sys/wait.h>
35 #include <sys/errno.h>
36 #include <sys/ioctl.h>
37 #include <sys/fcntl.h>
38 #include <sys/param.h>
39 #include <sys/stat.h>
40 #include <unistd.h>
41 #include <sys/mount.h>
42 #include <libdisk.h>
43 #include <time.h>
44 #include <kenv.h>
45
46 static Chunk *chunk_list[MAX_CHUNKS];
47 static int nchunks;
48 static int rootdev_is_od;
49
50 /* arg to sort */
51 static int
52 chunk_compare(Chunk *c1, Chunk *c2)
53 {
54     if (!c1 && !c2)
55         return 0;
56     else if (!c1 && c2)
57         return 1;
58     else if (c1 && !c2)
59         return -1;
60     else if (!c1->private_data && !c2->private_data)
61         return 0;
62     else if (c1->private_data && !c2->private_data)
63         return 1;
64     else if (!c1->private_data && c2->private_data)
65         return -1;
66     else
67         return strcmp(((PartInfo *)(c1->private_data))->mountpoint, ((PartInfo *)(c2->private_data))->mountpoint);
68 }
69
70 static void
71 chunk_sort(void)
72 {
73     int i, j;
74
75     for (i = 0; i < nchunks; i++) {
76         for (j = 0; j < nchunks; j++) {
77             if (chunk_compare(chunk_list[j], chunk_list[j + 1]) > 0) {
78                 Chunk *tmp = chunk_list[j];
79
80                 chunk_list[j] = chunk_list[j + 1];
81                 chunk_list[j + 1] = tmp;
82             }
83         }
84     }
85 }
86
87 static void
88 check_rootdev(Chunk **list, int n)
89 {
90         int i;
91         Chunk *c;
92
93         rootdev_is_od = 0;
94         for (i = 0; i < n; i++) {
95                 c = *list++;
96                 if (c->type == part && (c->flags & CHUNK_IS_ROOT)
97                     && strncmp(c->disk->name, "od", 2) == 0)
98                         rootdev_is_od = 1;
99         }
100 }
101
102 static char *
103 name_of(Chunk *c1)
104 {
105     return c1->name;
106 }
107
108 static char *
109 mount_point(Chunk *c1)
110 {
111     if (c1->type == part && c1->subtype == FS_SWAP)
112         return "none";
113     else if (c1->type == part || c1->type == fat || c1->type == efi)
114         return ((PartInfo *)c1->private_data)->mountpoint;
115     return "/bogus";
116 }
117
118 static char *
119 fstype(Chunk *c1)
120 {
121     if (c1->type == fat || c1->type == efi)
122         return "msdosfs";
123     else if (c1->type == part) {
124         if (c1->subtype != FS_SWAP)
125             return "ufs";
126         else
127             return "swap";
128     }
129     return "bogus";
130 }
131
132 static char *
133 fstype_short(Chunk *c1)
134 {
135     if (c1->type == part) {
136         if (c1->subtype != FS_SWAP) {
137             if (rootdev_is_od == 0 && strncmp(c1->name, "od", 2) == 0)
138                 return "rw,noauto";
139             else
140                 return "rw";
141         }
142         else
143             return "sw";
144     }
145     else if (c1->type == fat) {
146         if (strncmp(c1->name, "od", 2) == 0)
147             return "ro,noauto";
148         else
149             return "ro";
150     }
151     else if (c1->type == efi)
152         return "rw";
153
154     return "bog";
155 }
156
157 static int
158 seq_num(Chunk *c1)
159 {
160     if (c1->type == part && c1->subtype != FS_SWAP) {
161         if (rootdev_is_od == 0 && strncmp(c1->name, "od", 2) == 0)
162             return 0;
163         else if (c1->flags & CHUNK_IS_ROOT)
164             return 1;
165         else
166             return 2;
167     }
168     return 0;
169 }
170
171 int
172 configFstab(dialogMenuItem *self)
173 {
174     Device **devs;
175     Disk *disk;
176     FILE *fstab;
177     int i;
178     Chunk *c1, *c2;
179
180         if (file_readable("/etc/fstab"))
181             return DITEM_SUCCESS;
182         else {
183             msgConfirm("Attempting to rebuild your /etc/fstab file.  Warning: If you had\n"
184                        "any CD devices in use before running %s then they may NOT\n"
185                        "be found by this run!", ProgName);
186         }
187
188     devs = deviceFind(NULL, DEVICE_TYPE_DISK);
189     if (!devs) {
190         msgConfirm("No disks found!");
191         return DITEM_FAILURE;
192     }
193
194     /* Record all the chunks */
195     nchunks = 0;
196     for (i = 0; devs[i]; i++) {
197         if (!devs[i]->enabled)
198             continue;
199         disk = (Disk *)devs[i]->private;
200         if (!disk->chunks)
201             msgFatal("No chunk list found for %s!", disk->name);
202         for (c1 = disk->chunks->part; c1; c1 = c1->next) {
203 #ifdef __powerpc__
204             if (c1->type == apple) {
205 #else
206             if (c1->type == freebsd) {
207 #endif
208                 for (c2 = c1->part; c2; c2 = c2->next) {
209                     if (c2->type == part && (c2->subtype == FS_SWAP || c2->private_data))
210                         chunk_list[nchunks++] = c2;
211                 }
212             }
213             else if (((c1->type == fat || c1->type == efi || c1->type == part) &&
214                     c1->private_data) || (c1->type == part && c1->subtype == FS_SWAP))
215                 chunk_list[nchunks++] = c1;
216         }
217     }
218     chunk_list[nchunks] = 0;
219     chunk_sort();
220     
221     fstab = fopen("/etc/fstab", "w");
222     if (!fstab) {
223         msgConfirm("Unable to create a new /etc/fstab file!  Manual intervention\n"
224                    "will be required.");
225         return DITEM_FAILURE;
226     }
227     
228     check_rootdev(chunk_list, nchunks);
229     
230     /* Go for the burn */
231     msgDebug("Generating /etc/fstab file\n");
232     fprintf(fstab, "# Device\t\tMountpoint\tFStype\tOptions\t\tDump\tPass#\n");
233     for (i = 0; i < nchunks; i++)
234         fprintf(fstab, "/dev/%s\t\t%s\t\t%s\t%s\t\t%d\t%d\n", name_of(chunk_list[i]), mount_point(chunk_list[i]),
235                 fstype(chunk_list[i]), fstype_short(chunk_list[i]), seq_num(chunk_list[i]), seq_num(chunk_list[i]));
236     
237     
238     fclose(fstab);
239     if (isDebug())
240         msgDebug("Wrote out /etc/fstab file\n");
241     return DITEM_SUCCESS;
242 }
243
244 #if 0
245 /* Do the work of sucking in a config file.
246  * config is the filename to read in.
247  * lines is a fixed (max) sized array of char*
248  * returns number of lines read.  line contents
249  * are malloc'd and must be freed by the caller.
250  */
251 static int
252 readConfig(char *config, char **lines, int max)
253 {
254     FILE *fp;
255     char line[256];
256     int i, nlines;
257
258     fp = fopen(config, "r");
259     if (!fp)
260         return -1;
261
262     nlines = 0;
263     /* Read in the entire file */
264     for (i = 0; i < max; i++) {
265         if (!fgets(line, sizeof line, fp))
266             break;
267         lines[nlines++] = strdup(line);
268     }
269     fclose(fp);
270     if (isDebug())
271         msgDebug("readConfig: Read %d lines from %s.\n", nlines, config);
272     return nlines;
273 }
274 #endif
275
276 #define MAX_LINES  2000 /* Some big number we're not likely to ever reach - I'm being really lazy here, I know */
277
278 #if 0
279 static void
280 readConfigFile(char *config, int marked)
281 {
282     char *lines[MAX_LINES], *cp, *cp2;
283     int i, nlines;
284
285     nlines = readConfig(config, lines, MAX_LINES);
286     if (nlines == -1)
287         return;
288
289     for (i = 0; i < nlines; i++) {
290         /* Skip the comments & non-variable settings */
291         if (lines[i][0] == '#' || !(cp = index(lines[i], '='))) {
292             free(lines[i]);
293             continue;
294         }
295         *cp++ = '\0';
296         /* Find quotes */
297         if ((cp2 = index(cp, '"')) || (cp2 = index(cp, '\047'))) {
298             cp = cp2 + 1;
299             cp2 = index(cp, *cp2);
300         }
301         /* If valid quotes, use it */
302         if (cp2) {
303             *cp2 = '\0';
304             /* If we have a legit value, set it */
305             if (strlen(cp))
306                 variable_set2(lines[i], cp, marked);
307         }
308         free(lines[i]);
309     }
310 }
311
312 /* Load the environment from rc.conf file(s) */
313 void
314 configEnvironmentRC_conf(void)
315 {
316     static struct {
317         char *fname;
318         int marked;
319     } configs[] = {
320         { "/etc/defaults/rc.conf", 0 },
321         { "/etc/rc.conf", 0 },
322         { "/etc/rc.conf.local", 0 },
323         { NULL, 0 },
324     };
325     int i;
326
327     for (i = 0; configs[i].fname; i++) {
328         if (file_readable(configs[i].fname))
329             readConfigFile(configs[i].fname, configs[i].marked);
330     }
331 }
332 #endif
333