version 1.6, 1997/10/20 06:13:42 |
version 1.6.2.5, 1997/11/11 00:47:38 |
|
|
/* util.c -- routines that don't really fit anywhere else... */ |
/* util.c -- routines that don't really fit anywhere else... */ |
|
|
#include <stdio.h> |
#include <stdio.h> |
|
#include <stdarg.h> |
#include <unistd.h> |
#include <unistd.h> |
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/param.h> |
#include <sys/param.h> |
|
|
#include "msg_defs.h" |
#include "msg_defs.h" |
#include "menu_defs.h" |
#include "menu_defs.h" |
|
|
|
/* |
|
* local prototypes |
|
*/ |
|
static int check_for __P((const char *type, const char *pathname)); |
|
|
|
|
void get_ramsize(void) |
void get_ramsize(void) |
{ |
{ |
Line 65 void get_ramsize(void) |
|
Line 71 void get_ramsize(void) |
|
|
|
static int asked = 0; |
static int asked = 0; |
|
|
void ask_sizemult () |
void ask_sizemult (void) |
{ |
{ |
if (!asked) { |
if (!asked) { |
msg_display (MSG_sizechoice, dlcylsize); |
msg_display (MSG_sizechoice, dlcylsize); |
Line 74 void ask_sizemult () |
|
Line 80 void ask_sizemult () |
|
asked = 1; |
asked = 1; |
} |
} |
|
|
|
void reask_sizemult (void) |
|
{ |
|
asked = 0; |
|
ask_sizemult (); |
|
} |
|
|
/* Returns 1 for "y" or "Y" and "n" otherwise. CR => default. */ |
/* Returns 1 for "y" or "Y" and "n" otherwise. CR => default. */ |
int |
int |
ask_ynquestion (char *quest, char def, ...) |
ask_ynquestion (char *quest, char def, ...) |
Line 86 ask_ynquestion (char *quest, char def, . |
|
Line 98 ask_ynquestion (char *quest, char def, . |
|
vsnprintf (line, STRSIZE, quest, ap); |
vsnprintf (line, STRSIZE, quest, ap); |
va_end(ap); |
va_end(ap); |
|
|
printf ("%s [%c]: ", line, def); |
if (def) |
|
printf ("%s [%c]: ", line, def); |
|
else |
|
printf ("%s: ", line); |
c = getchar(); |
c = getchar(); |
if (c == '\n') |
if (c == '\n') |
return def == 'y'; |
return def == 'y'; |
Line 96 ask_ynquestion (char *quest, char def, . |
|
Line 111 ask_ynquestion (char *quest, char def, . |
|
return c == 'y' || c == 'Y'; |
return c == 'y' || c == 'Y'; |
} |
} |
|
|
void |
|
extract_dist (void) |
|
{ |
|
int verbose; |
|
int numchar; |
|
char *files; |
|
char *p; |
|
|
|
msg_display (MSG_verboseextract); |
|
process_menu (MENU_noyes); |
|
verbose = yesno; |
|
|
|
numchar = collect (T_OUTPUT, &files, "/bin/ls %s/*.tar.gz", dist_dir); |
|
if (numchar < 0) { |
|
endwin(); |
|
(void)fprintf (stderr, msg_string(MSG_badls)); |
|
exit(1); |
|
} |
|
files[numchar] = '\0'; |
|
|
|
#ifndef DEBUG |
|
if (chdir("/mnt")) { |
|
endwin(); |
|
(void)fprintf(stderr, msg_string(MSG_realdir), "/mnt"); |
|
exit(1); |
|
} |
|
#else |
|
printf ("chdir (%s)\n", "/mnt"); |
|
#endif |
|
|
|
endwin(); |
|
p = strtok (files, " \n"); |
|
while (p != NULL) { |
|
(void)printf (msg_string(MSG_extracting), p); |
|
run_prog ("/usr/bin/tar --unlink -xpz%s -f %s", |
|
verbose ? "v":"", p); |
|
p= strtok (NULL, " \n"); |
|
} |
|
(void)printf(msg_string(MSG_endtar)); |
|
getchar(); |
|
puts(CL); |
|
wrefresh(stdscr); |
|
} |
|
|
|
|
|
void run_makedev (void) |
void run_makedev (void) |
{ |
{ |
msg_display (MSG_makedev); |
msg_display (MSG_makedev); |
sleep (1); |
sleep (1); |
#ifndef DEBUG |
|
if (chdir("/mnt/dev")) { |
/* make /dev, in case the user didn't extract it. */ |
endwin(); |
make_target_dir("/dev"); |
(void)fprintf(stderr, msg_string(MSG_realdir), "/mnt"); |
target_chdir_or_die("/dev"); |
exit(1); |
|
} |
|
#else |
|
printf ("chdir (%s)\n", "/mnt/dev"); |
|
#endif |
|
run_prog ("/bin/sh MAKEDEV all"); |
run_prog ("/bin/sh MAKEDEV all"); |
} |
} |
|
|
|
|
/* Load files from floppy. */ |
/* Load files from floppy. Requires a /mnt2 directory for mounting them. */ |
int get_via_floppy (void) |
int get_via_floppy (void) |
{ |
{ |
char realdir[STRSIZE]; |
|
char distname[STRSIZE]; |
char distname[STRSIZE]; |
char fddev[STRSIZE] = "/dev/fd0a"; |
char fddev[STRSIZE] = "/dev/fd0a"; |
char dirname[STRSIZE]; |
|
char fname[STRSIZE]; |
char fname[STRSIZE]; |
char fullname[STRSIZE]; |
char fullname[STRSIZE]; |
char **list; |
distinfo *list; |
char **last; |
|
char post[4]; |
char post[4]; |
int mounted = 0; |
int mounted = 0; |
|
int first; |
struct stat sb; |
struct stat sb; |
|
|
msg_prompt (MSG_distdir, dist_dir, dist_dir, STRSIZE, |
|
"unloading from floppy"); |
cd_dist_dir ("unloading from floppy"); |
if (*dist_dir == '/') |
|
snprintf (realdir, STRSIZE, "/mnt%s", dist_dir); |
|
else |
|
snprintf (realdir, STRSIZE, "/mnt/%s", dist_dir); |
|
strcpy (dist_dir, realdir); |
|
run_prog ("/bin/mkdir %s", realdir); |
|
clean_dist_dir = 1; |
|
#ifndef DEBUG |
|
if (chdir(realdir)) { |
|
endwin(); |
|
(void)fprintf(stderr, msg_string(MSG_realdir), realdir); |
|
exit(1); |
|
} |
|
#else |
|
printf ("chdir (%s)\n", realdir); |
|
#endif |
|
|
|
msg_prompt_add (MSG_fddev, fddev, fddev, STRSIZE); |
msg_prompt_add (MSG_fddev, fddev, fddev, STRSIZE); |
|
|
list = dist_list; |
list = dist_list; |
last = fd_last; |
while (list->name) { |
while (*last) { |
|
strcpy (post, ".aa"); |
strcpy (post, ".aa"); |
snprintf (dirname, STRSIZE, *list, rels, "/" ); |
snprintf (distname, STRSIZE, list->name, rels, dist_postfix); |
snprintf (distname, STRSIZE, *list, rels, dist_postfix); |
while (list->getit && strcmp(&post[1],list->fdlast) <= 0) { |
msg_display (MSG_fdload, dirname); |
snprintf (fname, STRSIZE, list->name, rels, post); |
process_menu (MENU_yesno); |
snprintf (fullname, STRSIZE, "/mnt2/%s", fname); |
while (yesno && strcmp(post,*last) <= 0) { |
first = 1; |
snprintf (fname, STRSIZE, *list, rels, post); |
|
snprintf (fullname, STRSIZE, "/mnt2/%s%s", dirname, |
|
fname); |
|
while (!mounted || stat(fullname, &sb)) { |
while (!mounted || stat(fullname, &sb)) { |
if (mounted) |
if (mounted) |
run_prog ("/sbin/umount /mnt2"); |
run_prog ("/sbin/umount /mnt2 " |
msg_display (MSG_fdmount, dirname, fname); |
"2>/dev/null"); |
process_menu (MENU_ok); |
if (first) |
while (!run_prog("/sbin/mount -t %s %s /mnt2", |
msg_display (MSG_fdmount, fname); |
|
else |
|
msg_display (MSG_fdnotfound, fname); |
|
process_menu (MENU_fdok); |
|
if (!yesno) |
|
return 0; |
|
while (run_prog("/sbin/mount -t %s %s /mnt2", |
fdtype, fddev)) { |
fdtype, fddev)) { |
msg_display (MSG_fdremount, dirname, |
msg_display (MSG_fdremount, fname); |
fname); |
|
process_menu (MENU_fdremount); |
process_menu (MENU_fdremount); |
if (!yesno) |
if (!yesno) |
return 0; |
return 0; |
} |
} |
mounted = 1; |
mounted = 1; |
|
first = 0; |
} |
} |
run_prog ("/bin/cat /mnt2/%s >> %s", fullname, |
run_prog ("/bin/cat %s >> %s", fullname, distname); |
distname); |
if (post[2] < 'z') |
if (post[1] < 'z') |
post[2]++; |
post[1]++; |
|
else |
else |
post[1]='a', post[2]++; |
post[2]='a', post[1]++; |
} |
} |
run_prog ("/sbin/umount /mnt2"); |
run_prog ("/sbin/umount /mnt2 2>/dev/null"); |
mounted = 0; |
mounted = 0; |
list++; |
list++; |
last++; |
|
} |
} |
#ifndef DEBUG |
#ifndef DEBUG |
chdir("/"); |
chdir("/"); /* back to current real root */ |
#endif |
#endif |
return 1; |
return 1; |
} |
} |
|
|
|
/* Get from a CDROM distribution. */ |
|
|
int |
int |
get_via_cdrom(void) |
get_via_cdrom(void) |
{ |
{ |
/* Get server and filepath */ |
/* Get server and filepath */ |
process_menu (MENU_cdromsource); |
process_menu (MENU_cdromsource); |
|
|
|
/* Fill in final default path. */ |
|
strncat (cdrom_dir, rels, STRSIZE-strlen(cdrom_dir)); |
|
strcat (cdrom_dir, "/"); |
|
strncat (cdrom_dir, machine, STRSIZE-strlen(cdrom_dir)); |
|
|
/* Mount it */ |
/* Mount it */ |
while (!run_prog ("/sbin/mount -rt cd9660 %s /mnt2", cdrom_dev)) { |
while (run_prog ("/sbin/mount -rt cd9660 /dev/%sa /mnt2", cdrom_dev)) { |
process_menu (MENU_cdrombadmount); |
process_menu (MENU_cdrombadmount); |
if (!yesno) |
if (!yesno) |
return 0; |
return 0; |
Line 254 get_via_cdrom(void) |
|
Line 208 get_via_cdrom(void) |
|
} |
} |
|
|
/* return location, don't clean... */ |
/* return location, don't clean... */ |
strcpy (dist_dir, "/mnt2"); |
strcpy (ext_dir, "/mnt2"); |
strncat (dist_dir, cdrom_dir, STRSIZE-strlen(dist_dir)-1); |
strncat (ext_dir, cdrom_dir, STRSIZE-strlen(ext_dir)-1); |
clean_dist_dir = 0; |
clean_dist_dir = 0; |
mnt2_mounted = 1; |
mnt2_mounted = 1; |
return 1; |
return 1; |
} |
} |
|
|
|
int |
|
get_via_localfs(void) |
|
{ |
|
/* Get device, filesystem, and filepath */ |
|
process_menu (MENU_localfssource); |
|
|
|
/* Mount it */ |
|
while (run_prog ("/sbin/mount -rt %s /dev/%s /mnt2", localfs_fs, |
|
localfs_dev)) { |
|
process_menu (MENU_localfsbadmount); |
|
if (!yesno) |
|
return 0; |
|
/* Verify distribution files exist. XXX */ |
|
} |
|
|
|
/* return location, don't clean... */ |
|
strcpy (ext_dir, "/mnt2"); |
|
strncat (ext_dir, localfs_dir, STRSIZE-strlen(ext_dir)-1); |
|
clean_dist_dir = 0; |
|
mnt2_mounted = 1; |
|
return 1; |
|
} |
|
|
|
void cd_dist_dir (char *forwhat) |
|
{ |
|
char *cwd; |
|
|
|
/* ask user for the mountpoint. */ |
|
msg_prompt (MSG_distdir, dist_dir, dist_dir, STRSIZE, forwhat); |
|
|
|
/* make sure the directory exists. */ |
|
make_target_dir(dist_dir); |
|
|
|
clean_dist_dir = 1; |
|
target_chdir_or_die(dist_dir); |
|
|
|
/* Set ext_dir for absolute path. */ |
|
cwd = getcwd (NULL,0); |
|
strncpy (ext_dir, cwd, STRSIZE); |
|
free (cwd); |
|
} |
|
|
|
|
|
/* Support for custom distribution fetches / unpacks. */ |
|
|
|
void toggle_getit (int num) |
|
{ |
|
dist_list[num].getit ^= 1; |
|
} |
|
|
|
void show_cur_distsets (void) |
|
{ |
|
distinfo *list; |
|
|
|
msg_display (MSG_cur_distsets); |
|
list = dist_list; |
|
while (list->name) { |
|
msg_printf_add ("%s%s\n", list->desc, list->getit ? |
|
msg_string(MSG_yes) : msg_string(MSG_no)); |
|
list++; |
|
} |
|
} |
|
|
|
|
|
/* Do we want a verbose extract? */ |
|
static int verbose = -1; |
|
|
|
void |
|
ask_verbose_dist (void) |
|
{ |
|
if (verbose < 0) { |
|
msg_display (MSG_verboseextract); |
|
process_menu (MENU_noyes); |
|
verbose = yesno; |
|
} |
|
} |
|
|
|
void |
|
extract_file (char *path) |
|
{ |
|
char *owd; |
|
int tarexit; |
|
|
|
owd = getcwd (NULL,0); |
|
|
|
/* cd to the target root. */ |
|
target_chdir_or_die("/"); |
|
|
|
/* now extract set files files into "./". */ |
|
(void)printf (msg_string(MSG_extracting), path); |
|
tarexit = run_prog ("/usr/bin/tar --unlink -xpz%s -f %s", |
|
verbose ? "v":"", path); |
|
/* Check tarexit for errors and give warning. */ |
|
if (tarexit) |
|
ask_ynquestion (msg_string(MSG_tarerror), 0, path); |
|
|
|
chdir (owd); |
|
free (owd); |
|
} |
|
|
|
|
|
/* Extract_dist **REQUIRES** an absolute path in ext_dir. Any code |
|
* that sets up dist_dir for use by extract_dist needs to put in the |
|
* full path name to the directory. |
|
*/ |
|
|
|
void |
|
extract_dist (void) |
|
{ |
|
char distname[STRSIZE]; |
|
char fname[STRSIZE]; |
|
distinfo *list; |
|
|
|
endwin(); |
|
list = dist_list; |
|
while (list->name) { |
|
if (list->getit) { |
|
(void)snprintf (distname, STRSIZE, list->name, rels, |
|
dist_postfix); |
|
(void)snprintf (fname, STRSIZE, "%s/%s", ext_dir, |
|
distname); |
|
extract_file (fname); |
|
} |
|
list++; |
|
} |
|
puts(CL); |
|
wrefresh(stdscr); |
|
} |
|
|
|
|
|
/* |
|
* Get and unpack the distribution. |
|
* show success_msg if installation completes. Otherwise,, |
|
* sHow failure_msg and wait for the user to ack it before continuing. |
|
* success_msg and failure_msg must both be 0-adic messages. |
|
*/ |
|
void get_and_unpack_sets(int success_msg, int failure_msg) |
|
{ |
|
/* Get the distribution files */ |
|
process_menu (MENU_distmedium); |
|
if (nodist) |
|
return; |
|
|
|
ask_verbose_dist (); |
|
|
|
if (got_dist) { |
|
/* Extract the distribution */ |
|
extract_dist (); |
|
|
|
/* Configure the system */ |
|
run_makedev (); |
|
|
|
/* Other configuration. */ |
|
mnt_net_config(); |
|
|
|
/* Clean up dist dir (use absolute path name) */ |
|
if (clean_dist_dir) |
|
run_prog ("/bin/rm -rf %s", ext_dir); |
|
|
|
/* Mounted dist dir? */ |
|
if (mnt2_mounted) |
|
run_prog ("/sbin/umount /mnt2"); |
|
|
|
/* Install/Upgrade complete ... reboot or exit to script */ |
|
msg_display (success_msg); |
|
process_menu (MENU_ok); |
|
} else { |
|
msg_display (failure_msg); |
|
process_menu (MENU_ok); |
|
} |
|
} |
|
|
|
/* |
|
* Do a quick sanity check that the target can reboot. |
|
* return 1 if everything OK, 0 if there is a problem. |
|
* Uses a table of files we expect to find after a base install/upgrade. |
|
*/ |
|
|
|
|
|
|
|
/* test flag and pathname to check for after unpacking. */ |
|
struct check_table { const char *testarg; const char *path;} checks[] = { |
|
{ "-f", "/netbsd" }, |
|
{ "-d ""/etc" }, |
|
{ "-f", "/etc/fstab" }, |
|
{ "-f", "/sbin/init" }, |
|
{ "-f", "/bin/sh" }, |
|
{ "-d" "/dev" }, |
|
{ "-c", "/dev/console" }, |
|
/* XXX check for rootdev in target /dev? */ |
|
{ "-f", "/etc/fstab" }, |
|
{ "-f", "/sbin/fsck" }, |
|
{ "-f", "/sbin/fsck_ffs" }, |
|
{ "-f", "/sbin/mount" }, |
|
{ "-f", "/sbin/mount_ffs" }, |
|
{ "-f", "/sbin/mount_nfs" }, |
|
#if defined(DEBUG) || 1 |
|
{ "-f", "/foo/bar" }, /* XXX */ |
|
#endif |
|
{ 0, 0 } |
|
|
|
}; |
|
|
|
|
|
/* |
|
* Check target for a single file. |
|
*/ |
|
static int check_for(const char *type, const char *pathname) |
|
{ |
|
int found; |
|
|
|
found = (target_test(type, pathname) == 0); |
|
if (found == 0) |
|
msg_display(MSG_rootmissing, pathname); |
|
return found; |
|
} |
|
|
|
int |
|
sanity_check() |
|
{ |
|
|
|
int target_ok = 1; |
|
struct check_table *p; |
|
|
|
for (p = checks; p->path; p++) { |
|
target_ok = target_ok && check_for(p->testarg, p->path); |
|
} |
|
if (target_ok) |
|
return 0; |
|
|
|
/* Uh, oh. Something's missing. */ |
|
msg_display(MSG_badroot); |
|
process_menu(MENU_ok); |
|
return 1; |
|
} |