Annotation of src/distrib/utils/sysinst/util.c, Revision 1.117.2.4.2.1
1.117.2.4.2.1! (snj 1:: /* $NetBSD: util.c,v 1.117.2.4 2004/09/16 03:31:08 jmc Exp $ */
1.1 phil 2:
3: /*
4: * Copyright 1997 Piermont Information Systems Inc.
5: * All rights reserved.
6: *
7: * Written by Philip A. Nelson for Piermont Information Systems Inc.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
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: * 3. All advertising materials mentioning features or use of this software
18: * must display the following acknowledgement:
1.42 cgd 19: * This product includes software developed for the NetBSD Project by
1.1 phil 20: * Piermont Information Systems Inc.
21: * 4. The name of Piermont Information Systems Inc. may not be used to endorse
22: * or promote products derived from this software without specific prior
23: * written permission.
24: *
25: * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
26: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
29: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35: * THE POSSIBILITY OF SUCH DAMAGE.
36: *
37: */
38:
39: /* util.c -- routines that don't really fit anywhere else... */
40:
41: #include <stdio.h>
1.10 jonathan 42: #include <stdarg.h>
1.1 phil 43: #include <unistd.h>
1.5 phil 44: #include <sys/types.h>
1.4 phil 45: #include <sys/param.h>
46: #include <sys/sysctl.h>
1.5 phil 47: #include <sys/stat.h>
1.2 phil 48: #include <curses.h>
1.37 bouyer 49: #include <errno.h>
1.101 dsl 50: #include <dirent.h>
1.64 mrg 51: #include <util.h>
1.1 phil 52: #include "defs.h"
1.5 phil 53: #include "md.h"
1.1 phil 54: #include "msg_defs.h"
55: #include "menu_defs.h"
1.4 phil 56:
1.97 dsl 57: distinfo dist_list[] = {
58: #ifdef SET_KERNEL_1_NAME
59: {SET_KERNEL_1_NAME, SET_KERNEL_1, MSG_set_kernel_1},
60: #endif
61: #ifdef SET_KERNEL_2_NAME
62: {SET_KERNEL_2_NAME, SET_KERNEL_2, MSG_set_kernel_2},
63: #endif
64: #ifdef SET_KERNEL_3_NAME
65: {SET_KERNEL_3_NAME, SET_KERNEL_3, MSG_set_kernel_3},
66: #endif
67: #ifdef SET_KERNEL_4_NAME
68: {SET_KERNEL_4_NAME, SET_KERNEL_4, MSG_set_kernel_4},
69: #endif
70: #ifdef SET_KERNEL_5_NAME
71: {SET_KERNEL_5_NAME, SET_KERNEL_5, MSG_set_kernel_5},
72: #endif
73: #ifdef SET_KERNEL_6_NAME
74: {SET_KERNEL_6_NAME, SET_KERNEL_6, MSG_set_kernel_6},
75: #endif
76: #ifdef SET_KERNEL_7_NAME
77: {SET_KERNEL_7_NAME, SET_KERNEL_7, MSG_set_kernel_7},
78: #endif
79: #ifdef SET_KERNEL_8_NAME
80: {SET_KERNEL_8_NAME, SET_KERNEL_8, MSG_set_kernel_8},
81: #endif
82: {"base", SET_BASE, MSG_set_base},
83: {"etc", SET_ETC, MSG_set_system},
84: {"comp", SET_COMPILER, MSG_set_compiler},
85: {"games", SET_GAMES, MSG_set_games},
86: {"man", SET_MAN_PAGES, MSG_set_man_pages},
87: {"misc", SET_MISC, MSG_set_misc},
88: {"text", SET_TEXT_TOOLS, MSG_set_text_tools},
89: {NULL, SET_X11, MSG_set_X11},
90: {"xbase", SET_X11_BASE, MSG_set_X11_base},
1.116 lukem 91: {"xcomp", SET_X11_PROG, MSG_set_X11_prog},
1.117 lukem 92: {"xetc", SET_X11_ETC, MSG_set_X11_etc},
1.97 dsl 93: {"xfont", SET_X11_FONTS, MSG_set_X11_fonts},
94: {"xserver", SET_X11_SERVERS, MSG_set_X11_servers},
95: #ifdef SET_MD_1_NAME
96: {SET_MD_1_NAME, SET_MD_1, MSG_set_md_1},
97: #endif
98: #ifdef SET_MD_2_NAME
99: {SET_MD_2_NAME, SET_MD_2, MSG_set_md_2},
100: #endif
101: #ifdef SET_MD_3_NAME
102: {SET_MD_3_NAME, SET_MD_3, MSG_set_md_3},
103: #endif
104: #ifdef SET_MD_4_NAME
105: {SET_MD_4_NAME, SET_MD_4, MSG_set_md_4},
106: #endif
107: {NULL, 0, NULL},
108: };
109:
1.14 jonathan 110: /*
111: * local prototypes
112: */
1.29 mrg 113: struct tarstats {
1.22 jonathan 114: int nselected;
115: int nfound;
116: int nnotfound;
117: int nerror;
118: int nsuccess;
1.44 cgd 119: int nskipped;
1.22 jonathan 120: } tarstats;
121:
1.117.2.4.2.1! (snj 122:: static int extract_file(int, int, int, char *path);
! 123:: static int extract_dist(int, int);
1.104 dsl 124: int distribution_sets_exist_p(const char *path);
125: static int check_for(unsigned int mode, const char *pathname);
1.4 phil 126:
1.97 dsl 127: #ifndef MD_SETS_SELECTED
128: #define MD_SETS_SELECTED (SET_KERNEL_1 | SET_SYSTEM | SET_X11 | SET_MD)
129: #endif
130: #ifndef MD_SETS_VALID
131: #define MD_SETS_VALID (SET_KERNEL | SET_SYSTEM | SET_X11 | SET_MD)
132: #endif
133:
134: unsigned int sets_valid = MD_SETS_VALID;
135: unsigned int sets_selected = (MD_SETS_SELECTED) & (MD_SETS_VALID);
1.104 dsl 136: unsigned int sets_installed = 0;
1.97 dsl 137:
1.29 mrg 138: int
1.96 dsl 139: dir_exists_p(const char *path)
1.22 jonathan 140: {
1.96 dsl 141:
1.54 fvdl 142: return file_mode_match(path, S_IFDIR);
143: }
1.29 mrg 144:
1.54 fvdl 145: int
1.96 dsl 146: file_exists_p(const char *path)
1.54 fvdl 147: {
1.96 dsl 148:
1.54 fvdl 149: return file_mode_match(path, S_IFREG);
1.22 jonathan 150: }
151:
1.29 mrg 152: int
1.96 dsl 153: file_mode_match(const char *path, unsigned int mode)
1.22 jonathan 154: {
1.54 fvdl 155: struct stat st;
1.29 mrg 156:
1.54 fvdl 157: return (stat(path, &st) == 0 && (st.st_mode & mode) != 0);
1.22 jonathan 158: }
159:
1.29 mrg 160: int
1.96 dsl 161: distribution_sets_exist_p(const char *path)
1.22 jonathan 162: {
163: char buf[STRSIZE];
164: int result;
165:
166: result = 1;
1.92 dsl 167: snprintf(buf, sizeof buf, "%s/%s", path, "etc.tgz");
1.59 hubertf 168: result = result && file_exists_p(buf);
169:
1.92 dsl 170: snprintf(buf, sizeof buf, "%s/%s", path, "base.tgz");
1.62 jdc 171: result = result && file_exists_p(buf);
172:
1.117.2.3 tron 173: if (result == 0) {
174: msg_display(MSG_badsetdir, path);
175: process_menu(MENU_ok, NULL);
176: }
177:
178: return result;
1.22 jonathan 179: }
180:
181:
1.117.2.4.2.1! (snj 182:: uint
1.96 dsl 183: get_ramsize(void)
1.4 phil 184: {
1.117.2.4.2.1! (snj 185:: uint64_t ramsize;
! 186:: size_t len = sizeof ramsize;
! 187:: int mib[2] = {CTL_HW, HW_PHYSMEM64};
1.4 phil 188:
1.78 christos 189: sysctl(mib, 2, &ramsize, &len, NULL, 0);
1.4 phil 190:
191: /* Find out how many Megs ... round up. */
1.117.2.4.2.1! (snj 192:: return (ramsize + MEG - 1) / MEG;
1.1 phil 193: }
194:
1.29 mrg 195: void
1.96 dsl 196: run_makedev(void)
1.3 phil 197: {
1.22 jonathan 198: char *owd;
199:
1.117.2.4.2.1! (snj 200:: msg_display_add("\n\n");
! 201:: msg_display_add(MSG_makedev);
1.14 jonathan 202:
1.78 christos 203: owd = getcwd(NULL, 0);
1.22 jonathan 204:
1.14 jonathan 205: /* make /dev, in case the user didn't extract it. */
206: make_target_dir("/dev");
1.10 jonathan 207: target_chdir_or_die("/dev");
1.115 dsl 208: run_program(0, "/bin/sh MAKEDEV all");
1.22 jonathan 209:
210: chdir(owd);
211: free(owd);
1.5 phil 212: }
213:
214:
1.29 mrg 215: /*
216: * Load files from floppy. Requires a /mnt2 directory for mounting them.
217: */
218: int
1.96 dsl 219: get_via_floppy(void)
1.5 phil 220: {
1.117.2.4.2.1! (snj 221:: char fddev[STRSIZE];
1.5 phil 222: char fname[STRSIZE];
1.78 christos 223: char full_name[STRSIZE];
1.34 garbled 224: char catcmd[STRSIZE];
1.7 phil 225: distinfo *list;
1.5 phil 226: char post[4];
1.8 phil 227: int first;
1.5 phil 228: struct stat sb;
229:
1.117.2.4.2.1! (snj 230:: (void)strlcpy(fddev, "/dev/fd0a", STRSIZE);
1.29 mrg 231: cd_dist_dir("unloading from floppy");
1.7 phil 232:
1.29 mrg 233: msg_prompt_add(MSG_fddev, fddev, fddev, STRSIZE);
1.5 phil 234:
235: list = dist_list;
1.97 dsl 236: while (list->desc) {
237: if (list->name == NULL) {
238: list++;
239: continue;
240: }
1.29 mrg 241: strcpy(post, ".aa");
1.97 dsl 242: while (sets_selected & list->set) {
1.92 dsl 243: snprintf(fname, sizeof fname, "%s%s", list->name, post);
244: snprintf(full_name, sizeof full_name, "/mnt2/%s",
245: fname);
1.8 phil 246: first = 1;
1.112 dsl 247: while (!mnt2_mounted || stat(full_name, &sb)) {
248: umount_mnt2();
1.8 phil 249: if (first)
1.29 mrg 250: msg_display(MSG_fdmount, fname);
1.8 phil 251: else
1.29 mrg 252: msg_display(MSG_fdnotfound, fname);
1.94 dsl 253: process_menu(MENU_fdok, NULL);
1.8 phil 254: if (!yesno)
255: return 0;
1.89 jmmv 256: else if (yesno == 2)
257: return 1;
1.115 dsl 258: while (run_program(0,
1.35 bouyer 259: "/sbin/mount -r -t %s %s /mnt2",
1.29 mrg 260: fdtype, fddev)) {
261: msg_display(MSG_fdremount, fname);
1.94 dsl 262: process_menu(MENU_fdremount, NULL);
1.5 phil 263: if (!yesno)
264: return 0;
1.112 dsl 265: if (yesno == 2)
1.89 jmmv 266: return 1;
1.5 phil 267: }
1.112 dsl 268: mnt2_mounted = 1;
1.8 phil 269: first = 0;
1.5 phil 270: }
1.111 itojun 271: snprintf(catcmd, sizeof(catcmd), "/bin/cat %s >> %s%s",
1.104 dsl 272: full_name, list->name, dist_postfix);
1.34 garbled 273: if (logging)
1.76 fvdl 274: (void)fprintf(logfp, "%s\n", catcmd);
1.34 garbled 275: if (scripting)
276: (void)fprintf(script, "%s\n", catcmd);
277: do_system(catcmd);
1.8 phil 278: if (post[2] < 'z')
279: post[2]++;
1.5 phil 280: else
1.29 mrg 281: post[2] = 'a', post[1]++;
1.5 phil 282: }
1.112 dsl 283: umount_mnt2();
1.5 phil 284: list++;
285: }
286: #ifndef DEBUG
1.10 jonathan 287: chdir("/"); /* back to current real root */
1.5 phil 288: #endif
1.6 phil 289: return 1;
290: }
291:
1.29 mrg 292: /*
293: * Get from a CDROM distribution.
294: */
1.6 phil 295: int
1.96 dsl 296: get_via_cdrom(void)
1.6 phil 297: {
1.28 fvdl 298:
299: /* Get CD-rom device name and path within CD-rom */
1.94 dsl 300: process_menu(MENU_cdromsource, NULL);
1.6 phil 301:
1.112 dsl 302: umount_mnt2();
1.22 jonathan 303:
1.6 phil 304: /* Mount it */
1.117.2.3 tron 305: for (;;) {
306: if (run_program(0, "/sbin/mount -rt cd9660 /dev/%s /mnt2",
307: cdrom_dev) == 0)
1.112 dsl 308: break;
1.94 dsl 309: process_menu(MENU_cdrombadmount, NULL);
1.6 phil 310: if (!yesno)
1.117.2.3 tron 311: return -1;
1.22 jonathan 312: }
1.112 dsl 313: mnt2_mounted = 1;
1.22 jonathan 314:
1.117.2.3 tron 315: snprintf(ext_dir, sizeof ext_dir, "%s/%s", "/mnt2", set_dir);
1.22 jonathan 316:
317: /* Verify distribution files exist. */
1.117.2.3 tron 318: if (distribution_sets_exist_p(ext_dir) == 0)
319: return -1;
1.6 phil 320:
321: /* return location, don't clean... */
322: clean_dist_dir = 0;
1.5 phil 323: return 1;
1.7 phil 324: }
325:
1.22 jonathan 326:
327: /*
328: * Get from a pathname inside an unmounted local filesystem
329: * (e.g., where sets were preloaded onto a local DOS partition)
330: */
1.29 mrg 331: int
1.96 dsl 332: get_via_localfs(void)
1.16 mhitch 333: {
1.22 jonathan 334:
1.16 mhitch 335: /* Get device, filesystem, and filepath */
1.94 dsl 336: process_menu (MENU_localfssource, NULL);
1.16 mhitch 337:
1.22 jonathan 338: again:
1.112 dsl 339: umount_mnt2();
1.22 jonathan 340:
1.16 mhitch 341: /* Mount it */
1.115 dsl 342: if (run_program(0, "/sbin/mount -rt %s /dev/%s /mnt2",
1.35 bouyer 343: localfs_fs, localfs_dev)) {
1.22 jonathan 344:
1.29 mrg 345: msg_display(MSG_localfsbadmount, localfs_dir, localfs_dev);
1.94 dsl 346: process_menu(MENU_localfsbadmount, NULL);
1.16 mhitch 347: if (!yesno)
348: return 0;
1.22 jonathan 349: if (!ignorerror)
1.29 mrg 350: goto again;
1.22 jonathan 351: }
1.112 dsl 352: mnt2_mounted = 1;
1.22 jonathan 353:
1.117.2.3 tron 354: snprintf(ext_dir, sizeof ext_dir, "%s/%s/%s",
355: "/mnt2", localfs_dir, set_dir);
1.22 jonathan 356:
357: /* Verify distribution files exist. */
1.117.2.3 tron 358: if (distribution_sets_exist_p(ext_dir) == 0)
359: return -1;
1.16 mhitch 360:
361: /* return location, don't clean... */
362: clean_dist_dir = 0;
363: return 1;
364: }
1.7 phil 365:
1.29 mrg 366: /*
367: * Get from an already-mounted pathname.
368: */
1.22 jonathan 369:
1.99 dsl 370: int
371: get_via_localdir(void)
1.22 jonathan 372: {
373:
1.117.2.3 tron 374: /* Get filepath */
1.94 dsl 375: process_menu(MENU_localdirsource, NULL);
1.22 jonathan 376:
1.117.2.3 tron 377: /*
378: * We have to have an absolute path ('cos pax runs in a
379: * different directory), make it so.
380: */
381: snprintf(ext_dir, sizeof ext_dir, "/%s/%s", localfs_dir, set_dir);
382:
383: if (distribution_sets_exist_p(ext_dir) == 0)
384: return -1;
1.22 jonathan 385:
386: /* return location, don't clean... */
387: clean_dist_dir = 0;
388: return 1;
389: }
390:
391:
1.29 mrg 392: void
1.107 dsl 393: cd_dist_dir(const char *forwhat)
1.7 phil 394: {
1.19 phil 395:
1.10 jonathan 396: /* ask user for the mountpoint. */
1.29 mrg 397: msg_prompt(MSG_distdir, dist_dir, dist_dir, STRSIZE, forwhat);
1.10 jonathan 398:
399: /* make sure the directory exists. */
400: make_target_dir(dist_dir);
1.7 phil 401:
402: clean_dist_dir = 1;
1.10 jonathan 403: target_chdir_or_die(dist_dir);
1.19 phil 404:
405: /* Set ext_dir for absolute path. */
1.103 dsl 406: getcwd(ext_dir, sizeof ext_dir);
1.7 phil 407: }
408:
1.10 jonathan 409:
1.29 mrg 410: /*
411: * Support for custom distribution fetches / unpacks.
412: */
1.97 dsl 413:
414: typedef struct {
415: distinfo *dist;
416: unsigned int sets;
417: struct info {
418: unsigned int set;
419: char label[44];
420: } i[32];
421: } set_menu_info_t;
422:
423: static int
1.108 dsl 424: set_toggle(menudesc *menu, void *arg)
1.97 dsl 425: {
426: set_menu_info_t *i = arg;
1.108 dsl 427: int set = i->i[menu->cursel].set;
1.97 dsl 428:
429: if (set & SET_KERNEL)
430: /* only one kernel set is allowed */
1.101 dsl 431: sets_selected &= ~SET_KERNEL | set;
1.97 dsl 432: sets_selected ^= set;
433: return 0;
434: }
435:
436: static int
1.108 dsl 437: set_all(menudesc *menu, void *arg)
1.97 dsl 438: {
439: set_menu_info_t *i = arg;
440:
441: sets_selected |= i->sets;
1.101 dsl 442: return 1;
1.97 dsl 443: }
444:
445: static int
1.108 dsl 446: set_none(menudesc *menu, void *arg)
1.29 mrg 447: {
1.97 dsl 448: set_menu_info_t *i = arg;
1.7 phil 449:
1.97 dsl 450: sets_selected &= ~i->sets;
1.101 dsl 451: return 1;
1.7 phil 452: }
453:
1.108 dsl 454: static int set_sublist(menudesc *menu, void *arg);
1.97 dsl 455:
456: static void
457: set_selected_sets(menudesc *menu, void *arg)
1.7 phil 458: {
459: distinfo *list;
1.97 dsl 460: static const char *yes, *no, *all, *some, *none;
461: const char *selected;
462: menu_ent *m;
463: set_menu_info_t *menu_info = arg;
464: struct info *i = menu_info->i;
465: unsigned int set;
466:
467: if (yes == NULL) {
1.100 dsl 468: yes = msg_string(MSG_Yes);
469: no = msg_string(MSG_No);
470: all = msg_string(MSG_All);
471: some = msg_string(MSG_Some);
472: none = msg_string(MSG_None);
1.97 dsl 473: }
1.7 phil 474:
1.29 mrg 475: msg_display(MSG_cur_distsets);
1.48 cgd 476: msg_table_add(MSG_cur_distsets_header);
1.97 dsl 477:
478: m = menu->opts;
479: for (list = menu_info->dist; list->desc; list++) {
480: if (!(menu_info->sets & list->set))
481: break;
482: if (!(sets_valid & list->set))
483: continue;
484: i->set = list->set;
485: m->opt_menu = OPT_NOMENU;
486: m->opt_flags = 0;
487: m->opt_name = i->label;
488: m->opt_action = set_toggle;
489: if (list->set & (list->set - 1)) {
490: /* multiple bits possible */
491: set = list->set & sets_valid;
492: selected = (set & sets_selected) == 0 ? none :
493: (set & sets_selected) == set ? all : some;
494: } else {
495: selected = list->set & sets_selected ? yes : no;;
496: }
497: snprintf(i->label, sizeof i->label,
498: msg_string(MSG_cur_distsets_row),
499: msg_string(list->desc), selected);
500: m++;
501: i++;
502: if (list->name != NULL)
503: continue;
504: m[-1].opt_action = set_sublist;
505: /* collapsed sublist */
506: set = list->set;
507: while (list[1].set & set)
508: list++;
509: }
510:
511: if (menu_info->sets == ~0u)
512: return;
513:
514: m->opt_menu = OPT_NOMENU;
515: m->opt_flags = 0;
516: m->opt_name = MSG_select_all;
517: m->opt_action = set_all;
518: m++;
519: m->opt_menu = OPT_NOMENU;
520: m->opt_flags = 0;
521: m->opt_name = MSG_select_none;
522: m->opt_action = set_none;
523: }
524:
525: static int
1.108 dsl 526: set_sublist(menudesc *menu, void *arg)
1.97 dsl 527: {
528: distinfo *list;
529: menu_ent me[32];
530: set_menu_info_t set_menu_info;
531: int sets;
532: int menu_no;
533: unsigned int set;
534: set_menu_info_t *i = arg;
535:
1.108 dsl 536: set = i->i[menu->cursel].set;
1.97 dsl 537: set_menu_info.sets = set;
538:
539: /* Count number of entries we require */
540: for (list = dist_list; list->set != set; list++)
541: if (list->desc == NULL)
542: return 0;
543: set_menu_info.dist = ++list;
544: for (sets = 2; list->set & set; list++)
545: if (sets_valid & list->set)
546: sets++;
547:
548: if (sets > nelem(me)) {
549: /* panic badly */
550: return 0;
551: }
552:
553: menu_no = new_menu(NULL, me, sets, 20, 10, 0, 44,
1.117.2.4.2.1! (snj 554:: MC_SUBMENU | MC_SCROLL | MC_DFLTEXIT,
1.101 dsl 555: set_selected_sets, NULL, NULL, NULL, MSG_install_selected_sets);
1.97 dsl 556:
557: if (menu_no == -1)
558: return 0;
559:
560: process_menu(menu_no, &set_menu_info);
561: free_menu(menu_no);
562:
563: return 0;
564: }
565:
566: void
567: customise_sets(void)
568: {
569: distinfo *list;
570: menu_ent me[32];
571: set_menu_info_t set_menu_info;
572: int sets;
573: int menu_no;
574: unsigned int set, valid = 0;
575:
576: /* Count number of entries we require */
577: for (sets = 0, list = dist_list; list->desc != NULL; list++) {
578: if (!(sets_valid & list->set))
579: continue;
580: sets++;
581: if (list->name != NULL) {
582: valid |= list->set;
583: continue;
584: }
585: /* collapsed sublist */
586: set = list->set;
587: while (list[1].set & set) {
588: valid |= list[1].set;
589: list++;
590: }
1.7 phil 591: }
1.97 dsl 592: if (sets > nelem(me)) {
593: /* panic badly */
594: return;
595: }
596:
597: /* Static initialisation is lazy, fix it now */
598: sets_valid &= valid;
599: sets_selected &= valid;
600:
601: menu_no = new_menu(NULL, me, sets, 0, 5, 0, 44,
602: MC_SCROLL | MC_NOBOX | MC_DFLTEXIT | MC_NOCLEAR,
1.101 dsl 603: set_selected_sets, NULL, NULL, NULL, MSG_install_selected_sets);
1.97 dsl 604:
605: if (menu_no == -1)
606: return;
607:
608: set_menu_info.dist = dist_list;
609: set_menu_info.sets = ~0u;
610: process_menu(menu_no, &set_menu_info);
611: free_menu(menu_no);
1.1 phil 612: }
1.10 jonathan 613:
1.117.2.4.2.1! (snj 614:: static int
1.117.2.3 tron 615: ask_verbose_dist(msg setup_done)
1.12 phil 616: {
1.117.2.4.2.1! (snj 617:: int verbose = 0;
1.29 mrg 618:
1.117.2.3 tron 619: wclear(stdscr);
620: wrefresh(stdscr);
621: if (setup_done != NULL)
622: msg_display(setup_done);
623: msg_display_add(MSG_verboseextract);
624: process_menu(MENU_extract, &verbose);
625: wclear(stdscr);
626: wrefresh(stdscr);
1.117.2.4.2.1! (snj 627::
! 628:: return verbose;
1.12 phil 629: }
630:
1.112 dsl 631: static int
1.117.2.4.2.1! (snj 632:: extract_file(int set, int update, int verbose, char *path)
1.12 phil 633: {
634: char *owd;
1.112 dsl 635: int tarexit;
1.12 phil 636:
1.104 dsl 637: owd = getcwd(NULL, 0);
1.12 phil 638:
1.22 jonathan 639: /* check tarfile exists */
640: if (!file_exists_p(path)) {
641: tarstats.nnotfound++;
1.44 cgd 642:
643: msg_display(MSG_notarfile, path);
1.117.2.3 tron 644: process_menu(MENU_noyes, deconst(MSG_notarfile_ok));
1.112 dsl 645: return yesno;
1.22 jonathan 646: }
647:
648: tarstats.nfound++;
1.14 jonathan 649: /* cd to the target root. */
1.117.2.2 he 650: if (update && set == SET_ETC) {
651: make_target_dir("/.sysinst");
652: target_chdir_or_die("/.sysinst");
653: } else
654: target_chdir_or_die("/");
1.12 phil 655:
1.117.2.4.2.1! (snj 656:: /* now extract set files into "./". */
1.117.2.3 tron 657: if (verbose == 0)
1.115 dsl 658: tarexit = run_program(RUN_DISPLAY | RUN_PROGRESS,
1.117.2.4.2.1! (snj 659:: "progress -zf %s tar --chroot -xhepf -", path);
1.117.2.3 tron 660: else if (verbose == 1)
1.115 dsl 661: tarexit = run_program(RUN_DISPLAY,
1.117.2.4.2.1! (snj 662:: "tar --chroot -zxhepf %s", path);
! 663:: else
! 664:: tarexit = run_program(RUN_DISPLAY | RUN_PROGRESS,
! 665:: "tar --chroot -zxhvepf %s", path);
1.22 jonathan 666:
1.112 dsl 667: chdir(owd);
668: free(owd);
669:
1.17 phil 670: /* Check tarexit for errors and give warning. */
1.22 jonathan 671: if (tarexit) {
672: tarstats.nerror++;
1.44 cgd 673: msg_display(MSG_tarerror, path);
1.94 dsl 674: process_menu(MENU_noyes, NULL);
1.112 dsl 675: return yesno;
1.22 jonathan 676: }
1.44 cgd 677:
1.117.2.2 he 678: if (update && set == SET_ETC) {
679: run_program(RUN_DISPLAY | RUN_CHROOT,
1.117.2.4.2.1! (snj 680:: "/usr/sbin/postinstall -s /.sysinst -d / fix");
1.117.2.2 he 681: }
682:
1.112 dsl 683: tarstats.nsuccess++;
684: return 2;
1.12 phil 685: }
686:
1.19 phil 687:
1.29 mrg 688: /*
1.37 bouyer 689: * Extract_dist **REQUIRES** an absolute path in ext_dir. Any code
1.19 phil 690: * that sets up dist_dir for use by extract_dist needs to put in the
691: * full path name to the directory.
692: */
693:
1.112 dsl 694: static int
1.117.2.4.2.1! (snj 695:: extract_dist(int update, int verbose)
1.12 phil 696: {
697: char fname[STRSIZE];
698: distinfo *list;
1.112 dsl 699: int extracted;
1.12 phil 700:
1.22 jonathan 701: /* reset failure/success counters */
1.31 perry 702: memset(&tarstats, 0, sizeof(tarstats));
1.22 jonathan 703:
1.32 garbled 704: /*endwin();*/
1.112 dsl 705: for (extracted = 2, list = dist_list; list->desc != NULL; list++) {
1.97 dsl 706: if (list->name == NULL)
707: continue;
1.112 dsl 708: if (!(sets_selected & list->set))
709: continue;
710: tarstats.nselected++;
711: if (extracted == 0) {
712: tarstats.nskipped++;
713: continue;
714: }
715: (void)snprintf(fname, sizeof fname, "%s/%s%s",
716: ext_dir, list->name, dist_postfix);
1.44 cgd 717:
1.112 dsl 718: /* if extraction failed and user aborted, punt. */
1.117.2.4.2.1! (snj 719:: extracted = extract_file(list->set, update, verbose, fname);
1.112 dsl 720: if (extracted == 2)
721: sets_installed |= list->set;
1.12 phil 722: }
1.22 jonathan 723:
1.63 jdc 724: wrefresh(curscr);
1.60 jdc 725: wmove(stdscr, 0, 0);
1.43 cgd 726: wclear(stdscr);
1.17 phil 727: wrefresh(stdscr);
1.22 jonathan 728:
729: if (tarstats.nerror == 0 && tarstats.nsuccess == tarstats.nselected) {
1.29 mrg 730: msg_display(MSG_endtarok);
1.117.2.4.2.1! (snj 731:: /* Give user a chance to see the success message */
! 732:: sleep(1);
1.22 jonathan 733: return 0;
734: }
1.112 dsl 735: /* We encountered errors. Let the user know. */
736: msg_display(MSG_endtar,
737: tarstats.nselected, tarstats.nnotfound, tarstats.nskipped,
738: tarstats.nfound, tarstats.nsuccess, tarstats.nerror);
739: process_menu(MENU_ok, NULL);
1.117.2.4.2.1! (snj 740:: msg_clear();
1.112 dsl 741: return extracted == 0;
1.12 phil 742: }
743:
1.37 bouyer 744: /*
1.29 mrg 745: * Get and unpack the distribution.
1.112 dsl 746: * Show success_msg if installation completes.
747: * Otherwise show failure_msg and wait for the user to ack it before continuing.
1.11 jonathan 748: * success_msg and failure_msg must both be 0-adic messages.
749: */
1.45 cgd 750: int
1.117.2.3 tron 751: get_and_unpack_sets(int update, msg setupdone_msg, msg success_msg, msg failure_msg)
1.11 jonathan 752: {
1.112 dsl 753: int got_dist;
1.117.2.4.2.1! (snj 754:: int verbose;
! 755:: distinfo *list;
1.29 mrg 756:
1.20 jonathan 757: /* Ensure mountpoint for distribution files exists in current root. */
1.112 dsl 758: (void)mkdir("/mnt2", S_IRWXU| S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH);
1.32 garbled 759: if (scripting)
760: (void)fprintf(script, "mkdir /mnt2\nchmod 755 /mnt2\n");
1.20 jonathan 761:
1.26 phil 762: /* Find out which files to "get" if we get files. */
763:
1.37 bouyer 764: /* ask user whether to do normal or verbose extraction */
1.117.2.4.2.1! (snj 765:: verbose = ask_verbose_dist(setupdone_msg);
1.37 bouyer 766:
1.117.2.3 tron 767: again:
1.11 jonathan 768: /* Get the distribution files */
1.46 cgd 769: do {
1.112 dsl 770: process_menu(MENU_distmedium, &got_dist);
1.46 cgd 771: } while (got_dist == -1);
1.26 phil 772:
1.112 dsl 773: if (got_dist == -2)
1.45 cgd 774: return 1;
1.20 jonathan 775:
1.112 dsl 776: if (got_dist != 1) {
777: msg_display(failure_msg);
778: process_menu(MENU_ok, NULL);
779: return 1;
780: }
1.11 jonathan 781:
1.117.2.3 tron 782: /* Extract the distribution, retry from top on errors. */
1.117.2.4.2.1! (snj 783:: if (extract_dist(update, verbose))
1.117.2.3 tron 784: goto again;
1.11 jonathan 785:
1.112 dsl 786: /* Configure the system */
1.117.2.4.2.1! (snj 787:: if (sets_installed & SET_BASE)
1.112 dsl 788: run_makedev();
1.11 jonathan 789:
1.117.2.4.2.1! (snj 790:: /* Save keybard type */
! 791:: save_kb_encoding();
! 792::
1.112 dsl 793: /* Other configuration. */
794: mnt_net_config();
795:
796: /* Clean up dist dir (use absolute path name) */
1.117.2.4.2.1! (snj 797:: if (clean_dist_dir) {
! 798:: msg_display(MSG_delete_dist_files, dist_dir);
! 799:: process_menu(MENU_yesno, deconst(MSG_Delete));
! 800:: if (yesno) {
! 801:: for (list = dist_list; list->desc != NULL; list++) {
! 802:: if (list->name == NULL)
! 803:: /* menu entry for a group of sets */
! 804:: continue;
! 805:: run_program(0, "/bin/rm -f %s/%s/%s%s",
! 806:: target_prefix(), dist_dir,
! 807:: list->name, dist_postfix);
! 808:: }
! 809:: /* chroot 'cos no rmdir in install fs */
! 810:: run_program(RUN_CHROOT | RUN_SILENT | RUN_ERROR_OK,
! 811:: "/bin/rmdir %s", dist_dir);
! 812:: }
1.112 dsl 813: }
1.14 jonathan 814:
1.112 dsl 815: /* Mounted dist dir? */
816: umount_mnt2();
1.22 jonathan 817:
1.112 dsl 818: /* Install/Upgrade complete ... reboot or exit to script */
819: msg_display(success_msg);
1.94 dsl 820: process_menu(MENU_ok, NULL);
1.112 dsl 821: return 0;
1.14 jonathan 822: }
1.22 jonathan 823:
1.112 dsl 824: void
825: umount_mnt2(void)
826: {
827: if (!mnt2_mounted)
828: return;
1.115 dsl 829: run_program(RUN_SILENT, "/sbin/umount /mnt2");
1.112 dsl 830: mnt2_mounted = 0;
831: }
1.22 jonathan 832:
1.14 jonathan 833:
834: /*
835: * Do a quick sanity check that the target can reboot.
836: * return 1 if everything OK, 0 if there is a problem.
837: * Uses a table of files we expect to find after a base install/upgrade.
838: */
839:
840: /* test flag and pathname to check for after unpacking. */
1.54 fvdl 841: struct check_table { unsigned int mode; const char *path;} checks[] = {
842: { S_IFREG, "/netbsd" },
843: { S_IFDIR, "/etc" },
844: { S_IFREG, "/etc/fstab" },
845: { S_IFREG, "/sbin/init" },
846: { S_IFREG, "/bin/sh" },
847: { S_IFREG, "/etc/rc" },
848: { S_IFREG, "/etc/rc.subr" },
849: { S_IFREG, "/etc/rc.conf" },
850: { S_IFDIR, "/dev" },
851: { S_IFCHR, "/dev/console" },
1.14 jonathan 852: /* XXX check for rootdev in target /dev? */
1.54 fvdl 853: { S_IFREG, "/etc/fstab" },
854: { S_IFREG, "/sbin/fsck" },
855: { S_IFREG, "/sbin/fsck_ffs" },
856: { S_IFREG, "/sbin/mount" },
857: { S_IFREG, "/sbin/mount_ffs" },
858: { S_IFREG, "/sbin/mount_nfs" },
1.20 jonathan 859: #if defined(DEBUG) || defined(DEBUG_CHECK)
1.54 fvdl 860: { S_IFREG, "/foo/bar" }, /* bad entry to exercise warning */
1.14 jonathan 861: #endif
862: { 0, 0 }
863:
864: };
865:
866: /*
867: * Check target for a single file.
868: */
1.29 mrg 869: static int
1.96 dsl 870: check_for(unsigned int mode, const char *pathname)
1.14 jonathan 871: {
1.18 jonathan 872: int found;
1.14 jonathan 873:
1.54 fvdl 874: found = (target_test(mode, pathname) == 0);
1.18 jonathan 875: if (found == 0)
1.14 jonathan 876: msg_display(MSG_rootmissing, pathname);
1.18 jonathan 877: return found;
1.14 jonathan 878: }
879:
1.25 jonathan 880: /*
881: * Check that all the files in check_table are present in the
882: * target root. Warn if not found.
883: */
1.14 jonathan 884: int
1.96 dsl 885: sanity_check(void)
1.14 jonathan 886: {
887: int target_ok = 1;
888: struct check_table *p;
889:
890: for (p = checks; p->path; p++) {
1.54 fvdl 891: target_ok = target_ok && check_for(p->mode, p->path);
1.14 jonathan 892: }
893: if (target_ok)
894: return 0;
895:
896: /* Uh, oh. Something's missing. */
897: msg_display(MSG_badroot);
1.94 dsl 898: process_menu(MENU_ok, NULL);
1.14 jonathan 899: return 1;
1.11 jonathan 900: }
1.32 garbled 901:
1.52 hubertf 902: /*
903: * Some globals to pass things back from callbacks
904: */
905: static char zoneinfo_dir[STRSIZE];
1.101 dsl 906: static int zonerootlen;
907: static char *tz_selected; /* timezonename (relative to share/zoneinfo */
1.91 dsl 908: static const char *tz_default; /* UTC, or whatever /etc/localtime points to */
1.52 hubertf 909: static char tz_env[STRSIZE];
1.101 dsl 910: static int save_cursel, save_topline;
1.52 hubertf 911:
912: /*
913: * Callback from timezone menu
914: */
915: static int
1.108 dsl 916: set_tz_select(menudesc *m, void *arg)
1.52 hubertf 917: {
918: time_t t;
1.101 dsl 919: char *new;
1.52 hubertf 920:
1.110 dsl 921: if (m && strcmp(tz_selected, m->opts[m->cursel].opt_name) != 0) {
1.117.2.4.2.1! (snj 922:: /* Change the displayed timezone */
1.101 dsl 923: new = strdup(m->opts[m->cursel].opt_name);
924: if (new == NULL)
925: return 0;
926: free(tz_selected);
927: tz_selected = new;
1.110 dsl 928: snprintf(tz_env, sizeof tz_env, "%.*s%s",
929: zonerootlen, zoneinfo_dir, tz_selected);
930: setenv("TZ", tz_env, 1);
1.101 dsl 931: }
1.117.2.4.2.1! (snj 932:: if (m)
! 933:: /* Warp curser to 'Exit' line on menu */
! 934:: m->cursel = -1;
! 935::
! 936:: /* Update displayed time */
1.52 hubertf 937: t = time(NULL);
938: msg_display(MSG_choose_timezone,
939: tz_default, tz_selected, ctime(&t), localtime(&t)->tm_zone);
940: return 0;
941: }
942:
1.101 dsl 943: static int
1.108 dsl 944: set_tz_back(menudesc *m, void *arg)
1.101 dsl 945: {
946:
947: zoneinfo_dir[zonerootlen] = 0;
948: m->cursel = save_cursel;
949: m->topline = save_topline;
950: return 0;
951: }
952:
953: static int
1.108 dsl 954: set_tz_dir(menudesc *m, void *arg)
1.101 dsl 955: {
956:
957: strlcpy(zoneinfo_dir + zonerootlen, m->opts[m->cursel].opt_name,
958: sizeof zoneinfo_dir - zonerootlen);
959: save_cursel = m->cursel;
960: save_topline = m->topline;
961: m->cursel = 0;
962: m->topline = 0;
963: return 0;
964: }
965:
1.52 hubertf 966: /*
967: * Alarm-handler to update example-display
968: */
969: static void
1.78 christos 970: /*ARGSUSED*/
1.52 hubertf 971: timezone_sig(int sig)
972: {
1.96 dsl 973:
1.108 dsl 974: set_tz_select(NULL, NULL);
1.74 grant 975: alarm(60);
1.52 hubertf 976: }
977:
1.101 dsl 978: static int
979: tz_sort(const void *a, const void *b)
980: {
1.107 dsl 981: return strcmp(((const menu_ent *)a)->opt_name, ((const menu_ent *)b)->opt_name);
1.101 dsl 982: }
983:
984: static void
985: tzm_set_names(menudesc *m, void *arg)
986: {
987: DIR *dir;
988: struct dirent *dp;
989: static int nfiles;
990: static int maxfiles = 32;
991: static menu_ent *tz_menu;
992: static char **tz_names;
993: void *p;
994: int maxfname;
995: char *fp;
996: struct stat sb;
997:
998: if (tz_menu == NULL)
999: tz_menu = malloc(maxfiles * sizeof *tz_menu);
1000: if (tz_names == NULL)
1001: tz_names = malloc(maxfiles * sizeof *tz_names);
1002: if (tz_menu == NULL || tz_names == NULL)
1003: return; /* error - skip timezone setting */
1004: while (nfiles > 0)
1005: free(tz_names[--nfiles]);
1006:
1007: dir = opendir(zoneinfo_dir);
1008: fp = strchr(zoneinfo_dir, 0);
1009: if (fp != zoneinfo_dir + zonerootlen) {
1010: tz_names[0] = 0;
1.102 dsl 1011: tz_menu[0].opt_name = msg_string(MSG_tz_back);
1.101 dsl 1012: tz_menu[0].opt_menu = OPT_NOMENU;
1013: tz_menu[0].opt_flags = 0;
1014: tz_menu[0].opt_action = set_tz_back;
1015: nfiles = 1;
1016: }
1017: maxfname = zoneinfo_dir + sizeof zoneinfo_dir - fp - 1;
1018: if (dir != NULL) {
1019: while ((dp = readdir(dir)) != NULL) {
1020: if (dp->d_namlen > maxfname || dp->d_name[0] == '.')
1021: continue;
1022: strlcpy(fp, dp->d_name, maxfname);
1023: if (stat(zoneinfo_dir, &sb) == -1)
1024: continue;
1025: if (nfiles >= maxfiles) {
1026: p = realloc(tz_menu, 2 * maxfiles * sizeof *tz_menu);
1027: if (p == NULL)
1028: break;
1029: tz_menu = p;
1030: p = realloc(tz_names, 2 * maxfiles * sizeof *tz_names);
1031: if (p == NULL)
1032: break;
1033: tz_names = p;
1034: maxfiles *= 2;
1035: }
1036: if (S_ISREG(sb.st_mode))
1037: tz_menu[nfiles].opt_action = set_tz_select;
1038: else if (S_ISDIR(sb.st_mode)) {
1039: tz_menu[nfiles].opt_action = set_tz_dir;
1.111 itojun 1040: strlcat(fp, "/",
1041: sizeof(zoneinfo_dir) - (fp - zoneinfo_dir));
1.101 dsl 1042: } else
1043: continue;
1044: tz_names[nfiles] = strdup(zoneinfo_dir + zonerootlen);
1045: tz_menu[nfiles].opt_name = tz_names[nfiles];
1046: tz_menu[nfiles].opt_menu = OPT_NOMENU;
1047: tz_menu[nfiles].opt_flags = 0;
1048: nfiles++;
1049: }
1050: closedir(dir);
1051: }
1052: *fp = 0;
1053:
1054: m->opts = tz_menu;
1055: m->numopts = nfiles;
1056: qsort(tz_menu, nfiles, sizeof *tz_menu, tz_sort);
1057: }
1058:
1.52 hubertf 1059: /*
1060: * Choose from the files in usr/share/zoneinfo and set etc/localtime
1061: */
1062: int
1.96 dsl 1063: set_timezone(void)
1.52 hubertf 1064: {
1065: char localtime_link[STRSIZE];
1066: char localtime_target[STRSIZE];
1067: int rc;
1068: time_t t;
1069: int menu_no;
1070:
1.101 dsl 1071: strlcpy(zoneinfo_dir, target_expand("/usr/share/zoneinfo/"),
1072: sizeof zoneinfo_dir - 1);
1073: zonerootlen = strlen(zoneinfo_dir);
1.92 dsl 1074: strlcpy(localtime_link, target_expand("/etc/localtime"),
1075: sizeof localtime_link);
1.52 hubertf 1076:
1077: /* Add sanity check that /mnt/usr/share/zoneinfo contains
1.101 dsl 1078: * something useful
1079: */
1.52 hubertf 1080:
1081: rc = readlink(localtime_link, localtime_target,
1.75 provos 1082: sizeof(localtime_target) - 1);
1.52 hubertf 1083: if (rc < 0) {
1.53 hubertf 1084: /* error, default to UTC */
1085: tz_default = "UTC";
1086: } else {
1087: localtime_target[rc] = '\0';
1.92 dsl 1088: tz_default = strchr(strstr(localtime_target, "zoneinfo"), '/') + 1;
1.52 hubertf 1089: }
1090:
1.101 dsl 1091: tz_selected = strdup(tz_default);
1092: snprintf(tz_env, sizeof(tz_env), "%s%s", zoneinfo_dir, tz_selected);
1.52 hubertf 1093: setenv("TZ", tz_env, 1);
1094: t = time(NULL);
1095: msg_display(MSG_choose_timezone,
1096: tz_default, tz_selected, ctime(&t), localtime(&t)->tm_zone);
1097:
1.101 dsl 1098: signal(SIGALRM, timezone_sig);
1099: alarm(60);
1.52 hubertf 1100:
1.101 dsl 1101: menu_no = new_menu(NULL, NULL, 14, 23, 9,
1.112 dsl 1102: 12, 32, MC_ALWAYS_SCROLL | MC_NOSHORTCUT,
1.101 dsl 1103: tzm_set_names, NULL, NULL,
1.95 dsl 1104: "\nPlease consult the install documents.", NULL);
1.92 dsl 1105: if (menu_no < 0)
1106: goto done; /* error - skip timezone setting */
1.101 dsl 1107:
1.94 dsl 1108: process_menu(menu_no, NULL);
1.52 hubertf 1109:
1110: free_menu(menu_no);
1111:
1112: signal(SIGALRM, SIG_IGN);
1113:
1114: snprintf(localtime_target, sizeof(localtime_target),
1115: "/usr/share/zoneinfo/%s", tz_selected);
1116: unlink(localtime_link);
1117: symlink(localtime_target, localtime_link);
1118:
1.92 dsl 1119: done:
1.52 hubertf 1120: return 1;
1.66 ad 1121: }
1122:
1123: int
1124: set_crypt_type(void)
1125: {
1126: FILE *pwc;
1127: char *fn;
1128:
1129: msg_display(MSG_choose_crypt);
1.94 dsl 1130: process_menu(MENU_crypttype, NULL);
1.66 ad 1131: fn = strdup(target_expand("/etc/passwd.conf"));
1.80 christos 1132: if (fn == NULL)
1133: return -1;
1.66 ad 1134:
1.68 itojun 1135: switch (yesno) {
1.69 itojun 1136: case 0:
1137: break;
1138: case 1: /* DES */
1139: rename(fn, target_expand("/etc/passwd.conf.pre-sysinst"));
1140: pwc = fopen(fn, "w");
1141: fprintf(pwc,
1142: "default:\n"
1.70 enami 1143: " localcipher = old\n"
1144: " ypcipher = old\n");
1.69 itojun 1145: fclose(pwc);
1146: break;
1147: case 2: /* MD5 */
1148: rename(fn, target_expand("/etc/passwd.conf.pre-sysinst"));
1.66 ad 1149: pwc = fopen(fn, "w");
1150: fprintf(pwc,
1151: "default:\n"
1152: " localcipher = md5\n"
1153: " ypcipher = md5\n");
1154: fclose(pwc);
1.68 itojun 1155: break;
1.69 itojun 1156: case 3: /* blowfish 2^7 */
1157: rename(fn, target_expand("/etc/passwd.conf.pre-sysinst"));
1.68 itojun 1158: pwc = fopen(fn, "w");
1159: fprintf(pwc,
1160: "default:\n"
1161: " localcipher = blowfish,7\n"
1162: " ypcipher = blowfish,7\n");
1163: fclose(pwc);
1164: break;
1.66 ad 1165: }
1166:
1.67 ad 1167: free(fn);
1.66 ad 1168: return (0);
1.56 fvdl 1169: }
1170:
1171: int
1.96 dsl 1172: set_root_password(void)
1.56 fvdl 1173: {
1.96 dsl 1174:
1.56 fvdl 1175: msg_display(MSG_rootpw);
1.94 dsl 1176: process_menu(MENU_yesno, NULL);
1.56 fvdl 1177: if (yesno)
1.117.2.4.2.1! (snj 1178:: run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
! 1179:: "passwd -l root");
1.73 grant 1180: return 0;
1181: }
1182:
1183: int
1.96 dsl 1184: set_root_shell(void)
1.73 grant 1185: {
1.117.2.4.2.1! (snj 1186:: const char *shellpath;
1.96 dsl 1187:
1.73 grant 1188: msg_display(MSG_rootsh);
1.117.2.4.2.1! (snj 1189:: process_menu(MENU_rootsh, &shellpath);
! 1190:: run_program(RUN_DISPLAY | RUN_CHROOT, "chpass -s %s root", shellpath);
1.56 fvdl 1191: return 0;
1.64 mrg 1192: }
1193:
1194: void
1195: scripting_vfprintf(FILE *f, const char *fmt, va_list ap)
1196: {
1.96 dsl 1197:
1.64 mrg 1198: if (f)
1199: (void)vfprintf(f, fmt, ap);
1200: if (scripting)
1201: (void)vfprintf(script, fmt, ap);
1202: }
1203:
1204: void
1205: scripting_fprintf(FILE *f, const char *fmt, ...)
1206: {
1207: va_list ap;
1208:
1209: va_start(ap, fmt);
1210: scripting_vfprintf(f, fmt, ap);
1211: va_end(ap);
1212: }
1213:
1214: void
1215: add_rc_conf(const char *fmt, ...)
1216: {
1217: FILE *f;
1218: va_list ap;
1219:
1220: va_start(ap, fmt);
1221: f = target_fopen("/etc/rc.conf", "a");
1222: if (f != 0) {
1223: scripting_fprintf(NULL, "cat <<EOF >>%s/etc/rc.conf\n",
1224: target_prefix());
1225: scripting_vfprintf(f, fmt, ap);
1226: fclose(f);
1227: scripting_fprintf(NULL, "EOF\n");
1228: }
1229: va_end(ap);
1.112 dsl 1230: }
1231:
1232: void
1233: enable_rc_conf(void)
1234: {
1235: const char *tp = target_prefix();
1236:
1.115 dsl 1237: run_program(0, "sed -an -e 's/^rc_configured=NO/rc_configured=YES/;"
1.112 dsl 1238: "H;$!d;g;w %s/etc/rc.conf' %s/etc/rc.conf",
1239: tp, tp);
1.64 mrg 1240: }
1241:
1242: int
1.96 dsl 1243: check_lfs_progs(void)
1.64 mrg 1244: {
1245:
1246: return (access("/sbin/dump_lfs", X_OK) == 0 &&
1247: access("/sbin/fsck_lfs", X_OK) == 0 &&
1248: access("/sbin/mount_lfs", X_OK) == 0 &&
1249: access("/sbin/newfs_lfs", X_OK) == 0);
1.32 garbled 1250: }
CVSweb <webmaster@jp.NetBSD.org>