]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/sade/config.c
Add another strategic screen clear.
[FreeBSD/FreeBSD.git] / usr.sbin / sade / config.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) 1995
10  *      Jordan Hubbard.  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 JORDAN HUBBARD ``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 JORDAN HUBBARD 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/disklabel.h>
39 #include <sys/wait.h>
40 #include <sys/errno.h>
41 #include <sys/ioctl.h>
42 #include <sys/fcntl.h>
43 #include <sys/param.h>
44 #include <sys/stat.h>
45 #include <unistd.h>
46 #include <sys/mount.h>
47
48 static Chunk *chunk_list[MAX_CHUNKS];
49 static int nchunks;
50 static int rootdev_is_od;
51
52 /* arg to sort */
53 static int
54 chunk_compare(Chunk *c1, Chunk *c2)
55 {
56     if (!c1 && !c2)
57         return 0;
58     else if (!c1 && c2)
59         return 1;
60     else if (c1 && !c2)
61         return -1;
62     else if (!c1->private_data && !c2->private_data)
63         return 0;
64     else if (c1->private_data && !c2->private_data)
65         return 1;
66     else if (!c1->private_data && c2->private_data)
67         return -1;
68     else
69         return strcmp(((PartInfo *)(c1->private_data))->mountpoint, ((PartInfo *)(c2->private_data))->mountpoint);
70 }
71
72 static void
73 chunk_sort(void)
74 {
75     int i, j;
76
77     for (i = 0; i < nchunks; i++) {
78         for (j = 0; j < nchunks; j++) {
79             if (chunk_compare(chunk_list[j], chunk_list[j + 1]) > 0) {
80                 Chunk *tmp = chunk_list[j];
81
82                 chunk_list[j] = chunk_list[j + 1];
83                 chunk_list[j + 1] = tmp;
84             }
85         }
86     }
87 }
88
89 static void
90 check_rootdev(Chunk **list, int n)
91 {
92         int i;
93         Chunk *c;
94
95         rootdev_is_od = 0;
96         for (i = 0; i < n; i++) {
97                 c = *list++;
98                 if (c->type == part && (c->flags & CHUNK_IS_ROOT)
99                     && strncmp(c->disk->name, "od", 2) == 0)
100                         rootdev_is_od = 1;
101         }
102 }
103
104 static char *
105 name_of(Chunk *c1)
106 {
107     return c1->name;
108 }
109
110 static char *
111 mount_point(Chunk *c1)
112 {
113     if (c1->type == part && c1->subtype == FS_SWAP)
114         return "none";
115     else if (c1->type == part || c1->type == fat)
116         return ((PartInfo *)c1->private_data)->mountpoint;
117     return "/bogus";
118 }
119
120 static char *
121 fstype(Chunk *c1)
122 {
123     if (c1->type == fat)
124         return "msdos";
125     else if (c1->type == part) {
126         if (c1->subtype != FS_SWAP)
127             return "ufs";
128         else
129             return "swap";
130     }
131     return "bogus";
132 }
133
134 static char *
135 fstype_short(Chunk *c1)
136 {
137     if (c1->type == part) {
138         if (c1->subtype != FS_SWAP) {
139             if (rootdev_is_od == 0 && strncmp(c1->name, "od", 2) == 0)
140                 return "rw,noauto";
141             else
142                 return "rw";
143         }
144         else
145             return "sw";
146     }
147     else if (c1->type == fat) {
148         if (strncmp(c1->name, "od", 2) == 0)
149             return "ro,noauto";
150         else
151             return "ro";
152     }
153     return "bog";
154 }
155
156 static int
157 seq_num(Chunk *c1)
158 {
159     if (c1->type == part && c1->subtype != FS_SWAP) {
160         if (rootdev_is_od == 0 && strncmp(c1->name, "od", 2) == 0)
161             return 0;
162         else if (c1->flags & CHUNK_IS_ROOT)
163             return 1;
164         else
165             return 2;
166     }
167     return 0;
168 }
169
170 int
171 configFstab(dialogMenuItem *self)
172 {
173     Device **devs;
174     Disk *disk;
175     FILE *fstab;
176     int i, cnt;
177     Chunk *c1, *c2;
178
179     if (!RunningAsInit) {
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 sysinstall then they may NOT\n"
185                        "be found by this run!");
186         }
187     }
188
189     devs = deviceFind(NULL, DEVICE_TYPE_DISK);
190     if (!devs) {
191         msgConfirm("No disks found!");
192         return DITEM_FAILURE;
193     }
194
195     /* Record all the chunks */
196     nchunks = 0;
197     for (i = 0; devs[i]; i++) {
198         if (!devs[i]->enabled)
199             continue;
200         disk = (Disk *)devs[i]->private;
201         if (!disk->chunks)
202             msgFatal("No chunk list found for %s!", disk->name);
203         for (c1 = disk->chunks->part; c1; c1 = c1->next) {
204             if (c1->type == freebsd) {
205                 for (c2 = c1->part; c2; c2 = c2->next) {
206                     if (c2->type == part && (c2->subtype == FS_SWAP || c2->private_data))
207                         chunk_list[nchunks++] = c2;
208                 }
209             }
210             else if (c1->type == fat && c1->private_data)
211                 chunk_list[nchunks++] = c1;
212         }
213     }
214     chunk_list[nchunks] = 0;
215     chunk_sort();
216     
217     fstab = fopen("/etc/fstab", "w");
218     if (!fstab) {
219         msgConfirm("Unable to create a new /etc/fstab file!  Manual intervention\n"
220                    "will be required.");
221         return DITEM_FAILURE;
222     }
223     
224     check_rootdev(chunk_list, nchunks);
225     
226     /* Go for the burn */
227     msgDebug("Generating /etc/fstab file\n");
228     fprintf(fstab, "# Device\t\tMountpoint\tFStype\tOptions\t\tDump\tPass#\n");
229     for (i = 0; i < nchunks; i++)
230         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]),
231                 fstype(chunk_list[i]), fstype_short(chunk_list[i]), seq_num(chunk_list[i]), seq_num(chunk_list[i]));
232     
233     /* Now look for the CDROMs */
234     devs = deviceFind(NULL, DEVICE_TYPE_CDROM);
235     cnt = deviceCount(devs);
236     
237     /* Write out the CDROM entries */
238     for (i = 0; i < cnt; i++) {
239         char cdname[10];
240         
241         sprintf(cdname, "/cdrom%s", i ? itoa(i) : "");
242         if (Mkdir(cdname))
243             msgConfirm("Unable to make mount point for: %s", cdname);
244         else
245             fprintf(fstab, "/dev/%s\t\t%s\tcd9660\tro,noauto\t0\t0\n", devs[i]->name, cdname);
246     }
247     
248     /* And finally, a /proc. */
249     fprintf(fstab, "proc\t\t\t/proc\t\tprocfs\trw\t\t0\t0\n");
250     Mkdir("/proc");
251
252     fclose(fstab);
253     if (isDebug())
254         msgDebug("Wrote out /etc/fstab file\n");
255     return DITEM_SUCCESS;
256 }
257
258 /* Do the work of sucking in a config file.
259  * config is the filename to read in.
260  * lines is a fixed (max) sized array of char*
261  * returns number of lines read.  line contents
262  * are malloc'd and must be freed by the caller.
263  */
264 int
265 readConfig(char *config, char **lines, int max)
266 {
267     FILE *fp;
268     char line[256];
269     int i, nlines;
270
271     fp = fopen(config, "r");
272     if (!fp)
273         return -1;
274
275     nlines = 0;
276     /* Read in the entire file */
277     for (i = 0; i < max; i++) {
278         if (!fgets(line, sizeof line, fp))
279             break;
280         lines[nlines++] = strdup(line);
281     }
282     fclose(fp);
283     if (isDebug())
284         msgDebug("readConfig: Read %d lines from %s.\n", nlines, config);
285     return nlines;
286 }
287
288 #define MAX_LINES  2000 /* Some big number we're not likely to ever reach - I'm being really lazy here, I know */
289
290 static void
291 readConfigFile(char *config, int marked)
292 {
293     char *lines[MAX_LINES], *cp, *cp2;
294     int i, nlines;
295
296     nlines = readConfig(config, lines, MAX_LINES);
297     if (nlines == -1)
298         return;
299
300     for (i = 0; i < nlines; i++) {
301         /* Skip the comments & non-variable settings */
302         if (lines[i][0] == '#' || !(cp = index(lines[i], '='))) {
303             free(lines[i]);
304             continue;
305         }
306         *cp++ = '\0';
307         /* Find quotes */
308         if ((cp2 = index(cp, '"')) || (cp2 = index(cp, '\047'))) {
309             cp = cp2 + 1;
310             cp2 = index(cp, *cp2);
311         }
312         /* If valid quotes, use it */
313         if (cp2) {
314             *cp2 = '\0';
315             /* If we have a legit value, set it */
316             if (strlen(cp))
317                 variable_set2(lines[i], cp, marked);
318         }
319         free(lines[i]);
320     }
321 }
322
323 /* Load the environment from rc.conf file(s) */
324 void
325 configEnvironmentRC_conf(void)
326 {
327     static struct {
328         char *fname;
329         int marked;
330     } configs[] = {
331         { "/etc/defaults/rc.conf", 0 },
332         { "/etc/rc.conf", 0 },
333         { "/etc/rc.conf.local", 0 },
334         { NULL, 0 },
335     };
336     int i;
337
338     for (i = 0; configs[i].fname; i++) {
339         if (file_readable(configs[i].fname))
340             readConfigFile(configs[i].fname, configs[i].marked);
341     }
342 }
343
344 /* Load the environment from a resolv.conf file */
345 void
346 configEnvironmentResolv(char *config)
347 {
348     char *lines[MAX_LINES];
349     int i, nlines;
350
351     nlines = readConfig(config, lines, MAX_LINES);
352     if (nlines == -1)
353         return;
354     for (i = 0; i < nlines; i++) {
355         Boolean name_set = (Boolean)variable_get(VAR_NAMESERVER);
356
357         if (!strncmp(lines[i], "domain", 6) && !variable_get(VAR_DOMAINNAME))
358             variable_set2(VAR_DOMAINNAME, string_skipwhite(string_prune(lines[i] + 6)), 0);
359         else if (!name_set && !strncmp(lines[i], "nameserver", 10)) {
360             /* Only take the first nameserver setting - we're lame */
361             variable_set2(VAR_NAMESERVER, string_skipwhite(string_prune(lines[i] + 10)), 0);
362         }
363         free(lines[i]);
364     }
365 }
366
367 /* Version of below for dispatch routines */
368 int
369 configRC(dialogMenuItem *unused)
370 {
371     configRC_conf();
372     return DITEM_SUCCESS;
373 }
374
375 void
376 configRC_conf(void)
377 {
378     FILE *rcSite;
379     Variable *v;
380     int write_header;
381     static int did_marker = 0;
382
383     write_header = !file_readable("/etc/rc.conf");
384     rcSite = fopen("/etc/rc.conf", "a");
385     if (!rcSite)
386         return;
387     if (write_header) {
388         fprintf(rcSite, "# This file now contains just the overrides from /etc/defaults/rc.conf\n");
389         fprintf(rcSite, "# please make all changes to this file.\n\n");
390     }
391
392     /* Now do variable substitutions */
393     for (v = VarHead; v; v = v->next) {
394         if (v->dirty) {
395             if (!did_marker) {
396                 fprintf(rcSite, "# -- sysinstall generated deltas -- #\n");
397                 did_marker = 1;
398             }
399             fprintf(rcSite, "%s=\"%s\"\n", v->name, v->value);
400             v->dirty = 0;
401         }
402     }
403     fclose(rcSite);
404 }
405
406 int
407 configSaver(dialogMenuItem *self)
408 {
409     variable_set((char *)self->data, 1);
410     if (!variable_get(VAR_BLANKTIME))
411         variable_set2(VAR_BLANKTIME, "300", 1);
412     return DITEM_SUCCESS;
413 }
414
415 int
416 configSaverTimeout(dialogMenuItem *self)
417 {
418     return (variable_get_value(VAR_BLANKTIME,
419             "Enter time-out period in seconds for screen saver", 1) ?
420         DITEM_SUCCESS : DITEM_FAILURE);
421 }
422
423 int
424 configNTP(dialogMenuItem *self)
425 {
426     int status;
427
428     status = variable_get_value(VAR_NTPDATE_FLAGS,
429                                 "Enter the name of an NTP server", 1)
430              ? DITEM_SUCCESS : DITEM_FAILURE;
431     if (status == DITEM_SUCCESS) {
432         static char tmp[255];
433
434         snprintf(tmp, sizeof(tmp), "ntpdate_enable=YES,ntpdate_flags=%s",
435                  variable_get(VAR_NTPDATE_FLAGS));
436         self->data = tmp;
437         dmenuSetVariables(self);
438     }
439     return status;
440 }
441
442 int
443 configUsers(dialogMenuItem *self)
444 {
445     WINDOW *w = savescr();
446
447     dialog_clear_norefresh();
448     dmenuOpenSimple(&MenuUsermgmt, FALSE); 
449     restorescr(w);
450     return DITEM_SUCCESS;
451 }
452
453 int
454 configLinux(dialogMenuItem *self)
455 {
456     WINDOW *w = savescr();
457     int i;
458
459     dialog_clear_norefresh();
460     variable_set2(VAR_LINUX_ENABLE, "YES", 1);
461     msgNotify("Installing Linux compatibility library...");
462     i = package_add("linux_base");
463     restorescr(w);
464     return i;
465 }
466
467 static void
468 write_root_xprofile(char *str)
469 {
470     FILE *fp;
471     int len;
472     char **cp;
473     static char *flist[] = { /* take care of both xdm and startx */
474         "/root/.xinitrc",
475         "/root/.xsession",
476         "/usr/share/skel/dot.xinitrc",
477         "/usr/share/skel/dot.xsession",
478         NULL,
479     };
480
481     len = strlen(str);
482     for (cp = flist; *cp; cp++) {
483         fp = fopen(*cp, "w");
484         if (fp) {
485             fwrite(str, 1, len, fp);
486             fchmod(fileno(fp), 0755);
487             fclose(fp);
488         }
489     }
490 }
491
492 static int
493 gotit(char *fname)
494 {
495     char tmp[FILENAME_MAX];
496
497     snprintf(tmp, sizeof tmp, "/usr/X11R6/bin/%s", fname);
498     if (file_executable(tmp))
499         return TRUE;
500     snprintf(tmp, sizeof tmp, "/usr/local/bin/%s", fname);
501     return file_executable(tmp);
502 }
503
504 int
505 configXDesktop(dialogMenuItem *self)
506 {
507     char *desk;
508     int ret = DITEM_SUCCESS;
509     WINDOW *w = savescr();
510     
511     dialog_clear_norefresh();
512     if (!dmenuOpenSimple(&MenuXDesktops, FALSE) || !(desk = variable_get(VAR_DESKSTYLE))) {
513         restorescr(w);
514         return DITEM_FAILURE;
515     }
516     if (!strcmp(desk, "kde")) {
517         ret = package_add("kde");
518         if (DITEM_STATUS(ret) != DITEM_FAILURE && gotit("startkde"))
519             write_root_xprofile("exec startkde\n");
520     }
521     else if (!strcmp(desk, "gnome")) {
522         ret = package_add("gnomecore");
523         if (DITEM_STATUS(ret) != DITEM_FAILURE && gotit("gnome-session")) {
524             ret = package_add("afterstep");
525             if (DITEM_STATUS(ret) != DITEM_FAILURE && gotit("afterstep"))
526                 write_root_xprofile("gnome-session &\nexec afterstep");
527         }
528     }
529     else if (!strcmp(desk, "enlightenment")) {
530         ret = package_add("gnomecore");
531         if (DITEM_STATUS(ret) != DITEM_FAILURE && gotit("gnome-session")) {
532             ret = package_add("enlightenment");
533             if (DITEM_STATUS(ret) != DITEM_FAILURE && gotit("enlightenment"))
534                 write_root_xprofile("exec gnome-session\n");
535         }
536     }
537     else if (!strcmp(desk, "afterstep")) {
538         ret = package_add("afterstep");
539         if (DITEM_STATUS(ret) != DITEM_FAILURE && gotit("afterstep"))
540             write_root_xprofile("xterm &\nexec afterstep\n");
541     }
542     else if (!strcmp(desk, "windowmaker")) {
543         ret = package_add("windowmaker");
544         if (DITEM_STATUS(ret) != DITEM_FAILURE && gotit("wmaker.inst")) {
545             write_root_xprofile("xterm &\n[ ! -d $HOME/GNUstep/Library/WindowMaker ] && /usr/X11R6/bin/wmaker.inst\nexec /usr/X11R6/bin/wmaker\n");
546         }
547     }
548     else if (!strcmp(desk, "fvwm2")) {
549         ret = package_add("fvwm");
550         if (DITEM_STATUS(ret) != DITEM_FAILURE && gotit("fvwm2"))
551             write_root_xprofile("xterm &\nexec fvwm2\n");
552     }
553     if (DITEM_STATUS(ret) == DITEM_FAILURE)
554         msgConfirm("An error occurred while adding the package(s) required\n"
555                    "by this desktop type.  Please change installation media\n"
556                    "and/or select a different, perhaps simpler, desktop\n"
557                    "environment and try again.");
558     restorescr(w);
559     return ret;
560 }
561
562 int
563 configXSetup(dialogMenuItem *self)
564 {
565     char *config, *execfile, *style;
566     char *moused;
567     WINDOW *w;
568     
569     setenv("XWINHOME", "/usr/X11R6", 1);
570 tryagain:
571     w = savescr();
572     variable_unset(VAR_DESKSTYLE);
573     variable_unset(VAR_XF86_CONFIG);
574     dialog_clear_norefresh();
575     if (!dmenuOpenSimple(&MenuXF86Config, FALSE)) {
576         restorescr(w);
577         return DITEM_FAILURE;
578     }
579     config = variable_get(VAR_XF86_CONFIG);
580     style = variable_get(VAR_DESKSTYLE);
581     if (!config) {
582         if (style)
583             goto config_desktop;
584         else {
585             restorescr(w);
586             return DITEM_FAILURE;
587         }
588     }
589
590     if (file_readable("/var/run/ld.so.hints"))
591         vsystem("/sbin/ldconfig -m /usr/lib /usr/X11R6/lib /usr/local/lib /usr/lib/compat");
592     else
593         vsystem("/sbin/ldconfig /usr/lib /usr/X11R6/lib /usr/local/lib /usr/lib/compat");
594     vsystem("/sbin/ldconfig -aout /usr/lib/compat/aout /usr/lib/aout /usr/X11R6/lib/aout /usr/local/lib/aout");
595     vsystem("/sbin/ifconfig lo0 127.0.0.1");
596     execfile = string_concat("/usr/X11R6/bin/", config);
597     if (file_executable(execfile)) {
598         moused = variable_get(VAR_MOUSED);
599         while (!moused || strcmp(moused, "YES")) {
600             if (msgYesNo("The X server may access the mouse in two ways: direct access\n"
601                          "or indirect access via the mouse daemon.  You have not\n"
602                          "configured the mouse daemon.  Would you like to configure it\n"
603                          "now?  If you intend to let the X server access the mouse\n"
604                          "directly, choose \"No\" at this time."))
605                 break;
606             dialog_clear_norefresh();
607             dmenuOpenSimple(&MenuMouse, FALSE); 
608             moused = variable_get(VAR_MOUSED);
609         }
610         if (moused && !strcmp(moused, "YES"))
611             msgConfirm("You have configured and are now running the mouse daemon.\n"
612                        "Choose \"/dev/sysmouse\" as the mouse port and \"SysMouse\" or\n"
613                        "\"MouseSystems\" as the mouse protocol in the X configuration\n"
614                        "utility.");
615         systemExecute(execfile);
616         if (!file_readable("/etc/XF86Config")) {
617             if (!msgYesNo("The XFree86 configuration process seems to have\nfailed.  Would you like to try again?"))
618                 goto tryagain;
619             else {
620                 restorescr(w);
621                 return DITEM_FAILURE;
622             }
623         }
624 config_desktop:
625         configXDesktop(self);
626         restorescr(w);
627         return DITEM_SUCCESS;
628     }
629     else {
630         msgConfirm("The XFree86 setup utility you chose does not appear to be installed!\n"
631                    "Please install this before attempting to configure XFree86.");
632         restorescr(w);
633         return DITEM_FAILURE;
634     }
635 }
636
637 int
638 configResolv(dialogMenuItem *ditem)
639 {
640     FILE *fp;
641     char *cp, *dp, *hp;
642
643     cp = variable_get(VAR_NAMESERVER);
644     if (!cp || !*cp)
645         goto skip;
646     Mkdir("/etc");
647     fp = fopen("/etc/resolv.conf", "w");
648     if (!fp)
649         return DITEM_FAILURE;
650     if (variable_get(VAR_DOMAINNAME))
651         fprintf(fp, "domain\t%s\n", variable_get(VAR_DOMAINNAME));
652     fprintf(fp, "nameserver\t%s\n", cp);
653     fclose(fp);
654     if (isDebug())
655         msgDebug("Wrote out /etc/resolv.conf\n");
656
657 skip:
658     dp = variable_get(VAR_DOMAINNAME);
659     cp = variable_get(VAR_IPADDR);
660     hp = variable_get(VAR_HOSTNAME);
661     /* Tack ourselves into /etc/hosts */
662     fp = fopen("/etc/hosts", "w");
663     if (!fp)
664         return DITEM_FAILURE;
665     /* Add an entry for localhost */
666     if (dp)
667         fprintf(fp, "127.0.0.1\t\tlocalhost.%s localhost\n", dp);
668     else
669         fprintf(fp, "127.0.0.1\t\tlocalhost\n");
670     /* Now the host entries, if applicable */
671     if (cp && cp[0] != '0' && hp) {
672         char cp2[255];
673
674         if (!index(hp, '.'))
675             cp2[0] = '\0';
676         else {
677             SAFE_STRCPY(cp2, hp);
678             *(index(cp2, '.')) = '\0';
679         }
680         fprintf(fp, "%s\t\t%s %s\n", cp, hp, cp2);
681         fprintf(fp, "%s\t\t%s.\n", cp, hp);
682     }
683     fclose(fp);
684     if (isDebug())
685         msgDebug("Wrote out /etc/hosts\n");
686     return DITEM_SUCCESS;
687 }
688
689 int
690 configRouter(dialogMenuItem *self)
691 {
692     int ret;
693
694     ret = variable_get_value(VAR_ROUTER,
695                              "Please specify the router you wish to use.  Routed is\n"
696                              "provided with the stock system and gated is provided\n"
697                              "as an optional package which this installation system\n"
698                              "will attempt to load if you select gated.  Any other\n"
699                              "choice of routing daemon will be assumed to be something\n"
700                              "the user intends to install themselves before rebooting\n"
701                              "the system.  If you don't want any routing daemon, choose NO", 1)
702       ? DITEM_SUCCESS : DITEM_FAILURE;
703   
704     if (ret == DITEM_SUCCESS) {
705         char *cp = variable_get(VAR_ROUTER);
706     
707         if (cp && strcmp(cp, "NO")) {
708             variable_set2(VAR_ROUTER_ENABLE, "YES", 1);
709             if (!strcmp(cp, "gated")) {
710                 if (package_add("gated") != DITEM_SUCCESS) {
711                     msgConfirm("Unable to load gated package.  Falling back to no router.");
712                     variable_unset(VAR_ROUTER);
713                     variable_unset(VAR_ROUTERFLAGS);
714                     variable_set2(VAR_ROUTER_ENABLE, "NO", 1);
715                     cp = NULL;
716                 }
717             }
718             if (cp) {
719                 /* Now get the flags, if they chose a router */
720                 ret = variable_get_value(VAR_ROUTERFLAGS, 
721                                          "Please Specify the routing daemon flags; if you're running routed\n"
722                                          "then -q is the right choice for nodes and -s for gateway hosts.\n", 1)
723                   ? DITEM_SUCCESS : DITEM_FAILURE;
724                 if (ret != DITEM_SUCCESS)
725                     variable_unset(VAR_ROUTERFLAGS);
726             }
727         }
728         else {
729             /* No router case */
730             variable_set2(VAR_ROUTER_ENABLE, "NO", 1);
731             variable_unset(VAR_ROUTERFLAGS);
732             variable_unset(VAR_ROUTER);
733         }
734     }
735     return ret;
736 }
737
738 /* Shared between us and index_initialize() */
739 extern PkgNode Top, Plist;
740
741 int
742 configPackages(dialogMenuItem *self)
743 {
744     int i;
745     PkgNodePtr tmp;
746
747     /* Did we get an INDEX? */
748     i = index_initialize("packages/INDEX");
749     if (DITEM_STATUS(i) == DITEM_FAILURE)
750         return i;
751
752     while (1) {
753         int ret, pos, scroll;
754
755         /* Bring up the packages menu */
756         pos = scroll = 0;
757         index_menu(&Top, &Top, &Plist, &pos, &scroll);
758
759         if (Plist.kids && Plist.kids->name) {
760             /* Now show the packing list menu */
761             pos = scroll = 0;
762             ret = index_menu(&Plist, &Plist, NULL, &pos, &scroll);
763             if (ret & DITEM_LEAVE_MENU)
764                 break;
765             else if (DITEM_STATUS(ret) != DITEM_FAILURE) {
766                 for (tmp = Plist.kids; tmp && tmp->name; tmp = tmp->next)
767                     (void)index_extract(mediaDevice, &Top, tmp, FALSE);
768                 break;
769             }
770         }
771         else {
772             msgConfirm("No packages were selected for extraction.");
773             break;
774         }
775     }
776     tmp = Plist.kids;
777     while (tmp) {
778         PkgNodePtr tmp2 = tmp->next;
779            
780         safe_free(tmp);
781         tmp = tmp2;
782     }
783     index_init(NULL, &Plist);
784     return DITEM_SUCCESS;
785 }
786
787 /* Load pcnfsd package */
788 int
789 configPCNFSD(dialogMenuItem *self)
790 {
791     int ret;
792
793     ret = package_add("pcnfsd");
794     if (DITEM_STATUS(ret) == DITEM_SUCCESS) {
795         variable_set2(VAR_PCNFSD, "YES", 0);
796         variable_set2("mountd_flags", "-n", 1);
797     }
798     return ret;
799 }
800
801 int
802 configNFSServer(dialogMenuItem *self)
803 {
804     char cmd[256];
805
806     /* If we're an NFS server, we need an exports file */
807     if (!file_readable("/etc/exports")) {
808         WINDOW *w = savescr();
809
810         if (file_readable("/etc/exports.disabled"))
811             vsystem("mv /etc/exports.disabled /etc/exports");
812         else {
813             dialog_clear_norefresh();
814             msgConfirm("Operating as an NFS server means that you must first configure\n"
815                        "an /etc/exports file to indicate which hosts are allowed certain\n"
816                        "kinds of access to your local file systems.\n"
817                        "Press [ENTER] now to invoke an editor on /etc/exports\n");
818             vsystem("echo '#The following examples export /usr to 3 machines named after ducks,' > /etc/exports");
819             vsystem("echo '#/home and all directories under it to machines named after dead rock stars' >> /etc/exports");
820             vsystem("echo '#and, finally, /a to 2 privileged machines allowed to write on it as root.' >> /etc/exports");
821             vsystem("echo '#/usr                huey louie dewie' >> /etc/exports");
822             vsystem("echo '#/home   -alldirs    janice jimmy frank' >> /etc/exports");
823             vsystem("echo '#/a      -maproot=0  bill albert' >> /etc/exports");
824             vsystem("echo '#' >> /etc/exports");
825             vsystem("echo '# You should replace these lines with your actual exported filesystems.' >> /etc/exports");
826             vsystem("echo >> /etc/exports");
827             sprintf(cmd, "%s /etc/exports", variable_get(VAR_EDITOR));
828             dialog_clear();
829             systemExecute(cmd);
830         }
831         variable_set2(VAR_NFS_SERVER, "YES", 1);
832         restorescr(w);
833     }
834     else if (variable_get(VAR_NFS_SERVER)) { /* We want to turn it off again? */
835         vsystem("mv -f /etc/exports /etc/exports.disabled");
836         variable_unset(VAR_NFS_SERVER);
837     }
838     return DITEM_SUCCESS;
839 }