[BACK]Return to configmenu.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / distrib / utils / sysinst

Annotation of src/distrib/utils/sysinst/configmenu.c, Revision 1.7

1.7     ! garbled     1: /* $NetBSD: configmenu.c,v 1.6 2013/03/19 22:16:53 garbled Exp $ */
1.1       riz         2:
                      3: /*-
                      4:  * Copyright (c) 2012 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Jeffrey C. Rizzo
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     20:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     21:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     22:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     23:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     24:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     25:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     26:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     27:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     28:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     29:  * POSSIBILITY OF SUCH DAMAGE.
                     30:  */
                     31:
                     32: /* configmenu.c -- post-installation system configuration menu. */
                     33:
                     34: #include <stdio.h>
                     35: #include <curses.h>
                     36: #include <unistd.h>
                     37: #include "defs.h"
                     38: #include "msg_defs.h"
                     39: #include "menu_defs.h"
                     40:
                     41:
                     42: static int set_network(struct menudesc*, void *);
                     43: static int set_timezone_menu(struct menudesc *, void *);
                     44: static int set_root_shell(struct menudesc *, void *);
                     45: static int change_root_password(struct menudesc *, void *);
1.6       garbled    46: static int add_new_user(struct menudesc *, void *);
1.1       riz        47: static int set_binpkg(struct menudesc *, void *);
                     48: static int set_pkgsrc(struct menudesc *, void *);
                     49: static void config_list_init(void);
                     50: static void get_rootsh(void);
                     51: static int toggle_rcvar(struct menudesc *, void *);
                     52: static void configmenu_hdr(struct menudesc *, void *);
                     53: static int check_root_password(void);
                     54:
                     55: char pkgpath[STRSIZE];
                     56: char pkgsrcpath[STRSIZE];
                     57:
                     58: extern const char *tz_default;
                     59:
                     60: enum {
                     61:        CONFIGOPT_NETCONF,
                     62:        CONFIGOPT_TZ,
                     63:        CONFIGOPT_ROOTSH,
                     64:        CONFIGOPT_ROOTPW,
                     65:        CONFIGOPT_BINPKG,
                     66:        CONFIGOPT_PKGSRC,
                     67:        CONFIGOPT_SSHD,
                     68:        CONFIGOPT_NTPD,
                     69:        CONFIGOPT_NTPDATE,
                     70:        CONFIGOPT_MDNSD,
1.6       garbled    71:        CONFIGOPT_ADDUSER,
1.1       riz        72:        CONFIGOPT_LAST
                     73: };
                     74:
                     75: typedef struct configinfo {
                     76:        const char      *optname;
                     77:        uint            opt;
                     78:        const char      *rcvar;
                     79:        int             (*action)(struct menudesc *, void *);
                     80:        const char      *setting;
                     81: } configinfo;
                     82:
                     83:
                     84: configinfo config_list[] = {
                     85:        {MSG_Configure_network, CONFIGOPT_NETCONF, NULL, set_network, MSG_configure},
                     86:        {MSG_timezone, CONFIGOPT_TZ, NULL, set_timezone_menu, NULL},
                     87:        {MSG_Root_shell, CONFIGOPT_ROOTSH, NULL, set_root_shell, NULL},
                     88:        {MSG_change_rootpw, CONFIGOPT_ROOTPW, NULL, change_root_password, MSG_change},
                     89:        {MSG_enable_binpkg, CONFIGOPT_BINPKG, NULL, set_binpkg, MSG_configure},
                     90:        {MSG_get_pkgsrc, CONFIGOPT_PKGSRC, NULL, set_pkgsrc, MSG_install},
                     91:        {MSG_enable_sshd, CONFIGOPT_SSHD, "sshd", toggle_rcvar, NULL},
                     92:        {MSG_enable_ntpd, CONFIGOPT_NTPD, "ntpd", toggle_rcvar, NULL},
                     93:        {MSG_run_ntpdate, CONFIGOPT_NTPDATE, "ntpdate", toggle_rcvar, NULL},
                     94:        {MSG_enable_mdnsd, CONFIGOPT_MDNSD, "mdnsd", toggle_rcvar, NULL},
1.7     ! garbled    95:        {MSG_add_a_user, CONFIGOPT_ADDUSER, NULL, add_new_user, ""},
1.1       riz        96:        {NULL,          CONFIGOPT_LAST, NULL, NULL, NULL}
                     97: };
                     98:
                     99: static void
                    100: config_list_init(void)
                    101: {
                    102:        int i;
                    103:
                    104:        for (i=0; i < CONFIGOPT_LAST; i++) {
                    105:                switch (i) {
                    106:                case CONFIGOPT_TZ:
                    107:                        get_tz_default();
                    108:                        config_list[CONFIGOPT_TZ].setting = tz_default;
                    109:                        break;
                    110:                case CONFIGOPT_ROOTSH:
                    111:                        get_rootsh();
                    112:                        break;
                    113:                case CONFIGOPT_ROOTPW:
                    114:                        if (check_root_password())
                    115:                                config_list[i].setting = MSG_password_set;
                    116:                        else
                    117:                                config_list[i].setting = MSG_empty;
                    118:                        break;
                    119:                default:
                    120:                        if (config_list[i].rcvar != NULL) {
                    121:                                if (check_rcvar(config_list[i].rcvar))
                    122:                                        config_list[i].setting = MSG_YES;
                    123:                                else
                    124:                                        config_list[i].setting = MSG_NO;
                    125:                        }
                    126:                        break;
                    127:                }
                    128:        }
                    129: }
                    130:
                    131: static void
                    132: get_rootsh(void)
                    133: {
                    134:        static char *buf = NULL;
                    135:
                    136:        if (buf != NULL)
                    137:                free(buf);
                    138:
1.5       jdf       139:        if (target_already_root())
                    140:                collect(T_OUTPUT, &buf,
                    141:                    "/usr/bin/awk -F: '$1==\"root\" { print $NF; exit }'"
                    142:                    " /etc/passwd");
                    143:        else
                    144:                collect(T_OUTPUT, &buf,
                    145:                    "chroot %s /usr/bin/awk -F: '$1==\"root\" { print $NF; exit }'"
                    146:                    " /etc/passwd",target_prefix());
1.1       riz       147:
                    148:        config_list[CONFIGOPT_ROOTSH].setting = (const char *)buf;
                    149: }
                    150:
                    151: static void
                    152: set_config(menudesc *menu, int opt, void *arg)
                    153: {
                    154:        configinfo      **configp = arg;
                    155:        configinfo      *config = configp[opt];
                    156:        const char      *optname, *setting;
                    157:
                    158:        optname = config->optname;
                    159:        setting = msg_string(config->setting);
                    160:
                    161:        wprintw(menu->mw, "%-50s %-10s", msg_string(optname), setting);
                    162: }
                    163:
                    164: static int
                    165: init_config_menu(configinfo *conf, menu_ent *me, configinfo **ce)
                    166: {
                    167:        int     opt;
                    168:        int     configopts;
                    169:
                    170:        for (configopts = 0; ; conf++) {
                    171:                opt = conf->opt;
                    172:                if (opt == CONFIGOPT_LAST)
                    173:                        break;
                    174:                *ce = conf;
                    175:                me->opt_menu = OPT_NOMENU;
                    176:                me->opt_flags = 0;
                    177:                me->opt_name = NULL;  /* NULL so set_config will draw */
                    178:                me->opt_action = conf->action;
                    179:                configopts++;
                    180:                ce++;
                    181:                me++;
                    182:        }
                    183:
                    184:        return configopts;
                    185: }
                    186:
                    187: static int
                    188: /*ARGSUSED*/
                    189: set_timezone_menu(struct menudesc *menu, void *arg)
                    190: {
                    191:        configinfo **confp = arg;
                    192:        set_timezone();
                    193:        get_tz_default();
                    194:        confp[menu->cursel]->setting = tz_default;
                    195:        return 0;
                    196: }
                    197:
                    198: static int
                    199: set_root_shell(struct menudesc *menu, void *arg)
                    200: {
                    201:        configinfo **confp = arg;
                    202:
                    203:        process_menu(MENU_rootsh, &confp[menu->cursel]->setting);
                    204:        run_program(RUN_PROGRESS | RUN_CHROOT,
                    205:                "chpass -s %s root", confp[menu->cursel]->setting);
                    206:        return 0;
                    207: }
                    208:
                    209: static int
                    210: set_network(struct menudesc *menu, void *arg)
                    211: {
                    212:        network_up = 0;
                    213:        if (config_network())
                    214:                mnt_net_config();
                    215:        return 0;
                    216: }
                    217:
                    218: static int
                    219: check_root_password(void)
                    220: {
                    221:        char *buf;
                    222:        int rval;
                    223:
1.5       jdf       224:        if (target_already_root())
                    225:                collect(T_OUTPUT, &buf, "getent passwd root | cut -d: -f2");
                    226:        else
                    227:                collect(T_OUTPUT, &buf, "chroot %s getent passwd root | "
                    228:                    "chroot %s cut -d: -f2",
                    229:                    target_prefix(), target_prefix());
1.1       riz       230:
                    231:        if (logfp)
                    232:                fprintf(logfp,"buf %s strlen(buf) %zu\n", buf, strlen(buf));
                    233:
                    234:        if (strlen(buf) <= 1)  /* newline */
                    235:                rval = 0;
                    236:        else
                    237:                rval = 1;
                    238:        free(buf);
                    239:        return rval;
                    240: }
                    241:
                    242: static int
1.6       garbled   243: add_new_user(struct menudesc *menu, void *arg)
                    244: {
                    245:        char username[STRSIZE];
                    246:        int inwheel=0;
                    247:
                    248:        msg_prompt(MSG_addusername, NULL, username, sizeof username -1);
                    249:        process_menu(MENU_yesno, deconst(MSG_addusertowheel));
                    250:        inwheel = yesno;
                    251:        ushell = "/bin/csh";
                    252:        process_menu(MENU_usersh, NULL);
                    253:        if (inwheel)
                    254:                run_program(RUN_PROGRESS | RUN_CHROOT,
                    255:                    "/usr/sbin/useradd -m -s %s -G wheel %s",
                    256:                    ushell, username);
                    257:        else
                    258:                run_program(RUN_PROGRESS | RUN_CHROOT,
                    259:                    "/usr/sbin/useradd -m -s %s %s", ushell, username);
                    260:        run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
                    261:            "passwd -l %s", username);
                    262:        return 0;
                    263: }
                    264:
                    265: static int
1.1       riz       266: change_root_password(struct menudesc *menu, void *arg)
                    267: {
                    268:        configinfo **confp = arg;
                    269:
                    270:        msg_display(MSG_rootpw);
                    271:        process_menu(MENU_yesno, NULL);
                    272:        if (yesno)
                    273:                run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
                    274:                        "passwd -l root");
                    275:        confp[menu->cursel]->setting = MSG_password_set;
                    276:        return 0;
                    277: }
                    278:
                    279: static int
                    280: set_binpkg(struct menudesc *menu, void *arg)
                    281: {
                    282:        configinfo **confp = arg;
                    283:
                    284:        char pattern[STRSIZE];
                    285:
1.3       riz       286:        /* binary pkg config requires network at this point, so if
                    287:           it's not already configured, do it. */
                    288:        if (network_up == 0) {
                    289:                if (config_network())
                    290:                        mnt_net_config();
                    291:        }
                    292:
1.1       riz       293:        process_menu(MENU_binpkg, NULL);
                    294:        make_url(pkgpath, &pkg, pkg_dir);
                    295:        if ( run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
                    296:                "pkg_add %s/pkgin", pkgpath) != 0) {
                    297:                msg_display(MSG_pkgin_failed);
                    298:                process_menu(MENU_ok, NULL);
                    299:                confp[menu->cursel]->setting = MSG_failed;
                    300:                return 0;
                    301:        }
                    302:
1.2       riz       303:        /* configure pkgin to use $pkgpath as a repository */
                    304:        snprintf(pattern, STRSIZE, "s,^[^#].*$,%s,", pkgpath);
                    305:        replace("/usr/pkg/etc/pkgin/repositories.conf", pattern);
                    306:
1.1       riz       307:        run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
1.4       riz       308:                "/usr/pkg/bin/pkgin -y update");
1.1       riz       309:
                    310:        msg_display(MSG_binpkg_installed);
                    311:        process_menu(MENU_ok, NULL);
                    312:
                    313:        confp[menu->cursel]->setting = MSG_DONE;
                    314:        return 0;
                    315: }
                    316:
                    317: static int
                    318: set_pkgsrc(struct menudesc *menu, void *arg)
                    319: {
                    320:        configinfo **confp = arg;
                    321:        distinfo dist;
                    322:
                    323:        dist.name = "pkgsrc";
                    324:        dist.set = SET_PKGSRC;
                    325:        dist.desc = "source for 3rd-party packages";
                    326:        dist.marker_file = NULL;
                    327:
                    328:        int status = SET_RETRY;
                    329:
                    330:        do {
                    331:                status = get_pkgsrc();
                    332:                if (status == SET_OK) {
                    333:                        status = extract_file(&dist, 0);
                    334:                        continue;
                    335:                } else if (status == SET_SKIP) {
                    336:                        confp[menu->cursel]->setting = MSG_abandoned;
                    337:                        return 0;
                    338:                }
                    339:                process_menu(MENU_yesno, deconst(MSG_retry_pkgsrc_network));
                    340:                if (!yesno) {
                    341:                        confp[menu->cursel]->setting = MSG_abandoned;
                    342:                        return 1;
                    343:                }
                    344:        }
                    345:        while (status == SET_RETRY);
                    346:
                    347:
                    348:        confp[menu->cursel]->setting = MSG_DONE;
                    349:        return 0;
                    350: }
                    351:
                    352: static int
                    353: toggle_rcvar(struct menudesc *menu, void *arg)
                    354: {
                    355:        configinfo **confp = arg;
                    356:        int s;
                    357:        const char *setting, *varname;
                    358:        char pattern[STRSIZE];
                    359:        char buf[STRSIZE];
                    360:        char *cp;
                    361:        int found = 0;
                    362:        FILE *fp;
                    363:
                    364:        varname = confp[menu->cursel]->rcvar;
                    365:
                    366:        s = check_rcvar(varname);
                    367:
                    368:        /* we're toggling, so invert the sense */
                    369:        if (s) {
                    370:                confp[menu->cursel]->setting = MSG_NO;
                    371:                setting = "NO";
                    372:        } else {
                    373:                confp[menu->cursel]->setting = MSG_YES;
                    374:                setting = "YES";
                    375:        }
                    376:
                    377:        if (!(fp = fopen(target_expand("/etc/rc.conf"), "r"))) {
                    378:                msg_display(MSG_rcconf_delete_failed, varname);
                    379:                process_menu(MENU_ok, NULL);
                    380:                return -1;
                    381:        }
                    382:
                    383:        while (fgets(buf, sizeof buf, fp) != NULL) {
                    384:                cp = buf + strspn(buf, " \t"); /* Skip initial spaces */
                    385:                if (strncmp(cp, varname, strlen(varname)) == 0) {
                    386:                        cp += strlen(varname);
                    387:                        if (*cp != '=')
                    388:                                continue;
                    389:                        buf[strlen(buf) - 1] = 0;
                    390:                        snprintf(pattern, sizeof pattern,
                    391:                                        "s,^%s$,%s=%s,",
                    392:                                        buf, varname, setting);
                    393:                        found = 1;
                    394:                        break;
                    395:                }
                    396:        }
                    397:
                    398:        fclose(fp);
                    399:
                    400:        if (!found) {
                    401:                add_rc_conf("%s=%s\n", varname, setting);
                    402:                if (logfp) {
                    403:                        fprintf(logfp, "adding %s=%s\n", varname, setting);
                    404:                        fflush(logfp);
                    405:                }
                    406:        } else {
                    407:                if (logfp) {
                    408:                        fprintf(logfp, "replacement pattern is %s\n", pattern);
                    409:                        fflush(logfp);
                    410:                }
                    411:                replace("/etc/rc.conf", pattern);
                    412:        }
                    413:
                    414:        return 0;
                    415: }
                    416:
                    417: static void
                    418: configmenu_hdr(struct menudesc *menu, void *arg)
                    419: {
                    420:        msg_display(MSG_configmenu);
                    421: }
                    422:
                    423: void
                    424: do_configmenu()
                    425: {
                    426:        int             menu_no;
                    427:        int             opts;
                    428:        menu_ent        me[CONFIGOPT_LAST];
                    429:        configinfo      *ce[CONFIGOPT_LAST];
                    430:
                    431:         wrefresh(curscr);
                    432:         wmove(stdscr, 0, 0);
                    433:         wclear(stdscr);
                    434:         wrefresh(stdscr);
                    435:
                    436:        /* if the target isn't mounted already, figure it out. */
                    437:        if (target_mounted() == 0) {
                    438:                if (find_disks(msg_string(MSG_configure_prior)) < 0)
                    439:                        return;
                    440:
                    441:                if (mount_disks() != 0)
                    442:                        return;
                    443:        }
                    444:
                    445:        config_list_init();
                    446:        make_url(pkgpath, &pkg, pkg_dir);
                    447:        opts = init_config_menu(config_list, me, ce);
                    448:
                    449:        menu_no = new_menu(NULL, me, opts, 0, -4, 0, 70,
                    450:                MC_SCROLL | MC_NOBOX | MC_DFLTEXIT,
                    451:                configmenu_hdr, set_config, NULL, "XXX Help String",
                    452:                MSG_doneconfig);
                    453:
                    454:        process_menu(menu_no, ce);
                    455:        free_menu(menu_no);
                    456:
                    457:        sanity_check();
                    458:
                    459: }

CVSweb <webmaster@jp.NetBSD.org>