/* $NetBSD: main.c,v 1.33 2024/02/21 20:31:57 martin Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
* All rights reserved.
*
* Written by Philip A. Nelson for Piermont Information Systems Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Piermont Information Systems Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* Put 'messages' in a window that has a one-character border
* on the real screen.
*/
mainwin = newwin(getmaxy(stdscr) - 2, getmaxx(stdscr) - 2, 1, 1);
if (mainwin == NULL) {
(void)fprintf(stderr,
"sysinst: screen too small\n");
exit(1);
}
if (has_colors()) {
start_color();
do_coloring(clr_arg.fg,clr_arg.bg);
}
msg_window(mainwin);
/* Watch for signals and clean up */
(void)atexit(cleanup);
(void)signal(SIGINT, ttysighandler);
(void)signal(SIGQUIT, ttysighandler);
(void)signal(SIGHUP, miscsighandler);
/* redraw screen */
touchwin(stdscr);
refresh();
/* Ensure we have mountpoint for target filesystems */
mkdir(targetroot_mnt, S_IRWXU | S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH);
/*
* Search for sysinstmsg.* files in the given dir, collect
* their names and return the number of files found.
* fnames[0] is preallocated and duplicates are ignored.
*/
struct found_msgs {
char **lang_msg, **fnames;
int max_lang, num_lang;
if (lang_menu != -1) {
msg_display(MSG_hello);
process_menu(lang_menu, found.fnames);
}
done:
if (lang_menu != -1)
free_menu(lang_menu);
free(opt);
for (int i = 0; i < found.num_lang; i++) {
free(found.lang_msg[i]);
free(found.fnames[i]);
}
free(found.lang_msg);
free(found.fnames);
/* set locale according to selected language */
cp = msg_string(MSG_sysinst_message_locale);
if (cp) {
setlocale(LC_CTYPE, cp);
setenv("LC_CTYPE", cp, 1);
}
}
/* toplevel menu handler ... */
void
toplevel(void)
{
/*
* Undo any stateful side-effects of previous menu choices.
* XXX must be idempotent, since we get run each time the main
* menu is displayed.
*/
char *home = getenv("HOME");
if (home != NULL)
if (chdir(home) != 0)
(void)chdir("/");
unwind_mounts();
clear_swap();
/* Display banner message in (english, francais, deutsch..) */
msg_display(MSG_hello);
msg_display_add(MSG_md_hello);
if (md_may_remove_boot_medium())
msg_display_add(MSG_md_may_remove_boot_medium);
msg_display_add(MSG_thanks);
}
/* The usage ... */
static void
usage(void)
{
(void)fprintf(stderr, "usage: sysinst [-C bg:fg] [-D"
#ifndef NO_PARTMAN
"p"
#endif
"] [-f definition_file] "
"[-m message_catalog_dir]"
"\n"
"where:\n"
"\t-C bg:fg\n\t\tuse different color scheme\n"
"\t-D\n\t\trun in debug mode\n"
"\t-f definition_file\n\t\toverride built-in defaults from file\n"
"\t-m msg_catalog_dir\n\t\tuse translation files from msg_catalog_dir\n"
#ifndef NO_PARTMAN
"\t-p\n\t\tonly run the partition editor, no installation\n"
#endif
);
/*
* we need to cleanup(), but it was already scheduled with atexit(),
* so it'll be invoked on exit().
*/
exit(1);
}
static void
ttysighandler(int signo)
{
/*
* if we want to ignore a TTY signal (SIGINT or SIGQUIT), then we
* just return. If we want to forward a TTY signal, we forward it
* to the specified process group.
*
* This functionality is used when setting up and displaying child
* output so that the child gets the signal and presumably dies,
* but sysinst continues. We use this rather than actually ignoring
* the signals, because that will be passed on to a child
* through fork/exec, whereas special handlers get reset on exec..
*/
if (ttysig_ignore)
return;
if (ttysig_forward) {
killpg(ttysig_forward, signo);
return;
}
/*
* we need to cleanup(), but it was already scheduled with atexit(),
* so it'll be invoked on exit().
*/
exit(1);
}
static void
cleanup(void)
{
time_t tloc;
(void)time(&tloc);
#if 0
restore_etc();
#endif
/* Ensure we aren't inside the target tree */
chdir(getenv("HOME"));
unwind_mounts();
umount_mnt2();
clear_swap();
/*
* return true if we do not have any root certificates installed,
* so can not verify any trust chain.
* We rely on /etc/openssl being the OPENSSLDIR and test the
* "all in one" /etc/openssl/cert.pem first, if that is not found
* check if there are multiple regular files or symlinks in
* /etc/openssl/certs/.
*/
static bool
no_openssl_trust_anchors_available(void)
{
struct stat sb;
DIR *dir;
struct dirent *ent;
size_t cnt;
/* check the omnibus single file variant first */
if (stat("/etc/openssl/cert.pem", &sb) == 0 &&
S_ISREG(sb.st_mode) && sb.st_size > 0)
return false; /* exists and is a non-empty file */
/* look for files/symlinks in the certs subdirectory */
dir = opendir("/etc/openssl/certs");
if (dir == NULL)
return true;
for (cnt = 0; cnt < 2; ) {
ent = readdir(dir);
if (ent == NULL)
break;
switch (ent->d_type) {
case DT_REG:
case DT_LNK:
cnt++;
break;
default:
break;
}
}
closedir(dir);